In GetDexoptNeeded, check whether the oat file was compiled without image.
If there now is an image on disk, return that we need to recompile.
Test: manual
Bug: 214376933
Change-Id: If229a892e2729ffa882cb56a0b983df1bd94acc5
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index c9e6bbf..5e01aaa 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -1156,20 +1156,9 @@
LOG(INFO) << "Successfully mapped boot image methods";
}
-// Return whether a boot image has a profile. This means we'll need to pre-JIT
-// methods in that profile for performance.
-static bool HasImageWithProfile() {
- for (gc::space::ImageSpace* space : Runtime::Current()->GetHeap()->GetBootImageSpaces()) {
- if (!space->GetProfileFiles().empty()) {
- return true;
- }
- }
- return false;
-}
-
bool Jit::InZygoteUsingJit() {
Runtime* runtime = Runtime::Current();
- return runtime->IsZygote() && HasImageWithProfile() && runtime->UseJitCompilation();
+ return runtime->IsZygote() && runtime->HasImageWithProfile() && runtime->UseJitCompilation();
}
void Jit::CreateThreadPool() {
@@ -1290,7 +1279,7 @@
if (runtime->IsSystemServer() &&
UseJitCompilation() &&
options_->UseProfiledJitCompilation() &&
- HasImageWithProfile() &&
+ runtime->HasImageWithProfile() &&
!runtime->IsJavaDebuggable()) {
thread_pool_->AddTask(Thread::Current(), new JitProfileTask(dex_files, class_loader));
}
@@ -1624,11 +1613,12 @@
// JitAtFirstUse compiles the methods synchronously on mutator threads. While this should work
// in theory it is causing deadlocks in some jvmti tests related to Jit GC. Hence, disabling
// Jit GC for now (b/147208992).
- code_cache_->SetGarbageCollectCode(!jit_compiler_->GenerateDebugInfo() &&
- !Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled() &&
+ code_cache_->SetGarbageCollectCode(
+ !jit_compiler_->GenerateDebugInfo() &&
+ !runtime->GetInstrumentation()->AreExitStubsInstalled() &&
!JitAtFirstUse());
- if (is_system_server && HasImageWithProfile()) {
+ if (is_system_server && runtime->HasImageWithProfile()) {
// Disable garbage collection: we don't want it to delete methods we're compiling
// through boot and system server profiles.
// TODO(ngeoffray): Fix this so we still collect deoptimized and unused code.
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 7d2196f..914d2dd 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -946,8 +946,28 @@
VLOG(oat) << "Compiler filter not okay because Profile changed";
return false;
}
- return downgrade ? !CompilerFilter::IsBetter(current, target) :
- CompilerFilter::IsAsGoodAs(current, target);
+
+ if (downgrade) {
+ return !CompilerFilter::IsBetter(current, target);
+ }
+
+ if (CompilerFilter::DependsOnImageChecksum(current) &&
+ CompilerFilter::IsAsGoodAs(current, target)) {
+ // If the oat file has been compiled without an image, and the runtime is
+ // now running with an image loaded from disk, return that we need to
+ // re-compile. The recompilation will generate a better oat file, and with an app
+ // image for profile guided compilation.
+ const char* oat_boot_class_path_checksums =
+ file->GetOatHeader().GetStoreValueByKey(OatHeader::kBootClassPathChecksumsKey);
+ if (oat_boot_class_path_checksums != nullptr &&
+ !StartsWith(oat_boot_class_path_checksums, "i") &&
+ !Runtime::Current()->HasImageWithProfile()) {
+ DCHECK(!file->GetOatHeader().RequiresImage());
+ return false;
+ }
+ }
+
+ return CompilerFilter::IsAsGoodAs(current, target);
}
bool OatFileAssistant::ClassLoaderContextIsOkay(const OatFile& oat_file) const {
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index b4d6fd4..b090022 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -3397,4 +3397,13 @@
}
}
+bool Runtime::HasImageWithProfile() const {
+ for (gc::space::ImageSpace* space : GetHeap()->GetBootImageSpaces()) {
+ if (!space->GetProfileFiles().empty()) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace art
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 9f835bb..e7b71e2 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -1069,6 +1069,10 @@
return apex_versions_;
}
+ // Return whether a boot image has a profile. This means it's an in-memory
+ // image rather that an image loaded from disk.
+ bool HasImageWithProfile() const;
+
// Trigger a flag reload from system properties or device congfigs.
//
// Should only be called from runtime init and zygote post fork as