diff options
author | 2024-10-29 10:26:51 +0000 | |
---|---|---|
committer | 2024-11-07 14:23:49 +0000 | |
commit | 07a58eb1cb4b7c5b1f307af6676c8b52b3e5c0cd (patch) | |
tree | ec1843a1922681b77843d4d0aba44640083b3f71 | |
parent | 3086bbd64c0b8ca90c891f9cb73e057b7c7dc45b (diff) |
Revert^4 "IsMemorySharedMethod fix for intrinsics"
This reverts commit a5557d9da3e603a0531e566abf4d08579b9b8141.
Reason for revert: Fixed adding SetHotCounter in SetIntrinsic. We are
expecting both intrinsics and memory shared methods to have that set
as 0 i.e. hot. Intrinsics are always considered hot, and memory shared
methods use another counter. This is now DCHECKed in `Jit::AddSamples`.
Changes can be seen in patchsets 1..5. I also noticed that there were
comments in x86(_64) `s` files that needed to be moved to the right
place.
Test: art/test/testrunner/testrunner.py --host --64 -b --jit
Test: No timeout in presubmit-cts-deviceside-cloud (see b/78151261)
Test: No timeout in nexus_unit_test_multi_device_platform
Bug: 78151261
Bug: 162110941
Change-Id: Iee99f0d42fcdb3f5ab2b20b4b7a8126c7c03b358
-rw-r--r-- | runtime/art_method.cc | 3 | ||||
-rw-r--r-- | runtime/art_method.h | 8 | ||||
-rw-r--r-- | runtime/interpreter/mterp/arm64ng/main.S | 2 | ||||
-rw-r--r-- | runtime/interpreter/mterp/armng/main.S | 3 | ||||
-rw-r--r-- | runtime/interpreter/mterp/nterp.cc | 7 | ||||
-rw-r--r-- | runtime/interpreter/mterp/riscv64/main.S | 5 | ||||
-rw-r--r-- | runtime/interpreter/mterp/x86_64ng/main.S | 3 | ||||
-rw-r--r-- | runtime/interpreter/mterp/x86ng/main.S | 3 | ||||
-rw-r--r-- | runtime/jit/jit-inl.h | 17 | ||||
-rw-r--r-- | runtime/jit/jit.cc | 3 | ||||
-rw-r--r-- | tools/cpp-define-generator/art_method.def | 4 |
11 files changed, 50 insertions, 8 deletions
diff --git a/runtime/art_method.cc b/runtime/art_method.cc index 5c48575672..8c0c7f56cc 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -766,6 +766,9 @@ void ArtMethod::SetIntrinsic(Intrinsics intrinsic) { } else { SetAccessFlags(new_value); } + + // Intrinsics are considered hot from the first call. + SetHotCounter(); } void ArtMethod::SetNotIntrinsic() { diff --git a/runtime/art_method.h b/runtime/art_method.h index 30dc09f67f..51520ddd4c 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -356,6 +356,14 @@ class EXPORT ArtMethod final { } static bool IsMemorySharedMethod(uint32_t access_flags) { + // There's an overlap with `kAccMemorySharedMethod` and `kAccIntrinsicBits` but that's OK as + // intrinsics are always in the boot image and therefore memory shared. + static_assert((kAccMemorySharedMethod & kAccIntrinsicBits) != 0, + "kAccMemorySharedMethod deliberately overlaps intrinsic bits"); + if (IsIntrinsic(access_flags)) { + return true; + } + return (access_flags & kAccMemorySharedMethod) != 0; } diff --git a/runtime/interpreter/mterp/arm64ng/main.S b/runtime/interpreter/mterp/arm64ng/main.S index 7d83edbad1..995ff86f18 100644 --- a/runtime/interpreter/mterp/arm64ng/main.S +++ b/runtime/interpreter/mterp/arm64ng/main.S @@ -1541,6 +1541,8 @@ END \name .macro CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot, if_not_hot ldr wip, [x0, #ART_METHOD_ACCESS_FLAGS_OFFSET] tbz wip, #ART_METHOD_IS_MEMORY_SHARED_FLAG_BIT, \if_hot + // Intrinsics are always in the boot image and considered hot. + tbnz wip, #ART_METHOD_IS_INTRINSIC_FLAG_BIT, \if_hot ldr wip, [xSELF, #THREAD_SHARED_METHOD_HOTNESS_OFFSET] cbz wip, \if_hot add wip, wip, #-1 diff --git a/runtime/interpreter/mterp/armng/main.S b/runtime/interpreter/mterp/armng/main.S index 906536654b..5298840f92 100644 --- a/runtime/interpreter/mterp/armng/main.S +++ b/runtime/interpreter/mterp/armng/main.S @@ -1544,6 +1544,9 @@ END \name ldr ip, [r0, #ART_METHOD_ACCESS_FLAGS_OFFSET] tst ip, #ART_METHOD_IS_MEMORY_SHARED_FLAG beq \if_hot + // Intrinsics are always in the boot image and considered hot. + tst ip, #ART_METHOD_IS_INTRINSIC_FLAG + bne \if_hot ldr ip, [rSELF, #THREAD_SHARED_METHOD_HOTNESS_OFFSET] cmp ip, #0 beq \if_hot diff --git a/runtime/interpreter/mterp/nterp.cc b/runtime/interpreter/mterp/nterp.cc index a69dd8c4c7..2fe9c24fa6 100644 --- a/runtime/interpreter/mterp/nterp.cc +++ b/runtime/interpreter/mterp/nterp.cc @@ -695,8 +695,11 @@ extern "C" jit::OsrData* NterpHotMethod(ArtMethod* method, uint16_t* dex_pc_ptr, ScopedAssertNoThreadSuspension sants("In nterp"); Runtime* runtime = Runtime::Current(); if (method->IsMemorySharedMethod()) { - DCHECK_EQ(Thread::Current()->GetSharedMethodHotness(), 0u); - Thread::Current()->ResetSharedMethodHotness(); + if (!method->IsIntrinsic()) { + // Intrinsics are special and will be considered hot from the first call. + DCHECK_EQ(Thread::Current()->GetSharedMethodHotness(), 0u); + Thread::Current()->ResetSharedMethodHotness(); + } } else { // Move the counter to the initial threshold in case we have to re-JIT it. method->ResetCounter(runtime->GetJITOptions()->GetWarmupThreshold()); diff --git a/runtime/interpreter/mterp/riscv64/main.S b/runtime/interpreter/mterp/riscv64/main.S index a9b917ad35..11428646ad 100644 --- a/runtime/interpreter/mterp/riscv64/main.S +++ b/runtime/interpreter/mterp/riscv64/main.S @@ -249,9 +249,12 @@ END \name // - xSELF // Clobbers: t0 .macro CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot, if_not_hot + // TODO(solanes): Figure out if there's a way to load t0 only once. lwu t0, ART_METHOD_ACCESS_FLAGS_OFFSET(a0) BRANCH_IF_BIT_CLEAR t0, t0, ART_METHOD_IS_MEMORY_SHARED_FLAG_BIT, \if_hot - + lwu t0, ART_METHOD_ACCESS_FLAGS_OFFSET(a0) + // Intrinsics are always in the boot image and considered hot. + BRANCH_IF_BIT_SET t0, t0, ART_METHOD_IS_INTRINSIC_FLAG_BIT, \if_hot lwu t0, THREAD_SHARED_METHOD_HOTNESS_OFFSET(xSELF) // t0 := hotness beqz t0, \if_hot diff --git a/runtime/interpreter/mterp/x86_64ng/main.S b/runtime/interpreter/mterp/x86_64ng/main.S index f6f48ffcc3..80753c4fc2 100644 --- a/runtime/interpreter/mterp/x86_64ng/main.S +++ b/runtime/interpreter/mterp/x86_64ng/main.S @@ -1610,6 +1610,9 @@ END_FUNCTION \name .macro CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot, if_not_hot testl $$ART_METHOD_IS_MEMORY_SHARED_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%rdi) jz \if_hot + // Intrinsics are always in the boot image and considered hot. + testl $$ART_METHOD_IS_INTRINSIC_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%rdi) + jnz \if_hot movzwl rSELF:THREAD_SHARED_METHOD_HOTNESS_OFFSET, %esi testl %esi, %esi je \if_hot diff --git a/runtime/interpreter/mterp/x86ng/main.S b/runtime/interpreter/mterp/x86ng/main.S index 65a6a75df1..d2f4271f99 100644 --- a/runtime/interpreter/mterp/x86ng/main.S +++ b/runtime/interpreter/mterp/x86ng/main.S @@ -1687,6 +1687,9 @@ END_FUNCTION \name .macro CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot, if_not_hot testl $$ART_METHOD_IS_MEMORY_SHARED_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%eax) jz \if_hot + // Intrinsics are always in the boot image and considered hot. + testl $$ART_METHOD_IS_INTRINSIC_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%eax) + jnz \if_hot movzwl rSELF:THREAD_SHARED_METHOD_HOTNESS_OFFSET, %ecx testl %ecx, %ecx je \if_hot diff --git a/runtime/jit/jit-inl.h b/runtime/jit/jit-inl.h index 52099c2e1d..684e5c85b0 100644 --- a/runtime/jit/jit-inl.h +++ b/runtime/jit/jit-inl.h @@ -17,6 +17,7 @@ #ifndef ART_RUNTIME_JIT_JIT_INL_H_ #define ART_RUNTIME_JIT_JIT_INL_H_ +#include "android-base/macros.h" #include "jit/jit.h" #include "art_method.h" @@ -28,12 +29,20 @@ namespace art HIDDEN { namespace jit { inline void Jit::AddSamples(Thread* self, ArtMethod* method) { + // `hotness_count_` should always be 0 for intrinsics (which are considered hot from the first + // call), and for memory shared methods which use `shared_method_hotness`. + DCHECK_IMPLIES(method->IsIntrinsic(), method->CounterIsHot()); + DCHECK_IMPLIES(method->IsMemorySharedMethod(), method->CounterIsHot()); + if (method->CounterIsHot()) { if (method->IsMemorySharedMethod()) { - if (self->DecrementSharedMethodHotness() == 0) { - self->ResetSharedMethodHotness(); - } else { - return; + // Intrinsics do not use `shared_method_hotness`. + if (!method->IsIntrinsic()) { + if (self->DecrementSharedMethodHotness() == 0) { + self->ResetSharedMethodHotness(); + } else { + return; + } } } else { method->ResetCounter(Runtime::Current()->GetJITOptions()->GetWarmupThreshold()); diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc index 29f01e137b..66fc1e639a 100644 --- a/runtime/jit/jit.cc +++ b/runtime/jit/jit.cc @@ -1685,7 +1685,8 @@ void Jit::MaybeEnqueueCompilation(ArtMethod* method, Thread* self) { } static constexpr size_t kIndividualSharedMethodHotnessThreshold = 0x3f; - if (method->IsMemorySharedMethod()) { + // Intrinsics are always in the boot image and considered hot. + if (method->IsMemorySharedMethod() && !method->IsIntrinsic()) { MutexLock mu(self, lock_); auto it = shared_method_counters_.find(method); if (it == shared_method_counters_.end()) { diff --git a/tools/cpp-define-generator/art_method.def b/tools/cpp-define-generator/art_method.def index d5ba59998d..3c34247ec2 100644 --- a/tools/cpp-define-generator/art_method.def +++ b/tools/cpp-define-generator/art_method.def @@ -21,6 +21,10 @@ ASM_DEFINE(ART_METHOD_ACCESS_FLAGS_OFFSET, art::ArtMethod::AccessFlagsOffset().Int32Value()) +ASM_DEFINE(ART_METHOD_IS_INTRINSIC_FLAG, + art::kAccIntrinsic) +ASM_DEFINE(ART_METHOD_IS_INTRINSIC_FLAG_BIT, + art::MostSignificantBit(art::kAccIntrinsic)) ASM_DEFINE(ART_METHOD_IS_MEMORY_SHARED_FLAG, art::kAccMemorySharedMethod) ASM_DEFINE(ART_METHOD_IS_MEMORY_SHARED_FLAG_BIT, |