diff options
author | 2018-01-19 21:23:04 -0800 | |
---|---|---|
committer | 2018-01-19 21:55:33 -0800 | |
commit | e993458e8192b24621cb88a6ebcdbfd66f01da45 (patch) | |
tree | 4322c1b8b055cae814c28f326c07b301ca0f8b61 | |
parent | ba94510917814f9e79233bc6de192e87078c6941 (diff) |
ART: Allow oatstatus verification for app dependencies
Allow taking verification state from the oat file durin compilation
if the class is a dependency (thus not being compiled itself). This
is necessary in case the dependency itself has been quickened and
stripped, as quickened bytecodes are not supported during compile-
time verification.
Expose this through the CompilerCallbacks.
Bug: 72237763
Test: m test-art-host
Change-Id: I9b7d3a353d81a6422c3b145fd5c5b71f36c6f257
-rw-r--r-- | compiler/dex/quick_compiler_callbacks.cc | 15 | ||||
-rw-r--r-- | compiler/dex/quick_compiler_callbacks.h | 11 | ||||
-rw-r--r-- | dex2oat/dex2oat.cc | 1 | ||||
-rw-r--r-- | runtime/class_linker.cc | 11 | ||||
-rw-r--r-- | runtime/compiler_callbacks.h | 11 |
5 files changed, 42 insertions, 7 deletions
diff --git a/compiler/dex/quick_compiler_callbacks.cc b/compiler/dex/quick_compiler_callbacks.cc index 540bd0ce45..baf97a852e 100644 --- a/compiler/dex/quick_compiler_callbacks.cc +++ b/compiler/dex/quick_compiler_callbacks.cc @@ -17,6 +17,10 @@ #include "quick_compiler_callbacks.h" #include "driver/compiler_driver.h" +#include "mirror/class-inl.h" +#include "mirror/object.h" +#include "obj_ptr-inl.h" +#include "thread-current-inl.h" #include "verification_results.h" #include "verifier/method_verifier-inl.h" @@ -54,4 +58,15 @@ void QuickCompilerCallbacks::UpdateClassState(ClassReference ref, ClassStatus st } } +bool QuickCompilerCallbacks::CanUseOatStatusForVerification(mirror::Class* klass) { + // No dex files: conservatively false. + if (dex_files_ == nullptr) { + return false; + } + + // If the class isn't from one of the dex files, accept oat file data. + const DexFile* dex_file = &klass->GetDexFile(); + return std::find(dex_files_->begin(), dex_files_->end(), dex_file) == dex_files_->end(); +} + } // namespace art diff --git a/compiler/dex/quick_compiler_callbacks.h b/compiler/dex/quick_compiler_callbacks.h index 6d22f955a3..8a07e9c12c 100644 --- a/compiler/dex/quick_compiler_callbacks.h +++ b/compiler/dex/quick_compiler_callbacks.h @@ -23,12 +23,13 @@ namespace art { class CompilerDriver; +class DexFile; class VerificationResults; class QuickCompilerCallbacks FINAL : public CompilerCallbacks { public: explicit QuickCompilerCallbacks(CompilerCallbacks::CallbackMode mode) - : CompilerCallbacks(mode) {} + : CompilerCallbacks(mode), dex_files_(nullptr) {} ~QuickCompilerCallbacks() { } @@ -65,11 +66,19 @@ class QuickCompilerCallbacks FINAL : public CompilerCallbacks { void UpdateClassState(ClassReference ref, ClassStatus state) OVERRIDE; + bool CanUseOatStatusForVerification(mirror::Class* klass) OVERRIDE + REQUIRES_SHARED(Locks::mutator_lock_); + + void SetDexFiles(const std::vector<const DexFile*>* dex_files) { + dex_files_ = dex_files; + } + private: VerificationResults* verification_results_ = nullptr; bool does_class_unloading_ = false; CompilerDriver* compiler_driver_ = nullptr; std::unique_ptr<verifier::VerifierDeps> verifier_deps_; + const std::vector<const DexFile*>* dex_files_; }; } // namespace art diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 7796b3acc6..34ba4b34e7 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -1829,6 +1829,7 @@ class Dex2Oat FINAL { jobject class_loader = nullptr; if (!IsBootImage()) { class_loader = class_loader_context_->CreateClassLoader(dex_files_); + callbacks_->SetDexFiles(&dex_files); } // Register dex caches and key them to the class loader so that they only unload when the diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index b61fb4afe9..af45a69bd5 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -4252,17 +4252,16 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, ClassStatus& oat_file_class_status) { // If we're compiling, we can only verify the class using the oat file if // we are not compiling the image or if the class we're verifying is not part of - // the app. In other words, we will only check for preverification of bootclasspath - // classes. + // the compilation unit (app - dependencies). We will let the compiler callback + // tell us about the latter. if (Runtime::Current()->IsAotCompiler()) { + CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks(); // Are we compiling the bootclasspath? - if (Runtime::Current()->GetCompilerCallbacks()->IsBootImage()) { + if (callbacks->IsBootImage()) { return false; } // We are compiling an app (not the image). - - // Is this an app class? (I.e. not a bootclasspath class) - if (klass->GetClassLoader() != nullptr) { + if (!callbacks->CanUseOatStatusForVerification(klass.Ptr())) { return false; } } diff --git a/runtime/compiler_callbacks.h b/runtime/compiler_callbacks.h index 4560bca922..8395966404 100644 --- a/runtime/compiler_callbacks.h +++ b/runtime/compiler_callbacks.h @@ -25,6 +25,12 @@ namespace art { class CompilerDriver; +namespace mirror { + +class Class; + +} // namespace mirror + namespace verifier { class MethodVerifier; @@ -68,6 +74,11 @@ class CompilerCallbacks { virtual void UpdateClassState(ClassReference ref ATTRIBUTE_UNUSED, ClassStatus state ATTRIBUTE_UNUSED) {} + virtual bool CanUseOatStatusForVerification(mirror::Class* klass ATTRIBUTE_UNUSED) + REQUIRES_SHARED(Locks::mutator_lock_) { + return false; + } + protected: explicit CompilerCallbacks(CallbackMode mode) : mode_(mode) { } |