Skip to content

Commit 003cd45

Browse files
committed
Adapt JDK-8338383: Implementation of Synchronize Virtual Threads without Pinning
1 parent af0ecc2 commit 003cd45

File tree

6 files changed

+164
-91
lines changed

6 files changed

+164
-91
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ public final int arrayOopDescLengthOffset() {
302302
public final int threadCarrierThreadObjectOffset = getFieldOffset("JavaThread::_threadObj", Integer.class, "OopHandle");
303303
public final int threadScopedValueCacheOffset = getFieldOffset("JavaThread::_scopedValueCache", Integer.class, "OopHandle");
304304

305+
public final int javaThreadLockIDOffset = getFieldOffset("JavaThread::_lock_id", Integer.class, "int64_t", -1, JDK > 21);
306+
305307
public final int threadIsInVTMSTransitionOffset = getFieldOffset("JavaThread::_is_in_VTMS_transition", Integer.class, "bool");
306308
public final int threadIsInTmpVTMSTransitionOffset = getFieldOffset("JavaThread::_is_in_tmp_VTMS_transition", Integer.class, "bool", -1, JDK == 21);
307309
public final int threadIsDisableSuspendOffset = getFieldOffset("JavaThread::_is_disable_suspend", Integer.class, "bool", -1, JDK >= 22);
@@ -387,15 +389,18 @@ public int threadLastJavaFpOffset() {
387389
// The following three constants are declared as 64 bits uintptr_t, but known to be 32 bits
388390
public final int unlockedValue = getConstant("markWord::unlocked_value", Integer.class);
389391
public final int monitorValue = getConstant("markWord::monitor_value", Integer.class);
392+
public final int ageMaskInPlace = getConstant("markWord::age_mask_in_place", Integer.class);
393+
public final int unusedMark = getConstant("markWord::marked_value", Integer.class);
390394
// Identity hash code value when uninitialized.
391395
public final int uninitializedIdentityHashCodeValue = getConstant("markWord::no_hash", Integer.class);
392396

393397
// This field has no type in vmStructs.cpp
394-
public final int objectMonitorOwner = getFieldOffset("ObjectMonitor::_owner", Integer.class, null);
398+
public final int objectMonitorOwner = getFieldOffset("ObjectMonitor::_owner", Integer.class, JDK > 21 ? "int64_t" : null);
395399
public final int objectMonitorRecursions = getFieldOffset("ObjectMonitor::_recursions", Integer.class, "intptr_t");
396400
public final int objectMonitorCxq = getFieldOffset("ObjectMonitor::_cxq", Integer.class, "ObjectWaiter*");
397401
public final int objectMonitorEntryList = getFieldOffset("ObjectMonitor::_EntryList", Integer.class, "ObjectWaiter*");
398-
public final int objectMonitorSucc = getFieldOffset("ObjectMonitor::_succ", Integer.class, "JavaThread*");
402+
public final int objectMonitorSucc = getFieldOffset("ObjectMonitor::_succ", Integer.class, JDK > 21 ? "int64_t" : "JavaThread*");
403+
public final int objectMonitorStackLocker = getFieldOffset("ObjectMonitor::_stack_locker", Integer.class, "BasicLock*");
399404

400405
public final int contEntry = getFieldOffset("JavaThread::_cont_entry", Integer.class, "ContinuationEntry*", -1, JDK >= 24);
401406
public final int pinCount = getFieldOffset("ContinuationEntry::_pin_count", Integer.class, "uint32_t", -1, JDK >= 24);

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@
4040
import static jdk.graal.compiler.hotspot.HotSpotBackend.SHAREDRUNTIME_NOTIFY_JVMTI_VTHREAD_UNMOUNT;
4141
import static jdk.graal.compiler.hotspot.HotSpotBackend.UPDATE_BYTES_CRC32;
4242
import static jdk.graal.compiler.hotspot.HotSpotBackend.UPDATE_BYTES_CRC32C;
43+
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.HOTSPOT_CARRIER_THREAD_OOP_HANDLE_LOCATION;
4344
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.HOTSPOT_CONTINUATION_ENTRY_PIN_COUNT;
45+
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.HOTSPOT_CURRENT_THREAD_OOP_HANDLE_LOCATION;
4446
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.HOTSPOT_JAVA_THREAD_CONT_ENTRY;
47+
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.HOTSPOT_JAVA_THREAD_SCOPED_VALUE_CACHE_HANDLE_LOCATION;
48+
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.JAVA_THREAD_LOCK_ID_LOCATION;
4549
import static jdk.graal.compiler.java.BytecodeParserOptions.InlineDuringParsing;
4650
import static jdk.graal.compiler.nodes.ConstantNode.forBoolean;
4751
import static jdk.graal.compiler.nodes.ProfileData.BranchProbabilityData.injected;
@@ -69,7 +73,9 @@
6973
import jdk.graal.compiler.core.common.memory.BarrierType;
7074
import jdk.graal.compiler.core.common.memory.MemoryOrderMode;
7175
import jdk.graal.compiler.core.common.spi.ForeignCallDescriptor;
76+
import jdk.graal.compiler.core.common.type.ObjectStamp;
7277
import jdk.graal.compiler.core.common.type.StampFactory;
78+
import jdk.graal.compiler.core.common.type.TypeReference;
7379
import jdk.graal.compiler.debug.GraalError;
7480
import jdk.graal.compiler.hotspot.GraalHotSpotVMConfig;
7581
import jdk.graal.compiler.hotspot.HotSpotBackend;
@@ -78,6 +84,7 @@
7884
import jdk.graal.compiler.hotspot.nodes.HotSpotLoadReservedReferenceNode;
7985
import jdk.graal.compiler.hotspot.nodes.HotSpotStoreReservedReferenceNode;
8086
import jdk.graal.compiler.hotspot.nodes.KlassFullyInitializedCheckNode;
87+
import jdk.graal.compiler.hotspot.nodes.VirtualThreadUpdateJFRNode;
8188
import jdk.graal.compiler.hotspot.replacements.CallSiteTargetNode;
8289
import jdk.graal.compiler.hotspot.replacements.DigestBaseSnippets;
8390
import jdk.graal.compiler.hotspot.replacements.FastNotifyNode;
@@ -142,6 +149,8 @@
142149
import jdk.graal.compiler.nodes.java.DynamicNewInstanceWithExceptionNode;
143150
import jdk.graal.compiler.nodes.java.NewArrayNode;
144151
import jdk.graal.compiler.nodes.java.ValidateNewInstanceClassNode;
152+
import jdk.graal.compiler.nodes.memory.ReadNode;
153+
import jdk.graal.compiler.nodes.memory.WriteNode;
145154
import jdk.graal.compiler.nodes.memory.address.AddressNode;
146155
import jdk.graal.compiler.nodes.memory.address.OffsetAddressNode;
147156
import jdk.graal.compiler.nodes.spi.Replacements;
@@ -663,14 +672,28 @@ private static boolean isAnnotatedByChangesCurrentThread(ResolvedJavaMethod meth
663672
return false;
664673
}
665674

675+
private static AddressNode getScopedValueCacheAddress(GraphBuilderContext b, HotSpotInvocationPluginHelper helper) {
676+
CurrentJavaThreadNode javaThread = b.add(new CurrentJavaThreadNode(helper.getWordKind()));
677+
ValueNode scopedValueCacheHandle = helper.readJavaThreadScopedValueCache(javaThread);
678+
return b.add(OffsetAddressNode.create(scopedValueCacheHandle));
679+
}
680+
666681
private static void registerThreadPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
682+
BarrierSet barrierSet = replacements.getProviders().getPlatformConfigurationProvider().getBarrierSet();
667683
Registration r = new Registration(plugins, Thread.class, replacements);
668684
r.register(new InvocationPlugin("currentThread") {
669685
@Override
670686
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
671687
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
672-
ValueNode value = helper.readCurrentThreadObject(true);
673-
b.push(JavaKind.Object, value);
688+
CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(helper.getWordKind()));
689+
ValueNode vthreadHandle = helper.readJavaThreadVthread(thread);
690+
// Read the Object from the OopHandle
691+
AddressNode handleAddress = b.add(OffsetAddressNode.create(vthreadHandle));
692+
// JavaThread::_vthread is never compressed
693+
ObjectStamp threadStamp = StampFactory.objectNonNull(TypeReference.create(b.getAssumptions(), b.getMetaAccess().lookupJavaType(Thread.class)));
694+
ValueNode read = new ReadNode(handleAddress, HOTSPOT_CURRENT_THREAD_OOP_HANDLE_LOCATION, threadStamp,
695+
barrierSet.readBarrierType(HOTSPOT_CURRENT_THREAD_OOP_HANDLE_LOCATION, handleAddress, threadStamp), MemoryOrderMode.PLAIN);
696+
b.addPush(JavaKind.Object, read);
674697
}
675698
return true;
676699
}
@@ -680,8 +703,15 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
680703
@Override
681704
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
682705
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
683-
ValueNode value = helper.readCurrentThreadObject(false);
684-
b.push(JavaKind.Object, value);
706+
CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(helper.getWordKind()));
707+
ValueNode cthreadHandle = helper.readJavaThreadThreadObj(thread);
708+
// Read the Object from the OopHandle
709+
AddressNode handleAddress = b.add(OffsetAddressNode.create(cthreadHandle));
710+
// JavaThread::_threadObj is never compressed
711+
ObjectStamp threadStamp = StampFactory.objectNonNull(TypeReference.create(b.getAssumptions(), b.getMetaAccess().lookupJavaType(Thread.class)));
712+
ValueNode read = new ReadNode(handleAddress, HOTSPOT_CARRIER_THREAD_OOP_HANDLE_LOCATION, threadStamp,
713+
barrierSet.readBarrierType(HOTSPOT_CARRIER_THREAD_OOP_HANDLE_LOCATION, handleAddress, threadStamp), MemoryOrderMode.PLAIN);
714+
b.addPush(JavaKind.Object, read);
685715
}
686716
return true;
687717
}
@@ -693,7 +723,22 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
693723
GraalError.guarantee(ImageInfo.inImageRuntimeCode() || isAnnotatedByChangesCurrentThread(b.getMethod()), "method changes current Thread but is not annotated ChangesCurrentThread");
694724
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
695725
receiver.get(true);
696-
helper.setCurrentThread(thread);
726+
CurrentJavaThreadNode javaThread = b.add(new CurrentJavaThreadNode(helper.getWordKind()));
727+
ValueNode threadObjectHandle = helper.readJavaThreadVthread(javaThread);
728+
AddressNode handleAddress = b.add(OffsetAddressNode.create(threadObjectHandle));
729+
b.add(new WriteNode(handleAddress, HOTSPOT_CURRENT_THREAD_OOP_HANDLE_LOCATION, thread,
730+
barrierSet.writeBarrierType(HOTSPOT_CURRENT_THREAD_OOP_HANDLE_LOCATION), MemoryOrderMode.PLAIN));
731+
732+
if (JavaVersionUtil.JAVA_SPEC > 21) {
733+
GraalError.guarantee(config.javaThreadLockIDOffset != -1, "JavaThread::_lock_id should have been exported");
734+
// Change the lock_id of the JavaThread
735+
ValueNode tid = helper.loadField(thread, helper.getField(b.getMetaAccess().lookupJavaType(Thread.class), "tid"));
736+
OffsetAddressNode address = b.add(new OffsetAddressNode(javaThread, helper.asWord(config.javaThreadLockIDOffset)));
737+
b.add(new JavaWriteNode(JavaKind.Long, address, JAVA_THREAD_LOCK_ID_LOCATION, tid, BarrierType.NONE, false));
738+
}
739+
if (HotSpotReplacementsUtil.supportsVirtualThreadUpdateJFR(config)) {
740+
b.add(new VirtualThreadUpdateJFRNode(thread));
741+
}
697742
}
698743
return true;
699744
}
@@ -703,7 +748,11 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
703748
@Override
704749
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
705750
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
706-
b.push(JavaKind.Object, helper.readThreadScopedValueCache());
751+
AddressNode handleAddress = getScopedValueCacheAddress(b, helper);
752+
ObjectStamp stamp = StampFactory.object(TypeReference.create(b.getAssumptions(), b.getMetaAccess().lookupJavaType(Object[].class)));
753+
b.push(JavaKind.Object, b.add(new ReadNode(handleAddress, HOTSPOT_JAVA_THREAD_SCOPED_VALUE_CACHE_HANDLE_LOCATION, stamp,
754+
barrierSet.readBarrierType(HOTSPOT_JAVA_THREAD_SCOPED_VALUE_CACHE_HANDLE_LOCATION, handleAddress, stamp),
755+
MemoryOrderMode.PLAIN)));
707756
}
708757
return true;
709758
}
@@ -713,7 +762,10 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
713762
@Override
714763
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode cache) {
715764
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
716-
helper.setThreadScopedValueCache(cache);
765+
AddressNode handleAddress = getScopedValueCacheAddress(b, helper);
766+
b.add(new WriteNode(handleAddress, HOTSPOT_JAVA_THREAD_SCOPED_VALUE_CACHE_HANDLE_LOCATION, cache,
767+
barrierSet.writeBarrierType(HOTSPOT_JAVA_THREAD_SCOPED_VALUE_CACHE_HANDLE_LOCATION),
768+
MemoryOrderMode.PLAIN));
717769
}
718770
return true;
719771
}
@@ -911,6 +963,21 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
911963
}
912964
});
913965
}
966+
967+
if (JavaVersionUtil.JAVA_SPEC > 21) {
968+
r.registerConditional(config.javaThreadLockIDOffset != -1, new InvocationPlugin("setLockId", Receiver.class, long.class) {
969+
@Override
970+
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode tid) {
971+
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
972+
receiver.get(true);
973+
CurrentJavaThreadNode javaThread = b.add(new CurrentJavaThreadNode(helper.getWordKind()));
974+
OffsetAddressNode address = b.add(new OffsetAddressNode(javaThread, helper.asWord(config.javaThreadLockIDOffset)));
975+
b.add(new JavaWriteNode(JavaKind.Long, address, JAVA_THREAD_LOCK_ID_LOCATION, tid, BarrierType.NONE, false));
976+
}
977+
return true;
978+
}
979+
});
980+
}
914981
}
915982

916983
private static ResolvedJavaType resolveTypeAESCrypt(ResolvedJavaType context) {

0 commit comments

Comments
 (0)