Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-60876] Load all instantiated types in application layer #10661

Merged
merged 1 commit into from
Feb 13, 2025
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 @@ -37,16 +37,18 @@ struct PersistedAnalysisType {
annotationList @23 :List(Annotation);
classInitializationInfo @24 :ClassInitializationInfo;
hasArrayType @25 :Bool;
subTypes @26 :List(TypeId);
isAnySubtypeInstantiated @27 :Bool;
wrappedType :union {
none @26 :Void; # default
none @28 :Void; # default
serializationGenerated :group {
rawDeclaringClass @27 :Text;
rawTargetConstructor @28 :Text;
rawDeclaringClass @29 :Text;
rawTargetConstructor @30 :Text;
}
lambda :group {
capturingClass @29 :Text;
capturingClass @31 :Text;
}
proxyType @30 :Void;
proxyType @32 :Void;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ protected void setupNativeImage(String imageName, OptionValues options, Map<Meth
}
((HostedSnippetReflectionProvider) aProviders.getSnippetReflection()).setHeapScanner(heapScanner);
if (imageLayerLoader != null) {
imageLayerLoader.executeHeapScannerTasks();
imageLayerLoader.postFutureBigbangTasks();
}
HeapSnapshotVerifier heapVerifier = new SVMImageHeapVerifier(bb, imageHeap, heapScanner);
aUniverse.setHeapVerifier(heapVerifier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
import com.oracle.graal.pointsto.meta.BaseLayerType;
import com.oracle.graal.pointsto.util.AnalysisError;
import com.oracle.graal.pointsto.util.AnalysisFuture;
import com.oracle.graal.pointsto.util.CompletionExecutor.DebugContextRunnable;
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.classinitialization.ClassInitializationInfo;
import com.oracle.svm.core.graal.code.CGlobalDataInfo;
Expand Down Expand Up @@ -164,7 +165,7 @@ public class SVMImageLayerLoader extends ImageLayerLoader {
private final Map<Integer, BaseLayerMethod> baseLayerMethods = new ConcurrentHashMap<>();
private final Map<Integer, BaseLayerField> baseLayerFields = new ConcurrentHashMap<>();

protected final Set<AnalysisFuture<Void>> heapScannerTasks = ConcurrentHashMap.newKeySet();
protected final Set<DebugContextRunnable> futureBigbangTasks = ConcurrentHashMap.newKeySet();
protected final Map<Integer, Integer> typeToConstant = new ConcurrentHashMap<>();
protected final Map<String, Integer> stringToConstant = new ConcurrentHashMap<>();
protected final Map<Enum<?>, Integer> enumToConstant = new ConcurrentHashMap<>();
Expand Down Expand Up @@ -609,17 +610,28 @@ public void initializeBaseLayerType(AnalysisType type) {
return;
}
PersistedAnalysisType.Reader td = findType(id);
registerFlag(td.getIsInstantiated(), () -> type.registerAsInstantiated(PERSISTED));
registerFlag(td.getIsUnsafeAllocated(), () -> type.registerAsUnsafeAllocated(PERSISTED));
registerFlag(td.getIsReachable(), () -> type.registerAsReachable(PERSISTED));
registerFlag(td.getIsInstantiated(), debug -> type.registerAsInstantiated(PERSISTED));
registerFlag(td.getIsUnsafeAllocated(), debug -> type.registerAsUnsafeAllocated(PERSISTED));
registerFlag(td.getIsReachable(), debug -> type.registerAsReachable(PERSISTED));

if (!td.getIsInstantiated() && td.getIsAnySubtypeInstantiated()) {
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, debug -> getAnalysisTypeForBaseLayerId(subTypeReader.getId()));
}
}
}
}

private void registerFlag(boolean flag, Runnable runnable) {
private void registerFlag(boolean flag, DebugContextRunnable task) {
if (flag) {
if (universe.getBigbang() != null) {
universe.getBigbang().postTask(debug -> runnable.run());
universe.getBigbang().postTask(task);
} else {
heapScannerTasks.add(new AnalysisFuture<>(runnable));
futureBigbangTasks.add(task);
}
}
}
Expand Down Expand Up @@ -806,11 +818,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));
registerFlag(md.getIsVirtualRootMethod(), debug -> analysisMethod.registerAsVirtualRootMethod(PERSISTED));
registerFlag(md.getIsDirectRootMethod(), debug -> analysisMethod.registerAsDirectRootMethod(PERSISTED));
registerFlag(md.getIsInvoked(), debug -> analysisMethod.registerAsInvoked(PERSISTED));
registerFlag(md.getIsImplementationInvoked(), debug -> analysisMethod.registerAsImplementationInvoked(PERSISTED));
registerFlag(md.getIsIntrinsicMethod(), debug -> analysisMethod.registerAsIntrinsicMethod(PERSISTED));
}

