From 175093cbcb66e60c74d29a5bb8baa0d3fe1d7317 Mon Sep 17 00:00:00 2001 From: Tom Shull Date: Wed, 18 Dec 2024 18:29:43 +0100 Subject: [PATCH] Expose CapnProtoSchemaHolder to ImageLayerSingletons. --- .../SharedLayerSnapshotCapnProtoSchema.capnp | 1 + .../imagelayer/HostedDynamicLayerInfo.java | 6 +- .../SVMImageLayerSingletonLoader.java | 70 +++++++------ .../imagelayer/SVMImageLayerWriter.java | 99 ++++++++++--------- ...redLayerSnapshotCapnProtoSchemaHolder.java | 13 ++- 5 files changed, 109 insertions(+), 80 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/resources/SharedLayerSnapshotCapnProtoSchema.capnp b/substratevm/src/com.oracle.svm.hosted/resources/SharedLayerSnapshotCapnProtoSchema.capnp index 0ddb683ca041..411cac702b7e 100644 --- a/substratevm/src/com.oracle.svm.hosted/resources/SharedLayerSnapshotCapnProtoSchema.capnp +++ b/substratevm/src/com.oracle.svm.hosted/resources/SharedLayerSnapshotCapnProtoSchema.capnp @@ -255,6 +255,7 @@ struct SharedLayerSnapshot { singletonKeys @11 :List(ImageSingletonKey); singletonObjects @12 :List(ImageSingletonObject); fields @13 :List(PersistedAnalysisField); + nextLayerNumber @14 :Int32; } struct PrimitiveValue { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/HostedDynamicLayerInfo.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/HostedDynamicLayerInfo.java index 9945138aadfc..dda1d9348674 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/HostedDynamicLayerInfo.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/HostedDynamicLayerInfo.java @@ -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 @@ -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"); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerSingletonLoader.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerSingletonLoader.java index a6516558ffb2..06942a9695e0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerSingletonLoader.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerSingletonLoader.java @@ -86,7 +86,7 @@ private Map>> 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); } @@ -122,44 +122,50 @@ private Map>> loadImageSingletons0(Object forbiddenObject) public Class lookupClass(boolean optional, String className) { return imageLayerBuildingSupport.lookupClass(optional, className); } -} -class ImageSingletonLoaderImpl implements ImageSingletonLoader { - private final UnmodifiableEconomicMap keyStore; + public static class ImageSingletonLoaderImpl implements ImageSingletonLoader { + private final UnmodifiableEconomicMap keyStore; + private final SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Reader snapshotReader; - ImageSingletonLoaderImpl(UnmodifiableEconomicMap keyStore) { - this.keyStore = keyStore; - } + ImageSingletonLoaderImpl(UnmodifiableEconomicMap keyStore, SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Reader snapshotReader) { + this.keyStore = keyStore; + this.snapshotReader = snapshotReader; + } - @Override - public List readBoolList(String keyName) { - boolean[] l = (boolean[]) keyStore.get(keyName); - return IntStream.range(0, l.length).mapToObj(i -> l[i]).toList(); - } + @Override + public List 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 readIntList(String keyName) { - int[] l = (int[]) keyStore.get(keyName); - return IntStream.of(l).boxed().toList(); - } + @Override + public List 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 readStringList(String keyName) { + return List.of((String[]) keyStore.get(keyName)); + } - @Override - public List readStringList(String keyName) { - return List.of((String[]) keyStore.get(keyName)); + public SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Reader getSnapshotReader() { + return snapshotReader; + } } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java index c6c11b67ae0a..ecb7e5063914 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java @@ -1007,7 +1007,7 @@ public void writeImageSingletonInfo(List, 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); @@ -1069,59 +1069,68 @@ private static void writeImageSingletonKeyStore(ImageSingletonObject.Builder obj } } } -} -class ImageSingletonWriterImpl implements ImageSingletonWriter { - private final EconomicMap keyValueStore = EconomicMap.create(); + public static class ImageSingletonWriterImpl implements ImageSingletonWriter { + private final EconomicMap keyValueStore = EconomicMap.create(); + private final SharedLayerSnapshotCapnProtoSchemaHolder.SharedLayerSnapshot.Builder snapshotBuilder; - EconomicMap 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 getKeyValueStore() { + return keyValueStore; + } - @Override - public void writeBoolList(String keyName, List 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 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 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 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 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 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; + } } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SharedLayerSnapshotCapnProtoSchemaHolder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SharedLayerSnapshotCapnProtoSchemaHolder.java index 1db6d56da3ca..72d86aefda2c 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SharedLayerSnapshotCapnProtoSchemaHolder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SharedLayerSnapshotCapnProtoSchemaHolder.java @@ -4317,7 +4317,7 @@ public final org.capnproto.StructList.Reader { public Factory() { } @@ -4477,6 +4477,13 @@ public final void setFields(org.capnproto.StructList.Reader 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 { @@ -4561,6 +4568,10 @@ public final org.capnproto.StructList.Reader