summaryrefslogtreecommitdiff
path: root/runtime/jit/jit_code_cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/jit/jit_code_cache.cc')
-rw-r--r--runtime/jit/jit_code_cache.cc33
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);