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.cc43
1 files changed, 15 insertions, 28 deletions
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index ee5d5c7ce3..86eedca285 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -127,31 +127,19 @@ class JitCodeCache::JniStubData {
DCHECK(entrypoint == OatQuickMethodHeader::FromCodePointer(GetCode())->GetEntryPoint());
instrumentation::Instrumentation* instrum = Runtime::Current()->GetInstrumentation();
for (ArtMethod* m : GetMethods()) {
- // Because `m` might be in the process of being deleted:
- // - Call the dedicated method instead of the more generic UpdateMethodsCode
- // - Check the class status without a full read barrier; use ReadBarrier::IsMarked().
- bool can_set_entrypoint = true;
- if (NeedsClinitCheckBeforeCall(m)) {
- // To avoid resurrecting an unreachable object, we must not use a full read
- // barrier but we do not want to miss updating an entrypoint under common
- // circumstances, i.e. during a GC the class becomes visibly initialized,
- // the method becomes hot, we compile the thunk and want to update the
- // entrypoint while the method's declaring class field still points to the
- // from-space class object with the old status. Therefore we read the
- // declaring class without a read barrier and check if it's already marked.
- // If yes, we check the status of the to-space class object as intended.
- // Otherwise, there is no to-space object and the from-space class object
- // contains the most recent value of the status field; even if this races
- // with another thread doing a read barrier and updating the status, that's
- // no different from a race with a thread that just updates the status.
- // Such race can happen only for the zygote method pre-compilation, as we
- // otherwise compile only thunks for methods of visibly initialized classes.
- ObjPtr<mirror::Class> klass = m->GetDeclaringClass<kWithoutReadBarrier>();
- ObjPtr<mirror::Class> marked = ReadBarrier::IsMarked(klass.Ptr());
- ObjPtr<mirror::Class> checked_klass = (marked != nullptr) ? marked : klass;
- can_set_entrypoint = checked_klass->IsVisiblyInitialized();
- }
- if (can_set_entrypoint) {
+ // Because `m` might be in the process of being deleted,
+ // - use the `ArtMethod::StillNeedsClinitCheckMayBeDead()` to check if
+ // we can update the entrypoint, and
+ // - call `Instrumentation::UpdateNativeMethodsCodeToJitCode` instead of the
+ // more generic function `Instrumentation::UpdateMethodsCode()`.
+ // The `ArtMethod::StillNeedsClinitCheckMayBeDead()` checks the class status
+ // in the to-space object if any even if the method's declaring class points to
+ // the from-space class object. This way we do not miss updating an entrypoint
+ // even under uncommon circumstances, when during a GC the class becomes visibly
+ // initialized, the method becomes hot, we compile the thunk and want to update
+ // the entrypoint while the method's declaring class field still points to the
+ // from-space class object with the old status.
+ if (!m->StillNeedsClinitCheckMayBeDead()) {
instrum->UpdateNativeMethodsCodeToJitCode(m, entrypoint);
}
}
@@ -741,8 +729,7 @@ bool JitCodeCache::Commit(Thread* self,
}
if (compilation_kind == CompilationKind::kOsr) {
osr_code_map_.Put(method, code_ptr);
- } else if (NeedsClinitCheckBeforeCall(method) &&
- !method->GetDeclaringClass()->IsVisiblyInitialized()) {
+ } else if (method->StillNeedsClinitCheck()) {
// This situation currently only occurs in the jit-zygote mode.
DCHECK(!garbage_collect_code_);
DCHECK(method->IsPreCompiled());
@@ -1636,7 +1623,7 @@ bool JitCodeCache::NotifyCompilationOf(ArtMethod* method,
}
}
- if (NeedsClinitCheckBeforeCall(method) && !prejit) {
+ if (method->NeedsClinitCheckBeforeCall() && !prejit) {
// We do not need a synchronization barrier for checking the visibly initialized status
// or checking the initialized status just for requesting visible initialization.
ClassStatus status = method->GetDeclaringClass()