Skip to content

Commit 5c41e26

Browse files
committed
[GR-48573] Deopt in Unsafe allocate based on jvmti _should_notify_object_alloc.
PullRequest: graal/16276
2 parents 5d65e5a + a247f41 commit 5c41e26

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,13 @@ public long defaultPrototypeMarkWord() {
402402
*/
403403
public final int maxOopMapStackOffset = getFieldValue("CompilerToVM::Data::_max_oop_map_stack_offset", Integer.class, "int");
404404

405+
/**
406+
* Address of {@code _should_notify_object_alloc}, which, if non-zero, modifies the intrinsic
407+
* for {@code Unsafe.allocateInstance} to deopt when
408+
* {@code *shouldNotifyObjectAllocAddress != 0}.
409+
*/
410+
public final long shouldNotifyObjectAllocAddress = getFieldValue("CompilerToVM::Data::_should_notify_object_alloc", Long.class, "int*", 0L, JDK >= 23);
411+
405412
// G1 Collector Related Values.
406413
public final byte dirtyCardValue = getConstant("CardTable::dirty_card", Byte.class);
407414
public final byte g1YoungCardValue = getConstant("G1CardTable::g1_young_gen", Byte.class);

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import jdk.graal.compiler.nodes.ConstantNode;
9090
import jdk.graal.compiler.nodes.EndNode;
9191
import jdk.graal.compiler.nodes.FieldLocationIdentity;
92+
import jdk.graal.compiler.nodes.FixedGuardNode;
9293
import jdk.graal.compiler.nodes.IfNode;
9394
import jdk.graal.compiler.nodes.LogicNode;
9495
import jdk.graal.compiler.nodes.MergeNode;
@@ -169,6 +170,8 @@
169170
import jdk.vm.ci.code.Architecture;
170171
import jdk.vm.ci.code.TargetDescription;
171172
import jdk.vm.ci.meta.ConstantReflectionProvider;
173+
import jdk.vm.ci.meta.DeoptimizationAction;
174+
import jdk.vm.ci.meta.DeoptimizationReason;
172175
import jdk.vm.ci.meta.JavaKind;
173176
import jdk.vm.ci.meta.MetaAccessProvider;
174177
import jdk.vm.ci.meta.ResolvedJavaField;
@@ -244,7 +247,7 @@ public void run() {
244247
registerBigIntegerPlugins(invocationPlugins, config, replacements);
245248
registerSHAPlugins(invocationPlugins, config, replacements);
246249
registerBase64Plugins(invocationPlugins, config, metaAccess, replacements);
247-
registerUnsafePlugins(invocationPlugins, replacements);
250+
registerUnsafePlugins(invocationPlugins, replacements, config);
248251
StandardGraphBuilderPlugins.registerInvocationPlugins(snippetReflection, invocationPlugins, replacements, true, false, true, graalRuntime.getHostProviders().getLowerer());
249252
registerArrayPlugins(invocationPlugins, replacements, config);
250253
registerStringPlugins(invocationPlugins, replacements, wordTypes, foreignCalls, config);
@@ -479,7 +482,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
479482
});
480483
}
481484

482-
private static void registerUnsafePlugins(InvocationPlugins plugins, Replacements replacements) {
485+
private static void registerUnsafePlugins(InvocationPlugins plugins, Replacements replacements, GraalHotSpotVMConfig config) {
483486
Registration r = new Registration(plugins, "jdk.internal.misc.Unsafe", replacements);
484487
r.register(new InvocationPlugin("copyMemory0", Receiver.class, Object.class, long.class, Object.class, long.class, long.class) {
485488
@Override
@@ -492,6 +495,19 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
492495
r.register(new InvocationPlugin("allocateInstance", Receiver.class, Class.class) {
493496
@Override
494497
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode clazz) {
498+
if (b.getGraph().getProfilingInfo() != null && b.getGraph().getProfilingInfo().getDeoptimizationCount(DeoptimizationReason.RuntimeConstraint) > 20) {
499+
// Heuristic to prevent deoptimization loops.
500+
return false;
501+
}
502+
if (config.shouldNotifyObjectAllocAddress != 0) {
503+
try (HotSpotInvocationPluginHelper helper = new HotSpotInvocationPluginHelper(b, targetMethod, config)) {
504+
OffsetAddressNode address = OffsetAddressNode.create(helper.asWord(config.shouldNotifyObjectAllocAddress));
505+
ValueNode shouldPostVMObjectAlloc = b.add(new JavaReadNode(JavaKind.Int, address, LocationIdentity.ANY_LOCATION, BarrierType.NONE, MemoryOrderMode.PLAIN, false));
506+
LogicNode testShouldPostVMObjectAlloc = IntegerEqualsNode.create(shouldPostVMObjectAlloc, ConstantNode.forInt(0), NodeView.DEFAULT);
507+
FixedGuardNode guard = new FixedGuardNode(testShouldPostVMObjectAlloc, DeoptimizationReason.RuntimeConstraint, DeoptimizationAction.InvalidateRecompile);
508+
b.add(guard);
509+
}
510+
}
495511
/* Emits a null-check for the otherwise unused receiver. */
496512
unsafe.get(true);
497513
/*

0 commit comments

Comments
 (0)