Clear shared method bit when doing boot image profiling.
Otherwise, the profile saver thinks all methods in the boot image are
hot.
Test: 595-profile-saving
Bug: 223366272
Change-Id: Ieff95a6fe11cabfa9b3ccf1364b8dae080d08cf8
(cherry picked from commit 8bf5afd32336da9ae96668b2ef31f06678d30347)
Merged-In: Ieff95a6fe11cabfa9b3ccf1364b8dae080d08cf8
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 9b11c26..d8bd380 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -265,6 +265,15 @@
}
}
+ void ClearMemorySharedMethod() REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (IsIntrinsic() || IsAbstract()) {
+ return;
+ }
+ if (IsMemorySharedMethod()) {
+ ClearAccessFlags(kAccMemorySharedMethod);
+ }
+ }
+
void ClearPreCompiled() REQUIRES_SHARED(Locks::mutator_lock_) {
ClearAccessFlags(kAccPreCompiled | kAccCompileDontBother);
}
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 64adc55..c8dbc75 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1983,6 +1983,16 @@
}
if (!runtime->IsAotCompiler()) {
+ // If we are profiling the boot classpath, disable the shared memory for
+ // boot image method optimization. We need to disable it before doing
+ // ResetCounter below, as counters of shared memory method always hold the
+ // "hot" value.
+ if (runtime->GetJITOptions()->GetProfileSaverOptions().GetProfileBootClassPath()) {
+ header.VisitPackedArtMethods([&](ArtMethod& method) REQUIRES_SHARED(Locks::mutator_lock_) {
+ method.ClearMemorySharedMethod();
+ }, space->Begin(), image_pointer_size_);
+ }
+
ScopedTrace trace("AppImage:UpdateCodeItemAndNterp");
bool can_use_nterp = interpreter::CanRuntimeUseNterp();
uint16_t hotness_threshold = runtime->GetJITOptions()->GetWarmupThreshold();
@@ -3762,7 +3772,8 @@
}
}
- if (Runtime::Current()->IsZygote()) {
+ if (Runtime::Current()->IsZygote() &&
+ !Runtime::Current()->GetJITOptions()->GetProfileSaverOptions().GetProfileBootClassPath()) {
dst->SetMemorySharedMethod();
}
}
diff --git a/test/595-profile-saving/src/Main.java b/test/595-profile-saving/src/Main.java
index e693006..5b1a448 100644
--- a/test/595-profile-saving/src/Main.java
+++ b/test/595-profile-saving/src/Main.java
@@ -46,6 +46,11 @@
}
testAddMethodToProfile(file, bootMethod);
+ // We never expect System.console to be executed before Main.main gets invoked, and therefore
+ // it should never be in a profile.
+ Method bootNotInProfileMethod = System.class.getDeclaredMethod("console");
+ testMethodNotInProfile(file, bootNotInProfileMethod);
+
System.out.println("IsForBootImage: " + isForBootImage(file.getPath()));
} finally {
if (file != null) {
@@ -61,7 +66,16 @@
ensureProfileProcessing();
// Verify that the profile was saved and contains the method.
if (!presentInProfile(file.getPath(), m)) {
- throw new RuntimeException("Method with index " + m + " not in the profile");
+ throw new RuntimeException("Expected method " + m + " to be in the profile");
+ }
+ }
+
+ static void testMethodNotInProfile(File file, Method m) {
+ // Make sure the profile gets saved.
+ ensureProfileProcessing();
+ // Verify that the profile was saved and contains the method.
+ if (presentInProfile(file.getPath(), m)) {
+ throw new RuntimeException("Did not expect method " + m + " to be in the profile");
}
}