diff options
Diffstat (limited to 'runtime/jit/jit_code_cache.cc')
-rw-r--r-- | runtime/jit/jit_code_cache.cc | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index 4b69dc5c01..89be345875 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -649,6 +649,17 @@ void JitCodeCache::CopyInlineCacheInto( } } +static void ClearMethodCounter(ArtMethod* method, bool was_warm) + REQUIRES_SHARED(Locks::mutator_lock_) { + if (was_warm) { + method->SetPreviouslyWarm(); + } + method->ResetCounter(Runtime::Current()->GetJITOptions()->GetWarmupThreshold()); + // We add one sample so that the profile knows that the method was executed at least once. + // This is required for layout purposes. + method->UpdateCounter(/* new_samples= */ 1); +} + bool JitCodeCache::Commit(Thread* self, JitMemoryRegion* region, ArtMethod* method, @@ -716,9 +727,10 @@ bool JitCodeCache::Commit(Thread* self, bool single_impl_still_valid = true; for (ArtMethod* single_impl : cha_single_implementation_list) { if (!single_impl->HasSingleImplementation()) { - // Simply discard the compiled code. + // Simply discard the compiled code. Clear the counter so that it may be recompiled later. // Hopefully the class hierarchy will be more stable when compilation is retried. single_impl_still_valid = false; + ClearMethodCounter(method, /*was_warm=*/ false); break; } } @@ -813,6 +825,7 @@ bool JitCodeCache::RemoveMethod(ArtMethod* method, bool release_memory) { return false; } + ClearMethodCounter(method, /* was_warm= */ false); Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ nullptr); VLOG(jit) << "JIT removed (osr=" << std::boolalpha << osr << std::noboolalpha << ") " @@ -1234,6 +1247,15 @@ void JitCodeCache::MaybeUpdateInlineCache(ArtMethod* method, info->AddInvokeInfo(dex_pc, cls.Ptr()); } +void JitCodeCache::ResetHotnessCounter(ArtMethod* method, Thread* self) { + ScopedDebugDisallowReadBarriers sddrb(self); + MutexLock mu(self, *Locks::jit_lock_); + auto it = profiling_infos_.find(method); + DCHECK(it != profiling_infos_.end()); + it->second->ResetCounter(); +} + + void JitCodeCache::DoCollection(Thread* self) { ScopedTrace trace(__FUNCTION__); @@ -1584,6 +1606,8 @@ bool JitCodeCache::NotifyCompilationOf(ArtMethod* method, VLOG(jit) << "Not compiling " << method->PrettyMethod() << " because it has the resolution stub"; + // Give it a new chance to be hot. + ClearMethodCounter(method, /*was_warm=*/ false); return false; } } @@ -1684,12 +1708,15 @@ void JitCodeCache::InvalidateAllCompiledCode() { OatQuickMethodHeader::FromCodePointer(data.GetCode()); for (ArtMethod* method : data.GetMethods()) { if (method->GetEntryPointFromQuickCompiledCode() == method_header->GetEntryPoint()) { + ClearMethodCounter(method, /*was_warm=*/true); instr->InitializeMethodsCode(method, /*aot_code=*/ nullptr); } } } for (const auto& entry : method_code_map_) { ArtMethod* meth = entry.second; + // We were compiled, so we must be warm. + ClearMethodCounter(meth, /*was_warm=*/true); if (UNLIKELY(meth->IsObsolete())) { linker->SetEntryPointsForObsoleteMethod(meth); } else { @@ -1719,8 +1746,10 @@ void JitCodeCache::InvalidateCompiledCodeFor(ArtMethod* method, // Clear the method counter if we are running jitted code since we might want to jit this again in // the future. if (method_entrypoint == header->GetEntryPoint()) { - // The entrypoint is the one to invalidate, so we just update it to the interpreter entry point. + // The entrypoint is the one to invalidate, so we just update it to the interpreter entry point + // and clear the counter to get the method Jitted again. Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ nullptr); + ClearMethodCounter(method, /*was_warm=*/ true); } else { Thread* self = Thread::Current(); ScopedDebugDisallowReadBarriers sddrb(self); |