summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2018-01-19 21:23:04 -0800
committer Andreas Gampe <agampe@google.com> 2018-01-19 21:55:33 -0800
commite993458e8192b24621cb88a6ebcdbfd66f01da45 (patch)
tree4322c1b8b055cae814c28f326c07b301ca0f8b61
parentba94510917814f9e79233bc6de192e87078c6941 (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.cc15
-rw-r--r--compiler/dex/quick_compiler_callbacks.h11
-rw-r--r--dex2oat/dex2oat.cc1
-rw-r--r--runtime/class_linker.cc11
-rw-r--r--runtime/compiler_callbacks.h11
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) { }