Skip to content

Commit cb40e2d

Browse files
committed
[GR-65232] Refactor layer loader.
PullRequest: graal/20871
2 parents 448bb0e + 51b4a3e commit cb40e2d

File tree

3 files changed

+51
-49
lines changed

3 files changed

+51
-49
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public JavaType lookupAllowUnresolved(JavaType rawType) {
216216
AnalysisType result = optionalLookup(type);
217217
if (result == null) {
218218
result = createType(type);
219-
if (hostVM.useBaseLayer()) {
219+
if (hostVM.useBaseLayer() && result.isInBaseLayer()) {
220220
imageLayerLoader.initializeBaseLayerType(result);
221221
}
222222
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ public void forceInitializeHosted(Class<?> clazz, String reason, boolean allowIn
411411
InitKind initKind = ensureClassInitialized(clazz, allowInitializationErrors);
412412
if (initKind == InitKind.RUN_TIME) {
413413
assert allowInitializationErrors || !LinkAtBuildTimeSupport.singleton().linkAtBuildTime(clazz);
414-
if (ImageLayerBuildingSupport.buildingApplicationLayer()) {
414+
if (ImageLayerBuildingSupport.buildingExtensionLayer()) {
415415
/*
416416
* Special case for application layer building. If a base layer class was configured
417417
* with --initialize-at-build-time but its initialization failed, then the computed

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

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import java.util.stream.Stream;
5555
import java.util.stream.StreamSupport;
5656

57+
import org.graalvm.collections.EconomicMap;
5758
import org.graalvm.nativeimage.AnnotationAccess;
5859
import org.graalvm.nativeimage.ImageSingletons;
5960
import org.graalvm.nativeimage.c.function.CEntryPoint;
@@ -187,9 +188,9 @@ public class SVMImageLayerLoader extends ImageLayerLoader {
187188
private final Map<ResolvedJavaMethod, Boolean> methodHandleCallers = new ConcurrentHashMap<>();
188189

189190
/** Map from {@link SVMImageLayerSnapshotUtil#getTypeDescriptor} to base layer type ids. */
190-
private final Map<String, Integer> typeDescriptorToBaseLayerId = new HashMap<>();
191+
private EconomicMap<String, Integer> typeDescriptorToBaseLayerId;
191192
/** Map from {@link SVMImageLayerSnapshotUtil#getMethodDescriptor} to base layer method ids. */
192-
private final Map<String, Integer> methodDescriptorToBaseLayerId = new HashMap<>();
193+
private EconomicMap<String, Integer> methodDescriptorToBaseLayerId;
193194

194195
protected AnalysisUniverse universe;
195196
protected AnalysisMetaAccess metaAccess;
@@ -261,12 +262,16 @@ public void loadLayerAnalysis() {
261262
universe.setStartFieldId(snapshot.getNextFieldId());
262263
ImageHeapConstant.setCurrentId(snapshot.getNextConstantId());
263264

264-
for (PersistedAnalysisType.Reader typeData : snapshot.getTypes()) {
265+
StructList.Reader<PersistedAnalysisType.Reader> typesReader = snapshot.getTypes();
266+
typeDescriptorToBaseLayerId = EconomicMap.create(typesReader.size());
267+
for (PersistedAnalysisType.Reader typeData : typesReader) {
265268
String descriptor = typeData.getDescriptor().toString();
266269
typeDescriptorToBaseLayerId.put(descriptor, typeData.getId());
267270
}
268271

269-
for (PersistedAnalysisMethod.Reader methodData : snapshot.getMethods()) {
272+
StructList.Reader<PersistedAnalysisMethod.Reader> methodsReader = snapshot.getMethods();
273+
methodDescriptorToBaseLayerId = EconomicMap.create(methodsReader.size());
274+
for (PersistedAnalysisMethod.Reader methodData : methodsReader) {
270275
String descriptor = methodData.getDescriptor().toString();
271276
methodDescriptorToBaseLayerId.put(descriptor, methodData.getId());
272277
}
@@ -397,7 +402,7 @@ public AnalysisType getAnalysisTypeForBaseLayerId(int tid) {
397402
guarantee(types.containsKey(tid), "Type with id %d was not correctly loaded.", tid);
398403
/*
399404
* The type needs to be looked up because it ensures the type is completely created, as the
400-
* types Map is populated before the type is created.
405+
* types map is populated before the type is created.
401406
*/
402407
return universe.lookup(types.get(tid).getWrapped());
403408
}
@@ -406,29 +411,35 @@ private PersistedAnalysisType.Reader findType(int tid) {
406411
return binarySearchUnique(tid, snapshot.getTypes(), PersistedAnalysisType.Reader::getId);
407412
}
408413

414+
/**
415+
* Load the host VM type corresponding to the serialized type data.
416+
* <p>
417+
* First, find the corresponding host VM {@link Class} object by name using
418+
* {@link #lookupBaseLayerTypeInHostVM(String)}.
419+
* <p>
420+
* Then, lookup the hosted {@link Class} in the {@link AnalysisMetaAccess} which will trigger
421+
* creation of the corresponding {@link AnalysisType} object.
422+
* <p>
423+
* The {@link AnalysisType} constructor calls {@link #lookupHostedTypeInBaseLayer(AnalysisType)}
424+
* to check if the newly created type already exists in the base layer. If that's the case, the
425+
* {@link AnalysisType} object takes the same {@code id} as the corresponding base layer type
426+
* and this mapping is also registered in the {@link #types} map.
427+
*/
409428
private void loadType(PersistedAnalysisType.Reader typeData) {
410429
int tid = typeData.getId();
411430

412431
if (delegateLoadType(typeData)) {
413432
return;
414433
}
415434

416-
String name = typeData.getClassJavaName().toString();
417-
Class<?> clazz = lookupBaseLayerTypeInHostVM(name);
435+
Class<?> clazz = lookupBaseLayerTypeInHostVM(typeData.getClassJavaName().toString());
418436

419437
ResolvedJavaType superClass = getResolvedJavaTypeForBaseLayerId(typeData.getSuperClassTypeId());
420-
421438
ResolvedJavaType[] interfaces = streamInts(typeData.getInterfaces())
422439
.mapToObj(this::getResolvedJavaTypeForBaseLayerId).toArray(ResolvedJavaType[]::new);
423440

424441
if (clazz != null) {
425-
/*
426-
* When looking up the class by name, the host VM will create the corresponding
427-
* AnalysisType. During this process, the method lookupHostedTypeInBaseLayer will be
428-
* called to see if the type already exists in the base layer. If it is the case, the id
429-
* from the base layer will be reused and the ImageLayerLoader#types map will be
430-
* populated.
431-
*/
442+
/* Lookup the host VM type and create the analysis type. */
432443
metaAccess.lookupJavaType(clazz);
433444
}
434445

@@ -567,7 +578,6 @@ protected Class<?> lookupBaseLayerTypeInHostVM(String type) {
567578
return null;
568579
}
569580
while (arrayType > 0) {
570-
assert clazz != null;
571581
clazz = clazz.arrayType();
572582
arrayType--;
573583
}
@@ -664,39 +674,31 @@ yield switch (JavaKind.fromPrimitiveOrVoidTypeChar(typeChar)) {
664674

665675
@Override
666676
public int lookupHostedTypeInBaseLayer(AnalysisType type) {
667-
int id = getBaseLayerTypeId(type);
677+
/* Assume that the type was not reachable in the base image. */
678+
int id = -1;
679+
if (type.getWrapped() instanceof BaseLayerType baseLayerType) {
680+
id = baseLayerType.getBaseLayerId();
681+
} else {
682+
String typeDescriptor = imageLayerSnapshotUtil.getTypeDescriptor(type);
683+
Integer typeId = typeDescriptorToBaseLayerId.get(typeDescriptor);
684+
if (typeId != null) {
685+
id = typeId;
686+
initializeBaseLayerTypeBeforePublishing(type, findType(typeId));
687+
}
688+
}
668689
if (id == -1 || types.putIfAbsent(id, type) != null) {
669690
/* A complete type is treated as a different type than its incomplete version */
670691
return -1;
671692
}
672693
return id;
673694
}
674695

675-
private int getBaseLayerTypeId(AnalysisType type) {
696+
private static int getBaseLayerTypeId(AnalysisType type) {
697+
VMError.guarantee(type.isInBaseLayer());
676698
if (type.getWrapped() instanceof BaseLayerType baseLayerType) {
677699
return baseLayerType.getBaseLayerId();
678700
}
679-
PersistedAnalysisType.Reader typeData = findBaseLayerType(type);
680-
if (typeData == null) {
681-
/* The type was not reachable in the base image */
682-
return -1;
683-
}
684-
initializeBaseLayerTypeBeforePublishing(type, typeData);
685-
int id = typeData.getId();
686-
int hubIdentityHashCode = typeData.getHubIdentityHashCode();
687-
typeToHubIdentityHashCode.put(id, hubIdentityHashCode);
688-
return id;
689-
}
690-
691-
protected PersistedAnalysisType.Reader findBaseLayerType(AnalysisType type) {
692-
assert !(type.getWrapped() instanceof BaseLayerType);
693-
String typeDescriptor = imageLayerSnapshotUtil.getTypeDescriptor(type);
694-
Integer typeId = typeDescriptorToBaseLayerId.get(typeDescriptor);
695-
if (typeId == null) {
696-
/* The type was not reachable in the base image */
697-
return null;
698-
}
699-
return findType(typeId);
701+
return type.getId();
700702
}
701703

702704
/**
@@ -726,6 +728,10 @@ private void initializeBaseLayerTypeBeforePublishing(AnalysisType type, Persiste
726728
} else {
727729
classInitializationSupport.withUnsealedConfiguration(() -> classInitializationSupport.initializeAtRunTime(clazz, "computed in a previous layer"));
728730
}
731+
732+
/* Extract and record the base layer identity hashcode for this type. */
733+
int hubIdentityHashCode = typeData.getHubIdentityHashCode();
734+
typeToHubIdentityHashCode.put(typeData.getId(), hubIdentityHashCode);
729735
}
730736

731737
/**
@@ -734,11 +740,8 @@ private void initializeBaseLayerTypeBeforePublishing(AnalysisType type, Persiste
734740
*/
735741
@Override
736742
public void initializeBaseLayerType(AnalysisType type) {
737-
int id = getBaseLayerTypeId(type);
738-
if (id == -1) {
739-
return;
740-
}
741-
PersistedAnalysisType.Reader td = findType(id);
743+
VMError.guarantee(type.isInBaseLayer());
744+
PersistedAnalysisType.Reader td = findType(getBaseLayerTypeId(type));
742745
registerFlag(td.getIsInstantiated(), debug -> type.registerAsInstantiated(PERSISTED));
743746
registerFlag(td.getIsUnsafeAllocated(), debug -> type.registerAsUnsafeAllocated(PERSISTED));
744747
registerFlag(td.getIsReachable(), debug -> type.registerAsReachable(PERSISTED));
@@ -1782,9 +1785,8 @@ private void scanCompanionField(DynamicHub hub) {
17821785
}
17831786

17841787
public ClassInitializationInfo getClassInitializationInfo(AnalysisType type) {
1785-
PersistedAnalysisType.Reader typeMap = findType(type.getId());
1786-
1787-
var initInfo = typeMap.getClassInitializationInfo();
1788+
PersistedAnalysisType.Reader typeData = findType(type.getId());
1789+
var initInfo = typeData.getClassInitializationInfo();
17881790
if (initInfo.getIsNoInitializerNoTracking()) {
17891791
return ClassInitializationInfo.forNoInitializerInfo(false);
17901792
} else if (initInfo.getIsInitializedNoTracking()) {

0 commit comments

Comments
 (0)