diff options
| author | Vladimir Marko <vmarko@google.com> | 2018-11-30 17:01:50 +0000 |
|---|---|---|
| committer | Vladimir Marko <vmarko@google.com> | 2018-12-06 16:26:43 +0000 |
| commit | 2afaff7e9171992b0e2e95d0f485782d28e1b9dc (patch) | |
| tree | 96c7ea4a13e8a9a191d58002de89fb005231980e /compiler/driver | |
| parent | 6a98f89c4ad645b04d6c80d3d7e260c59bf6f193 (diff) | |
| download | art-2afaff7e9171992b0e2e95d0f485782d28e1b9dc.tar.gz art-2afaff7e9171992b0e2e95d0f485782d28e1b9dc.tar.bz2 art-2afaff7e9171992b0e2e95d0f485782d28e1b9dc.zip | |
Refactor CompilerDriver::CompileAll().
Treat verification results and image classes as mutable
only in CompilerDriver::PreCompile(), and treat them as
immutable during compilation, accessed through the
CompilerOptions. This severs the dependency of the inliner
on the CompilerDriver.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I594a0213ca6a5003c19b4bd488af98db4358d51d
Diffstat (limited to 'compiler/driver')
| -rw-r--r-- | compiler/driver/compiler_driver-inl.h | 5 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 93 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.h | 47 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver_test.cc | 18 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.cc | 42 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.h | 15 |
6 files changed, 111 insertions, 109 deletions
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index 792f508199..63dcb4664c 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -99,11 +99,6 @@ inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField( return std::make_pair(fast_get, fast_put); } -inline VerificationResults* CompilerDriver::GetVerificationResults() const { - DCHECK(Runtime::Current()->IsAotCompiler()); - return verification_results_; -} - } // namespace art #endif // ART_COMPILER_DRIVER_COMPILER_DRIVER_INL_H_ diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 67cabef641..18f7105769 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -245,16 +245,12 @@ class CompilerDriver::AOTCompilationStats { CompilerDriver::CompilerDriver( const CompilerOptions* compiler_options, - VerificationResults* verification_results, Compiler::Kind compiler_kind, - HashSet<std::string>* image_classes, size_t thread_count, int swap_fd) : compiler_options_(compiler_options), - verification_results_(verification_results), compiler_(Compiler::Create(this, compiler_kind)), compiler_kind_(compiler_kind), - image_classes_(std::move(image_classes)), number_of_soft_verifier_failures_(0), had_hard_verifier_failure_(false), parallel_thread_count_(thread_count), @@ -266,10 +262,6 @@ CompilerDriver::CompilerDriver( compiler_->Init(); - if (GetCompilerOptions().IsBootImage()) { - CHECK(image_classes_ != nullptr) << "Expected image classes for boot image"; - } - compiled_method_storage_.SetDedupeEnabled(compiler_options_->DeduplicateCode()); } @@ -325,9 +317,8 @@ void CompilerDriver::CompileAll(jobject class_loader, TimingLogger* timings) { DCHECK(!Runtime::Current()->IsStarted()); - InitializeThreadPools(); + CheckThreadPools(); - PreCompile(class_loader, dex_files, timings); if (GetCompilerOptions().IsBootImage()) { // We don't need to setup the intrinsics for non boot image compilation, as // those compilations will pick up a boot image that have the ArtMethod already @@ -343,8 +334,6 @@ void CompilerDriver::CompileAll(jobject class_loader, if (GetCompilerOptions().GetDumpStats()) { stats_->Dump(); } - - FreeThreadPools(); } static optimizer::DexToDexCompiler::CompilationLevel GetDexToDexCompilationLevel( @@ -496,7 +485,7 @@ static void CompileMethodDex2Dex( optimizer::DexToDexCompiler* const compiler = &driver->GetDexToDexCompiler(); if (compiler->ShouldCompileMethod(method_ref)) { - VerificationResults* results = driver->GetVerificationResults(); + const VerificationResults* results = driver->GetCompilerOptions().GetVerificationResults(); DCHECK(results != nullptr); const VerifiedMethod* verified_method = results->GetVerifiedMethod(method_ref); // Do not optimize if a VerifiedMethod is missing. SafeCast elision, @@ -574,7 +563,7 @@ static void CompileMethodQuick( } else if ((access_flags & kAccAbstract) != 0) { // Abstract methods don't have code. } else { - VerificationResults* results = driver->GetVerificationResults(); + const VerificationResults* results = driver->GetCompilerOptions().GetVerificationResults(); DCHECK(results != nullptr); const VerifiedMethod* verified_method = results->GetVerifiedMethod(method_ref); bool compile = @@ -881,7 +870,9 @@ static void EnsureVerifiedOrVerifyAtRuntime(jobject jclass_loader, void CompilerDriver::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files, - TimingLogger* timings) { + TimingLogger* timings, + /*inout*/ HashSet<std::string>* image_classes, + /*out*/ VerificationResults* verification_results) { CheckThreadPools(); VLOG(compiler) << "Before precompile " << GetMemoryUsageString(false); @@ -898,7 +889,7 @@ void CompilerDriver::PreCompile(jobject class_loader, // 6) Update the set of image classes. // 7) For deterministic boot image, initialize bitstrings for type checking. - LoadImageClasses(timings); + LoadImageClasses(timings, image_classes); VLOG(compiler) << "LoadImageClasses: " << GetMemoryUsageString(false); if (compiler_options_->IsAnyCompilationEnabled()) { @@ -932,7 +923,7 @@ void CompilerDriver::PreCompile(jobject class_loader, ResolveConstStrings(dex_files, /*only_startup_strings=*/ true, timings); } - Verify(class_loader, dex_files, timings); + Verify(class_loader, dex_files, timings, verification_results); VLOG(compiler) << "Verify: " << GetMemoryUsageString(false); if (had_hard_verifier_failure_ && GetCompilerOptions().AbortOnHardVerifierFailure()) { @@ -957,7 +948,7 @@ void CompilerDriver::PreCompile(jobject class_loader, VLOG(compiler) << "InitializeClasses: " << GetMemoryUsageString(false); } - UpdateImageClasses(timings); + UpdateImageClasses(timings, image_classes); VLOG(compiler) << "UpdateImageClasses: " << GetMemoryUsageString(false); if (kBitstringSubtypeCheckEnabled && @@ -1071,7 +1062,8 @@ class RecordImageClassesVisitor : public ClassVisitor { }; // Make a list of descriptors for classes to include in the image -void CompilerDriver::LoadImageClasses(TimingLogger* timings) { +void CompilerDriver::LoadImageClasses(TimingLogger* timings, + /*inout*/ HashSet<std::string>* image_classes) { CHECK(timings != nullptr); if (!GetCompilerOptions().IsBootImage()) { return; @@ -1082,15 +1074,15 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings) { Thread* self = Thread::Current(); ScopedObjectAccess soa(self); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - CHECK(image_classes_ != nullptr); - for (auto it = image_classes_->begin(), end = image_classes_->end(); it != end;) { + CHECK(image_classes != nullptr); + for (auto it = image_classes->begin(), end = image_classes->end(); it != end;) { const std::string& descriptor(*it); StackHandleScope<1> hs(self); Handle<mirror::Class> klass( hs.NewHandle(class_linker->FindSystemClass(self, descriptor.c_str()))); if (klass == nullptr) { VLOG(compiler) << "Failed to find class " << descriptor; - it = image_classes_->erase(it); + it = image_classes->erase(it); self->ClearException(); } else { ++it; @@ -1140,10 +1132,10 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings) { // We walk the roots looking for classes so that we'll pick up the // above classes plus any classes them depend on such super // classes, interfaces, and the required ClassLinker roots. - RecordImageClassesVisitor visitor(image_classes_); + RecordImageClassesVisitor visitor(image_classes); class_linker->VisitClasses(&visitor); - CHECK(!image_classes_->empty()); + CHECK(!image_classes->empty()); } static void MaybeAddToImageClasses(Thread* self, @@ -1312,7 +1304,8 @@ class ClinitImageUpdate { DISALLOW_COPY_AND_ASSIGN(ClinitImageUpdate); }; -void CompilerDriver::UpdateImageClasses(TimingLogger* timings) { +void CompilerDriver::UpdateImageClasses(TimingLogger* timings, + /*inout*/ HashSet<std::string>* image_classes) { if (GetCompilerOptions().IsBootImage()) { TimingLogger::ScopedTiming t("UpdateImageClasses", timings); @@ -1324,7 +1317,7 @@ void CompilerDriver::UpdateImageClasses(TimingLogger* timings) { VariableSizedHandleScope hs(Thread::Current()); std::string error_msg; std::unique_ptr<ClinitImageUpdate> update(ClinitImageUpdate::Create(hs, - image_classes_, + image_classes, Thread::Current(), runtime->GetClassLinker())); @@ -1393,12 +1386,6 @@ bool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompi } } -const VerifiedMethod* CompilerDriver::GetVerifiedMethod(const DexFile* dex_file, - uint32_t method_idx) const { - MethodReference ref(dex_file, method_idx); - return verification_results_->GetVerifiedMethod(ref); -} - bool CompilerDriver::IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc) { if (!compiler_options_->IsVerificationEnabled()) { // If we didn't verify, every cast has to be treated as non-safe. @@ -1764,7 +1751,8 @@ static void LoadAndUpdateStatus(const ClassAccessor& accessor, bool CompilerDriver::FastVerify(jobject jclass_loader, const std::vector<const DexFile*>& dex_files, - TimingLogger* timings) { + TimingLogger* timings, + /*out*/ VerificationResults* verification_results) { verifier::VerifierDeps* verifier_deps = Runtime::Current()->GetCompilerCallbacks()->GetVerifierDeps(); // If there exist VerifierDeps that aren't the ones we just created to output, use them to verify. @@ -1812,7 +1800,7 @@ bool CompilerDriver::FastVerify(jobject jclass_loader, // - Quickening will not do checkcast ellision. // TODO(ngeoffray): Reconsider this once we refactor compiler filters. for (const ClassAccessor::Method& method : accessor.GetMethods()) { - verification_results_->CreateVerifiedMethodFor(method.GetReference()); + verification_results->CreateVerifiedMethodFor(method.GetReference()); } } } else if (!compiler_only_verifies) { @@ -1830,8 +1818,9 @@ bool CompilerDriver::FastVerify(jobject jclass_loader, void CompilerDriver::Verify(jobject jclass_loader, const std::vector<const DexFile*>& dex_files, - TimingLogger* timings) { - if (FastVerify(jclass_loader, dex_files, timings)) { + TimingLogger* timings, + /*out*/ VerificationResults* verification_results) { + if (FastVerify(jclass_loader, dex_files, timings, verification_results)) { return; } @@ -2530,7 +2519,7 @@ void CompilerDriver::InitializeClasses(jobject class_loader, // SetVerificationAttempted so that the access flags are set. If we do not do this they get // changed at runtime resulting in more dirty image pages. // Also create conflict tables. - // Only useful if we are compiling an image (image_classes_ is not null). + // Only useful if we are compiling an image. ScopedObjectAccess soa(Thread::Current()); VariableSizedHandleScope hs(soa.Self()); InitializeArrayClassesAndCreateConflictTablesVisitor visitor(hs); @@ -2569,8 +2558,9 @@ static void CompileDexFile(CompilerDriver* driver, ClassReference ref(&dex_file, class_def_index); const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); ClassAccessor accessor(dex_file, class_def_index); + CompilerDriver* const driver = context.GetCompiler(); // Skip compiling classes with generic verifier failures since they will still fail at runtime - if (context.GetCompiler()->GetVerificationResults()->IsClassRejected(ref)) { + if (driver->GetCompilerOptions().GetVerificationResults()->IsClassRejected(ref)) { return; } // Use a scoped object access to perform to the quick SkipClass check. @@ -2602,8 +2592,6 @@ static void CompileDexFile(CompilerDriver* driver, // Go to native so that we don't block GC during compilation. ScopedThreadSuspension sts(soa.Self(), kNative); - CompilerDriver* const driver = context.GetCompiler(); - // Can we run DEX-to-DEX compiler on this class ? optimizer::DexToDexCompiler::CompilationLevel dex_to_dex_compilation_level = GetDexToDexCompilationLevel(soa.Self(), *driver, jclass_loader, dex_file, class_def); @@ -2775,31 +2763,6 @@ CompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const { return compiled_method; } -bool CompilerDriver::IsMethodVerifiedWithoutFailures(uint32_t method_idx, - uint16_t class_def_idx, - const DexFile& dex_file) const { - const VerifiedMethod* verified_method = GetVerifiedMethod(&dex_file, method_idx); - if (verified_method != nullptr) { - return !verified_method->HasVerificationFailures(); - } - - // If we can't find verification metadata, check if this is a system class (we trust that system - // classes have their methods verified). If it's not, be conservative and assume the method - // has not been verified successfully. - - // TODO: When compiling the boot image it should be safe to assume that everything is verified, - // even if methods are not found in the verification cache. - const char* descriptor = dex_file.GetClassDescriptor(dex_file.GetClassDef(class_def_idx)); - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - Thread* self = Thread::Current(); - ScopedObjectAccess soa(self); - bool is_system_class = class_linker->FindSystemClass(self, descriptor) != nullptr; - if (!is_system_class) { - self->ClearException(); - } - return is_system_class; -} - std::string CompilerDriver::GetMemoryUsageString(bool extended) const { std::ostringstream oss; const gc::Heap* const heap = Runtime::Current()->GetHeap(); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 714b2d1fc8..7c0fc6450f 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -76,7 +76,6 @@ template <class Allocator> class SrcMap; class TimingLogger; class VdexFile; class VerificationResults; -class VerifiedMethod; enum EntryPointCallingConvention { // ABI of invocations to a method's interpreter entry point. @@ -95,9 +94,7 @@ class CompilerDriver { // can assume will be in the image, with null implying all available // classes. CompilerDriver(const CompilerOptions* compiler_options, - VerificationResults* verification_results, Compiler::Kind compiler_kind, - HashSet<std::string>* image_classes, size_t thread_count, int swap_fd); @@ -106,6 +103,17 @@ class CompilerDriver { // Set dex files classpath. void SetClasspathDexFiles(const std::vector<const DexFile*>& dex_files); + // Initialize and destroy thread pools. This is exposed because we do not want + // to do this twice, for PreCompile() and CompileAll(). + void InitializeThreadPools(); + void FreeThreadPools(); + + void PreCompile(jobject class_loader, + const std::vector<const DexFile*>& dex_files, + TimingLogger* timings, + /*inout*/ HashSet<std::string>* image_classes, + /*out*/ VerificationResults* verification_results) + REQUIRES(!Locks::mutator_lock_); void CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files, TimingLogger* timings) @@ -124,8 +132,6 @@ class CompilerDriver { Handle<mirror::ClassLoader> h_class_loader) REQUIRES(!Locks::mutator_lock_); - VerificationResults* GetVerificationResults() const; - const CompilerOptions& GetCompilerOptions() const { return *compiler_options_; } @@ -194,7 +200,6 @@ class CompilerDriver { REQUIRES_SHARED(Locks::mutator_lock_); - const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const; bool IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc); size_t GetThreadCount() const { @@ -219,12 +224,6 @@ class CompilerDriver { void RecordClassStatus(const ClassReference& ref, ClassStatus status); - // Checks if the specified method has been verified without failures. Returns - // false if the method is not in the verification results (GetVerificationResults). - bool IsMethodVerifiedWithoutFailures(uint32_t method_idx, - uint16_t class_def_idx, - const DexFile& dex_file) const; - // Get memory usage during compilation. std::string GetMemoryUsageString(bool extended) const; @@ -265,13 +264,9 @@ class CompilerDriver { } private: - void PreCompile(jobject class_loader, - const std::vector<const DexFile*>& dex_files, - TimingLogger* timings) + void LoadImageClasses(TimingLogger* timings, /*inout*/ HashSet<std::string>* image_classes) REQUIRES(!Locks::mutator_lock_); - void LoadImageClasses(TimingLogger* timings) REQUIRES(!Locks::mutator_lock_); - // Attempt to resolve all type, methods, fields, and strings // referenced from code in the dex file following PathClassLoader // ordering semantics. @@ -291,11 +286,13 @@ class CompilerDriver { // verification was successful. bool FastVerify(jobject class_loader, const std::vector<const DexFile*>& dex_files, - TimingLogger* timings); + TimingLogger* timings, + /*out*/ VerificationResults* verification_results); void Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files, - TimingLogger* timings); + TimingLogger* timings, + /*out*/ VerificationResults* verification_results); void VerifyDexFile(jobject class_loader, const DexFile& dex_file, @@ -326,14 +323,13 @@ class CompilerDriver { TimingLogger* timings) REQUIRES(!Locks::mutator_lock_); - void UpdateImageClasses(TimingLogger* timings) REQUIRES(!Locks::mutator_lock_); + void UpdateImageClasses(TimingLogger* timings, /*inout*/ HashSet<std::string>* image_classes) + REQUIRES(!Locks::mutator_lock_); void Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files, TimingLogger* timings); - void InitializeThreadPools(); - void FreeThreadPools(); void CheckThreadPools(); // Resolve const string literals that are loaded from dex code. If only_startup_strings is @@ -343,7 +339,6 @@ class CompilerDriver { /*inout*/ TimingLogger* timings); const CompilerOptions* const compiler_options_; - VerificationResults* const verification_results_; std::unique_ptr<Compiler> compiler_; Compiler::Kind compiler_kind_; @@ -359,12 +354,6 @@ class CompilerDriver { // All method references that this compiler has compiled. MethodTable compiled_methods_; - // Image classes to be updated by PreCompile(). - // TODO: Remove this member which is a non-const pointer to the CompilerOptions' data. - // Pass this explicitly to the PreCompile() which should be called directly from - // Dex2Oat rather than implicitly by CompileAll(). - HashSet<std::string>* image_classes_; - std::atomic<uint32_t> number_of_soft_verifier_failures_; bool had_hard_verifier_failure_; diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc index fe1568da83..b9241292ee 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -42,20 +42,18 @@ namespace art { class CompilerDriverTest : public CommonCompilerTest { protected: - void CompileAll(jobject class_loader) REQUIRES(!Locks::mutator_lock_) { - TimingLogger timings("CompilerDriverTest::CompileAll", false, false); - TimingLogger::ScopedTiming t(__FUNCTION__, &timings); + void CompileAllAndMakeExecutable(jobject class_loader) REQUIRES(!Locks::mutator_lock_) { + TimingLogger timings("CompilerDriverTest::CompileAllAndMakeExecutable", false, false); dex_files_ = GetDexFiles(class_loader); - SetDexFilesForOatFile(dex_files_); - compiler_driver_->CompileAll(class_loader, dex_files_, &timings); - t.NewTiming("MakeAllExecutable"); + CompileAll(class_loader, dex_files_, &timings); + TimingLogger::ScopedTiming t("MakeAllExecutable", &timings); MakeAllExecutable(class_loader); } void EnsureCompiled(jobject class_loader, const char* class_name, const char* method, const char* signature, bool is_virtual) REQUIRES(!Locks::mutator_lock_) { - CompileAll(class_loader); + CompileAllAndMakeExecutable(class_loader); Thread::Current()->TransitionFromSuspendedToRunnable(); bool started = runtime_->Start(); CHECK(started); @@ -106,7 +104,7 @@ class CompilerDriverTest : public CommonCompilerTest { // Disabled due to 10 second runtime on host // TODO: Update the test for hash-based dex cache arrays. Bug: 30627598 TEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) { - CompileAll(nullptr); + CompileAllAndMakeExecutable(nullptr); // All libcore references should resolve ScopedObjectAccess soa(Thread::Current()); @@ -266,7 +264,7 @@ TEST_F(CompilerDriverProfileTest, ProfileGuidedCompilation) { ASSERT_TRUE(dex_file->EnableWrite()); } - CompileAll(class_loader); + CompileAllAndMakeExecutable(class_loader); std::unordered_set<std::string> m = GetExpectedMethodsForClass("Main"); std::unordered_set<std::string> s = GetExpectedMethodsForClass("Second"); @@ -310,7 +308,7 @@ TEST_F(CompilerDriverVerifyTest, VerifyCompilation) { } ASSERT_NE(class_loader, nullptr); - CompileAll(class_loader); + CompileAllAndMakeExecutable(class_loader); CheckVerifiedClass(class_loader, "LMain;"); CheckVerifiedClass(class_loader, "LSecond;"); diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc index b28c7e0edb..8d1ae3d524 100644 --- a/compiler/driver/compiler_options.cc +++ b/compiler/driver/compiler_options.cc @@ -24,9 +24,14 @@ #include "arch/instruction_set_features.h" #include "base/runtime_debug.h" #include "base/variant_map.h" +#include "class_linker.h" #include "cmdline_parser.h" #include "compiler_options_map-inl.h" +#include "dex/dex_file-inl.h" +#include "dex/verification_results.h" +#include "dex/verified_method.h" #include "runtime.h" +#include "scoped_thread_state_change-inl.h" #include "simple_compiler_options_map.h" namespace art { @@ -44,6 +49,7 @@ CompilerOptions::CompilerOptions() no_inline_from_(), dex_files_for_oat_file_(), image_classes_(), + verification_results_(nullptr), image_type_(ImageType::kNone), compiling_with_core_image_(false), baseline_(false), @@ -141,4 +147,40 @@ bool CompilerOptions::IsImageClass(const char* descriptor) const { return image_classes_.find(StringPiece(descriptor)) != image_classes_.end(); } +const VerificationResults* CompilerOptions::GetVerificationResults() const { + DCHECK(Runtime::Current()->IsAotCompiler()); + return verification_results_; +} + +const VerifiedMethod* CompilerOptions::GetVerifiedMethod(const DexFile* dex_file, + uint32_t method_idx) const { + MethodReference ref(dex_file, method_idx); + return verification_results_->GetVerifiedMethod(ref); +} + +bool CompilerOptions::IsMethodVerifiedWithoutFailures(uint32_t method_idx, + uint16_t class_def_idx, + const DexFile& dex_file) const { + const VerifiedMethod* verified_method = GetVerifiedMethod(&dex_file, method_idx); + if (verified_method != nullptr) { + return !verified_method->HasVerificationFailures(); + } + + // If we can't find verification metadata, check if this is a system class (we trust that system + // classes have their methods verified). If it's not, be conservative and assume the method + // has not been verified successfully. + + // TODO: When compiling the boot image it should be safe to assume that everything is verified, + // even if methods are not found in the verification cache. + const char* descriptor = dex_file.GetClassDescriptor(dex_file.GetClassDef(class_def_idx)); + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + Thread* self = Thread::Current(); + ScopedObjectAccess soa(self); + bool is_system_class = class_linker->FindSystemClass(self, descriptor) != nullptr; + if (!is_system_class) { + self->ClearException(); + } + return is_system_class; +} + } // namespace art diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index a8f246dcab..bd12bf7dda 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -47,6 +47,8 @@ class DexFile; enum class InstructionSet; class InstructionSetFeatures; class ProfileCompilationInfo; +class VerificationResults; +class VerifiedMethod; // Enum for CheckProfileMethodsCompiled. Outside CompilerOptions so it can be forward-declared. enum class ProfileMethodsCheck : uint8_t { @@ -283,6 +285,16 @@ class CompilerOptions final { bool IsImageClass(const char* descriptor) const; + const VerificationResults* GetVerificationResults() const; + + const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const; + + // Checks if the specified method has been verified without failures. Returns + // false if the method is not in the verification results (GetVerificationResults). + bool IsMethodVerifiedWithoutFailures(uint32_t method_idx, + uint16_t class_def_idx, + const DexFile& dex_file) const; + bool ParseCompilerOptions(const std::vector<std::string>& options, bool ignore_unrecognized, std::string* error_msg); @@ -381,6 +393,9 @@ class CompilerOptions final { // Must not be empty for real boot image, only for tests pretending to compile boot image. HashSet<std::string> image_classes_; + // Results of AOT verification. + const VerificationResults* verification_results_; + ImageType image_type_; bool compiling_with_core_image_; bool baseline_; |
