Skip to content

Commit 6d441a8

Browse files
committed
Allow language interpreter to run on z/OS and s390x architecture.
1 parent 8fa7b17 commit 6d441a8

File tree

10 files changed

+233
-13
lines changed

10 files changed

+233
-13
lines changed

sdk/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
This changelog summarizes major changes between GraalVM SDK versions. The main focus is on APIs exported by GraalVM SDK.
44

5+
## Version 26.0.0
6+
* GR-65048: GR-65048: Introduced the `-Dpolyglot.engine.allowUnsupportedPlatform=true` system property to enable Truffle to run on unsupported platforms. If this property is enabled then the failure will be suppressed. Please see follow-up errors and warnings for instructions on how to continue. Note that using an unsupported platform will also force the fallback runtime without runtime optimization.
7+
58
## Version 25.0.0
69
* GR-60636 Truffle now stops compiling when the code cache fills up on HotSpot. A warning is printed when that happens.
710
* GR-51664 Improved `PolyglotException#toString` and `PolyglotException#printStackTrace`.

sdk/src/org.graalvm.polyglot/src/org/graalvm/polyglot/Engine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ static Map<String, String> readOptionsFromSystemProperties(Map<String, String> o
781781
for (Object systemKey : properties.keySet()) {
782782
String key = (String) systemKey;
783783
if ("polyglot.engine.AllowExperimentalOptions".equals(key) || key.equals("polyglot.engine.resourcePath") || key.startsWith("polyglot.engine.resourcePath.") ||
784-
key.equals("polyglot.engine.userResourceCache")) {
784+
key.equals("polyglot.engine.userResourceCache") || key.equals("polyglot.engine.allowUnsupportedPlatform")) {
785785
continue;
786786
}
787787
if (key.startsWith(systemPropertyPrefix)) {

truffle/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
This changelog summarizes major changes between Truffle versions relevant to languages implementors building upon the Truffle framework. The main focus is on APIs exported by Truffle.
44

5+
## Version 26.0
6+
* GR-65048: Introduced `InternalResource.OS.UNSUPPORTED` and `InternalResource.CPUArchitecture.UNSUPPORTED` to represent unsupported platforms. Execution on unsupported platforms must be explicitly enabled using the system property `-Dpolyglot.engine.allowUnsupportedPlatform=true`. If this property is not set, calls to `OS.getCurrent()` or `CPUArchitecture.getCurrent()` will throw an `IllegalStateException` when running on an unsupported platform. `InternalResource` implementations should handle the unsupported platform and describe possible steps in the error message on how to proceed.
7+
58
## Version 25.0
69
* GR-31495 Added ability to specify language and instrument specific options using `Source.Builder.option(String, String)`. Languages may describe available source options by implementing `TruffleLanguage.getSourceOptionDescriptors()` and `TruffleInstrument.getSourceOptionDescriptors()` respectively.
710
* GR-61493 Added `RootNode.prepareForCall` which allows root nodes to prepare themselves for use as a call target (or to validate whether they can be used as a call target).

truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/SubprocessTestUtils.java

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import java.util.Collections;
6767
import java.util.EnumSet;
6868
import java.util.Formatter;
69+
import java.util.HashSet;
6970
import java.util.List;
7071
import java.util.Map;
7172
import java.util.Objects;
@@ -74,6 +75,7 @@
7475
import java.util.Set;
7576
import java.util.concurrent.TimeUnit;
7677
import java.util.function.Consumer;
78+
import java.util.function.Predicate;
7779
import java.util.logging.Level;
7880
import java.util.regex.Matcher;
7981
import java.util.regex.Pattern;
@@ -87,6 +89,8 @@
8789
import javax.management.remote.JMXServiceURL;
8890

8991
import org.graalvm.nativeimage.ImageInfo;
92+
import org.graalvm.options.OptionDescriptor;
93+
import org.graalvm.options.OptionDescriptors;
9094
import org.junit.Assert;
9195
import org.junit.Assume;
9296
import org.junit.Test;
@@ -188,11 +192,11 @@ private static Method findTestMethod(Class<?> testClass) {
188192
}
189193

190194
private static Subprocess execute(Method testMethod, boolean failOnNonZeroExitCode, List<String> prefixVMOptions,
191-
List<String> postfixVmOptions, Duration timeout, Consumer<ProcessHandle> onStart) throws IOException, InterruptedException {
195+
List<String> postfixVmOptions, boolean removeOptimizedRuntimeOptions, Duration timeout, Consumer<ProcessHandle> onStart) throws IOException, InterruptedException {
192196
String enclosingElement = testMethod.getDeclaringClass().getName();
193197
String testName = testMethod.getName();
194198
Subprocess subprocess = javaHelper(
195-
configure(getVmArgs(), prefixVMOptions, postfixVmOptions),
199+
configure(getVmArgs(), prefixVMOptions, postfixVmOptions, removeOptimizedRuntimeOptions),
196200
null, null,
197201
List.of("com.oracle.mxtool.junit.MxJUnitWrapper", String.format("%s#%s", enclosingElement, testName)),
198202
timeout, onStart);
@@ -202,8 +206,9 @@ private static Subprocess execute(Method testMethod, boolean failOnNonZeroExitCo
202206
return subprocess;
203207
}
204208

205-
private static List<String> configure(List<String> vmArgs, List<String> prefixVMOptions, List<String> postfixVmOptions) {
209+
private static List<String> configure(List<String> vmArgs, List<String> prefixVMOptions, List<String> postfixVmOptions, boolean removeOptimizedRuntimeOptions) {
206210
List<String> newVmArgs = new ArrayList<>();
211+
Predicate<String> optimizedRuntimeFilter = removeOptimizedRuntimeOptions ? new OptimizedRuntimeOptionsFilter() : (s) -> true;
207212
newVmArgs.addAll(vmArgs.stream().filter(vmArg -> {
208213
for (String toRemove : getForbiddenVmOptions()) {
209214
if (vmArg.startsWith(toRemove)) {
@@ -221,14 +226,14 @@ private static List<String> configure(List<String> vmArgs, List<String> prefixVM
221226
}
222227
}
223228
return true;
224-
}).collect(Collectors.toList()));
229+
}).filter(optimizedRuntimeFilter).toList());
225230
for (String additionalVmOption : prefixVMOptions) {
226-
if (!additionalVmOption.startsWith(TO_REMOVE_PREFIX)) {
231+
if (!additionalVmOption.startsWith(TO_REMOVE_PREFIX) && optimizedRuntimeFilter.test(additionalVmOption)) {
227232
newVmArgs.add(1, additionalVmOption);
228233
}
229234
}
230235
for (String additionalVmOption : postfixVmOptions) {
231-
if (!additionalVmOption.startsWith(TO_REMOVE_PREFIX)) {
236+
if (!additionalVmOption.startsWith(TO_REMOVE_PREFIX) && optimizedRuntimeFilter.test(additionalVmOption)) {
232237
newVmArgs.add(additionalVmOption);
233238
}
234239
}
@@ -466,6 +471,7 @@ public static final class Builder {
466471
private Duration timeout;
467472
private Consumer<Subprocess> onExit;
468473
private Consumer<ProcessHandle> onStart;
474+
private boolean removeOptimizedRuntimeOptions;
469475

470476
private Builder(Class<?> testClass, Runnable run) {
471477
this.testClass = testClass;
@@ -496,6 +502,17 @@ public Builder postfixVmOption(String... options) {
496502
return this;
497503
}
498504

505+
/**
506+
* Removes all {@code OptimizedRuntimeOptions} from the command line.
507+
* <p>
508+
* This method is useful in tests that require fallback to the default Truffle runtime,
509+
* which does not support optimized runtime options.
510+
*/
511+
public Builder removeOptimizedRuntimeOptions(boolean value) {
512+
removeOptimizedRuntimeOptions = value;
513+
return this;
514+
}
515+
499516
/**
500517
* Disables assertions in {@code forClass}.
501518
*/
@@ -535,7 +552,7 @@ public void run() throws IOException, InterruptedException {
535552
if (isSubprocess()) {
536553
runnable.run();
537554
} else {
538-
Subprocess process = execute(findTestMethod(testClass), failOnNonZeroExit, prefixVmArgs, postfixVmArgs, timeout, onStart);
555+
Subprocess process = execute(findTestMethod(testClass), failOnNonZeroExit, prefixVmArgs, postfixVmArgs, removeOptimizedRuntimeOptions, timeout, onStart);
539556
if (onExit != null) {
540557
try {
541558
onExit.accept(process);
@@ -1175,4 +1192,34 @@ private void skipWhite() throws IOException {
11751192
}
11761193
}
11771194
}
1195+
1196+
private static final class OptimizedRuntimeOptionsFilter implements Predicate<String> {
1197+
1198+
private final Set<String> toRemove;
1199+
1200+
OptimizedRuntimeOptionsFilter() {
1201+
Set<String> optionNames;
1202+
try {
1203+
Class<?> options = Class.forName("com.oracle.truffle.runtime.OptimizedRuntimeOptions");
1204+
OptionDescriptors descriptors = (OptionDescriptors) ReflectionUtils.invokeStatic(options, "getDescriptors");
1205+
optionNames = new HashSet<>();
1206+
for (OptionDescriptor descriptor : descriptors) {
1207+
optionNames.add(String.format("-Dpolyglot.%s", descriptor.getName()));
1208+
}
1209+
} catch (ClassNotFoundException e) {
1210+
optionNames = Set.of();
1211+
}
1212+
toRemove = optionNames;
1213+
}
1214+
1215+
@Override
1216+
public boolean test(String s) {
1217+
int index = s.lastIndexOf("=");
1218+
if (index > 0) {
1219+
String key = s.substring(0, index);
1220+
return !toRemove.contains(key);
1221+
}
1222+
return true;
1223+
}
1224+
}
11781225
}

truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/InternalResourceTest.java

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import java.nio.file.attribute.FileTime;
6060
import java.time.Instant;
6161
import java.util.ArrayList;
62+
import java.util.HashMap;
6263
import java.util.List;
6364
import java.util.Map;
6465
import java.util.Objects;
@@ -72,10 +73,13 @@
7273
import com.oracle.truffle.api.instrumentation.TruffleInstrument;
7374
import com.oracle.truffle.api.test.OSUtils;
7475
import com.oracle.truffle.api.test.ReflectionUtils;
76+
import com.oracle.truffle.api.test.SubprocessTestUtils;
7577
import com.oracle.truffle.api.test.common.TestUtils;
7678
import com.oracle.truffle.tck.tests.TruffleTestAssumptions;
79+
import org.graalvm.nativeimage.ImageInfo;
7780
import org.graalvm.polyglot.Context;
7881
import org.graalvm.polyglot.Engine;
82+
import org.graalvm.polyglot.PolyglotException;
7983
import org.junit.Assert;
8084
import org.junit.BeforeClass;
8185
import org.junit.Test;
@@ -91,6 +95,7 @@
9195
import static org.junit.Assert.assertNotNull;
9296
import static org.junit.Assert.assertTrue;
9397
import static com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest.assertFails;
98+
import static org.junit.Assume.assumeFalse;
9499

95100
public class InternalResourceTest {
96101

@@ -1308,6 +1313,83 @@ protected Object execute(RootNode node, Env env, Object[] contextArguments, Obje
13081313
}
13091314
}
13101315

1316+
@Test
1317+
public void testUnsupportedPlatformDisabled() throws IOException, InterruptedException {
1318+
assumeFalse(ImageInfo.inImageCode());
1319+
SubprocessTestUtils.newBuilder(InternalResourceTest.class, () -> {
1320+
var prevProperties = setUnsupportedArchitecture();
1321+
try {
1322+
AbstractPolyglotTest.assertFails(() -> Context.create(), PolyglotException.class, (e) -> {
1323+
assertEquals("java.lang.IllegalStateException: Unsupported operating system: 'z/os'. " +
1324+
"If you want to continue using this unsupported platform, set the system property '-Dpolyglot.engine.allowUnsupportedPlatform=true'. " +
1325+
"Note that unsupported platforms require additional command line options to be functional.", e.getMessage());
1326+
});
1327+
} finally {
1328+
restoreArchitecture(prevProperties);
1329+
}
1330+
}).removeOptimizedRuntimeOptions(true).run();
1331+
}
1332+
1333+
@Test
1334+
public void testUnsupportedPlatformEnabled() throws IOException, InterruptedException {
1335+
assumeFalse(ImageInfo.inImageCode());
1336+
SubprocessTestUtils.newBuilder(InternalResourceTest.class, () -> {
1337+
var prevProperties = setUnsupportedArchitecture();
1338+
try {
1339+
AbstractPolyglotTest.assertFails(() -> Context.create(), PolyglotException.class, (e) -> {
1340+
assertEquals("java.lang.IllegalStateException: Truffle is running on an unsupported platform. " +
1341+
"On unsupported platforms, you must explicitly set the default cache directory " +
1342+
"using the system property '-Dpolyglot.engine.userResourceCache=<path_to_cache_folder>'.", e.getMessage());
1343+
});
1344+
} finally {
1345+
restoreArchitecture(prevProperties);
1346+
}
1347+
}).removeOptimizedRuntimeOptions(true).prefixVmOption("-Dpolyglot.engine.allowUnsupportedPlatform=true").run();
1348+
}
1349+
1350+
@Test
1351+
public void testUnsupportedPlatformEnabledWithExplicitCacheFolder() throws IOException, InterruptedException {
1352+
assumeFalse(ImageInfo.inImageCode());
1353+
Path tmp = SubprocessTestUtils.isSubprocess() ? null : Files.createTempDirectory("test_cache_root").toAbsolutePath();
1354+
try {
1355+
SubprocessTestUtils.newBuilder(InternalResourceTest.class, () -> {
1356+
var prevProperties = setUnsupportedArchitecture();
1357+
try {
1358+
Context context = Context.create();
1359+
context.close();
1360+
} finally {
1361+
restoreArchitecture(prevProperties);
1362+
}
1363+
}).//
1364+
prefixVmOption("-Dpolyglot.engine.allowUnsupportedPlatform=true").//
1365+
prefixVmOption("-Dpolyglot.engine.userResourceCache=" + tmp).//
1366+
removeOptimizedRuntimeOptions(true).//
1367+
onExit((subprocess) -> {
1368+
assertTrue(subprocess.output.stream().anyMatch((l) -> l.contains("Truffle is running on an unsupported platform where the TruffleAttach library is unavailable.")));
1369+
}).//
1370+
run();
1371+
} finally {
1372+
if (tmp != null) {
1373+
delete(tmp);
1374+
}
1375+
}
1376+
}
1377+
1378+
private static Map<String, String> setUnsupportedArchitecture() {
1379+
Map<String, String> prev = new HashMap<>();
1380+
prev.put("os.name", System.getProperty("os.name"));
1381+
prev.put("os.arch", System.getProperty("os.arch"));
1382+
System.setProperty("os.name", "z/os");
1383+
System.setProperty("os.arch", "s390x");
1384+
return prev;
1385+
}
1386+
1387+
private static void restoreArchitecture(Map<String, String> properties) {
1388+
for (var entry : properties.entrySet()) {
1389+
System.setProperty(entry.getKey(), entry.getValue());
1390+
}
1391+
}
1392+
13111393
private static String findLine(String pattern, String[] lines) {
13121394
Pattern p = Pattern.compile(pattern);
13131395
for (String line : lines) {

truffle/src/com.oracle.truffle.api/snapshot.sigtest

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ CLSS public final static !enum com.oracle.truffle.api.InternalResource$CPUArchit
181181
outer com.oracle.truffle.api.InternalResource
182182
fld public final static com.oracle.truffle.api.InternalResource$CPUArchitecture AARCH64
183183
fld public final static com.oracle.truffle.api.InternalResource$CPUArchitecture AMD64
184+
fld public final static com.oracle.truffle.api.InternalResource$CPUArchitecture UNSUPPORTED
184185
meth public java.lang.String toString()
185186
meth public static com.oracle.truffle.api.InternalResource$CPUArchitecture getCurrent()
186187
meth public static com.oracle.truffle.api.InternalResource$CPUArchitecture valueOf(java.lang.String)
@@ -213,13 +214,14 @@ CLSS public final static !enum com.oracle.truffle.api.InternalResource$OS
213214
outer com.oracle.truffle.api.InternalResource
214215
fld public final static com.oracle.truffle.api.InternalResource$OS DARWIN
215216
fld public final static com.oracle.truffle.api.InternalResource$OS LINUX
217+
fld public final static com.oracle.truffle.api.InternalResource$OS UNSUPPORTED
216218
fld public final static com.oracle.truffle.api.InternalResource$OS WINDOWS
217219
meth public java.lang.String toString()
218220
meth public static com.oracle.truffle.api.InternalResource$OS getCurrent()
219221
meth public static com.oracle.truffle.api.InternalResource$OS valueOf(java.lang.String)
220222
meth public static com.oracle.truffle.api.InternalResource$OS[] values()
221223
supr java.lang.Enum<com.oracle.truffle.api.InternalResource$OS>
222-
hfds id
224+
hfds PROPERTY_ALLOW_UNSUPPORTED_PLATFORM,allowsUnsupportedPlatformValue,id
223225

224226
CLSS public com.oracle.truffle.api.OptimizationFailedException
225227
cons public init(java.lang.Throwable,com.oracle.truffle.api.RootCallTarget)

0 commit comments

Comments
 (0)