RFR: 8256302: releasing oopStorage when deflating allows for faster deleting
Daniel D. Daugherty
dcubed at openjdk.org
Thu Jun 1 20:28:12 UTC 2023
On Fri, 2 Dec 2022 07:35:40 GMT, Robbin Ehn <rehn at openjdk.org> wrote:
>>> You can ask by doing `_object().is_null()`
>>
>> Are you allowed to do that when safepoint-safe?
>
>> > You can ask by doing `_object().is_null()`
>>
>> Are you allowed to do that when safepoint-safe?
>
> Yes, since we are only checking if we have pointer to an oop and not actually touching the oop it self.
>
> oop* _obj;
> ...
> return _obj == NULL;
The sanity check code that @robehn proposed has an error:
ObjectMonitor::~ObjectMonitor() {
+ if (UseNewCode) guarantee(_object.is_null(), "Destructor must never be called if weak handle is not released.");
}
The `_object.is_null()` always returns false because the `_object` field is allocated
as a WeakHandle at ObjectMonitor construction time so it is never null.
The right code is this:
ObjectMonitor::~ObjectMonitor() {
+ if (UseNewCode) guarantee(_object.peek() == nullptr, "Destructor must never be called if weak handle is not released.");
}
but that code blows up with this PR because we are calling WeakHandle.peek() from a
thread state of `_thread_blocked` which results in this failure mode:
# Internal Error (/System/Volumes/Data/work/shared/bug_hunt/8256302_for_jdk21.git/open/src/hotspot/share/oops/accessBackend.cpp:224), pid=87344, tid=23555
# assert(state == _thread_in_vm || state == _thread_in_Java || state == _thread_new) failed: Wrong thread state for accesses: 10
<snip>
V [libjvm.dylib+0x6ec95c] report_vm_error(char const*, int, char const*, char const*, ...)+0x1ac
V [libjvm.dylib+0x10098] AccessInternal::check_access_thread_state()+0xb8
V [libjvm.dylib+0x382bd1] AccessInternal::RuntimeDispatch<593988ull, oopDesc*, (AccessInternal::BarrierType)2>::load(void*)+0x11
V [libjvm.dylib+0x382b81] std::__1::enable_if<!(HasDecorator<593988ull, AS_RAW>::value), oopDesc*>::type AccessInternal::PreRuntimeDispatch::load<593988ull, oopDesc*>(void*)+0x41
V [libjvm.dylib+0x382b38] oopDesc* AccessInternal::load_reduce_types<593988ull, oopDesc*>(oopDesc**)+0x18
V [libjvm.dylib+0x382b02] oopDesc* AccessInternal::load<593924ull, oopDesc*, oopDesc*>(oopDesc**)+0x22
V [libjvm.dylib+0x382a38] AccessInternal::OopLoadProxy<oopDesc*, 593920ull>::operator oopDesc*()+0x18
V [libjvm.dylib+0x5f62f6] WeakHandle::peek() const+0x76
V [libjvm.dylib+0xfefcab] ObjectMonitor::~ObjectMonitor()+0x3b
V [libjvm.dylib+0xfefd05] ObjectMonitor::~ObjectMonitor()+0x15
V [libjvm.dylib+0x1279b74] delete_monitors(GrowableArray<ObjectMonitor*>*)+0x84
V [libjvm.dylib+0x12796c0] ObjectSynchronizer::deflate_idle_monitors(ObjectMonitorsHashtable*)+0x510
V [libjvm.dylib+0xfa0f6b] MonitorDeflationThread::monitor_deflation_thread_entry(JavaThread*, JavaThread*)+0x12b
Remember, the key piece of this idea is that we want to delete the ObjectMonitors
from the MonitorDeflationThread while the thread is in `_thread_blocked` so that
we don't delay any safepoints.
If we do that, then we can't do even the simplest thing with the _object WeakHandle.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/11296#issuecomment-1572729642
More information about the hotspot-runtime-dev
mailing list