private PersistedAnalysisMethod.Reader getMethodData(AnalysisMethod analysisMethod) {
Expand Down Expand Up @@ -1063,10 +1075,10 @@ public void initializeBaseLayerField(AnalysisField analysisField) {
if (!analysisField.isStatic() && (isAccessed || isRead)) {
analysisField.getDeclaringClass().getInstanceFields(true);
}
registerFlag(isAccessed, () -> analysisField.registerAsAccessed(PERSISTED));
registerFlag(isRead, () -> analysisField.registerAsRead(PERSISTED));
registerFlag(fieldData.getIsWritten(), () -> analysisField.registerAsWritten(PERSISTED));
registerFlag(fieldData.getIsFolded(), () -> analysisField.registerAsFolded(PERSISTED));
registerFlag(isAccessed, debug -> analysisField.registerAsAccessed(PERSISTED));
registerFlag(isRead, debug -> analysisField.registerAsRead(PERSISTED));
registerFlag(fieldData.getIsWritten(), debug -> analysisField.registerAsWritten(PERSISTED));
registerFlag(fieldData.getIsFolded(), debug -> analysisField.registerAsFolded(PERSISTED));
}

private PersistedAnalysisField.Reader getFieldData(AnalysisField analysisField) {
Expand Down Expand Up @@ -1094,10 +1106,11 @@ private PersistedAnalysisField.Reader getFieldData(AnalysisField analysisField)
return null;
}

public void executeHeapScannerTasks() {
guarantee(universe.getHeapScanner() != null, "Those tasks should only be executed when the bigbang is not null.");
for (AnalysisFuture<Void> task : heapScannerTasks) {
task.ensureDone();
public void postFutureBigbangTasks() {
BigBang bigbang = universe.getBigbang();
guarantee(bigbang != null, "Those tasks should only be executed when the bigbang is not null.");
for (DebugContextRunnable task : futureBigbangTasks) {
bigbang.postTask(task);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import java.util.function.IntFunction;
import java.util.function.ObjIntConsumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

Expand Down Expand Up @@ -93,6 +94,7 @@
import com.oracle.graal.pointsto.heap.ImageHeapPrimitiveArray;
import com.oracle.graal.pointsto.heap.ImageHeapRelocatableConstant;
import com.oracle.graal.pointsto.infrastructure.OriginalFieldProvider;
import com.oracle.graal.pointsto.meta.AnalysisElement;
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.graal.pointsto.meta.AnalysisType;
Expand Down Expand Up @@ -451,6 +453,15 @@ private void persistType(AnalysisType type, Supplier<PersistedAnalysisType.Build

delegatePersistType(type, builder);

Set<AnalysisType> subTypes = type.getSubTypes().stream().filter(AnalysisElement::isTrackedAcrossLayers).collect(Collectors.toSet());
var subTypesBuilder = builder.initSubTypes(subTypes.size());
int i = 0;
for (AnalysisType subType : subTypes) {
subTypesBuilder.set(i, subType.getId());
i++;
}
builder.setIsAnySubtypeInstantiated(type.isAnySubtypeInstantiated());

afterTypeAdded(type);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
@SuppressWarnings("all")
public final class SharedLayerSnapshotCapnProtoSchemaHolder {
public static class PersistedAnalysisType {
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)4,(short)13);
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)4,(short)14);
public static final class Factory extends org.capnproto.StructFactory<Builder, Reader> {
public Factory() {
}
Expand Down Expand Up @@ -307,13 +307,32 @@ public final void setHasArrayType(boolean value) {
_setBooleanField(104, value);
}

public final boolean hasSubTypes() {
return !_pointerFieldIsNull(11);
}
public final org.capnproto.PrimitiveList.Int.Builder getSubTypes() {
return _getPointerField(org.capnproto.PrimitiveList.Int.factory, 11, null, 0);
}
public final void setSubTypes(org.capnproto.PrimitiveList.Int.Reader value) {
_setPointerField(org.capnproto.PrimitiveList.Int.factory, 11, value);
}
public final org.capnproto.PrimitiveList.Int.Builder initSubTypes(int size) {
return _initPointerField(org.capnproto.PrimitiveList.Int.factory, 11, size);
}
public final boolean getIsAnySubtypeInstantiated() {
return _getBooleanField(105);
}
public final void setIsAnySubtypeInstantiated(boolean value) {
_setBooleanField(105, value);
}

public final WrappedType.Builder getWrappedType() {
return new PersistedAnalysisType.WrappedType.Builder(segment, data, pointers, dataSize, pointerCount);
}
public final WrappedType.Builder initWrappedType() {
_setShortField(7,(short)0);
_clearPointerField(11);
_clearPointerField(12);
_clearPointerField(13);
return new PersistedAnalysisType.WrappedType.Builder(segment, data, pointers, dataSize, pointerCount);
}

Expand Down Expand Up @@ -461,14 +480,25 @@ public final boolean getHasArrayType() {
return _getBooleanField(104);
}

public final boolean hasSubTypes() {
return !_pointerFieldIsNull(11);
}
public final org.capnproto.PrimitiveList.Int.Reader getSubTypes() {
return _getPointerField(org.capnproto.PrimitiveList.Int.factory, 11, null, 0);
}

public final boolean getIsAnySubtypeInstantiated() {
return _getBooleanField(105);
}

public WrappedType.Reader getWrappedType() {
return new PersistedAnalysisType.WrappedType.Reader(segment, data, pointers, dataSize, pointerCount, nestingLimit);
}

}

public static class WrappedType {
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)4,(short)13);
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)4,(short)14);
public static final class Factory extends org.capnproto.StructFactory<Builder, Reader> {
public Factory() {
}
Expand Down Expand Up @@ -524,8 +554,8 @@ public final SerializationGenerated.Builder getSerializationGenerated() {
}
public final SerializationGenerated.Builder initSerializationGenerated() {
_setShortField(7, (short)PersistedAnalysisType.WrappedType.Which.SERIALIZATION_GENERATED.ordinal());
_clearPointerField(11);
_clearPointerField(12);
_clearPointerField(13);
return new PersistedAnalysisType.WrappedType.SerializationGenerated.Builder(segment, data, pointers, dataSize, pointerCount);
}

Expand All @@ -537,7 +567,7 @@ public final Lambda.Builder getLambda() {
}
public final Lambda.Builder initLambda() {
_setShortField(7, (short)PersistedAnalysisType.WrappedType.Which.LAMBDA.ordinal());
_clearPointerField(11);
_clearPointerField(12);
return new PersistedAnalysisType.WrappedType.Lambda.Builder(segment, data, pointers, dataSize, pointerCount);
}

Expand Down Expand Up @@ -611,7 +641,7 @@ public enum Which {
_NOT_IN_SCHEMA,
}
public static class SerializationGenerated {
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)4,(short)13);
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)4,(short)14);
public static final class Factory extends org.capnproto.StructFactory<Builder, Reader> {
public Factory() {
}
Expand Down Expand Up @@ -639,34 +669,34 @@ public final Reader asReader() {
return new Reader(segment, data, pointers, dataSize, pointerCount, 0x7fffffff);
}
public final boolean hasRawDeclaringClass() {
return !_pointerFieldIsNull(11);
return !_pointerFieldIsNull(12);
}
public final org.capnproto.Text.Builder getRawDeclaringClass() {
return _getPointerField(org.capnproto.Text.factory, 11, null, 0, 0);
return _getPointerField(org.capnproto.Text.factory, 12, null, 0, 0);
}
public final void setRawDeclaringClass(org.capnproto.Text.Reader value) {
_setPointerField(org.capnproto.Text.factory, 11, value);
_setPointerField(org.capnproto.Text.factory, 12, value);
}
public final void setRawDeclaringClass(String value) {
_setPointerField(org.capnproto.Text.factory, 11, new org.capnproto.Text.Reader(value));
_setPointerField(org.capnproto.Text.factory, 12, new org.capnproto.Text.Reader(value));
}
public final org.capnproto.Text.Builder initRawDeclaringClass(int size) {
return _initPointerField(org.capnproto.Text.factory, 11, size);
return _initPointerField(org.capnproto.Text.factory, 12, size);
}
public final boolean hasRawTargetConstructor() {
return !_pointerFieldIsNull(12);
return !_pointerFieldIsNull(13);
}
public final org.capnproto.Text.Builder getRawTargetConstructor() {
return _getPointerField(org.capnproto.Text.factory, 12, null, 0, 0);
return _getPointerField(org.capnproto.Text.factory, 13, null, 0, 0);
}
public final void setRawTargetConstructor(org.capnproto.Text.Reader value) {
_setPointerField(org.capnproto.Text.factory, 12, value);
_setPointerField(org.capnproto.Text.factory, 13, value);
}
public final void setRawTargetConstructor(String value) {
_setPointerField(org.capnproto.Text.factory, 12, new org.capnproto.Text.Reader(value));
_setPointerField(org.capnproto.Text.factory, 13, new org.capnproto.Text.Reader(value));
}
public final org.capnproto.Text.Builder initRawTargetConstructor(int size) {
return _initPointerField(org.capnproto.Text.factory, 12, size);
return _initPointerField(org.capnproto.Text.factory, 13, size);
}
}

