[jmm-dev] VarHandle.safepoint() methods

Paul Sandoz paul.sandoz at oracle.com
Fri Jan 6 23:56:09 UTC 2017

> On 6 Jan 2017, at 09:11, Gil Tene <gil at azul.com> wrote:
> An annotation on a method is probably just as good. I agree. The semantics should probably be that there are no checkpoint crossing boundaries taken between any operations in the method, or in any code it calls (it's ok to cross a checkpoint boundary on the call or return from the annotated method).
> And that annotation does not have to be HotSpot specific. In fact, it probably should not be HotSpot specific if we want to add an unmap() call to a JDK MappedByteBuffer and DirectByteBuffer classes [which is the motivation here]. This could be a JDK-only annotation maybe, at least to start, as I can see correctness and security concerns. E.g. what if someone runs an infinite loop or a blocking call in an @NoCheckpointBoundaries annotated method? [both could cause deadlocks].

Yes, hashing this out first internally to the JDK may mean we can make progress faster and can help determine how the mechanism be publicly exposed safely and efficiently.

By HotSpot specific i was thinking about the VM associated annotations such as @Contented, @Stable, @DontInline etc. currently located in the jdk.internal.vm.annotation package.


> The key here is that the indication needed from the java code is not about where to place checkpoint crossing boundaries, but where NOT to place them. Allowing the JVM to place boundaries anywhere it wants except for where it is specifically told not to. This will let this sort of thing fit in with the mass amount of existing code, use existing safepoint mechanisms, and achieve a zero-cost-for-Java-threads-that-don't-call-checkpoint() performance level [which is critical for things like buf.get()].
> For reference, Zing already implements a checkpoint mechanism in the JVM, using the existing per-thread safepoint polling mechanisms. So we have some experience with how it works and wth the various considerations. We use checkpoints for various JVM-internal stuff that requires this sort of "make sure everyone has crossed some line in the sand so that we know it is safe to proceed" functionality and wants to achieve it without adding any execution cost to Java threads. E.g. we use it in some of our GC mechanisms and phase shifts, for concurrent monitor deflation, and for some other internal-bookkeeping mechanisms.
> In our implementation, a checkpoint is not a STW pause, but an awaiting for threads to [concurrently] "cross a line in the sand" before proceeding. In Zing, a checkpoint() call completes once all Java threads are known to no longer be executing code that preceded a safepoint crossing boundary that executes after the checkpoint() call has been initiated [blocking counts as "being at a checkpoint crossing boundary"]. We achieve this by leveraging the existing in-code safepoint polling mechanism. We individually cause each Java threads to reach a safepoint and then let it proceed immediately (without blocking or waiting). Once we have verified that all Java threads have crossed the boundary (basically once we have managed to grab and release all their JVM locks), the checkpoint is complete. In our implementation, threads can be safepointed individually because safepoint polling is done on a per-thread indicators. But a global safepoint indicator (like the one HotSpot uses) can just as easily be used. It would not be concurrent, and would cause a (very short) STW pause, but would achieve the same semantic promise to the checkpoint()-using algorithm. And this discussion about unamp() is a good example of where such a mechansims can be generically useful.
> — Gil.
>> On Jan 6, 2017, at 1:56 AM, Andrew Haley <aph at redhat.com> wrote:
>> On 05/01/17 18:37, Paul Sandoz wrote:
>>> If we just consider an implementation specific solution i wonder if
>>> it’s possible to annotate the wrapped MappeByteBuffer methods with
>>> a hotspot specific annotation declaring they are “no check point
>>> boundaries" scoped. When a method is compiled/inlined the scope
>>> might be coarsened. That is likely easier to optimize than
>>> Runtime.callWithNoCheckpointBoundaries?
>> I have no problem at all doing this with a solution that is specific
>> to MappedByteBuffer.  Define a couple of Unsafe methods and I'm done.
>> (Well, it still requires surgery to the JIT, but that's OK.)
>> But my feeling is this: the problem has persisted so long (15 years)
>> because of what I consider to be a deficiency in the language.  It
>> ought to be possible to write this kind of thing in Pure Java, but
>> it's not.  There are other places in the library where this kind of
>> mechanism could be used.  So I'm willing to put in the effort to
>> get this standardized in a way that everyone is happy with.
>> Andrew.

More information about the jmm-dev mailing list