Skip to content

Commit d946a7c

Browse files
committed
[GR-64554] Introduce DuplicableImageSingletons.
PullRequest: graal/20654
2 parents 817b607 + fc75d1c commit d946a7c

File tree

18 files changed

+256
-44
lines changed

18 files changed

+256
-44
lines changed

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/PinnedObjectSupportImpl.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,22 @@
2424
*/
2525
package com.oracle.svm.core.genscavenge;
2626

27+
import java.util.EnumSet;
28+
2729
import org.graalvm.nativeimage.PinnedObject;
2830
import org.graalvm.nativeimage.Platform;
2931
import org.graalvm.nativeimage.Platforms;
3032
import org.graalvm.word.Pointer;
3133

3234
import com.oracle.svm.core.Uninterruptible;
3335
import com.oracle.svm.core.heap.AbstractPinnedObjectSupport;
36+
import com.oracle.svm.core.layeredimagesingleton.InitialLayerOnlyImageSingleton;
37+
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
3438

3539
import jdk.graal.compiler.nodes.NamedLocationIdentity;
3640

3741
/** Support for pinning objects to a memory address with {@link PinnedObject}. */
38-
public final class PinnedObjectSupportImpl extends AbstractPinnedObjectSupport {
42+
public final class PinnedObjectSupportImpl extends AbstractPinnedObjectSupport implements InitialLayerOnlyImageSingleton {
3943
@Platforms(Platform.HOSTED_ONLY.class)
4044
public PinnedObjectSupportImpl() {
4145
}
@@ -62,4 +66,14 @@ private static void modifyPinnedObjectCount(Object object, int delta) {
6266

6367
assert oldValue < Integer.MAX_VALUE;
6468
}
69+
70+
@Override
71+
public EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
72+
return LayeredImageSingletonBuilderFlags.ALL_ACCESS;
73+
}
74+
75+
@Override
76+
public boolean accessibleInFutureLayers() {
77+
return true;
78+
}
6579
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import java.util.List;
2929
import java.util.Map;
3030

31-
import com.oracle.svm.core.jdk.SystemPropertiesSupport;
3231
import org.graalvm.nativeimage.ImageSingletons;
3332
import org.graalvm.nativeimage.hosted.Feature;
3433
import org.graalvm.nativeimage.impl.PinnedObjectSupport;
@@ -60,7 +59,9 @@
6059
import com.oracle.svm.core.heap.BarrierSetProvider;
6160
import com.oracle.svm.core.heap.Heap;
6261
import com.oracle.svm.core.image.ImageHeapLayouter;
62+
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
6363
import com.oracle.svm.core.jdk.RuntimeSupportFeature;
64+
import com.oracle.svm.core.jdk.SystemPropertiesSupport;
6465
import com.oracle.svm.core.jvmstat.PerfDataFeature;
6566
import com.oracle.svm.core.jvmstat.PerfDataHolder;
6667
import com.oracle.svm.core.jvmstat.PerfManager;
@@ -100,7 +101,9 @@ public void duringSetup(DuringSetupAccess access) {
100101
ImageSingletons.add(Heap.class, new HeapImpl());
101102
ImageSingletons.add(ImageHeapInfo.class, new ImageHeapInfo());
102103
ImageSingletons.add(GCAllocationSupport.class, new GenScavengeAllocationSupport());
103-
ImageSingletons.add(PinnedObjectSupport.class, new PinnedObjectSupportImpl());
104+
if (ImageLayerBuildingSupport.firstImageBuild()) {
105+
ImageSingletons.add(PinnedObjectSupport.class, new PinnedObjectSupportImpl());
106+
}
104107

105108
if (ImageSingletons.contains(PerfManager.class)) {
106109
ImageSingletons.lookup(PerfManager.class).register(createPerfData());

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/PosixLogHandler.java

+19-3
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,33 @@
2525
package com.oracle.svm.core.posix;
2626

2727
import java.io.FileDescriptor;
28+
import java.util.EnumSet;
2829

30+
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
2931
import org.graalvm.nativeimage.LogHandler;
3032
import org.graalvm.nativeimage.c.type.CCharPointer;
3133
import org.graalvm.word.UnsignedWord;
3234

3335
import com.oracle.svm.core.SubstrateDiagnostics;
36+
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
3437
import com.oracle.svm.core.feature.InternalFeature;
3538
import com.oracle.svm.core.headers.LibC;
39+
import com.oracle.svm.core.layeredimagesingleton.InitialLayerOnlyImageSingleton;
40+
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
3641
import com.oracle.svm.core.log.Log;
3742
import com.oracle.svm.core.thread.VMThreads;
38-
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
3943

4044
@AutomaticallyRegisteredFeature
4145
class PosixLogHandlerFeature implements InternalFeature {
4246
@Override
4347
public void beforeAnalysis(BeforeAnalysisAccess access) {
44-
Log.finalizeDefaultLogHandler(new PosixLogHandler());
48+
if (ImageLayerBuildingSupport.firstImageBuild()) {
49+
Log.finalizeDefaultLogHandler(new PosixLogHandler());
50+
}
4551
}
4652
}
4753

48-
public class PosixLogHandler implements LogHandler {
54+
public class PosixLogHandler implements LogHandler, InitialLayerOnlyImageSingleton {
4955

5056
@Override
5157
public void log(CCharPointer bytes, UnsignedWord length) {
@@ -88,4 +94,14 @@ public void fatalError() {
8894
private static FileDescriptor getOutputFile() {
8995
return FileDescriptor.err;
9096
}
97+
98+
@Override
99+
public EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
100+
return LayeredImageSingletonBuilderFlags.RUNTIME_ACCESS_ONLY;
101+
}
102+
103+
@Override
104+
public boolean accessibleInFutureLayers() {
105+
return true;
106+
}
91107
}

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/linux/LinuxPhysicalMemorySupportImpl.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import java.util.ArrayList;
3232
import java.util.List;
3333

34-
import jdk.graal.compiler.word.Word;
3534
import org.graalvm.nativeimage.ImageSingletons;
3635
import org.graalvm.word.UnsignedWord;
3736

@@ -40,9 +39,12 @@
4039
import com.oracle.svm.core.feature.InternalFeature;
4140
import com.oracle.svm.core.heap.PhysicalMemory;
4241
import com.oracle.svm.core.heap.PhysicalMemory.PhysicalMemorySupport;
42+
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
4343
import com.oracle.svm.core.posix.headers.Unistd;
4444
import com.oracle.svm.core.util.VMError;
4545

46+
import jdk.graal.compiler.word.Word;
47+
4648
public class LinuxPhysicalMemorySupportImpl implements PhysicalMemorySupport {
4749

4850
private static final long K = 1024;
@@ -121,7 +123,7 @@ private static long parseFirstNumber(String str) {
121123
class LinuxPhysicalMemorySupportFeature implements InternalFeature {
122124
@Override
123125
public void beforeAnalysis(BeforeAnalysisAccess access) {
124-
if (!ImageSingletons.contains(PhysicalMemorySupport.class)) {
126+
if (ImageLayerBuildingSupport.firstImageBuild() && !ImageSingletons.contains(PhysicalMemorySupport.class)) {
125127
ImageSingletons.add(PhysicalMemorySupport.class, new LinuxPhysicalMemorySupportImpl());
126128
}
127129
}

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/linux/LinuxProcessPropertiesSupport.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,31 @@
2424
*/
2525
package com.oracle.svm.core.posix.linux;
2626

27+
import java.util.EnumSet;
28+
2729
import org.graalvm.nativeimage.impl.ProcessPropertiesSupport;
2830

29-
import com.oracle.svm.core.posix.PosixProcessPropertiesSupport;
3031
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
32+
import com.oracle.svm.core.layeredimagesingleton.InitialLayerOnlyImageSingleton;
33+
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
34+
import com.oracle.svm.core.posix.PosixProcessPropertiesSupport;
3135

3236
@AutomaticallyRegisteredImageSingleton(ProcessPropertiesSupport.class)
33-
public class LinuxProcessPropertiesSupport extends PosixProcessPropertiesSupport {
37+
public class LinuxProcessPropertiesSupport extends PosixProcessPropertiesSupport implements InitialLayerOnlyImageSingleton {
3438

3539
@Override
3640
public String getExecutableName() {
3741
final String exefileString = "/proc/self/exe";
3842
return realpath(exefileString);
3943
}
44+
45+
@Override
46+
public EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
47+
return LayeredImageSingletonBuilderFlags.RUNTIME_ACCESS_ONLY;
48+
}
49+
50+
@Override
51+
public boolean accessibleInFutureLayers() {
52+
return true;
53+
}
4054
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/CTypeConversionSupportImpl.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
import java.nio.charset.Charset;
2929
import java.nio.charset.StandardCharsets;
3030
import java.util.Arrays;
31+
import java.util.EnumSet;
3132

32-
import jdk.graal.compiler.word.Word;
3333
import org.graalvm.nativeimage.ImageSingletons;
3434
import org.graalvm.nativeimage.c.type.CCharPointer;
3535
import org.graalvm.nativeimage.c.type.CCharPointerPointer;
@@ -45,9 +45,13 @@
4545
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
4646
import com.oracle.svm.core.handles.PrimitiveArrayView;
4747
import com.oracle.svm.core.jdk.DirectByteBufferUtil;
48+
import com.oracle.svm.core.layeredimagesingleton.InitialLayerOnlyImageSingleton;
49+
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
50+
51+
import jdk.graal.compiler.word.Word;
4852

4953
@AutomaticallyRegisteredImageSingleton(CTypeConversionSupport.class)
50-
class CTypeConversionSupportImpl implements CTypeConversionSupport {
54+
class CTypeConversionSupportImpl implements CTypeConversionSupport, InitialLayerOnlyImageSingleton {
5155

5256
static final CCharPointerHolder NULL_HOLDER = new CCharPointerHolder() {
5357
@Override
@@ -189,6 +193,16 @@ public ByteBuffer asByteBuffer(PointerBase address, int size) {
189193
ByteBuffer byteBuffer = DirectByteBufferUtil.allocate(address.rawValue(), size);
190194
return byteBuffer.order(ConfigurationValues.getTarget().arch.getByteOrder());
191195
}
196+
197+
@Override
198+
public EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
199+
return LayeredImageSingletonBuilderFlags.RUNTIME_ACCESS_ONLY;
200+
}
201+
202+
@Override
203+
public boolean accessibleInFutureLayers() {
204+
return true;
205+
}
192206
}
193207

194208
final class CCharPointerHolderImpl implements CCharPointerHolder {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/function/IsolateSupportImpl.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
*/
2525
package com.oracle.svm.core.c.function;
2626

27+
import java.util.EnumSet;
2728
import java.util.List;
2829

29-
import jdk.graal.compiler.word.Word;
3030
import org.graalvm.nativeimage.Isolate;
3131
import org.graalvm.nativeimage.IsolateThread;
3232
import org.graalvm.nativeimage.Isolates.CreateIsolateParameters;
@@ -41,14 +41,18 @@
4141
import com.oracle.svm.core.c.function.CEntryPointNativeFunctions.IsolateThreadPointer;
4242
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
4343
import com.oracle.svm.core.graal.stackvalue.UnsafeStackValue;
44+
import com.oracle.svm.core.layeredimagesingleton.InitialLayerOnlyImageSingleton;
45+
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
4446
import com.oracle.svm.core.memory.NativeMemory;
4547
import com.oracle.svm.core.nmt.NmtCategory;
4648
import com.oracle.svm.core.option.SubstrateOptionsParser;
4749
import com.oracle.svm.core.os.MemoryProtectionProvider;
4850
import com.oracle.svm.core.os.MemoryProtectionProvider.UnsupportedDomainException;
4951

52+
import jdk.graal.compiler.word.Word;
53+
5054
@AutomaticallyRegisteredImageSingleton(IsolateSupport.class)
51-
public final class IsolateSupportImpl implements IsolateSupport {
55+
public final class IsolateSupportImpl implements IsolateSupport, InitialLayerOnlyImageSingleton {
5256
private static final String ISOLATES_DISABLED_MESSAGE = "Spawning of multiple isolates is disabled, use " +
5357
SubstrateOptionsParser.commandArgument(SubstrateOptions.SpawnIsolates, "+") + " option.";
5458
private static final String PROTECTION_DOMAIN_UNSUPPORTED_MESSAGE = "Protection domains are unavailable";
@@ -167,4 +171,14 @@ private static void throwOnError(int code) {
167171
throw new IsolateException(message);
168172
}
169173
}
174+
175+
@Override
176+
public EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
177+
return LayeredImageSingletonBuilderFlags.RUNTIME_ACCESS_ONLY;
178+
}
179+
180+
@Override
181+
public boolean accessibleInFutureLayers() {
182+
return true;
183+
}
170184
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/handles/ObjectHandlesSupportImpl.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@
2424
*/
2525
package com.oracle.svm.core.handles;
2626

27+
import java.util.EnumSet;
28+
2729
import org.graalvm.nativeimage.ObjectHandles;
2830
import org.graalvm.nativeimage.impl.ObjectHandlesSupport;
2931

3032
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
33+
import com.oracle.svm.core.layeredimagesingleton.InitialLayerOnlyImageSingleton;
34+
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
3135

3236
@AutomaticallyRegisteredImageSingleton(ObjectHandlesSupport.class)
33-
class ObjectHandlesSupportImpl implements ObjectHandlesSupport {
37+
class ObjectHandlesSupportImpl implements ObjectHandlesSupport, InitialLayerOnlyImageSingleton {
3438
final ObjectHandlesImpl globalHandles = new ObjectHandlesImpl();
3539

3640
@Override
@@ -42,4 +46,19 @@ public ObjectHandles getGlobalHandles() {
4246
public ObjectHandles createHandles() {
4347
return new ObjectHandlesImpl();
4448
}
49+
50+
@Override
51+
public EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
52+
/*
53+
* In some cases object instances are accessed during code initialized at buildtime.
54+
* However, when this is done, one must be very careful to ensure analysis sees all changes
55+
* made to these objects.
56+
*/
57+
return LayeredImageSingletonBuilderFlags.ALL_ACCESS;
58+
}
59+
60+
@Override
61+
public boolean accessibleInFutureLayers() {
62+
return true;
63+
}
4564
}

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

+11-3
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
package com.oracle.svm.core.heap;
2626

2727
import java.lang.management.ManagementFactory;
28+
import java.util.EnumSet;
2829

29-
import jdk.graal.compiler.word.Word;
3030
import org.graalvm.nativeimage.ImageSingletons;
3131
import org.graalvm.nativeimage.Platform;
3232
import org.graalvm.word.UnsignedWord;
@@ -36,18 +36,21 @@
3636
import com.oracle.svm.core.Uninterruptible;
3737
import com.oracle.svm.core.container.Container;
3838
import com.oracle.svm.core.container.OperatingSystem;
39-
import com.oracle.svm.core.layeredimagesingleton.RuntimeOnlyImageSingleton;
39+
import com.oracle.svm.core.layeredimagesingleton.InitialLayerOnlyImageSingleton;
40+
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
4041
import com.oracle.svm.core.util.UnsignedUtils;
4142
import com.oracle.svm.core.util.VMError;
4243
import com.sun.management.OperatingSystemMXBean;
4344

45+
import jdk.graal.compiler.word.Word;
46+
4447
/**
4548
* Contains static methods to get configuration of physical memory.
4649
*/
4750
public class PhysicalMemory {
4851

4952
/** Implemented by operating-system specific code. */
50-
public interface PhysicalMemorySupport extends RuntimeOnlyImageSingleton {
53+
public interface PhysicalMemorySupport extends InitialLayerOnlyImageSingleton {
5154
/** Get the size of physical memory from the OS. */
5255
UnsignedWord size();
5356

@@ -62,6 +65,11 @@ public interface PhysicalMemorySupport extends RuntimeOnlyImageSingleton {
6265
default long usedSize() {
6366
return -1L;
6467
}
68+
69+
@Override
70+
default EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
71+
return LayeredImageSingletonBuilderFlags.RUNTIME_ACCESS_ONLY;
72+
}
6573
}
6674

6775
private static final UnsignedWord UNSET_SENTINEL = UnsignedUtils.MAX_VALUE;
+16-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,17 +24,19 @@
2424
*/
2525
package com.oracle.svm.core.layeredimagesingleton;
2626

27-
import java.util.EnumSet;
28-
29-
public interface RuntimeOnlyImageSingleton extends LayeredImageSingleton {
30-
31-
@Override
32-
default EnumSet<LayeredImageSingletonBuilderFlags> getImageBuilderFlags() {
33-
return LayeredImageSingletonBuilderFlags.RUNTIME_ACCESS_ONLY;
34-
}
35-
36-
@Override
37-
default PersistFlags preparePersist(ImageSingletonWriter writer) {
38-
return PersistFlags.NOTHING;
39-
}
27+
/**
28+
* A Duplicable ImageSingleton can have multiple instances of the object installed in the Image Heap
29+
* (at most one per a layer). The specific instance referred to from a given piece of code is
30+
* dependent on the layer in which the code was installed in.
31+
*
32+
* It is expected that either the installed objects (1) have no instance fields or (2) have instance
33+
* fields which have been made layer-aware through other means (e.g. using a layered ImageHeapMap).
34+
*
35+
* Note this is a temporary marker and eventually all instances of {@link DuplicableImageSingleton}s
36+
* should be removed. This marker should only be used when there is not a correctness issue with
37+
* installing multiple instances of the singleton. Instead, the marker indicates there is merely a
38+
* performance/memory overhead due to having multiple copies of this singleton installed (via
39+
* different layers) within the image heap.
40+
*/
41+
public interface DuplicableImageSingleton extends LayeredImageSingleton {
4042
}

0 commit comments

Comments
 (0)