From 51b8aafd3beb8855a258383a9eb876a783375629 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Fri, 9 Jun 2017 15:17:05 +0100 Subject: Fix HClinitCheck elimination in instruction builder. To handle escaping instances of erroneous classes correctly, we can omit the HClinitCheck only when using a class in the static method of the very same class. Even for superclasses we need to do the check. The new test exposes the cases where we were previously diverging from the RI. Also clean up the CompilerDriver by inlining one function directly to the HInstructionBuild::IsInitialized(.) and removing some related functions that are no longer used. The size of the aosp_taimen-userdebug prebuilts: - before: arm/boot*.oat: 16891788 arm64/boot*.oat: 19815520 oat/arm64/services.odex: 20071624 - after: arm/boot*.oat: 16949532 (+56.4KiB, +0.34%) arm64/boot*.oat: 19889752 (+72.5KiB, +0.37%) oat/arm64/services.odex: 20224328 (+149.1KiB, +0.76%) with minor changes to other app prebuilts. Note: Some of that could be reclaimed by reinstating the old optimization for classes where no bytecode can be executed during initialization (no to execute in that class or superclasses). Test: 174-escaping-instance-of-bad-class Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: testrunner.py --jvm -t 174 Test: Pixel 2 XL boots. Test: testrunner.py --target --optimizing Bug: 62478025 Change-Id: I41f026ea7fecc615c06e87f3b6cb847de0ede8a6 --- compiler/driver/compiler_driver.cc | 86 -------------------------------------- 1 file changed, 86 deletions(-) (limited to 'compiler/driver/compiler_driver.cc') diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 7e6fdaf633..b24b0362a3 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -112,7 +112,6 @@ class CompilerDriver::AOTCompilationStats { public: AOTCompilationStats() : stats_lock_("AOT compilation statistics lock"), - resolved_types_(0), unresolved_types_(0), resolved_instance_fields_(0), unresolved_instance_fields_(0), resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0), type_based_devirtualization_(0), @@ -127,7 +126,6 @@ class CompilerDriver::AOTCompilationStats { } void Dump() { - DumpStat(resolved_types_, unresolved_types_, "types resolved"); DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved"); DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_, "static fields resolved"); @@ -177,16 +175,6 @@ class CompilerDriver::AOTCompilationStats { #define STATS_LOCK() #endif - void TypeDoesntNeedAccessCheck() REQUIRES(!stats_lock_) { - STATS_LOCK(); - resolved_types_++; - } - - void TypeNeedsAccessCheck() REQUIRES(!stats_lock_) { - STATS_LOCK(); - unresolved_types_++; - } - void ResolvedInstanceField() REQUIRES(!stats_lock_) { STATS_LOCK(); resolved_instance_fields_++; @@ -233,9 +221,6 @@ class CompilerDriver::AOTCompilationStats { private: Mutex stats_lock_; - size_t resolved_types_; - size_t unresolved_types_; - size_t resolved_instance_fields_; size_t unresolved_instance_fields_; @@ -1334,77 +1319,6 @@ void CompilerDriver::UpdateImageClasses(TimingLogger* timings) { } } -bool CompilerDriver::CanAssumeClassIsLoaded(mirror::Class* klass) { - Runtime* runtime = Runtime::Current(); - if (!runtime->IsAotCompiler()) { - DCHECK(runtime->UseJitCompilation()); - // Having the klass reference here implies that the klass is already loaded. - return true; - } - if (!GetCompilerOptions().IsBootImage()) { - // Assume loaded only if klass is in the boot image. App classes cannot be assumed - // loaded because we don't even know what class loader will be used to load them. - bool class_in_image = runtime->GetHeap()->FindSpaceFromObject(klass, false)->IsImageSpace(); - return class_in_image; - } - std::string temp; - const char* descriptor = klass->GetDescriptor(&temp); - return GetCompilerOptions().IsImageClass(descriptor); -} - -bool CompilerDriver::CanAccessTypeWithoutChecks(ObjPtr referrer_class, - ObjPtr resolved_class) { - if (resolved_class == nullptr) { - stats_->TypeNeedsAccessCheck(); - return false; // Unknown class needs access checks. - } - bool is_accessible = resolved_class->IsPublic(); // Public classes are always accessible. - if (!is_accessible) { - if (referrer_class == nullptr) { - stats_->TypeNeedsAccessCheck(); - return false; // Incomplete referrer knowledge needs access check. - } - // Perform access check, will return true if access is ok or false if we're going to have to - // check this at runtime (for example for class loaders). - is_accessible = referrer_class->CanAccess(resolved_class); - } - if (is_accessible) { - stats_->TypeDoesntNeedAccessCheck(); - } else { - stats_->TypeNeedsAccessCheck(); - } - return is_accessible; -} - -bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(ObjPtr referrer_class, - ObjPtr resolved_class, - bool* finalizable) { - if (resolved_class == nullptr) { - stats_->TypeNeedsAccessCheck(); - // Be conservative. - *finalizable = true; - return false; // Unknown class needs access checks. - } - *finalizable = resolved_class->IsFinalizable(); - bool is_accessible = resolved_class->IsPublic(); // Public classes are always accessible. - if (!is_accessible) { - if (referrer_class == nullptr) { - stats_->TypeNeedsAccessCheck(); - return false; // Incomplete referrer knowledge needs access check. - } - // Perform access and instantiable checks, will return true if access is ok or false if we're - // going to have to check this at runtime (for example for class loaders). - is_accessible = referrer_class->CanAccess(resolved_class); - } - bool result = is_accessible && resolved_class->IsInstantiable(); - if (result) { - stats_->TypeDoesntNeedAccessCheck(); - } else { - stats_->TypeNeedsAccessCheck(); - } - return result; -} - void CompilerDriver::ProcessedInstanceField(bool resolved) { if (!resolved) { stats_->UnresolvedInstanceField(); -- cgit v1.2.3-59-g8ed1b