Skip to content

Commit 9bd367e

Browse files
committed
[GR-61459] Ensure objects are not modified while graphs are persisted
PullRequest: graal/19840
2 parents e358584 + 7df7d98 commit 9bd367e

File tree

3 files changed

+47
-23
lines changed

3 files changed

+47
-23
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/util/ObjectCopier.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ void makeId(Object obj, ObjectPath objectPath) {
787787
checkIllegalValue(LocationIdentity.class, obj, objectPath, "must come from a static field");
788788
checkIllegalValue(HashSet.class, obj, objectPath, "hashes are typically not stable across VM executions");
789789

790+
prepareObject(obj);
790791
makeStringId(clazz.getName(), objectPath);
791792
ClassInfo classInfo = makeClassInfo(clazz, objectPath);
792793
classInfo.fields().forEach((fieldDesc, f) -> {
@@ -799,6 +800,11 @@ void makeId(Object obj, ObjectPath objectPath) {
799800
}
800801
}
801802

803+
@SuppressWarnings("unused")
804+
protected void prepareObject(Object obj) {
805+
/* Hook to prepare special objects */
806+
}
807+
802808
private ClassInfo makeClassInfo(Class<?> clazz, ObjectPath objectPath) {
803809
try {
804810
return classInfos.computeIfAbsent(clazz, this::makeClassInfo);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/LoadImageSingletonFeature.java

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
package com.oracle.svm.hosted.imagelayer;
2626

2727
import static com.oracle.svm.hosted.imagelayer.LoadImageSingletonFeature.CROSS_LAYER_SINGLETON_TABLE_SYMBOL;
28+
import static com.oracle.svm.hosted.imagelayer.LoadImageSingletonFeature.getCrossLayerSingletonMappingInfo;
2829

2930
import java.util.ArrayList;
3031
import java.util.Comparator;
@@ -102,7 +103,7 @@
102103
public class LoadImageSingletonFeature implements InternalFeature, FeatureSingleton, UnsavedSingleton {
103104
public static final String CROSS_LAYER_SINGLETON_TABLE_SYMBOL = "__layered_singleton_table_start";
104105

105-
private static CrossLayerSingletonMappingInfo getCrossLayerSingletonMappingInfo() {
106+
static CrossLayerSingletonMappingInfo getCrossLayerSingletonMappingInfo() {
106107
return (CrossLayerSingletonMappingInfo) ImageSingletons.lookup(LoadImageSingletonFactory.class);
107108
}
108109

@@ -454,7 +455,7 @@ class CrossLayerSingletonMappingInfo extends LoadImageSingletonFactory implement
454455
/**
455456
* Map of all slot infos (past & present). Is created in {@link #assignSlots}.
456457
*/
457-
private Map<Class<?>, SlotInfo> currentKeyToSlotInfoMap;
458+
Map<Class<?>, SlotInfo> currentKeyToSlotInfoMap;
458459

459460
/**
460461
* Map of constant identifiers for MultiLayer objects installed in this layer.
@@ -467,7 +468,7 @@ class CrossLayerSingletonMappingInfo extends LoadImageSingletonFactory implement
467468
private final Map<Class<?>, LoadImageSingletonDataImpl> layerKeyToSingletonDataMap = new ConcurrentHashMap<>();
468469

469470
boolean sealedSingletonLookup = false;
470-
private CGlobalData<Pointer> singletonTableStart;
471+
CGlobalData<Pointer> singletonTableStart;
471472
int referenceSize = 0;
472473

473474
@Override
@@ -524,7 +525,7 @@ private LoadImageSingletonData getImageSingletonInfo(Class<?> keyClass, SlotReco
524525
return result;
525526
}
526527

527-
if (result.kind == SlotRecordKind.MULTI_LAYERED_SINGLETON) {
528+
if (result.getKind() == SlotRecordKind.MULTI_LAYERED_SINGLETON) {
528529
if (!ImageSingletons.contains(keyClass)) {
529530
/*
530531
* If the singleton doesn't exist, ensure this is allowed.
@@ -580,7 +581,7 @@ void assignSlots(HostedMetaAccess metaAccess) {
580581
* singleton a slot now.
581582
*/
582583
slotAssignment = nextFreeSlot++;
583-
slotInfo = new SlotInfo(keyClass, slotAssignment, info.kind);
584+
slotInfo = new SlotInfo(keyClass, slotAssignment, info.getKind());
584585
}
585586
var prior = currentKeyToSlotInfoMap.put(keyClass, slotInfo);
586587
assert prior == null : prior;
@@ -689,28 +690,33 @@ public static Object createFromLoader(ImageSingletonLoader loader) {
689690

690691
return new CrossLayerSingletonMappingInfo(Map.copyOf(keyClassToSlotInfoMap), Map.copyOf(keyClassToObjectIDListMap));
691692
}
693+
}
692694

693-
class LoadImageSingletonDataImpl implements LoadImageSingletonData {
695+
class LoadImageSingletonDataImpl implements LoadImageSingletonFactory.LoadImageSingletonData {
694696

695-
private final Class<?> key;
696-
private final SlotRecordKind kind;
697+
private final Class<?> key;
698+
private final SlotRecordKind kind;
697699

698-
LoadImageSingletonDataImpl(Class<?> key, SlotRecordKind kind) {
699-
this.key = key;
700-
this.kind = kind;
701-
}
700+
LoadImageSingletonDataImpl(Class<?> key, SlotRecordKind kind) {
701+
this.key = key;
702+
this.kind = kind;
703+
}
702704

703-
@Override
704-
public Class<?> getLoadType() {
705-
return kind == SlotRecordKind.APPLICATION_LAYER_SINGLETON ? key : key.arrayType();
706-
}
705+
public SlotRecordKind getKind() {
706+
return kind;
707+
}
707708

708-
@Override
709-
public SingletonAccessInfo getAccessInfo() {
710-
assert singletonTableStart != null;
711-
CGlobalDataInfo cglobal = CGlobalDataFeature.singleton().registerAsAccessedOrGet(singletonTableStart);
712-
int slotNum = currentKeyToSlotInfoMap.get(key).slotNum();
713-
return new SingletonAccessInfo(cglobal, slotNum * referenceSize);
714-
}
709+
@Override
710+
public Class<?> getLoadType() {
711+
return kind == SlotRecordKind.APPLICATION_LAYER_SINGLETON ? key : key.arrayType();
712+
}
713+
714+
@Override
715+
public LoadImageSingletonFactory.SingletonAccessInfo getAccessInfo() {
716+
CrossLayerSingletonMappingInfo singleton = getCrossLayerSingletonMappingInfo();
717+
assert singleton.singletonTableStart != null;
718+
CGlobalDataInfo cglobal = CGlobalDataFeature.singleton().registerAsAccessedOrGet(singleton.singletonTableStart);
719+
int slotNum = singleton.currentKeyToSlotInfoMap.get(key).slotNum();
720+
return new LoadImageSingletonFactory.SingletonAccessInfo(cglobal, slotNum * singleton.referenceSize);
715721
}
716722
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerSnapshotUtil.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import com.oracle.svm.util.ReflectionUtil;
8181

8282
import jdk.graal.compiler.api.replacements.SnippetReflectionProvider;
83+
import jdk.graal.compiler.debug.CounterKey;
8384
import jdk.graal.compiler.nodes.EncodedGraph;
8485
import jdk.graal.compiler.nodes.FieldLocationIdentity;
8586
import jdk.graal.compiler.util.ObjectCopier;
@@ -338,6 +339,17 @@ public SVMGraphEncoder(Map<Object, Field> externalValues) {
338339
addBuiltin(new FastThreadLocalLocationIdentityBuiltIn());
339340
addBuiltin(new VMThreadLocalInfoBuiltIn());
340341
}
342+
343+
@Override
344+
protected void prepareObject(Object obj) {
345+
if (obj instanceof CounterKey counterKey) {
346+
/*
347+
* The name needs to be cached before we persist the graph to avoid modifying the
348+
* field during the encoding.
349+
*/
350+
counterKey.getName();
351+
}
352+
}
341353
}
342354

343355
public abstract static class AbstractSVMGraphDecoder extends ObjectCopier.Decoder {

0 commit comments

Comments
 (0)