Skip to content

Commit 259b37b

Browse files
committed
[GR-52945] Label some Layered Image Singletons.
PullRequest: graal/17566
2 parents fe20679 + ef82e6d commit 259b37b

File tree

18 files changed

+259
-47
lines changed

18 files changed

+259
-47
lines changed

substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/LLVMFeature.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@
2727
import java.nio.file.Path;
2828
import java.util.Map;
2929

30-
import jdk.graal.compiler.graph.Node;
31-
import jdk.graal.compiler.graph.NodeClass;
32-
import jdk.graal.compiler.nodes.java.LoadExceptionObjectNode;
33-
import jdk.graal.compiler.options.OptionValues;
34-
import jdk.graal.compiler.phases.util.Providers;
35-
import jdk.graal.compiler.replacements.TargetGraphBuilderPlugins;
3630
import org.graalvm.nativeimage.ImageSingletons;
3731
import org.graalvm.nativeimage.Platform;
3832
import org.graalvm.nativeimage.Platforms;
@@ -58,6 +52,7 @@
5852
import com.oracle.svm.core.graal.llvm.util.LLVMOptions;
5953
import com.oracle.svm.core.graal.meta.RuntimeConfiguration;
6054
import com.oracle.svm.core.graal.snippets.NodeLoweringProvider;
55+
import com.oracle.svm.core.layeredimagesingleton.UnsupportedLayeredSingleton;
6156
import com.oracle.svm.core.option.HostedOptionKey;
6257
import com.oracle.svm.core.snippets.ExceptionUnwind;
6358
import com.oracle.svm.core.util.UserError;
@@ -72,14 +67,21 @@
7267
import com.oracle.svm.hosted.image.ObjectFileFactory;
7368
import com.oracle.svm.util.ModuleSupport;
7469

