Skip to content

Commit

Permalink
[GR-51158] Implement VirtualThread.notifyJvmtiDisableSuspend intrinsic.
Browse files Browse the repository at this point in the history
PullRequest: graal/16529
  • Loading branch information
mur47x111 committed Jan 11, 2024
2 parents ed2da78 + c2a7b23 commit 34f4e93
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 148 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import jdk.graal.compiler.core.common.PermanentBailoutException;
import jdk.graal.compiler.core.test.SubprocessTest;
import jdk.graal.compiler.serviceprovider.GraalServices;
import jdk.graal.compiler.serviceprovider.JavaVersionUtil;
import jdk.graal.compiler.test.AddExports;
import jdk.graal.compiler.test.SubprocessUtil;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
Expand All @@ -42,6 +36,11 @@
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import jdk.graal.compiler.core.common.PermanentBailoutException;
import jdk.graal.compiler.core.test.SubprocessTest;
import jdk.graal.compiler.serviceprovider.GraalServices;
import jdk.graal.compiler.test.AddExports;
import jdk.graal.compiler.test.SubprocessUtil;
import jdk.jfr.Event;
import jdk.jfr.Recording;
import jdk.vm.ci.meta.ResolvedJavaMethod;
Expand All @@ -61,7 +60,6 @@
public class TestGetEventWriter extends SubprocessTest {

private static void initializeJFR() {
Assume.assumeTrue("JDK-8282420 came in JDK 19", JavaVersionUtil.JAVA_SPEC >= 19);
Assume.assumeTrue("Requires JDK-8290075", GraalServices.hasLookupMethodWithCaller());
try (Recording r = new Recording()) {
r.start();
Expand All @@ -82,7 +80,6 @@ static class InitializationEvent extends Event {

@Test
public void test() throws IOException, InterruptedException {
Assume.assumeTrue("JDK-8282420 came in JDK 19", JavaVersionUtil.JAVA_SPEC >= 19);
launchSubprocess(() -> {
try {
initializeJFR();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@
*/
package jdk.graal.compiler.replacements.test;

import static jdk.graal.compiler.serviceprovider.JavaVersionUtil.JAVA_SPEC;
import static org.junit.Assume.assumeTrue;

import jdk.graal.compiler.jtt.JTTTest;
import org.junit.Test;

import jdk.graal.compiler.jtt.JTTTest;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.InvalidInstalledCodeException;

Expand All @@ -49,7 +46,6 @@ public static short floatToFloat16(float f) {
*/
@Test
public void binary16RoundTrip() {
assumeTrue("Interpreter returns different result for silent NaNs prior to JDK-8302976", JAVA_SPEC >= 21);
for (int i = Short.MIN_VALUE; i < Short.MAX_VALUE; i++) {
short s = (short) i;
Result result = test("float16ToFloat", s);
Expand Down Expand Up @@ -248,7 +244,6 @@ public void roundFloatToBinary16FullBinade() throws InvalidInstalledCodeExceptio
*/
@Test
public void binary16NaNRoundTrip() {
assumeTrue("Interpreter returns different result for silent NaNs prior to JDK-8302976", JAVA_SPEC >= 21);
// A NaN has a nonzero significand
for (int i = 1; i <= 0x3ff; i++) {
short binary16NaN = (short) (NAN_EXPONENT | i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ public final int arrayOopDescLengthOffset() {

public final int threadIsInVTMSTransitionOffset = getFieldOffset("JavaThread::_is_in_VTMS_transition", Integer.class, "bool");
public final int threadIsInTmpVTMSTransitionOffset = getFieldOffset("JavaThread::_is_in_tmp_VTMS_transition", Integer.class, "bool");
public final int threadIsDisableSuspendOffset = getFieldOffset("JavaThread::_is_disable_suspend", Integer.class, "bool", -1, JDK >= 22);

public final int javaLangThreadJFREpochOffset = getFieldValue("java_lang_Thread::_jfr_epoch_offset", Integer.class, "int");
public final int javaLangThreadTIDOffset = getFieldValue("java_lang_Thread::_tid_offset", Integer.class, "int");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -622,52 +622,48 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
}
});

if (JavaVersionUtil.JAVA_SPEC >= 19) {
r.register(new InvocationPlugin("currentCarrierThread") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode value = helper.readCurrentThreadObject(false);
b.push(JavaKind.Object, value);
}
return true;
r.register(new InvocationPlugin("currentCarrierThread") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
ValueNode value = helper.readCurrentThreadObject(false);
b.push(JavaKind.Object, value);
}
});
return true;
}
});

r.register(new InlineOnlyInvocationPlugin("setCurrentThread", Receiver.class, Thread.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode thread) {
GraalError.guarantee(Services.IS_IN_NATIVE_IMAGE || isAnnotatedByChangesCurrentThread(b.getMethod()), "method changes current Thread but is not annotated ChangesCurrentThread");
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
receiver.get();
helper.setCurrentThread(thread);
}
return true;
r.register(new InlineOnlyInvocationPlugin("setCurrentThread", Receiver.class, Thread.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode thread) {
GraalError.guarantee(Services.IS_IN_NATIVE_IMAGE || isAnnotatedByChangesCurrentThread(b.getMethod()), "method changes current Thread but is not annotated ChangesCurrentThread");
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
receiver.get();
helper.setCurrentThread(thread);
}
});
}
return true;
}
});

if (JavaVersionUtil.JAVA_SPEC >= 20) {
r.registerConditional(config.threadScopedValueCacheOffset != -1, new InvocationPlugin("scopedValueCache") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
b.push(JavaKind.Object, helper.readThreadScopedValueCache());
}
return true;
r.registerConditional(config.threadScopedValueCacheOffset != -1, new InvocationPlugin("scopedValueCache") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
b.push(JavaKind.Object, helper.readThreadScopedValueCache());
}
});
return true;
}
});

