Add verify-profile compiler filter
Only verifies and dex2dex compiles classes in the profile. Goal
is to reduce application launch time.
~2x faster than interpret-only for Facebook.
Bug: 27688727
(cherry picked from commit a079e3aa62cceb76c1c1811e6e09bcaf75e20289)
Change-Id: Iad5aa1adee3aa6c2408820e8cbbab2d4412021b8
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index cd9d80f..ea16cb2 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -383,6 +383,9 @@
compiler_->Init();
+ if (compiler_options->VerifyOnlyProfile()) {
+ CHECK(profile_compilation_info_ != nullptr) << "Requires profile";
+ }
if (boot_image_) {
CHECK(image_classes_.get() != nullptr) << "Expected image classes for boot image";
}
@@ -830,10 +833,12 @@
const bool verification_enabled = compiler_options_->IsVerificationEnabled();
const bool never_verify = compiler_options_->NeverVerify();
+ const bool verify_only_profile = compiler_options_->VerifyOnlyProfile();
// We need to resolve for never_verify since it needs to run dex to dex to add the
// RETURN_VOID_NO_BARRIER.
- if (never_verify || verification_enabled) {
+ // Let the verifier resolve as needed for the verify_only_profile case.
+ if ((never_verify || verification_enabled) && !verify_only_profile) {
Resolve(class_loader, dex_files, timings);
VLOG(compiler) << "Resolve: " << GetMemoryUsageString(false);
}
@@ -918,6 +923,22 @@
return result;
}
+bool CompilerDriver::ShouldVerifyClassBasedOnProfile(const DexFile& dex_file,
+ uint16_t class_idx) const {
+ if (!compiler_options_->VerifyOnlyProfile()) {
+ // No profile, verify everything.
+ return true;
+ }
+ DCHECK(profile_compilation_info_ != nullptr);
+ bool result = profile_compilation_info_->ContainsClass(dex_file, class_idx);
+ if (kDebugProfileGuidedCompilation) {
+ LOG(INFO) << "[ProfileGuidedCompilation] "
+ << (result ? "Verified" : "Skipped") << " method:"
+ << dex_file.GetClassDescriptor(dex_file.GetClassDef(class_idx));
+ }
+ return result;
+}
+
class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor {
public:
ResolveCatchBlockExceptionsClassVisitor(
@@ -2197,6 +2218,10 @@
ATRACE_CALL();
ScopedObjectAccess soa(Thread::Current());
const DexFile& dex_file = *manager_->GetDexFile();
+ if (!manager_->GetCompiler()->ShouldVerifyClassBasedOnProfile(dex_file, class_def_index)) {
+ // Skip verification since the class is not in the profile.
+ return;
+ }
const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
const char* descriptor = dex_file.GetClassDescriptor(class_def);
ClassLinker* class_linker = manager_->GetClassLinker();
@@ -2665,6 +2690,7 @@
case mirror::Class::kStatusRetryVerificationAtRuntime:
case mirror::Class::kStatusVerified:
case mirror::Class::kStatusInitialized:
+ case mirror::Class::kStatusResolved:
break; // Expected states.
default:
LOG(FATAL) << "Unexpected class status for class "