Skip to content

Commit 3e248ce

Browse files
committed
Reviewer comments
1 parent e72ba1e commit 3e248ce

3 files changed

Lines changed: 45 additions & 38 deletions

File tree

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/reflect/serialize/SerializationSupport.java

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import java.lang.reflect.Modifier;
3131
import java.util.function.Consumer;
3232
import java.util.function.Function;
33-
import java.util.function.Predicate;
3433

3534
import org.graalvm.collections.EconomicMap;
3635
import org.graalvm.collections.MapCursor;
@@ -111,50 +110,58 @@ private StubForAbstractClass() {
111110
private DynamicHub stubConstructorClass;
112111
private DynamicHub serializedLambdaClass;
113112

114-
/**
115-
* The ids are either a {@link DynamicHubKey} or {@code DynamicHub.typeID}.
116-
*/
117-
public record SerializationLookupKey(Object declaringClassId, Object targetConstructorClassId) {
113+
public record HostedSerializationLookupKey(DynamicHubKey declaringClassId, DynamicHubKey targetConstructorClassId) {
114+
}
115+
116+
public record SerializationLookupKey(int declaringClassId, int targetConstructorClassId) {
118117
}
119118

119+
@Platforms(Platform.HOSTED_ONLY.class) //
120+
private EconomicMap<HostedSerializationLookupKey, Object> hostedConstructorAccessors;
120121
@UnknownObjectField(fullyQualifiedTypes = "org.graalvm.collections.EconomicMapImpl", availability = AfterCompilation.class) //
121-
private final EconomicMap<SerializationLookupKey, Object> constructorAccessors;
122+
private EconomicMap<SerializationLookupKey, Object> constructorAccessors;
122123

123124
/**
124125
* The constructor accessors need to be rescanned manually because the
125126
* {@link SerializationSupport#constructorAccessors} map is only available after compilation.
126127
*/
127128
@Platforms(Platform.HOSTED_ONLY.class) //
128-
private Consumer<Object> scanObject;
129+
private Consumer<Object> objectRescanner;
129130

130131
public SerializationSupport() {
131-
constructorAccessors = EconomicMap.create();
132+
hostedConstructorAccessors = EconomicMap.create();
133+
constructorAccessors = null;
132134
}
133135

134136
public void setStubConstructor(DynamicHub stubConstructorClass) {
135-
VMError.guarantee(this.stubConstructorClass == null, "Cannot reset stubConstructor");
137+
VMError.guarantee(this.stubConstructorClass == null, "Cannot set stubConstructor again");
136138
this.stubConstructorClass = stubConstructorClass;
137139
}
138140

139141
public void setSerializedLambdaClass(DynamicHub serializedLambdaClass) {
142+
VMError.guarantee(this.serializedLambdaClass == null, "Cannot set serializedLambdaClass again");
140143
this.serializedLambdaClass = serializedLambdaClass;
141144
}
142145

143146
private DynamicHub getSerializedLambdaClass() {
144147
return serializedLambdaClass;
145148
}
146149

147-
public void setScanObject(Consumer<Object> scanObject) {
148-
this.scanObject = scanObject;
150+
@Platforms(Platform.HOSTED_ONLY.class)
151+
public void setObjectRescanner(Consumer<Object> objectRescanner) {
152+
VMError.guarantee(this.serializedLambdaClass == null, "Cannot set objectRescanner again");
153+
this.objectRescanner = objectRescanner;
149154
}
150155

151156
@Platforms(Platform.HOSTED_ONLY.class)
152157
public Object addConstructorAccessor(DynamicHub declaringClass, DynamicHub targetConstructorClass, Object constructorAccessor) {
153158
VMError.guarantee(constructorAccessor instanceof SubstrateConstructorAccessor, "Not a SubstrateConstructorAccessor: %s", constructorAccessor);
154-
SerializationLookupKey key = BuildPhaseProvider.isHostedUniverseBuilt() ? new SerializationLookupKey(declaringClass.getTypeID(), targetConstructorClass.getTypeID())
155-
: new SerializationLookupKey(new DynamicHubKey(declaringClass), new DynamicHubKey(targetConstructorClass));
156-
scanObject.accept(constructorAccessor);
157-
return constructorAccessors.putIfAbsent(key, constructorAccessor);
159+
VMError.guarantee(!BuildPhaseProvider.isHostedUniverseBuilt());
160+
HostedSerializationLookupKey key = new HostedSerializationLookupKey(new DynamicHubKey(declaringClass), new DynamicHubKey(targetConstructorClass));
161+
objectRescanner.accept(constructorAccessor);
162+
synchronized (hostedConstructorAccessors) {
163+
return hostedConstructorAccessors.putIfAbsent(key, constructorAccessor);
164+
}
158165
}
159166

160167
@Platforms(Platform.HOSTED_ONLY.class)
@@ -170,7 +177,7 @@ public SerializationLookupKey getKeyFromConstructorAccessorClass(Class<?> constr
170177

171178
@Platforms(Platform.HOSTED_ONLY.class)
172179
public boolean isGeneratedSerializationClassLoader(ClassLoader classLoader) {
173-
var constructorAccessorsCursor = constructorAccessors.getEntries();
180+
var constructorAccessorsCursor = hostedConstructorAccessors.getEntries();
174181
while (constructorAccessorsCursor.advance()) {
175182
if (constructorAccessorsCursor.getValue().getClass().getClassLoader() == classLoader) {
176183
return true;
@@ -181,7 +188,7 @@ public boolean isGeneratedSerializationClassLoader(ClassLoader classLoader) {
181188

182189
@Platforms(Platform.HOSTED_ONLY.class)
183190
public String getClassLoaderSerializationLookupKey(ClassLoader classLoader) {
184-
var constructorAccessorsCursor = constructorAccessors.getEntries();
191+
var constructorAccessorsCursor = hostedConstructorAccessors.getEntries();
185192
while (constructorAccessorsCursor.advance()) {
186193
if (constructorAccessorsCursor.getValue().getClass().getClassLoader() == classLoader) {
187194
var key = constructorAccessorsCursor.getKey();
@@ -208,14 +215,17 @@ public int getTypeID() {
208215
}
209216
}
210217

218+
@Platforms(Platform.HOSTED_ONLY.class) //
219+
private EconomicMap<DynamicHubKey, RuntimeDynamicAccessMetadata> hostedClasses = EconomicMap.create();
211220
@UnknownObjectField(fullyQualifiedTypes = "org.graalvm.collections.EconomicMapImpl", availability = AfterCompilation.class) //
212-
private final EconomicMap<Object /* DynamicHubKey or DynamicHub.typeID */, RuntimeDynamicAccessMetadata> classes = EconomicMap.create();
221+
private EconomicMap<Integer, RuntimeDynamicAccessMetadata> classes = null;
213222
private final EconomicMap<String, RuntimeDynamicAccessMetadata> lambdaCapturingClasses = EconomicMap.create();
214223

215224
@Platforms(Platform.HOSTED_ONLY.class)
216225
public void registerSerializationTargetClass(AccessCondition cnd, DynamicHub hub, boolean preserved) {
217-
synchronized (classes) {
218-
var previous = classes.putIfAbsent(BuildPhaseProvider.isHostedUniverseBuilt() ? hub.getTypeID() : new DynamicHubKey(hub), RuntimeDynamicAccessMetadata.createHosted(cnd, preserved));
226+
VMError.guarantee(!BuildPhaseProvider.isHostedUniverseBuilt());
227+
synchronized (hostedClasses) {
228+
var previous = hostedClasses.putIfAbsent(new DynamicHubKey(hub), RuntimeDynamicAccessMetadata.createHosted(cnd, preserved));
219229
if (previous != null) {
220230
previous.addCondition(cnd);
221231
if (!preserved) {
@@ -226,28 +236,23 @@ public void registerSerializationTargetClass(AccessCondition cnd, DynamicHub hub
226236
}
227237

228238
public void replaceHubKeyWithTypeID() {
229-
replaceHubKeyWithTypeID(classes, key -> key instanceof DynamicHubKey, SerializationSupport::getTypeID);
230-
replaceHubKeyWithTypeID(constructorAccessors, SerializationSupport::shouldReplaceSerializationLookupKey, SerializationSupport::replaceSerializationLookupKey);
239+
classes = EconomicMap.create();
240+
replaceHubKeyWithTypeID(hostedClasses, classes, SerializationSupport::getTypeID);
241+
hostedClasses = null;
242+
constructorAccessors = EconomicMap.create();
243+
replaceHubKeyWithTypeID(hostedConstructorAccessors, constructorAccessors, SerializationSupport::replaceSerializationLookupKey);
244+
hostedConstructorAccessors = null;
231245
}
232246

233-
private static <T, U> void replaceHubKeyWithTypeID(EconomicMap<T, U> map, Predicate<T> condition, Function<T, T> converter) {
234-
EconomicMap<T, U> newEntries = EconomicMap.create();
235-
var cursor = map.getEntries();
247+
private static <T, U, V> void replaceHubKeyWithTypeID(EconomicMap<T, U> hostedMap, EconomicMap<V, U> map, Function<T, V> converter) {
248+
var cursor = hostedMap.getEntries();
236249
while (cursor.advance()) {
237250
T key = cursor.getKey();
238-
if (condition.test(key)) {
239-
newEntries.put(converter.apply(key), cursor.getValue());
240-
cursor.remove();
241-
}
251+
map.put(converter.apply(key), cursor.getValue());
242252
}
243-
map.putAll(newEntries);
244253
}
245254

246-
private static boolean shouldReplaceSerializationLookupKey(SerializationLookupKey key) {
247-
return key.declaringClassId() instanceof DynamicHubKey && key.targetConstructorClassId() instanceof DynamicHubKey;
248-
}
249-
250-
private static SerializationLookupKey replaceSerializationLookupKey(SerializationLookupKey key) {
255+
private static SerializationLookupKey replaceSerializationLookupKey(HostedSerializationLookupKey key) {
251256
return new SerializationLookupKey(getTypeID(key.declaringClassId()), getTypeID(key.targetConstructorClassId()));
252257
}
253258

@@ -333,11 +338,13 @@ public static boolean isRegisteredForSerialization(DynamicHub hub) {
333338
}
334339

335340
public boolean isRegisteredForSerialization0(DynamicHub dynamicHub) {
341+
SubstrateUtil.guaranteeRuntimeOnly();
336342
var conditionSet = classes.get(dynamicHub.getTypeID());
337343
return conditionSet != null && conditionSet.satisfied();
338344
}
339345

340346
public static boolean isPreservedForSerialization(DynamicHub dynamicHub) {
347+
SubstrateUtil.guaranteeRuntimeOnly();
341348
for (SerializationSupport singleton : SerializationSupport.layeredSingletons()) {
342349
var conditionSet = singleton.classes.get(dynamicHub.getTypeID());
343350
if (conditionSet != null) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,8 @@ protected void delegatePersistType(AnalysisType type, PersistedAnalysisType.Buil
534534
if (type.toJavaName(true).contains(GENERATED_SERIALIZATION)) {
535535
WrappedType.SerializationGenerated.Builder b = builder.getWrappedType().initSerializationGenerated();
536536
var key = SerializationSupport.currentLayer().getKeyFromConstructorAccessorClass(type.getJavaClass());
537-
b.setRawDeclaringClassId((Integer) key.declaringClassId());
538-
b.setRawTargetConstructorId((Integer) key.targetConstructorClassId());
537+
b.setRawDeclaringClassId(key.declaringClassId());
538+
b.setRawTargetConstructorId(key.targetConstructorClassId());
539539
} else if (LambdaUtils.isLambdaType(type)) {
540540
WrappedType.Lambda.Builder b = builder.getWrappedType().initLambda();
541541
b.setCapturingClass(LambdaUtils.capturingClass(type.toJavaName()));

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/serialize/SerializationFeature.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ private void registerConstructorAccessor(AccessCondition cnd, Class<?> serializa
464464
void beforeAnalysis(Feature.BeforeAnalysisAccess beforeAnalysisAccess) {
465465
setAnalysisAccess(beforeAnalysisAccess);
466466
BeforeAnalysisAccessImpl accessImpl = (BeforeAnalysisAccessImpl) beforeAnalysisAccess;
467-
serializationSupport.setScanObject(object -> accessImpl.rescanObject(object, OtherReason.UNKNOWN));
467+
serializationSupport.setObjectRescanner(object -> accessImpl.rescanObject(object, OtherReason.UNKNOWN));
468468
universe = accessImpl.getUniverse();
469469
stubConstructor = newConstructorForSerialization(SerializationSupport.StubForAbstractClass.class, null);
470470
pendingConstructorRegistrations.forEach(Runnable::run);

0 commit comments

Comments
 (0)