Expand All @@ -676,17 +706,17 @@ public static final class Reader extends org.capnproto.StructReader {
}

public boolean hasRawDeclaringClass() {
return !_pointerFieldIsNull(11);
return !_pointerFieldIsNull(12);
}
public org.capnproto.Text.Reader getRawDeclaringClass() {
return _getPointerField(org.capnproto.Text.factory, 11, null, 0, 0);
return _getPointerField(org.capnproto.Text.factory, 12, null, 0, 0);
}

public boolean hasRawTargetConstructor() {
return !_pointerFieldIsNull(12);
return !_pointerFieldIsNull(13);
}
public org.capnproto.Text.Reader getRawTargetConstructor() {
return _getPointerField(org.capnproto.Text.factory, 12, null, 0, 0);
return _getPointerField(org.capnproto.Text.factory, 13, null, 0, 0);
}

}
Expand All @@ -695,7 +725,7 @@ public org.capnproto.Text.Reader getRawTargetConstructor() {


public static class Lambda {
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)4,(short)13);
public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)4,(short)14);
public static final class Factory extends org.capnproto.StructFactory<Builder, Reader> {
public Factory() {
}
Expand Down Expand Up @@ -723,19 +753,19 @@ public final Reader asReader() {
return new Reader(segment, data, pointers, dataSize, pointerCount, 0x7fffffff);
}
public final boolean hasCapturingClass() {
return !_pointerFieldIsNull(11);
return !_pointerFieldIsNull(12);
}
public final org.capnproto.Text.Builder getCapturingClass() {
return _getPointerField(org.capnproto.Text.factory, 11, null, 0, 0);
return _getPointerField(org.capnproto.Text.factory, 12, null, 0, 0);
}
public final void setCapturingClass(org.capnproto.Text.Reader value) {
_setPointerField(org.capnproto.Text.factory, 11, value);
_setPointerField(org.capnproto.Text.factory, 12, value);
}
public final void setCapturingClass(String value) {
_setPointerField(org.capnproto.Text.factory, 11, new org.capnproto.Text.Reader(value));
_setPointerField(org.capnproto.Text.factory, 12, new org.capnproto.Text.Reader(value));
}
public final org.capnproto.Text.Builder initCapturingClass(int size) {
return _initPointerField(org.capnproto.Text.factory, 11, size);
return _initPointerField(org.capnproto.Text.factory, 12, size);
}
}

Expand All @@ -745,10 +775,10 @@ public static final class Reader extends org.capnproto.StructReader {
}

public boolean hasCapturingClass() {
return !_pointerFieldIsNull(11);
return !_pointerFieldIsNull(12);
}
public org.capnproto.Text.Reader getCapturingClass() {
return _getPointerField(org.capnproto.Text.factory, 11, null, 0, 0);
return _getPointerField(org.capnproto.Text.factory, 12, null, 0, 0);
}

}
Expand Down
Loading