r.registerConditional(config.threadScopedValueCacheOffset != -1, new InvocationPlugin("setScopedValueCache", Object[].class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode cache) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
helper.setThreadScopedValueCache(cache);
}
return true;
r.registerConditional(config.threadScopedValueCacheOffset != -1, new InvocationPlugin("setScopedValueCache", Object[].class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode cache) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
helper.setThreadScopedValueCache(cache);
}
});
}
return true;
}
});
}

// @formatter:off
Expand Down Expand Up @@ -721,8 +717,8 @@ private static void inlineNativeNotifyJvmtiFunctions(GraalHotSpotVMConfig config
}

private static void registerVirtualThreadPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
if (JavaVersionUtil.JAVA_SPEC >= 21 && config.supportJVMTIVThreadNotification()) {
Registration r = new Registration(plugins, "java.lang.VirtualThread", replacements);
Registration r = new Registration(plugins, "java.lang.VirtualThread", replacements);
if (config.supportJVMTIVThreadNotification()) {
r.register(new InvocationPlugin("notifyJvmtiStart", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
Expand Down Expand Up @@ -763,18 +759,38 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
return true;
}
});
r.register(new InvocationPlugin("notifyJvmtiHideFrames", Receiver.class, boolean.class) {
}
r.register(new InvocationPlugin("notifyJvmtiHideFrames", Receiver.class, boolean.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode hide) {
if (config.doJVMTIVirtualThreadTransitions) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
receiver.get();
// unconditionally update the temporary VTMS transition bit in current
// JavaThread
GraalError.guarantee(config.threadIsInTmpVTMSTransitionOffset != -1, "JavaThread::_is_in_tmp_VTMS_transition is not exported");
CurrentJavaThreadNode javaThread = b.add(new CurrentJavaThreadNode(helper.getWordKind()));
OffsetAddressNode address = b.add(new OffsetAddressNode(javaThread, helper.asWord(config.threadIsInTmpVTMSTransitionOffset)));
b.add(new JavaWriteNode(JavaKind.Boolean, address, HotSpotReplacementsUtil.HOTSPOT_JAVA_THREAD_IS_IN_TMP_VTMS_TRANSITION, hide, BarrierType.NONE, false));
}
}
return true;
}
});

