8304303: implement VirtualThread class notifyJvmti methods as C2 intrinsics

Reviewed-by: vlivanov, lmesnik
This commit is contained in:
Serguei Spitsyn 2023-03-20 19:55:16 +00:00
parent 2d0d057d66
commit bc0ed730f2
20 changed files with 325 additions and 174 deletions

View file

@ -56,6 +56,7 @@ import jdk.internal.vm.ThreadContainers;
import jdk.internal.vm.annotation.ChangesCurrentThread;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.Hidden;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import jdk.internal.vm.annotation.JvmtiMountTransition;
import sun.nio.ch.Interruptible;
import sun.security.action.GetPropertyAction;
@ -210,7 +211,7 @@ final class VirtualThread extends BaseVirtualThread {
}
// notify JVMTI before mount
if (notifyJvmtiEvents) notifyJvmtiMountBegin(firstRun);
notifyJvmtiMount(true, firstRun);
try {
cont.run();
@ -287,11 +288,10 @@ final class VirtualThread extends BaseVirtualThread {
@ChangesCurrentThread
private void run(Runnable task) {
assert state == RUNNING;
boolean notifyJvmti = notifyJvmtiEvents;
// first mount
mount();
if (notifyJvmti) notifyJvmtiMountEnd(true);
notifyJvmtiMount(false, true);
// emit JFR event if enabled
if (VirtualThreadStartEvent.isTurnedOn()) {
@ -319,7 +319,7 @@ final class VirtualThread extends BaseVirtualThread {
} finally {
// last unmount
if (notifyJvmti) notifyJvmtiUnmountBegin(true);
notifyJvmtiUnmount(true, true);
unmount();
// final state
@ -381,35 +381,27 @@ final class VirtualThread extends BaseVirtualThread {
/**
* Sets the current thread to the current carrier thread.
* @return true if JVMTI was notified
*/
@ChangesCurrentThread
@JvmtiMountTransition
private boolean switchToCarrierThread() {
boolean notifyJvmti = notifyJvmtiEvents;
if (notifyJvmti) {
notifyJvmtiHideFrames(true);
}
private void switchToCarrierThread() {
notifyJvmtiHideFrames(true);
Thread carrier = this.carrierThread;
assert Thread.currentThread() == this
&& carrier == Thread.currentCarrierThread();
carrier.setCurrentThread(carrier);
return notifyJvmti;
}
/**
* Sets the current thread to the given virtual thread.
* If {@code notifyJvmti} is true then JVMTI is notified.
*/
@ChangesCurrentThread
@JvmtiMountTransition
private void switchToVirtualThread(VirtualThread vthread, boolean notifyJvmti) {
private void switchToVirtualThread(VirtualThread vthread) {
Thread carrier = vthread.carrierThread;
assert carrier == Thread.currentCarrierThread();
carrier.setCurrentThread(vthread);
if (notifyJvmti) {
notifyJvmtiHideFrames(false);
}
notifyJvmtiHideFrames(false);
}
/**
@ -419,17 +411,15 @@ final class VirtualThread extends BaseVirtualThread {
*/
@ChangesCurrentThread
private boolean yieldContinuation() {
boolean notifyJvmti = notifyJvmtiEvents;
// unmount
if (notifyJvmti) notifyJvmtiUnmountBegin(false);
notifyJvmtiUnmount(true, false);
unmount();
try {
return Continuation.yield(VTHREAD_SCOPE);
} finally {
// re-mount
mount();
if (notifyJvmti) notifyJvmtiMountEnd(false);
notifyJvmtiMount(false, false);
}
}
@ -446,7 +436,7 @@ final class VirtualThread extends BaseVirtualThread {
setState(PARKED);
// notify JVMTI that unmount has completed, thread is parked
if (notifyJvmtiEvents) notifyJvmtiUnmountEnd(false);
notifyJvmtiUnmount(false, false);
// may have been unparked while parking
if (parkPermit && compareAndSetState(PARKED, RUNNABLE)) {
@ -462,7 +452,7 @@ final class VirtualThread extends BaseVirtualThread {
setState(RUNNABLE);
// notify JVMTI that unmount has completed, thread is runnable
if (notifyJvmtiEvents) notifyJvmtiUnmountEnd(false);
notifyJvmtiUnmount(false, false);
// external submit if there are no tasks in the local task queue
if (currentThread() instanceof CarrierThread ct && ct.getQueuedTaskCount() == 0) {
@ -483,7 +473,7 @@ final class VirtualThread extends BaseVirtualThread {
assert (state() == TERMINATED) && (carrierThread == null);
if (executed) {
if (notifyJvmtiEvents) notifyJvmtiUnmountEnd(true);
notifyJvmtiUnmount(false, true);
}
// notify anyone waiting for this virtual thread to terminate
@ -651,11 +641,11 @@ final class VirtualThread extends BaseVirtualThread {
@ChangesCurrentThread
private Future<?> scheduleUnpark(Runnable unparker, long nanos) {
// need to switch to current carrier thread to avoid nested parking
boolean notifyJvmti = switchToCarrierThread();
switchToCarrierThread();
try {
return UNPARKER.schedule(unparker, nanos, NANOSECONDS);
} finally {
switchToVirtualThread(this, notifyJvmti);
switchToVirtualThread(this);
}
}
@ -666,11 +656,11 @@ final class VirtualThread extends BaseVirtualThread {
private void cancel(Future<?> future) {
if (!future.isDone()) {
// need to switch to current carrier thread to avoid nested parking
boolean notifyJvmti = switchToCarrierThread();
switchToCarrierThread();
try {
future.cancel(false);
} finally {
switchToVirtualThread(this, notifyJvmti);
switchToVirtualThread(this);
}
}
}
@ -690,11 +680,11 @@ final class VirtualThread extends BaseVirtualThread {
int s = state();
if (s == PARKED && compareAndSetState(PARKED, RUNNABLE)) {
if (currentThread instanceof VirtualThread vthread) {
boolean notifyJvmti = vthread.switchToCarrierThread();
vthread.switchToCarrierThread();
try {
submitRunContinuation();
} finally {
switchToVirtualThread(vthread, notifyJvmti);
switchToVirtualThread(vthread);
}
} else {
submitRunContinuation();
@ -1055,20 +1045,15 @@ final class VirtualThread extends BaseVirtualThread {
// -- JVM TI support --
private static volatile boolean notifyJvmtiEvents; // set by VM
@IntrinsicCandidate
@JvmtiMountTransition
private native void notifyJvmtiMountBegin(boolean firstMount);
private native void notifyJvmtiMount(boolean hide, boolean firstMount);
@IntrinsicCandidate
@JvmtiMountTransition
private native void notifyJvmtiMountEnd(boolean firstMount);
@JvmtiMountTransition
private native void notifyJvmtiUnmountBegin(boolean lastUnmount);
@JvmtiMountTransition
private native void notifyJvmtiUnmountEnd(boolean lastUnmount);
private native void notifyJvmtiUnmount(boolean hide, boolean lastUnmount);
@IntrinsicCandidate
@JvmtiMountTransition
private native void notifyJvmtiHideFrames(boolean hide);