RFR 8247808: Move JVMTI strong oops to OopStorage
Stefan Karlsson
stefan.karlsson at oracle.com
Thu Jun 18 07:25:37 UTC 2020
Hi Coleen,
On 2020-06-17 23:25, coleen.phillimore at oracle.com wrote:
> Summary: Remove JVMTI oops_do calls from JVMTI and GCs
>
> Tested with tier1-3, also built shenandoah to verify shenandoah changes.
>
> open webrev at http://cr.openjdk.java.net/~coleenp/2020/8247808.01/webrev
https://cr.openjdk.java.net/~coleenp/2020/8247808.01/webrev/src/hotspot/share/prims/jvmtiImpl.cpp.udiff.html
JvmtiBreakpoint::~JvmtiBreakpoint() {
- if (_class_holder != NULL) {
- NativeAccess<>::oop_store(_class_holder, (oop)NULL);
- OopStorageSet::vm_global()->release(_class_holder);
+ if (_class_holder.resolve() != NULL) {
+ _class_holder.release();
}
}
Could this be changed to peek() / release() instead? The resolve() call
is going to keep the object alive until next for ZGC marking cycle.
The rest looks OK.
Below are some comments about things that I find odd and non-obvious
from reading the code, and may be potentials for cleanups to make it
easier for the next to understand the code:
The above code assumes that as soon as OopHandle::create has been
called, we won't store NULL into the _obj pointer. If someone does, then
we would leak the memory. OopHandle has a function ptr_raw, that allows
someone to clear the _obj pointer. I have to assume that this function
isn't used in this code.
---
214 void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
215 _method = bp._method;
216 _bci = bp._bci;
217 _class_holder = OopHandle::create(bp._class_holder.resolve());
218 }
This one looks odd, because the _class_holder is overwritten without
releasing the old OopHandle. This is currently OK, because copy is only
called from clone, which just created a new JvmtiBreakpoint:
GrowableElement *clone() {
JvmtiBreakpoint *bp = new JvmtiBreakpoint();
bp->copy(*this);
return bp;
}
I think this would have been much more obvious if copy/clone were a
copy constructor.
With that said, it looks like we now have two JvmtiBreakpoints with the
same OopHandle contents. So, OopHandle::release will be called twice.
Now that works because release clears the oop value:
inline void OopHandle::release() {
// Clear the OopHandle first
NativeAccess<>::oop_store(_obj, (oop)NULL);
OopStorageSet::vm_global()->release(_obj);
}
and the resolve() != NULL check will prevent the OopHandle from being
released twice:
+ if (_class_holder.resolve() != NULL) {
+ _class_holder.release();
}
StefanK
> bug link https://bugs.openjdk.java.net/browse/JDK-8247808
>
> Thanks,
> Coleen
More information about the serviceability-dev
mailing list