Record class status after verification.
The class status was recorded when doing vdex verification, or
any compilation (quickening or optimizing), but not when only doing
verification.
bug:37446669
Test:compiler_driver_test
(cherry picked from commit c7da1d61ba0fc38950f303813d4ba8c2d6d05c7f)
Change-Id: I8f111273bab1fa5a6211f7d0ed07b520479b67a3
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index e823f67..1a44524 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2181,6 +2181,10 @@
CHECK(klass->ShouldVerifyAtRuntime() || klass->IsVerified() || klass->IsErroneous())
<< klass->PrettyDescriptor() << ": state=" << klass->GetStatus();
+ // Class has a meaningful status for the compiler now, record it.
+ ClassReference ref(manager_->GetDexFile(), class_def_index);
+ manager_->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
+
// It is *very* problematic if there are verification errors in the boot classpath. For example,
// we rely on things working OK without verification when the decryption dialog is brought up.
// So abort in a debug build if we find this violated.
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 35aa1ee..5b9ffb7 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -23,6 +23,7 @@
#include "art_method-inl.h"
#include "class_linker-inl.h"
#include "common_compiler_test.h"
+#include "compiled_class.h"
#include "dex_file.h"
#include "dex_file_types.h"
#include "gc/heap.h"
@@ -322,6 +323,47 @@
CheckCompiledMethods(class_loader, "LSecond;", s);
}
+// Test that a verify only compiler filter updates the CompiledClass map,
+// which will be used for OatClass.
+class CompilerDriverVerifyTest : public CompilerDriverTest {
+ protected:
+ CompilerFilter::Filter GetCompilerFilter() const OVERRIDE {
+ return CompilerFilter::kVerifyProfile;
+ }
+
+ void CheckVerifiedClass(jobject class_loader, const std::string& clazz) const {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ Thread* self = Thread::Current();
+ ScopedObjectAccess soa(self);
+ StackHandleScope<1> hs(self);
+ Handle<mirror::ClassLoader> h_loader(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
+ mirror::Class* klass = class_linker->FindClass(self, clazz.c_str(), h_loader);
+ ASSERT_NE(klass, nullptr);
+ EXPECT_TRUE(klass->IsVerified());
+
+ CompiledClass* compiled_class = compiler_driver_->GetCompiledClass(
+ ClassReference(&klass->GetDexFile(), klass->GetDexTypeIndex().index_));
+ ASSERT_NE(compiled_class, nullptr);
+ EXPECT_EQ(compiled_class->GetStatus(), mirror::Class::kStatusVerified);
+ }
+};
+
+TEST_F(CompilerDriverVerifyTest, VerifyCompilation) {
+ Thread* self = Thread::Current();
+ jobject class_loader;
+ {
+ ScopedObjectAccess soa(self);
+ class_loader = LoadDex("ProfileTestMultiDex");
+ }
+ ASSERT_NE(class_loader, nullptr);
+
+ CompileAll(class_loader);
+
+ CheckVerifiedClass(class_loader, "LMain;");
+ CheckVerifiedClass(class_loader, "LSecond;");
+}
+
// TODO: need check-cast test (when stub complete & we can throw/catch
} // namespace art