Skip to content

Commit 3359acd

Browse files
committed
[GR-64589] Use floating code base reads for virtual dispatch outside deopt targets.
PullRequest: graal/23310
2 parents 1e01493 + d9e5694 commit 3359acd

3 files changed

Lines changed: 40 additions & 21 deletions

File tree

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/ReservedRegisters.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,12 @@
3030
import org.graalvm.nativeimage.Platform;
3131
import org.graalvm.nativeimage.Platforms;
3232

33+
import com.oracle.svm.core.graal.nodes.ReadReservedRegisterFixedNode;
34+
import com.oracle.svm.core.graal.nodes.ReadReservedRegisterFloatingNode;
35+
import com.oracle.svm.core.meta.SharedMethod;
36+
3337
import jdk.graal.compiler.api.replacements.Fold;
38+
import jdk.graal.compiler.nodes.StructuredGraph;
3439
import jdk.vm.ci.code.Register;
3540
import jdk.vm.ci.code.RegisterValue;
3641
import jdk.vm.ci.meta.JavaValue;
@@ -102,4 +107,20 @@ public boolean isAllowedInFrameState(JavaValue value) {
102107
public boolean isReservedRegister(Register r) {
103108
return r.equals(frameRegister) || r.equals(heapBaseRegister) || r.equals(threadRegister) || r.equals(codeBaseRegister);
104109
}
110+
111+
/**
112+
* Determines whether a graph must use fixed read nodes for a reserved register or can use
113+
* floating reads instead.
114+
*
115+
* A floating node to access the register is more efficient: it allows value numbering of
116+
* multiple accesses, including floating nodes that use it as an input. But for deoptimization
117+
* target methods, we must not do value numbering because there is no proxying at deoptimization
118+
* entry points for this node, so the value is not restored during deoptimization.
119+
*
120+
* @see ReadReservedRegisterFixedNode
121+
* @see ReadReservedRegisterFloatingNode
122+
*/
123+
public boolean mustUseFixedRead(StructuredGraph graph) {
124+
return graph.method() instanceof SharedMethod m && m.isDeoptTarget();
125+
}
105126
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/NonSnippetLowerings.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import com.oracle.svm.core.graal.nodes.LoadOpenTypeWorldDispatchTableStartingOffset;
5252
import com.oracle.svm.core.graal.nodes.LoweredDeadEndNode;
5353
import com.oracle.svm.core.graal.nodes.ReadReservedRegisterFixedNode;
54+
import com.oracle.svm.core.graal.nodes.ReadReservedRegisterFloatingNode;
5455
import com.oracle.svm.core.graal.nodes.ThrowBytecodeExceptionNode;
5556
import com.oracle.svm.core.hub.crema.CremaSupport;
5657
import com.oracle.svm.core.imagelayer.DynamicImageLayerInfo;
@@ -668,13 +669,14 @@ ValueNode createVirtualMethodAddressLoad(
668669

669670
ValueNode virtualMethodAddress;
670671
if (relativeCodePointers) {
671-
/*
672-
* GR-64589: this can be a floating read outside of deoptimization target methods,
673-
* but this code has no knowledge of deoptimization (class ReadReservedRegister).
674-
*/
675-
FixedWithNextNode codeBase = graph.add(new ReadReservedRegisterFixedNode(ReservedRegisters.singleton().getCodeBaseRegister()));
676-
graph.addBeforeFixed(prependTo, codeBase);
677-
672+
ValueNode codeBase;
673+
ReservedRegisters rr = ReservedRegisters.singleton();
674+
if (rr.mustUseFixedRead(graph)) {
675+
codeBase = graph.add(new ReadReservedRegisterFixedNode(rr.getCodeBaseRegister()));
676+
graph.addBeforeFixed(prependTo, (FixedWithNextNode) codeBase);
677+
} else {
678+
codeBase = graph.unique(new ReadReservedRegisterFloatingNode(rr.getCodeBaseRegister()));
679+
}
678680
virtualMethodAddress = graph.unique(new AddNode(vtableEntry, codeBase));
679681
} else {
680682
virtualMethodAddress = vtableEntry;

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/nodes/ReadReservedRegister.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import com.oracle.svm.core.ReservedRegisters;
2828
import com.oracle.svm.core.graal.nodes.ReadReservedRegisterFixedNode;
2929
import com.oracle.svm.core.graal.nodes.ReadReservedRegisterFloatingNode;
30-
import com.oracle.svm.hosted.code.SubstrateCompilationDirectives;
3130

3231
import jdk.graal.compiler.nodes.StructuredGraph;
3332
import jdk.graal.compiler.nodes.ValueNode;
@@ -36,30 +35,27 @@
3635
public class ReadReservedRegister {
3736

3837
public static ValueNode createReadStackPointerNode(StructuredGraph graph) {
39-
return createReadNode(graph, ReservedRegisters.singleton().getFrameRegister());
38+
var rr = ReservedRegisters.singleton();
39+
return createReadNode(rr.mustUseFixedRead(graph), rr.getFrameRegister());
4040
}
4141

4242
public static ValueNode createReadIsolateThreadNode(StructuredGraph graph) {
43-
return createReadNode(graph, ReservedRegisters.singleton().getThreadRegister());
43+
var rr = ReservedRegisters.singleton();
44+
return createReadNode(rr.mustUseFixedRead(graph), rr.getThreadRegister());
4445
}
4546

4647
public static ValueNode createReadHeapBaseNode(StructuredGraph graph) {
47-
return createReadNode(graph, ReservedRegisters.singleton().getHeapBaseRegister());
48+
var rr = ReservedRegisters.singleton();
49+
return createReadNode(rr.mustUseFixedRead(graph), rr.getHeapBaseRegister());
4850
}
4951

5052
public static ValueNode createReadCodeBaseNode(StructuredGraph graph) {
51-
return createReadNode(graph, ReservedRegisters.singleton().getCodeBaseRegister());
53+
var rr = ReservedRegisters.singleton();
54+
return createReadNode(rr.mustUseFixedRead(graph), rr.getCodeBaseRegister());
5255
}
5356

54-
private static ValueNode createReadNode(StructuredGraph graph, Register register) {
55-
/*
56-
* A floating node to access the register is more efficient: it allows value numbering of
57-
* multiple accesses, including floating nodes that use it as an input. But for
58-
* deoptimization target methods, we must not do value numbering because there is no
59-
* proxying at deoptimization entry points for this node, so the value is not restored
60-
* during deoptimization.
61-
*/
62-
if (SubstrateCompilationDirectives.isDeoptTarget(graph.method())) {
57+
private static ValueNode createReadNode(boolean useFixedRead, Register register) {
58+
if (useFixedRead) {
6359
return new ReadReservedRegisterFixedNode(register);
6460
} else {
6561
return new ReadReservedRegisterFloatingNode(register);

0 commit comments

Comments
 (0)