Skip to content

Commit e35f7e3

Browse files
committed
Ensure that code base is determined after initializing heap base.
1 parent a14af8c commit e35f7e3

3 files changed

Lines changed: 33 additions & 8 deletions

File tree

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/nodes/ReadReservedRegisterFixedNode.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import jdk.graal.compiler.nodes.spi.NodeLIRBuilderTool;
3737
import jdk.vm.ci.code.Register;
3838

39+
/** @see ReadReservedRegisterFloatingNode */
3940
@NodeInfo(cycles = NodeCycles.CYCLES_0, size = NodeSize.SIZE_0)
4041
public final class ReadReservedRegisterFixedNode extends FixedWithNextNode implements LIRLowerable {
4142
public static final NodeClass<ReadReservedRegisterFixedNode> TYPE = NodeClass.create(ReadReservedRegisterFixedNode.class);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/nodes/ReadReservedRegisterFloatingNode.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
package com.oracle.svm.core.graal.nodes;
2626

2727
import com.oracle.svm.core.FrameAccess;
28+
import com.oracle.svm.core.ReservedRegisters;
29+
import com.oracle.svm.core.graal.snippets.CEntryPointSnippets;
2830

2931
import jdk.graal.compiler.core.common.LIRKind;
3032
import jdk.graal.compiler.graph.NodeClass;
@@ -36,6 +38,22 @@
3638
import jdk.graal.compiler.nodes.spi.NodeLIRBuilderTool;
3739
import jdk.vm.ci.code.Register;
3840

41+
/**
42+
* A floating node to read a reserved register, which is more efficient because it allows value
43+
* numbering of multiple accesses, including floating nodes that use it as an input. This is safe
44+
* without explicit dependencies because reserved registers generally contain the same value
45+
* throughout a method's execution.
46+
*
47+
* However, these floating reads are also used in the methods that initialize reserved registers
48+
* when entering an isolate (see {@link CEntryPointSnippets}). We carefully use separate methods and
49+
* prevent inlining to avoid that the compiler can move register reads before their writes.
50+
*
51+
* Also, these nodes must not be used for deoptimization target methods because there is no proxying
52+
* at deoptimization entry points for them, so deoptimization would not restore the values.
53+
*
54+
* @see ReservedRegisters
55+
* @see ReadReservedRegisterFixedNode
56+
*/
3957
@NodeInfo(cycles = NodeCycles.CYCLES_0, size = NodeSize.SIZE_0)
4058
public final class ReadReservedRegisterFloatingNode extends FloatingNode implements LIRLowerable {
4159
public static final NodeClass<ReadReservedRegisterFloatingNode> TYPE = NodeClass.create(ReadReservedRegisterFloatingNode.class);

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,10 @@ public final class CEntryPointSnippets extends SubstrateTemplates implements Sni
163163
public static final SubstrateForeignCallDescriptor FAIL_FATALLY = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "failFatally", HAS_SIDE_EFFECT, LocationIdentity.any());
164164
public static final SubstrateForeignCallDescriptor VERIFY_ISOLATE_THREAD = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "verifyIsolateThread", HAS_SIDE_EFFECT,
165165
LocationIdentity.any());
166+
public static final SubstrateForeignCallDescriptor INIT_CODE_BASE = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "initCodeBase", HAS_SIDE_EFFECT, LocationIdentity.any());
166167

167168
public static final SubstrateForeignCallDescriptor[] FOREIGN_CALLS = {CREATE_ISOLATE, INITIALIZE_ISOLATE, ATTACH_THREAD, ENSURE_JAVA_THREAD, ENTER_BY_ISOLATE,
168-
DETACH_CURRENT_THREAD, REPORT_EXCEPTION, TEAR_DOWN_ISOLATE, IS_ATTACHED, FAIL_FATALLY, VERIFY_ISOLATE_THREAD};
169+
DETACH_CURRENT_THREAD, REPORT_EXCEPTION, TEAR_DOWN_ISOLATE, IS_ATTACHED, FAIL_FATALLY, VERIFY_ISOLATE_THREAD, INIT_CODE_BASE};
169170

170171
@NodeIntrinsic(value = ForeignCallNode.class)
171172
public static native int runtimeCall(@ConstantNodeParameter ForeignCallDescriptor descriptor, CEntryPointCreateIsolateParameters parameters);
@@ -185,9 +186,6 @@ public final class CEntryPointSnippets extends SubstrateTemplates implements Sni
185186
@NodeIntrinsic(value = ForeignCallNode.class)
186187
public static native int runtimeCallInitializeIsolate(@ConstantNodeParameter ForeignCallDescriptor descriptor, CEntryPointCreateIsolateParameters parameters);
187188

188-
@NodeIntrinsic(value = ForeignCallNode.class)
189-
public static native int runtimeCallTearDownIsolate(@ConstantNodeParameter ForeignCallDescriptor descriptor);
190-
191189
@NodeIntrinsic(value = ForeignCallNode.class)
192190
public static native boolean runtimeCallIsAttached(@ConstantNodeParameter ForeignCallDescriptor descriptor, Isolate isolate);
193191

@@ -197,6 +195,9 @@ public final class CEntryPointSnippets extends SubstrateTemplates implements Sni
197195
@NodeIntrinsic(value = ForeignCallNode.class)
198196
public static native void runtimeCallFailFatally(@ConstantNodeParameter ForeignCallDescriptor descriptor, int code, CCharPointer message);
199197

198+
@NodeIntrinsic(value = ForeignCallNode.class)
199+
public static native void runtimeCallInitCodeBase(@ConstantNodeParameter ForeignCallDescriptor descriptor);
200+
200201
@Fold
201202
static boolean hasHeapBase() {
202203
return ImageSingletons.lookup(CompressEncoding.class).hasBase();
@@ -210,8 +211,13 @@ private static void setHeapBase(PointerBase heapBase) {
210211
}
211212
}
212213

213-
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE)
214-
@NeverInline("Heap base register is set in caller, prevent reads from floating before that.")
214+
/**
215+
* Initializes the code base register, which accesses the heap using the heap base register. To
216+
* prevent the compiler from moving reads from this method to before the heap base register is
217+
* initialized in a caller, this method is a foreign call target that does not get inlined.
218+
*/
219+
@SubstrateForeignCallTarget(stubCallingConvention = false)
220+
@Uninterruptible(reason = "Thread state not yet set up.")
215221
private static void initCodeBase() {
216222
CodePointer codeBase;
217223
if (ImageLayerBuildingSupport.buildingImageLayer()) {
@@ -243,7 +249,7 @@ public static void earlyInitHeapBase(PointerBase heapBase) {
243249
public static void initBaseRegisters(PointerBase heapBase) {
244250
setHeapBase(heapBase);
245251
if (SubstrateOptions.useRelativeCodePointers()) {
246-
initCodeBase();
252+
runtimeCallInitCodeBase(INIT_CODE_BASE);
247253
}
248254
}
249255

@@ -683,7 +689,7 @@ private static int detachCurrentThread() {
683689

684690
@Snippet(allowMissingProbabilities = true)
685691
public static int tearDownIsolateSnippet() {
686-
return runtimeCallTearDownIsolate(TEAR_DOWN_ISOLATE);
692+
return runtimeCall(TEAR_DOWN_ISOLATE);
687693
}
688694

689695
@SubstrateForeignCallTarget(stubCallingConvention = false)

0 commit comments

Comments
 (0)