70+
import jdk.graal.compiler.graph.Node;
71+
import jdk.graal.compiler.graph.NodeClass;
72+
import jdk.graal.compiler.nodes.java.LoadExceptionObjectNode;
73+
import jdk.graal.compiler.options.OptionValues;
74+
import jdk.graal.compiler.phases.util.Providers;
75+
import jdk.graal.compiler.replacements.TargetGraphBuilderPlugins;
76+
7577
/*
7678
* This feature enables the LLVM backend of Native Image. It does so by registering the backend,
7779
* lowerings, code cache and exception handling mechanism required to emit LLVM bitcode
7880
* from Graal graphs, and compile this bitcode into machine code.
7981
*/
8082
@AutomaticallyRegisteredFeature
8183
@Platforms({Platform.LINUX.class, Platform.DARWIN.class})
82-
public class LLVMFeature implements Feature, InternalFeature {
84+
public class LLVMFeature implements Feature, InternalFeature, UnsupportedLayeredSingleton {
8385

8486
@Override
8587
public boolean isInConfiguration(IsInConfigurationAccess access) {

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/thread/PosixVMThreads.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,10 @@
5151
import com.oracle.svm.core.util.TimeUtils;
5252
import com.oracle.svm.core.util.VMError;
5353

54-
import jdk.graal.compiler.api.replacements.Fold;
55-
5654
@AutomaticallyRegisteredImageSingleton(VMThreads.class)
5755
public final class PosixVMThreads extends VMThreads {
58-
@Fold
56+
57+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
5958
public static PosixVMThreads singleton() {
6059
return (PosixVMThreads) ImageSingletons.lookup(VMThreads.class);
6160
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/PhysicalMemory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.oracle.svm.core.Containers;
4242
import com.oracle.svm.core.SubstrateOptions;
4343
import com.oracle.svm.core.Uninterruptible;
44+
import com.oracle.svm.core.layeredimagesingleton.RuntimeOnlyImageSingleton;
4445
import com.oracle.svm.core.stack.StackOverflowCheck;
4546
import com.oracle.svm.core.thread.PlatformThreads;
4647
import com.oracle.svm.core.thread.VMOperation;
@@ -54,7 +55,7 @@
5455
public class PhysicalMemory {
5556

5657
/** Implemented by operating-system specific code. */
57-
public interface PhysicalMemorySupport {
58+
public interface PhysicalMemorySupport extends RuntimeOnlyImageSingleton {
5859
/** Get the size of physical memory from the OS. */
5960
UnsignedWord size();
6061
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.layeredimagesingleton;
26+
27+
import org.graalvm.nativeimage.ImageSingletons;
28+
29+
public interface LayeredImageSingletonSupport {
30+
31+
static LayeredImageSingletonSupport singleton() {
32+
return ImageSingletons.lookup(LayeredImageSingletonSupport.class);
33+
}
34+
35+
<T> T runtimeLookup(Class<T> key);
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.layeredimagesingleton;
26+
27+
import java.util.EnumSet;
28+
29+
public interface RuntimeOnlyImageSingleton extends LayeredImageSingleton {
30+
31+
@Override
32+
default EnumSet<ImageBuilderFlags> getImageBuilderFlags() {
33+
return EnumSet.of(ImageBuilderFlags.RUNTIME_ACCESS, ImageBuilderFlags.ALLOW_CONSTANT_FOLDING);
34+
}
35+
36+
@Override
37+
default PersistFlags preparePersist(ImageSingletonWriter writer) {
38+
return PersistFlags.NOTHING;
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.layeredimagesingleton;
26+
27+
/**
28+
* This is used to wrap singletons which are only allowed to be accessed at runtime. When a
29+
* singleton wrapped with this is called during image build time an error is thrown.
30+
*/
31+
public record RuntimeOnlyWrapper(LayeredImageSingleton wrappedObject) {
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.layeredimagesingleton;
26+
27+
import java.util.EnumSet;
28+
29+
import com.oracle.svm.core.util.VMError;
30+
31+
/**
32+
* Marker for singletons which currently cannot be part of layered images.
33+
*/
34+
public interface UnsupportedLayeredSingleton extends LayeredImageSingleton {
35+
36+
@Override
37+
default EnumSet<ImageBuilderFlags> getImageBuilderFlags() {
38+
return EnumSet.of(ImageBuilderFlags.UNSUPPORTED);
39+
}
40+
41+
@Override
42+
default PersistFlags preparePersist(ImageSingletonWriter writer) {
43+
throw VMError.shouldNotReachHere("Unsupported feature singleton cannot be added to image");
44+
}
45+
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMThreads.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.oracle.svm.core.heap.VMOperationInfos;
4949
import com.oracle.svm.core.jdk.UninterruptibleUtils;
5050
import com.oracle.svm.core.jdk.UninterruptibleUtils.AtomicWord;
51+
import com.oracle.svm.core.layeredimagesingleton.RuntimeOnlyImageSingleton;
5152
import com.oracle.svm.core.locks.VMCondition;
5253
import com.oracle.svm.core.locks.VMLockSupport;
5354
import com.oracle.svm.core.locks.VMMutex;
@@ -65,17 +66,16 @@
6566
import com.oracle.svm.core.util.VMError;
6667

6768
import jdk.graal.compiler.api.directives.GraalDirectives;
68-
import jdk.graal.compiler.api.replacements.Fold;
6969
import jdk.graal.compiler.core.common.SuppressFBWarnings;
7070
import jdk.graal.compiler.replacements.ReplacementsUtil;
7171
import jdk.graal.compiler.replacements.nodes.AssertionNode;
7272

7373
/**
7474
* Utility methods for the manipulation and iteration of {@link IsolateThread}s.
7575
*/
76-
public abstract class VMThreads {
76+
public abstract class VMThreads implements RuntimeOnlyImageSingleton {
7777

78-
@Fold
78+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
7979
public static VMThreads singleton() {
8080
return ImageSingletons.lookup(VMThreads.class);
8181
}

substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/stubs/AMD64StubForeignCallsFeature.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232

3333
import java.util.EnumSet;
3434

35+
import org.graalvm.nativeimage.Platform.AMD64;
36+
import org.graalvm.nativeimage.Platforms;
37+
38+
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
39+
import com.oracle.svm.core.layeredimagesingleton.FeatureSingleton;
40+
import com.oracle.svm.core.layeredimagesingleton.UnsavedSingleton;
41+
3542
import jdk.graal.compiler.replacements.StringLatin1InflateNode;
3643
import jdk.graal.compiler.replacements.StringUTF16CompressNode;
3744
import jdk.graal.compiler.replacements.nodes.AESNode;
@@ -57,16 +64,11 @@
5764
import jdk.graal.compiler.replacements.nodes.MessageDigestNode.SHA512Node;
5865
import jdk.graal.compiler.replacements.nodes.VectorizedHashCodeNode;
5966
import jdk.graal.compiler.replacements.nodes.VectorizedMismatchNode;
60-
import org.graalvm.nativeimage.Platform.AMD64;
61-
import org.graalvm.nativeimage.Platforms;
62-
63-
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
64-
6567
import jdk.vm.ci.amd64.AMD64.CPUFeature;
6668

6769
@AutomaticallyRegisteredFeature
6870
@Platforms(AMD64.class)
69-
public class AMD64StubForeignCallsFeature extends StubForeignCallsFeatureBase {
71+
public class AMD64StubForeignCallsFeature extends StubForeignCallsFeatureBase implements FeatureSingleton, UnsavedSingleton {
7072

7173
private static final EnumSet<CPUFeature> BASELINE = EnumSet.of(SSE2);
7274

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageSingletonsSupportImpl.java

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@
3535

3636
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingleton;
3737
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingleton.PersistFlags;
38+
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonSupport;
3839
import com.oracle.svm.core.layeredimagesingleton.LoadedLayeredImageSingletonInfo;
40+
import com.oracle.svm.core.layeredimagesingleton.RuntimeOnlyWrapper;
3941
import com.oracle.svm.core.util.UserError;
4042
import com.oracle.svm.hosted.heap.SVMImageLayerLoader;
4143

42-
public final class ImageSingletonsSupportImpl extends ImageSingletonsSupport {
44+
public final class ImageSingletonsSupportImpl extends ImageSingletonsSupport implements LayeredImageSingletonSupport {
4345

4446
@Override
4547
public <T> void add(Class<T> key, T value) {
@@ -48,7 +50,12 @@ public <T> void add(Class<T> key, T value) {
4850

4951
@Override
5052
public <T> T lookup(Class<T> key) {
51-
return HostedManagement.getAndAssertExists().doLookup(key);
53+
return HostedManagement.getAndAssertExists().doLookup(key, false);
54+
}
55+
56+
@Override
57+
public <T> T runtimeLookup(Class<T> key) {
58+
return HostedManagement.getAndAssertExists().doLookup(key, true);
5259
}
5360

5461
@Override
@@ -135,9 +142,15 @@ public static void persist() {
135142
}
136143

137144
private final Map<Class<?>, Object> configObjects;
145+
private final boolean checkUnsupported;
138146

139147
public HostedManagement() {
148+
this(false);
149+
}
150+
151+
public HostedManagement(boolean checkUnsupported) {
140152
this.configObjects = new ConcurrentHashMap<>();
153+
this.checkUnsupported = checkUnsupported;
141154
}
142155

143156
<T> void doAdd(Class<T> key, T value) {
@@ -150,28 +163,40 @@ private void doAddInternal(Class<?> key, Object value) {
150163
throw UserError.abort("ImageSingletons do not allow null value for key %s", key.getTypeName());
151164
}
152165

166+
Object storedValue = value;
153167
if (value instanceof LayeredImageSingleton singleton) {
154168
assert singleton.verifyImageBuilderFlags();
155169

156-
if (singleton.getImageBuilderFlags().contains(LayeredImageSingleton.ImageBuilderFlags.UNSUPPORTED)) {
170+
if (checkUnsupported && singleton.getImageBuilderFlags().contains(LayeredImageSingleton.ImageBuilderFlags.UNSUPPORTED)) {
157171
throw UserError.abort("Unsupported image singleton is being installed %s %s", key.getTypeName(), singleton);
158172
}
173+
174+
if (!singleton.getImageBuilderFlags().contains(LayeredImageSingleton.ImageBuilderFlags.BUILDTIME_ACCESS)) {
175+
storedValue = new RuntimeOnlyWrapper(singleton);
176+
}
159177
}
160178

161-
Object prevValue = configObjects.putIfAbsent(key, value);
179+
Object prevValue = configObjects.putIfAbsent(key, storedValue);
162180

163181
if (prevValue != null) {
164182
throw UserError.abort("ImageSingletons.add must not overwrite existing key %s%nExisting value: %s%nNew value: %s", key.getTypeName(), prevValue, value);
165183
}
166184
}
167185

168-
<T> T doLookup(Class<T> key) {
186+
<T> T doLookup(Class<T> key, boolean stripRuntimeOnly) {
169187
checkKey(key);
170188
Object result = configObjects.get(key);
171189
if (result == null) {
172190
throw UserError.abort("ImageSingletons do not contain key %s", key.getTypeName());
173191
} else if (result == SINGLETON_INSTALLATION_FOBIDDEN) {
174192
throw UserError.abort("A LayeredImageSingleton was installed in a prior layer which forbids creating the singleton in a subsequent layer. Key %s", key.getTypeName());
193+
} else if (result instanceof RuntimeOnlyWrapper wrapper) {
194+
if (!stripRuntimeOnly) {
195+
throw UserError.abort("A LayeredImageSingleton was accessed during image building which does not have %s access. Key: %s, object %s",
196+
LayeredImageSingleton.ImageBuilderFlags.BUILDTIME_ACCESS, key, wrapper.wrappedObject());
197+
}
198+
result = wrapper.wrappedObject();
199+
175200
}
176201
return key.cast(result);
177202
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@
173173
import com.oracle.svm.core.hub.LayoutEncoding;
174174
import com.oracle.svm.core.image.ImageHeapLayouter;
175175
import com.oracle.svm.core.jdk.ServiceCatalogSupport;
176+
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonSupport;
176177
import com.oracle.svm.core.option.HostedOptionValues;
177178
import com.oracle.svm.core.option.OptionClassFilter;
178179
import com.oracle.svm.core.option.RuntimeOptionValues;
@@ -528,8 +529,9 @@ public void run(Map<Method, CEntryPointData> entryPoints,
528529

529530
var hostedOptionValues = new HostedOptionValues(optionProvider.getHostedValues());
530531
SVMImageLayerSupport imageLayerSupport = SVMImageLayerSupport.initialize(hostedOptionValues);
531-
ImageSingletonsSupportImpl.HostedManagement.install(new ImageSingletonsSupportImpl.HostedManagement(), imageLayerSupport);
532+
ImageSingletonsSupportImpl.HostedManagement.install(new ImageSingletonsSupportImpl.HostedManagement(imageLayerSupport.enabled()), imageLayerSupport);
532533

534+
ImageSingletons.add(LayeredImageSingletonSupport.class, (LayeredImageSingletonSupport) ImageSingletonsSupportImpl.get());
533535
ImageSingletons.add(SVMImageLayerSupport.class, imageLayerSupport);
534536
ImageSingletons.add(ProgressReporter.class, reporter);
535537
ImageSingletons.add(DeadlockWatchdog.class, loader.watchdog);

0 commit comments

Comments
 (0)