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