if (JavaVersionUtil.JAVA_SPEC >= 22) {
r.register(new InvocationPlugin("notifyJvmtiDisableSuspend", Receiver.class, boolean.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode hide) {
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode enter) {
if (config.doJVMTIVirtualThreadTransitions) {
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
receiver.get();
// unconditionally update the temporary VTMS transition bit in current
// unconditionally update the is_disable_suspend bit in current
// JavaThread
GraalError.guarantee(config.threadIsInTmpVTMSTransitionOffset != -1L, "JavaThread::_is_in_tmp_VTMS_transition is not exported");
GraalError.guarantee(config.threadIsDisableSuspendOffset != -1, "JavaThread::_is_disable_suspend is not exported");
CurrentJavaThreadNode javaThread = b.add(new CurrentJavaThreadNode(helper.getWordKind()));
OffsetAddressNode address = b.add(new OffsetAddressNode(javaThread, helper.asWord(config.threadIsInTmpVTMSTransitionOffset)));
b.add(new JavaWriteNode(JavaKind.Boolean, address, HotSpotReplacementsUtil.HOTSPOT_JAVA_THREAD_IS_IN_TMP_VTMS_TRANSITION, hide, BarrierType.NONE, false));
OffsetAddressNode address = b.add(new OffsetAddressNode(javaThread, helper.asWord(config.threadIsDisableSuspendOffset)));
b.add(new JavaWriteNode(JavaKind.Boolean, address, HotSpotReplacementsUtil.HOTSPOT_JAVA_THREAD_IS_DISABLE_SUSPEND, enter, BarrierType.NONE, false));
}
}
return true;
Expand Down Expand Up @@ -898,10 +914,8 @@ private static void registerAESPlugins(InvocationPlugins plugins, GraalHotSpotVM
r.registerConditional(config.electronicCodeBookEncrypt != 0L, new ElectronicCodeBookCryptPlugin(CryptMode.ENCRYPT));
r.registerConditional(config.electronicCodeBookDecrypt != 0L, new ElectronicCodeBookCryptPlugin(CryptMode.DECRYPT));

if (JavaVersionUtil.JAVA_SPEC >= 18) {
r = new Registration(plugins, "com.sun.crypto.provider.GaloisCounterMode", replacements);
r.registerConditional(config.galoisCounterModeCrypt != 0L, new GaloisCounterModeCryptPlugin());
}
r = new Registration(plugins, "com.sun.crypto.provider.GaloisCounterMode", replacements);
r.registerConditional(config.galoisCounterModeCrypt != 0L, new GaloisCounterModeCryptPlugin());

r = new Registration(plugins, "com.sun.crypto.provider.CounterMode", replacements);
r.registerConditional(CounterModeAESNode.isSupported(arch), new CounterModeCryptPlugin() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ public UnimplementedGraalIntrinsics() {
"jdk/jfr/internal/JVM.getEventWriter()Ljdk/jfr/internal/event/EventWriter;");

add(toBeInvestigated, // @formatter:off
// JDK-8311218
"java/lang/VirtualThread.notifyJvmtiDisableSuspend(Z)V",
// JDK-8309130: x86_64 AVX512 intrinsics for Arrays.sort methods (GR-48679)
"java/util/DualPivotQuicksort.partition(Ljava/lang/Class;Ljava/lang/Object;JIIIILjava/util/DualPivotQuicksort$PartitionOperation;)[I",
"java/util/DualPivotQuicksort.sort(Ljava/lang/Class;Ljava/lang/Object;JIILjava/util/DualPivotQuicksort$SortOperation;)V",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

import java.lang.ref.Reference;

import org.graalvm.word.LocationIdentity;

import jdk.graal.compiler.api.replacements.Fold;
import jdk.graal.compiler.api.replacements.Fold.InjectedParameter;
import jdk.graal.compiler.core.common.SuppressFBWarnings;
Expand Down Expand Up @@ -58,10 +60,7 @@
import jdk.graal.compiler.nodes.type.StampTool;
import jdk.graal.compiler.replacements.ReplacementsUtil;
import jdk.graal.compiler.replacements.nodes.ReadRegisterNode;
import jdk.graal.compiler.serviceprovider.JavaVersionUtil;
import jdk.graal.compiler.word.Word;
import org.graalvm.word.LocationIdentity;

import jdk.vm.ci.code.Register;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
Expand Down Expand Up @@ -293,11 +292,9 @@ public static Object getPendingException(Word thread) {
* After that, it is never changed. In the presence of virtual threads from JDK 19 onwards, this
* value can change when a virtual thread is unmounted and then mounted again.
*/
public static final LocationIdentity JAVA_THREAD_CURRENT_THREAD_OBJECT_LOCATION = JavaVersionUtil.JAVA_SPEC < 19 ? NamedLocationIdentity.immutable("JavaThread::_threadObj")
: NamedLocationIdentity.mutable("JavaThread::_vthread");
public static final LocationIdentity JAVA_THREAD_CURRENT_THREAD_OBJECT_LOCATION = NamedLocationIdentity.mutable("JavaThread::_vthread");

public static final LocationIdentity JAVA_THREAD_CARRIER_THREAD_OBJECT_LOCATION = JavaVersionUtil.JAVA_SPEC < 19 ? JAVA_THREAD_CURRENT_THREAD_OBJECT_LOCATION
: NamedLocationIdentity.mutable("JavaThread::_threadObj");
public static final LocationIdentity JAVA_THREAD_CARRIER_THREAD_OBJECT_LOCATION = NamedLocationIdentity.mutable("JavaThread::_threadObj");

public static final LocationIdentity JAVA_THREAD_OSTHREAD_LOCATION = NamedLocationIdentity.mutable("JavaThread::_osthread");

Expand Down Expand Up @@ -884,17 +881,16 @@ public static NamedLocationIdentity mutable(String name) {
* This represents the contents of the OopHandle used to store the current thread. Virtual
* thread support makes this mutable.
*/
public static final LocationIdentity HOTSPOT_CURRENT_THREAD_OOP_HANDLE_LOCATION = JavaVersionUtil.JAVA_SPEC < 19 ? HOTSPOT_OOP_HANDLE_LOCATION
: OopHandleLocationIdentity.mutable("_vthread OopHandle contents");
public static final LocationIdentity HOTSPOT_CURRENT_THREAD_OOP_HANDLE_LOCATION = OopHandleLocationIdentity.mutable("_vthread OopHandle contents");

public static final LocationIdentity HOTSPOT_CARRIER_THREAD_OOP_HANDLE_LOCATION = JavaVersionUtil.JAVA_SPEC < 19 ? HOTSPOT_OOP_HANDLE_LOCATION
: OopHandleLocationIdentity.mutable("_threadObj OopHandle contents");
public static final LocationIdentity HOTSPOT_CARRIER_THREAD_OOP_HANDLE_LOCATION = OopHandleLocationIdentity.mutable("_threadObj OopHandle contents");

public static final LocationIdentity HOTSPOT_JAVA_THREAD_SCOPED_VALUE_CACHE_HANDLE_LOCATION = OopHandleLocationIdentity.mutable("_scopedValueCache OopHandle contents");

public static final LocationIdentity HOTSPOT_VTMS_NOTIFY_JVMTI_EVENTS = NamedLocationIdentity.mutable("JvmtiVTMSTransitionDisabler::_VTMS_notify_jvmti_events");
public static final LocationIdentity HOTSPOT_JAVA_THREAD_IS_IN_VTMS_TRANSITION = NamedLocationIdentity.mutable("JavaThread::_is_in_VTMS_transition");
public static final LocationIdentity HOTSPOT_JAVA_THREAD_IS_IN_TMP_VTMS_TRANSITION = NamedLocationIdentity.mutable("JavaThread::_is_in_tmp_VTMS_transition");
public static final LocationIdentity HOTSPOT_JAVA_THREAD_IS_DISABLE_SUSPEND = NamedLocationIdentity.mutable("JavaThread::_is_disable_suspend");
public static final LocationIdentity HOTSPOT_JAVA_LANG_THREAD_IS_IN_VTMS_TRANSITION = NamedLocationIdentity.mutable("Thread::_is_in_VTMS_transition");

@Fold
Expand Down
Loading

0 comments on commit 34f4e93

Please sign in to comment.