diff options
author | 2021-11-17 13:16:35 +0000 | |
---|---|---|
committer | 2021-11-22 15:28:02 +0000 | |
commit | c17656bcf477e57d59ff051037c96994fd0ac8f2 (patch) | |
tree | 78704cdca54c7437a34c9ca4b9da27ed6e9c0f4d /runtime/entrypoints/entrypoint_utils-inl.h | |
parent | 53296a7ed4ccf1cccfb32ed9da3aae90bc8b7ff2 (diff) |
JNI: Rewrite locking for synchronized methods.
Lock and unlock in dedicated entrypoints instead of the
`JniMethodStart*()` and `JniMethodEnd*()` entrypoints.
Update x86 and x86-64 lock/unlock entrypoints to use the
same checks as arm and arm64.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: run-gtests.sh
Test: testrunner.py --target --optimizing
Bug: 172332525
Change-Id: I82b5af211aa22479f8b0eec7f3a50bc92ec87eca
Diffstat (limited to 'runtime/entrypoints/entrypoint_utils-inl.h')
-rw-r--r-- | runtime/entrypoints/entrypoint_utils-inl.h | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 3333b5fe0e..fd6bf1fb86 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -777,23 +777,27 @@ inline bool NeedsClinitCheckBeforeCall(ArtMethod* method) { return method->IsStatic() && !method->IsConstructor(); } -inline jobject GetGenericJniSynchronizationObject(Thread* self, ArtMethod* called) +inline ObjPtr<mirror::Object> GetGenericJniSynchronizationObject(Thread* self, ArtMethod* called) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(!called->IsCriticalNative()); DCHECK(!called->IsFastNative()); DCHECK(self->GetManagedStack()->GetTopQuickFrame() != nullptr); DCHECK_EQ(*self->GetManagedStack()->GetTopQuickFrame(), called); + // We do not need read barriers here. + // On method entry, all reference arguments are to-space references and we mark the + // declaring class of a static native method if needed. When visiting thread roots at + // the start of a GC, we visit all these references to ensure they point to the to-space. if (called->IsStatic()) { // Static methods synchronize on the declaring class object. - // The `jclass` is a pointer to the method's declaring class. - return reinterpret_cast<jobject>(called->GetDeclaringClassAddressWithoutBarrier()); + return called->GetDeclaringClass<kWithoutReadBarrier>(); } else { // Instance methods synchronize on the `this` object. // The `this` reference is stored in the first out vreg in the caller's frame. - // The `jobject` is a pointer to the spill slot. uint8_t* sp = reinterpret_cast<uint8_t*>(self->GetManagedStack()->GetTopQuickFrame()); size_t frame_size = RuntimeCalleeSaveFrame::GetFrameSize(CalleeSaveType::kSaveRefsAndArgs); - return reinterpret_cast<jobject>(sp + frame_size + static_cast<size_t>(kRuntimePointerSize)); + StackReference<mirror::Object>* this_ref = reinterpret_cast<StackReference<mirror::Object>*>( + sp + frame_size + static_cast<size_t>(kRuntimePointerSize)); + return this_ref->AsMirrorPtr(); } } |