Skip to content

Commit

Permalink
[GR-41487] Add runtime pagesize validation.
Browse files Browse the repository at this point in the history
PullRequest: graal/13374
  • Loading branch information
teshull committed Mar 13, 2023
2 parents 382eca0 + 8f02c46 commit 808c2f2
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,12 @@ public int getImageHeapNullRegionSize() {
return 0;
}

@Fold
@Override
public boolean allowPageSizeMismatch() {
return true;
}

@Override
public boolean walkImageHeapObjects(ObjectVisitor visitor) {
VMOperation.guaranteeInProgressAtSafepoint("Must only be called at a safepoint");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ public boolean joinThreadUnmanaged(OSThreadHandle threadHandle, WordPointer thre
if (SynchAPI.NoTransitions.WaitForSingleObject((WinBase.HANDLE) threadHandle, SynchAPI.INFINITE()) != SynchAPI.WAIT_OBJECT_0()) {
return false;
}
// Since only an int is written, first clear word
threadExitStatus.write(WordFactory.zero());
if (Process.NoTransitions.GetExitCodeThread((WinBase.HANDLE) threadHandle, (CIntPointer) threadExitStatus) == 0) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,7 @@ public ReportingSupport(Path reportingPath) {
@Option(help = "Define PageSize of a machine that runs the image. The default = 0 (== same as host machine page size)")//
protected static final HostedOptionKey<Integer> PageSize = new HostedOptionKey<>(0);

@Fold
public static int getPageSize() {
int value = PageSize.getValue();
if (value == 0) {
Expand All @@ -844,6 +845,7 @@ public static int getPageSize() {
return 4096;
}
}
assert value > 0;
return value;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ private CEntryPointErrors() {
@Description("Current target does not support the following CPU features that are required by the image.") //
public static final int CPU_FEATURE_CHECK_FAILED = 23;

@Description("Image page size is incompatible with run-time page size. Rebuild image with -H:PageSize=[pagesize] to set appropriately.") //
public static final int PAGE_SIZE_CHECK_FAILED = 24;

public static String getDescription(int code) {
String result = null;
if (code >= 0 && code < DESCRIPTIONS.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@
import org.graalvm.nativeimage.c.type.WordPointer;
import org.graalvm.word.LocationIdentity;
import org.graalvm.word.PointerBase;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordFactory;

import com.oracle.svm.core.CPUFeatureAccess;
import com.oracle.svm.core.IsolateArgumentParser;
import com.oracle.svm.core.IsolateListenerSupport;
import com.oracle.svm.core.Isolates;
import com.oracle.svm.core.JavaMainWrapper.JavaMainSupport;
import com.oracle.svm.core.NeverInline;
import com.oracle.svm.core.RuntimeAssertionsSupport;
import com.oracle.svm.core.SubstrateDiagnostics;
import com.oracle.svm.core.SubstrateOptions;
Expand All @@ -86,6 +88,7 @@
import com.oracle.svm.core.graal.nodes.CEntryPointEnterNode;
import com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode;
import com.oracle.svm.core.graal.nodes.CEntryPointUtilityNode;
import com.oracle.svm.core.heap.Heap;
import com.oracle.svm.core.heap.ReferenceHandler;
import com.oracle.svm.core.heap.ReferenceHandlerThread;
import com.oracle.svm.core.heap.RestrictHeapAccess;
Expand All @@ -94,6 +97,7 @@
import com.oracle.svm.core.log.Log;
import com.oracle.svm.core.option.RuntimeOptionParser;
import com.oracle.svm.core.os.MemoryProtectionProvider;
import com.oracle.svm.core.os.VirtualMemoryProvider;
import com.oracle.svm.core.snippets.SnippetRuntime;
import com.oracle.svm.core.snippets.SnippetRuntime.SubstrateForeignCallDescriptor;
import com.oracle.svm.core.snippets.SubstrateForeignCallTarget;
Expand All @@ -103,6 +107,7 @@
import com.oracle.svm.core.thread.VMOperationControl;
import com.oracle.svm.core.thread.VMThreads;
import com.oracle.svm.core.thread.VMThreads.SafepointBehavior;
import com.oracle.svm.core.util.UnsignedUtils;
import com.oracle.svm.core.util.VMError;

import jdk.internal.misc.Unsafe;
Expand Down Expand Up @@ -205,6 +210,14 @@ private static int createIsolate(CEntryPointCreateIsolateParameters parameters,
if (cpuFeatureAccess.verifyHostSupportsArchitectureEarly() != 0) {
return CEntryPointErrors.CPU_FEATURE_CHECK_FAILED;
}

UnsignedWord runtimePageSize = VirtualMemoryProvider.get().getGranularity();
UnsignedWord imagePageSize = WordFactory.unsigned(SubstrateOptions.getPageSize());
boolean validPageSize = runtimePageSize.equal(imagePageSize) ||
(Heap.getHeap().allowPageSizeMismatch() && UnsignedUtils.isAMultiple(imagePageSize, runtimePageSize));
if (!validPageSize) {
return CEntryPointErrors.PAGE_SIZE_CHECK_FAILED;
}
CLongPointer parsedArgs = StackValue.get(IsolateArgumentParser.getStructSize());
IsolateArgumentParser.parse(parameters, parsedArgs);

Expand All @@ -217,6 +230,12 @@ private static int createIsolate(CEntryPointCreateIsolateParameters parameters,
setHeapBase(Isolates.getHeapBase(isolate.read()));
}

return createIsolate0(parsedArgs, isolate, vmThreadSize);
}

@Uninterruptible(reason = "Thread state not yet set up.")
@NeverInline(value = "Ensure this code cannot rise above where heap base is set.")
private static int createIsolate0(CLongPointer parsedArgs, WordPointer isolate, int vmThreadSize) {
IsolateArgumentParser.singleton().persistOptions(parsedArgs);
IsolateListenerSupport.singleton().afterCreateIsolate(isolate.read());

Expand All @@ -226,7 +245,7 @@ private static int createIsolate(CEntryPointCreateIsolateParameters parameters,
return CEntryPointErrors.THREADING_INITIALIZATION_FAILED;
}
}
error = attachThread(isolate.read(), false, false, vmThreadSize, true);
int error = attachThread(isolate.read(), false, false, vmThreadSize, true);
if (error != CEntryPointErrors.NO_ERROR) {
return error;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.graalvm.word.Pointer;
import org.graalvm.word.UnsignedWord;

import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.hub.PredefinedClassesSupport;
Expand Down Expand Up @@ -167,6 +168,14 @@ public List<Class<?>> getLoadedClasses() {
@Fold
public abstract int getImageHeapNullRegionSize();

/**
* Returns whether the runtime page size doesn't have to match the page size set at image
* creation ({@link SubstrateOptions#getPageSize()}). If there is a mismatch, then the page size
* set at image creation must be a multiple of the runtime page size.
*/
@Fold
public abstract boolean allowPageSizeMismatch();

/**
* Returns true if the given object is located in the image heap.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.Phase;
import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
Expand Down Expand Up @@ -746,6 +747,27 @@ protected EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, BytecodePro
}
}

// Wrapper to clearly identify phase
class TrivialInlinePhase extends Phase {
final InliningGraphDecoder decoder;
final HostedMethod method;

TrivialInlinePhase(InliningGraphDecoder decoder, HostedMethod method) {
this.decoder = decoder;
this.method = method;
}

@Override
protected void run(StructuredGraph graph) {
decoder.decode(method);
}

@Override
public CharSequence getName() {
return "TrivialInline";
}
}

@SuppressWarnings("try")
private void doInlineTrivial(DebugContext debug, HostedMethod method) {
/*
Expand All @@ -770,7 +792,7 @@ private void doInlineTrivial(DebugContext debug, HostedMethod method) {
try (var s = debug.scope("InlineTrivial", graph, method, this)) {
var inliningPlugin = new TrivialInliningPlugin();
var decoder = new InliningGraphDecoder(graph, providers, inliningPlugin);
decoder.decode(method);
new TrivialInlinePhase(decoder, method).apply(graph);

if (inliningPlugin.inlinedDuringDecoding) {
CanonicalizerPhase.create().apply(graph, providers);
Expand Down

0 comments on commit 808c2f2

Please sign in to comment.