summaryrefslogtreecommitdiff
path: root/runtime/art_method-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/art_method-inl.h')
-rw-r--r--runtime/art_method-inl.h26
1 files changed, 26 insertions, 0 deletions
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index 6e051424bd..b1d8a4ef54 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -669,6 +669,32 @@ inline void ArtMethod::UpdateEntrypoints(const Visitor& visitor, PointerSize poi
}
}
+template <ReadBarrierOption kReadBarrierOption>
+inline bool ArtMethod::StillNeedsClinitCheck() {
+ if (!NeedsClinitCheckBeforeCall()) {
+ return false;
+ }
+ ObjPtr<mirror::Class> klass = GetDeclaringClass<kReadBarrierOption>();
+ return !klass->IsVisiblyInitialized();
+}
+
+inline bool ArtMethod::StillNeedsClinitCheckMayBeDead() {
+ if (!NeedsClinitCheckBeforeCall()) {
+ return false;
+ }
+ // To avoid resurrecting an unreachable object, or crashing the GC in some GC phases,
+ // we must not use a full read barrier. 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.
+ ObjPtr<mirror::Class> klass = GetDeclaringClass<kWithoutReadBarrier>();
+ ObjPtr<mirror::Class> marked = ReadBarrier::IsMarked(klass.Ptr());
+ ObjPtr<mirror::Class> checked_klass = (marked != nullptr) ? marked : klass;
+ return !checked_klass->IsVisiblyInitialized();
+}
+
inline CodeItemInstructionAccessor ArtMethod::DexInstructions() {
return CodeItemInstructionAccessor(*GetDexFile(), GetCodeItem());
}