Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ struct SharedLayerSnapshot {
singletonKeys @11 :List(ImageSingletonKey);
singletonObjects @12 :List(ImageSingletonObject);
fields @13 :List(PersistedAnalysisField);
nextLayerNumber @14 :Int32;
}

struct PrimitiveValue {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ public PersistFlags preparePersist(ImageSingletonWriter writer) {
/*
* First write out next layer number.
*/
writer.writeInt("nextLayerNumber", nextLayerNumber);
var snapshotBuilder = ((SVMImageLayerWriter.ImageSingletonWriterImpl) writer).getSnapshotBuilder();
snapshotBuilder.setNextLayerNumber(nextLayerNumber);

/*
* Next write the start of the code section
Expand Down Expand Up @@ -228,7 +229,8 @@ public static Object createFromLoader(ImageSingletonLoader loader) {
assert loader.readIntList("offsets").size() == loader.readIntList("methodOffsetIDs").size() : Assertions.errorMessage("Offsets and methodIDs are incompatible", loader.readIntList("offsets"),
loader.readIntList("methodIDs"));

int layerNumber = loader.readInt("nextLayerNumber");
var snapshotReader = ((SVMImageLayerSingletonLoader.ImageSingletonLoaderImpl) loader).getSnapshotReader();
int layerNumber = snapshotReader.getNextLayerNumber();

String codeSectionStartSymbol = loader.readString("codeSectionStartSymbol");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private Map<Object, Set<Class<?>>> loadImageSingletons0(Object forbiddenObject)
try {
Class<?> clazz = imageLayerBuildingSupport.lookupClass(false, className);
Method createMethod = ReflectionUtil.lookupMethod(clazz, "createFromLoader", ImageSingletonLoader.class);
result = createMethod.invoke(null, new ImageSingletonLoaderImpl(keyStore));
result = createMethod.invoke(null, new ImageSingletonLoaderImpl(keyStore, snapshot));
} catch (Throwable t) {
throw VMError.shouldNotReachHere("Failed to recreate image singleton", t);
}
Expand Down Expand Up @@ -122,44 +122,50 @@ private Map<Object, Set<Class<?>>> loadImageSingletons0(Object forbiddenObject)
public Class<?> lookupClass(boolean optional, String className) {
return imageLayerBuildingSupport.lookupClass(optional, className);
}
}

class ImageSingletonLoaderImpl implements ImageSingletonLoader {
private final UnmodifiableEconomicMap<String, Object> keyStore;
public static class ImageSingletonLoaderImpl implements ImageSingletonLoader {
private final UnmodifiableEconomicMap<String, Object> keyStore;
private final SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Reader snapshotReader;

ImageSingletonLoaderImpl(UnmodifiableEconomicMap<String, Object> keyStore) {
this.keyStore = keyStore;
}
ImageSingletonLoaderImpl(UnmodifiableEconomicMap<String, Object> keyStore, SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Reader snapshotReader) {
this.keyStore = keyStore;
this.snapshotReader = snapshotReader;
}

@Override
public List<Boolean> readBoolList(String keyName) {
boolean[] l = (boolean[]) keyStore.get(keyName);
return IntStream.range(0, l.length).mapToObj(i -> l[i]).toList();
}
@Override
public List<Boolean> readBoolList(String keyName) {
boolean[] l = (boolean[]) keyStore.get(keyName);
return IntStream.range(0, l.length).mapToObj(i -> l[i]).toList();
}

@Override
public int readInt(String keyName) {
return (int) keyStore.get(keyName);
}
@Override
public int readInt(String keyName) {
return (int) keyStore.get(keyName);
}

@Override
public List<Integer> readIntList(String keyName) {
int[] l = (int[]) keyStore.get(keyName);
return IntStream.of(l).boxed().toList();
}
@Override
public List<Integer> readIntList(String keyName) {
int[] l = (int[]) keyStore.get(keyName);
return IntStream.of(l).boxed().toList();
}

@Override
public long readLong(String keyName) {
return (long) keyStore.get(keyName);
}
@Override
public long readLong(String keyName) {
return (long) keyStore.get(keyName);
}

@Override
public String readString(String keyName) {
return (String) keyStore.get(keyName);
}
@Override
public String readString(String keyName) {
return (String) keyStore.get(keyName);
}

@Override
public List<String> readStringList(String keyName) {
return List.of((String[]) keyStore.get(keyName));
}

@Override
public List<String> readStringList(String keyName) {
return List.of((String[]) keyStore.get(keyName));
public SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Reader getSnapshotReader() {
return snapshotReader;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ public void writeImageSingletonInfo(List<Map.Entry<Class<?>, Object>> layeredIma
}
String key = singletonInfo.getKey().getName();
if (!singletonInfoMap.containsKey(singleton)) {
var writer = new ImageSingletonWriterImpl();
var writer = new ImageSingletonWriterImpl(snapshotBuilder);
var flags = singleton.preparePersist(writer);
boolean persistData = flags == LayeredImageSingleton.PersistFlags.CREATE;
var info = new SingletonPersistInfo(flags, persistData ? nextID++ : -1, persistData ? writer.getKeyValueStore() : null);
Expand Down Expand Up @@ -1069,59 +1069,68 @@ private static void writeImageSingletonKeyStore(ImageSingletonObject.Builder obj
}
}
}
}

class ImageSingletonWriterImpl implements ImageSingletonWriter {
private final EconomicMap<String, Object> keyValueStore = EconomicMap.create();
public static class ImageSingletonWriterImpl implements ImageSingletonWriter {
private final EconomicMap<String, Object> keyValueStore = EconomicMap.create();
private final SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Builder snapshotBuilder;

EconomicMap<String, Object> getKeyValueStore() {
return keyValueStore;
}
ImageSingletonWriterImpl(SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Builder snapshotBuilder) {
this.snapshotBuilder = snapshotBuilder;
}

private static boolean nonNullEntries(List<?> list) {
return list.stream().filter(Objects::isNull).findAny().isEmpty();
}
EconomicMap<String, Object> getKeyValueStore() {
return keyValueStore;
}

@Override
public void writeBoolList(String keyName, List<Boolean> value) {
assert nonNullEntries(value);
boolean[] b = new boolean[value.size()];
for (int i = 0; i < value.size(); i++) {
b[i] = value.get(i);
private static boolean nonNullEntries(List<?> list) {
return list.stream().filter(Objects::isNull).findAny().isEmpty();
}
var previous = keyValueStore.put(keyName, b);
assert previous == null : Assertions.errorMessage(keyName, previous);
}

@Override
public void writeInt(String keyName, int value) {
var previous = keyValueStore.put(keyName, value);
assert previous == null : previous;
}
@Override
public void writeBoolList(String keyName, List<Boolean> value) {
assert nonNullEntries(value);
boolean[] b = new boolean[value.size()];
for (int i = 0; i < value.size(); i++) {
b[i] = value.get(i);
}
var previous = keyValueStore.put(keyName, b);
assert previous == null : Assertions.errorMessage(keyName, previous);
}

@Override
public void writeIntList(String keyName, List<Integer> value) {
assert nonNullEntries(value);
var previous = keyValueStore.put(keyName, value.stream().mapToInt(i -> i).toArray());
assert previous == null : Assertions.errorMessage(keyName, previous);
}
@Override
public void writeInt(String keyName, int value) {
var previous = keyValueStore.put(keyName, value);
assert previous == null : previous;
}

@Override
public void writeLong(String keyName, long value) {
var previous = keyValueStore.put(keyName, value);
assert previous == null : Assertions.errorMessage(keyName, previous);
}
@Override
public void writeIntList(String keyName, List<Integer> value) {
assert nonNullEntries(value);
var previous = keyValueStore.put(keyName, value.stream().mapToInt(i -> i).toArray());
assert previous == null : Assertions.errorMessage(keyName, previous);
}

@Override
public void writeString(String keyName, String value) {
var previous = keyValueStore.put(keyName, value);
assert previous == null : Assertions.errorMessage(keyName, previous);
}
@Override
public void writeLong(String keyName, long value) {
var previous = keyValueStore.put(keyName, value);
assert previous == null : Assertions.errorMessage(keyName, previous);
}

@Override
public void writeStringList(String keyName, List<String> value) {
assert nonNullEntries(value);
var previous = keyValueStore.put(keyName, value.toArray(String[]::new));
assert previous == null : Assertions.errorMessage(keyName, previous);
@Override
public void writeString(String keyName, String value) {
var previous = keyValueStore.put(keyName, value);
assert previous == null : Assertions.errorMessage(keyName, previous);
}

@Override
public void writeStringList(String keyName, List<String> value) {
assert nonNullEntries(value);
var previous = keyValueStore.put(keyName, value.toArray(String[]::new));
assert previous == null : Assertions.errorMessage(keyName, previous);
}

public SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Builder getSnapshotBuilder() {
return snapshotBuilder;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4317,7 +4317,7 @@ public final org.capnproto.StructList.Reader<com.oracle.svm.hosted.imagelayer.Sh


public static class SharedLayerSnapshot {
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)4,(short)7);
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)5,(short)7);
public static final class Factory extends org.capnproto.StructFactory<Builder, Reader> {
public Factory() {
}
Expand Down Expand Up @@ -4477,6 +4477,13 @@ public final void setFields(org.capnproto.StructList.Reader<com.oracle.svm.hoste
public final org.capnproto.StructList.Builder<com.oracle.svm.hosted.imagelayer.SharedLayerSnapshotCapnProtoSchemaHolder.PersistedAnalysisField.Builder> initFields(int size) {
return _initPointerField(com.oracle.svm.hosted.imagelayer.SharedLayerSnapshotCapnProtoSchemaHolder.PersistedAnalysisField.listFactory, 6, size);
}
public final int getNextLayerNumber() {
return _getIntField(8);
}
public final void setNextLayerNumber(int value) {
_setIntField(8, value);
}

}

public static final class Reader extends org.capnproto.StructReader {
Expand Down Expand Up @@ -4561,6 +4568,10 @@ public final org.capnproto.StructList.Reader<com.oracle.svm.hosted.imagelayer.Sh
return _getPointerField(com.oracle.svm.hosted.imagelayer.SharedLayerSnapshotCapnProtoSchemaHolder.PersistedAnalysisField.listFactory, 6, null, 0);
}

public final int getNextLayerNumber() {
return _getIntField(8);
}

}

}
Expand Down