diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerMethod.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerMethod.java index 2d32cc0189ab..8305ddbbccfc 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerMethod.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerMethod.java @@ -51,6 +51,8 @@ * method, using the information from the base layer. */ public class BaseLayerMethod extends BaseLayerElement implements ResolvedJavaMethod { + private static final String CLINIT = ""; + private final int id; private final ResolvedJavaType declaringClass; private final String name; @@ -153,7 +155,7 @@ public boolean isDeclared() { @Override public boolean isClassInitializer() { - throw unimplemented(); + return name.equals(CLINIT); } @Override diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerLoader.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerLoader.java index 6edc749261b1..6296e92c97b9 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerLoader.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerLoader.java @@ -739,24 +739,29 @@ private void initializeBaseLayerTypeBeforePublishing(AnalysisType type, Persiste public void initializeBaseLayerType(AnalysisType type) { VMError.guarantee(type.isInBaseLayer()); PersistedAnalysisType.Reader td = findType(getBaseLayerTypeId(type)); - registerFlag(td.getIsInstantiated(), _ -> type.registerAsInstantiated(PERSISTED)); - registerFlag(td.getIsUnsafeAllocated(), _ -> type.registerAsUnsafeAllocated(PERSISTED)); - registerFlag(td.getIsReachable(), _ -> type.registerAsReachable(PERSISTED)); + postTask(td.getIsInstantiated(), _ -> type.registerAsInstantiated(PERSISTED)); + postTask(td.getIsUnsafeAllocated(), _ -> type.registerAsUnsafeAllocated(PERSISTED)); + postTask(td.getIsReachable(), _ -> type.registerAsReachable(PERSISTED)); - if (!td.getIsInstantiated() && td.getIsAnySubtypeInstantiated()) { + if (td.getIsAnySubtypeInstantiated()) { + /* + * Once a base layer type is loaded, loading all its instantiated subtypes ensures that + * the application layer typestate is coherent with the base layer typestate. Otherwise, + * unwanted optimizations could occur as the typestate would not contain some missed + * types from the base layer. + */ var subTypesReader = td.getSubTypes(); for (int i = 0; i < subTypesReader.size(); ++i) { int tid = subTypesReader.get(i); var subTypeReader = findType(tid); - if (subTypeReader.getIsInstantiated()) { - registerFlag(true, _ -> getAnalysisTypeForBaseLayerId(subTypeReader.getId())); - } + /* Only load instantiated subtypes. */ + postTask(subTypeReader.getIsInstantiated(), _ -> getAnalysisTypeForBaseLayerId(subTypeReader.getId())); } } } - private void registerFlag(boolean flag, DebugContextRunnable task) { - if (flag) { + private void postTask(boolean condition, DebugContextRunnable task) { + if (condition) { if (universe.getBigbang() != null) { universe.getBigbang().postTask(task); } else { @@ -1022,11 +1027,11 @@ public void addBaseLayerMethod(AnalysisMethod analysisMethod) { methods.putIfAbsent(analysisMethod.getId(), analysisMethod); PersistedAnalysisMethod.Reader md = getMethodData(analysisMethod); - registerFlag(md.getIsVirtualRootMethod(), _ -> analysisMethod.registerAsVirtualRootMethod(PERSISTED)); - registerFlag(md.getIsDirectRootMethod(), _ -> analysisMethod.registerAsDirectRootMethod(PERSISTED)); - registerFlag(md.getIsInvoked(), _ -> analysisMethod.registerAsInvoked(PERSISTED)); - registerFlag(md.getIsImplementationInvoked(), _ -> analysisMethod.registerAsImplementationInvoked(PERSISTED)); - registerFlag(md.getIsIntrinsicMethod(), _ -> analysisMethod.registerAsIntrinsicMethod(PERSISTED)); + postTask(md.getIsVirtualRootMethod(), _ -> analysisMethod.registerAsVirtualRootMethod(PERSISTED)); + postTask(md.getIsDirectRootMethod(), _ -> analysisMethod.registerAsDirectRootMethod(PERSISTED)); + postTask(md.getIsInvoked(), _ -> analysisMethod.registerAsInvoked(PERSISTED)); + postTask(md.getIsImplementationInvoked(), _ -> analysisMethod.registerAsImplementationInvoked(PERSISTED)); + postTask(md.getIsIntrinsicMethod(), _ -> analysisMethod.registerAsIntrinsicMethod(PERSISTED)); AnalysisMethod.CompilationBehavior compilationBehavior = AnalysisMethod.CompilationBehavior.values()[md.getCompilationBehaviorOrdinal()]; analysisMethod.setCompilationBehavior(compilationBehavior); @@ -1309,17 +1314,17 @@ public void initializeBaseLayerField(AnalysisField analysisField) { if (!analysisField.isStatic() && (isAccessed || isRead)) { analysisField.getDeclaringClass().getInstanceFields(true); } - registerFlag(isAccessed, _ -> { + postTask(isAccessed, _ -> { analysisField.injectDeclaredType(); analysisField.registerAsAccessed(PERSISTED); }); - registerFlag(isRead, _ -> analysisField.registerAsRead(PERSISTED)); - registerFlag(fieldData.getIsWritten(), _ -> { + postTask(isRead, _ -> analysisField.registerAsRead(PERSISTED)); + postTask(fieldData.getIsWritten(), _ -> { analysisField.injectDeclaredType(); analysisField.registerAsWritten(PERSISTED); }); - registerFlag(fieldData.getIsFolded(), _ -> analysisField.registerAsFolded(PERSISTED)); - registerFlag(fieldData.getIsUnsafeAccessed(), _ -> analysisField.registerAsUnsafeAccessed(PERSISTED)); + postTask(fieldData.getIsFolded(), _ -> analysisField.registerAsFolded(PERSISTED)); + postTask(fieldData.getIsUnsafeAccessed(), _ -> analysisField.registerAsUnsafeAccessed(PERSISTED)); /* * Inject the base layer position. If the position computed for this layer, either before