Skip to content

Commit e18bf16

Browse files
committed
Improve loading of base layer elements
1 parent c31b058 commit e18bf16

24 files changed

+508
-146
lines changed

substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/PointsToAnalyzer.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import com.oracle.graal.pointsto.heap.HostedValuesProvider;
5050
import com.oracle.graal.pointsto.heap.ImageHeap;
5151
import com.oracle.graal.pointsto.heap.ImageLayerLoader;
52+
import com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil;
5253
import com.oracle.graal.pointsto.heap.ImageLayerWriter;
5354
import com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor;
5455
import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
@@ -162,14 +163,17 @@ private PointsToAnalyzer(String mainEntryClass, OptionValues options) {
162163
aUniverse.setBigBang(bigbang);
163164
ImageHeap heap = new ImageHeap();
164165
HostedValuesProvider hostedValuesProvider = new HostedValuesProvider(aMetaAccess, aUniverse);
166+
ImageLayerSnapshotUtil imageLayerSnapshotUtil = new ImageLayerSnapshotUtil();
165167
ImageLayerLoader imageLayerLoader = new ImageLayerLoader();
168+
imageLayerLoader.setImageLayerSnapshotUtil(imageLayerSnapshotUtil);
166169
imageLayerLoader.setUniverse(aUniverse);
167170
aUniverse.setImageLayerLoader(imageLayerLoader);
168171
StandaloneImageHeapScanner heapScanner = new StandaloneImageHeapScanner(bigbang, heap, aMetaAccess,
169172
snippetReflection, aConstantReflection, new AnalysisObjectScanningObserver(bigbang), analysisClassLoader, hostedValuesProvider);
170173
aUniverse.setHeapScanner(heapScanner);
171174
imageLayerLoader.executeHeapScannerTasks();
172-
ImageLayerWriter imageLayerWriter = new ImageLayerWriter();
175+
ImageLayerWriter imageLayerWriter = new ImageLayerWriter(true);
176+
imageLayerWriter.setImageLayerSnapshotUtil(imageLayerSnapshotUtil);
173177
imageLayerWriter.setImageHeap(heap);
174178
HeapSnapshotVerifier heapVerifier = new StandaloneHeapSnapshotVerifier(bigbang, heap, heapScanner);
175179
aUniverse.setHeapVerifier(heapVerifier);

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerLoader.java

Lines changed: 105 additions & 48 deletions
Large diffs are not rendered by default.

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerSnapshotUtil.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public class ImageLayerSnapshotUtil {
7171
public static final String METHODS_TAG = "methods";
7272
public static final String FIELDS_TAG = "fields";
7373
public static final String IS_INTERNAL_TAG = "is internal";
74+
public static final String IS_STATIC_TAG = "is static";
7475
public static final String FIELD_TYPE_TAG = "field type";
7576
public static final String CLASS_JAVA_NAME_TAG = "class java name";
7677
public static final String CAN_BE_STATICALLY_BOUND_TAG = "can be statically bound";
@@ -85,6 +86,7 @@ public class ImageLayerSnapshotUtil {
8586
public static final String IS_IMPLEMENTATION_INVOKED = "is implementation invoked";
8687
public static final String IS_INTRINSIC_METHOD = "is intrinsic method";
8788
public static final String ANNOTATIONS_TAG = "annotations";
89+
public static final String ANNOTATION_VALUES_TAG = "annotation values";
8890
public static final String IS_INSTANTIATED = "is instantiated";
8991
public static final String IS_UNSAFE_ALLOCATED = "is unsafe allocated";
9092
public static final String IS_REACHABLE = "is reachable";
@@ -104,8 +106,11 @@ public class ImageLayerSnapshotUtil {
104106
public static final String GENERATED_SERIALIZATION_TAG = "generated serialization";
105107
public static final String LAMBDA_TYPE_TAG = "lambda type";
106108
public static final String CAPTURING_CLASS_TAG = "capturing class";
109+
public static final String PROXY_TYPE_TAG = "proxy type";
107110
public static final String RAW_DECLARING_CLASS_TAG = "raw declaring class";
108111
public static final String RAW_TARGET_CONSTRUCTOR_CLASS_TAG = "raw target constructor class";
112+
public static final String INSTANCE_FIELDS_TAG = "instance fields";
113+
public static final String INSTANCE_FIELDS_WITH_SUPER_TAG = "instance fields with super";
109114
public static final String CONSTANTS_TAG = "constants";
110115
public static final String CONSTANTS_TO_RELINK_TAG = "constants to relink";
111116
public static final String TID_TAG = "tid";
@@ -118,8 +123,17 @@ public class ImageLayerSnapshotUtil {
118123
public static final String METHOD_TYPE_PARAMETERS_TAG = "method type parameters";
119124
public static final String METHOD_TYPE_RETURN_TAG = "method type return";
120125
public static final String FACTORY_TAG = "factory";
126+
public static final String C_ENTRY_POINT_CALL_STUB_METHOD_TAG = "CEntryPointCallStubMethod";
127+
public static final String REFLECTION_EXPAND_SIGNATURE_METHOD_TAG = "reflection expand signature method";
128+
public static final String JNI_JAVA_CALL_VARIANT_WRAPPER_METHOD_TAG = "jni java call variant wrapper method";
121129
public static final String OUTLINED_SB_TAG = "outlinedSB";
130+
public static final String ORIGINAL_METHOD_ID_TAG = "original method id";
131+
public static final String NOT_AS_PUBLISHED_TAG = "not as published";
122132
public static final String TARGET_CONSTRUCTOR_TAG = "target constructor";
133+
public static final String INSTANTIATED_TYPE_TAG = "instantiated type";
134+
public static final String WRAPPED_MEMBER_CLASS_TAG = "wrapped member class";
135+
public static final String WRAPPED_MEMBER_NAME_TAG = "wrapped member name";
136+
public static final String WRAPPED_MEMBER_ARGUMENTS_TAG = "wrapped member arguments";
123137
public static final String THROW_ALLOCATED_OBJECT_TAG = "throw allocated object";
124138
public static final String IDENTITY_HASH_CODE_TAG = "identityHashCode";
125139
public static final String PARENT_CONSTANT_ID_TAG = "parent constant id";
@@ -146,6 +160,7 @@ public class ImageLayerSnapshotUtil {
146160
public static final String ARRAY_TAG = "array";
147161
public static final String PRIMITIVE_ARRAY_TAG = "primitive array";
148162
public static final String RELOCATED_CONSTANT_TAG = "relocation constant";
163+
public static final String FIELD_CHECK_TAG = "field check";
149164
public static final String FIELD_ACCESSED_TAG = "accessed";
150165
public static final String FIELD_READ_TAG = "read";
151166
public static final String FIELD_WRITTEN_TAG = "written";

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerWriter.java

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.IDENTITY_HASH_CODE_TAG;
5252
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.ID_TAG;
5353
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.IMAGE_HEAP_SIZE_TAG;
54+
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.INSTANCE_FIELDS_TAG;
55+
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.INSTANCE_FIELDS_WITH_SUPER_TAG;
5456
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.INSTANCE_TAG;
5557
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.INTERFACES_TAG;
5658
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.INTRINSIC_TAG;
@@ -66,6 +68,7 @@
6668
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.IS_INVOKED;
6769
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.IS_LINKED_TAG;
6870
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.IS_REACHABLE;
71+
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.IS_STATIC_TAG;
6972
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.IS_SYNTHETIC_TAG;
7073
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.IS_UNSAFE_ALLOCATED;
7174
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.IS_VAR_ARGS_TAG;
@@ -84,8 +87,8 @@
8487
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.PARENT_CONSTANT_INDEX_TAG;
8588
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.POSITION_TAG;
8689
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.PRIMITIVE_ARRAY_TAG;
87-
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.RETURN_TYPE_TAG;
8890
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.RELOCATED_CONSTANT_TAG;
91+
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.RETURN_TYPE_TAG;
8992
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.SIMULATED_TAG;
9093
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.SOURCE_FILE_NAME_TAG;
9194
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.STRENGTHENED_GRAPH_TAG;
@@ -98,6 +101,8 @@
98101

99102
import java.io.IOException;
100103
import java.io.PrintWriter;
104+
import java.lang.annotation.Annotation;
105+
import java.lang.reflect.AnnotatedElement;
101106
import java.lang.reflect.Executable;
102107
import java.lang.reflect.Field;
103108
import java.nio.ByteBuffer;
@@ -208,7 +213,6 @@ public ImageLayerWriter() {
208213
this(true);
209214
}
210215

211-
@SuppressWarnings({"this-escape", "unused"})
212216
public ImageLayerWriter(boolean useSharedLayerGraphs) {
213217
this.useSharedLayerGraphs = useSharedLayerGraphs;
214218
this.useSharedLayerStrengthenedGraphs = false;
@@ -278,12 +282,6 @@ public void persistAnalysisInfo() {
278282
jsonMap.put(NEXT_METHOD_ID_TAG, aUniverse.getNextMethodId());
279283
jsonMap.put(NEXT_FIELD_ID_TAG, aUniverse.getNextFieldId());
280284

281-
/*
282-
* $$TypeSwitch classes should not be instantiated as they are only used as a container for
283-
* a static method, so no constant of those types should be created. This filter can be
284-
* removed after a mechanism for determining which types have to be persisted is added, or
285-
* if a stable name is implemented for them.
286-
*/
287285
for (AnalysisType type : aUniverse.getTypes().stream().filter(AnalysisType::isTrackedAcrossLayers).toList()) {
288286
checkTypeStability(type);
289287
persistType(type);
@@ -312,6 +310,16 @@ public void persistAnalysisInfo() {
312310
jsonMap.put(CONSTANTS_TO_RELINK_TAG, constantsToRelink);
313311
}
314312

313+
private void persistAnnotations(AnnotatedElement annotatedElement, EconomicMap<String, Object> typeMap) {
314+
Class<? extends Annotation>[] annotationTypes = AnnotationAccess.getAnnotationTypes(annotatedElement);
315+
persistAnnotations(annotatedElement, typeMap, annotationTypes);
316+
}
317+
318+
@SuppressWarnings("unused")
319+
protected void persistAnnotations(AnnotatedElement annotatedElement, EconomicMap<String, Object> typeMap, Class<? extends Annotation>[] annotationTypes) {
320+
typeMap.put(ANNOTATIONS_TAG, Arrays.stream(annotationTypes).map(Class::getName).toList());
321+
}
322+
315323
/**
316324
* A hook used to persist more general information about the base layer not accessible in
317325
* pointsto.
@@ -338,6 +346,15 @@ protected void persistType(AnalysisType type) {
338346
*/
339347
persistType(superclass);
340348
}
349+
350+
for (AnalysisType interfaceType : type.getInterfaces()) {
351+
/*
352+
* Some persisted types are not reachable. In this case, the interfaces have to be
353+
* persisted manually as well.
354+
*/
355+
persistType(interfaceType);
356+
}
357+
341358
EconomicMap<String, Object> typeMap = EconomicMap.create();
342359

343360
persistType(type, typeMap);
@@ -364,8 +381,17 @@ protected void persistType(AnalysisType type, EconomicMap<String, Object> typeMa
364381
typeMap.put(IS_INITIALIZED_TAG, type.isInitialized());
365382
typeMap.put(IS_LINKED_TAG, type.isLinked());
366383
typeMap.put(SOURCE_FILE_NAME_TAG, type.getSourceFileName());
367-
if (type.getEnclosingType() != null) {
368-
typeMap.put(ENCLOSING_TYPE_TAG, type.getEnclosingType().getId());
384+
try {
385+
AnalysisType enclosingType = type.getEnclosingType();
386+
if (enclosingType != null) {
387+
typeMap.put(ENCLOSING_TYPE_TAG, enclosingType.getId());
388+
}
389+
} catch (AnalysisError.TypeNotFoundError e) {
390+
/*
391+
* GR-59571: The enclosing type is not automatically created when the inner type is
392+
* created. If the enclosing type is missing, it is ignored for now. This try/catch
393+
* block could be removed after the trackAcrossLayers is fully implemented.
394+
*/
369395
}
370396
if (type.isArray()) {
371397
typeMap.put(COMPONENT_TYPE_TAG, type.getComponentType().getId());
@@ -374,7 +400,9 @@ protected void persistType(AnalysisType type, EconomicMap<String, Object> typeMa
374400
typeMap.put(SUPER_CLASS_TAG, type.getSuperclass().getId());
375401
}
376402
typeMap.put(INTERFACES_TAG, Arrays.stream(type.getInterfaces()).map(AnalysisType::getId).toList());
377-
typeMap.put(ANNOTATIONS_TAG, Arrays.stream(AnnotationAccess.getAnnotationTypes(type)).map(Class::getName).toList());
403+
typeMap.put(INSTANCE_FIELDS_TAG, Arrays.stream(type.getInstanceFields(false)).map(field -> ((AnalysisField) field).getId()).toList());
404+
typeMap.put(INSTANCE_FIELDS_WITH_SUPER_TAG, Arrays.stream(type.getInstanceFields(true)).map(field -> ((AnalysisField) field).getId()).toList());
405+
persistAnnotations(type, typeMap);
378406

379407
typeMap.put(IS_INSTANTIATED, type.isInstantiated());
380408
typeMap.put(IS_UNSAFE_ALLOCATED, type.isUnsafeAllocated());
@@ -410,6 +438,9 @@ protected void persistMethod(AnalysisMethod method, EconomicMap<String, Object>
410438
methodMap.put(ARGUMENTS_TAG, Arrays.stream(executable.getParameterTypes()).map(Class::getName).toList());
411439
methodMap.put(CLASS_NAME_TAG, executable.getDeclaringClass().getName());
412440
}
441+
442+
persistType(method.getSignature().getReturnType());
443+
413444
methodMap.put(TID_TAG, method.getDeclaringClass().getId());
414445
methodMap.put(ARGUMENT_IDS_TAG, method.getSignature().toParameterList(null).stream().map(AnalysisType::getId).toList());
415446
methodMap.put(ID_TAG, method.getId());
@@ -429,7 +460,7 @@ protected void persistMethod(AnalysisMethod method, EconomicMap<String, Object>
429460
if (intrinsicMethod != null) {
430461
methodMap.put(METHOD_HANDLE_INTRINSIC_TAG, intrinsicMethod.name());
431462
}
432-
methodMap.put(ANNOTATIONS_TAG, Arrays.stream(AnnotationAccess.getAnnotationTypes(method)).map(Class::getName).toList());
463+
persistAnnotations(method, methodMap);
433464

434465
methodMap.put(IS_VIRTUAL_ROOT_METHOD, method.isVirtualRootMethod());
435466
methodMap.put(IS_DIRECT_ROOT_METHOD, method.isDirectRootMethod());
@@ -524,11 +555,13 @@ protected void persistField(AnalysisField field) {
524555
if (originalField != null && !originalField.getDeclaringClass().equals(field.getDeclaringClass().getJavaClass())) {
525556
fieldMap.put(CLASS_NAME_TAG, originalField.getDeclaringClass().getName());
526557
}
558+
fieldMap.put(IS_STATIC_TAG, field.isStatic());
527559
fieldMap.put(IS_INTERNAL_TAG, field.isInternal());
560+
fieldMap.put(IS_SYNTHETIC_TAG, field.isSynthetic());
528561
fieldMap.put(FIELD_TYPE_TAG, field.getType().getId());
529562
fieldMap.put(MODIFIERS_TAG, field.getModifiers());
530563
fieldMap.put(POSITION_TAG, field.getPosition());
531-
fieldMap.put(ANNOTATIONS_TAG, Arrays.stream(AnnotationAccess.getAnnotationTypes(field)).map(Class::getName).toList());
564+
persistAnnotations(field, fieldMap);
532565

533566
String tid = String.valueOf(field.getDeclaringClass().getId());
534567
fieldsMap.computeIfAbsent(tid, key -> new ConcurrentHashMap<>()).put(field.getName(), fieldMap);

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,20 @@
4040
public class BaseLayerField extends BaseLayerElement implements ResolvedJavaField {
4141
private final int id;
4242
private final String name;
43-
private final AnalysisType declaringClass;
44-
private final AnalysisType type;
43+
private final ResolvedJavaType declaringClass;
44+
private final ResolvedJavaType type;
4545
private final boolean isInternal;
46+
private final boolean isSynthetic;
4647
private final int modifiers;
4748

48-
public BaseLayerField(int id, String name, AnalysisType declaringClass, AnalysisType type, boolean isInternal, int modifiers, Annotation[] annotations) {
49+
public BaseLayerField(int id, String name, ResolvedJavaType declaringClass, ResolvedJavaType type, boolean isInternal, boolean isSynthetic, int modifiers, Annotation[] annotations) {
4950
super(annotations);
5051
this.id = id;
5152
this.name = name;
5253
this.declaringClass = declaringClass;
5354
this.type = type;
5455
this.isInternal = isInternal;
56+
this.isSynthetic = isSynthetic;
5557
this.modifiers = modifiers;
5658
}
5759

@@ -76,7 +78,7 @@ public boolean isInternal() {
7678

7779
@Override
7880
public boolean isSynthetic() {
79-
throw GraalError.unimplemented("This field is incomplete and should not be used.");
81+
return isSynthetic;
8082
}
8183

8284
@Override
@@ -86,12 +88,12 @@ public String getName() {
8688

8789
@Override
8890
public JavaType getType() {
89-
return type.getWrapped();
91+
return type;
9092
}
9193

9294
@Override
9395
public ResolvedJavaType getDeclaringClass() {
94-
return declaringClass.getWrapped();
96+
return declaringClass;
9597
}
9698

9799
@Override

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public ExceptionHandler[] getExceptionHandlers() {
166166

167167
@Override
168168
public StackTraceElement asStackTraceElement(int bci) {
169-
throw GraalError.unimplemented("This method is incomplete and should not be used.");
169+
return new StackTraceElement(declaringClass.toClassName(), name, declaringClass.getSourceFileName(), -1);
170170
}
171171

172172
@Override

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public class BaseLayerType extends BaseLayerElement implements ResolvedJavaType,
6464
private final ResolvedJavaType superClass;
6565
private final ResolvedJavaType[] interfaces;
6666
private final ResolvedJavaType objectType;
67+
private ResolvedJavaField[] instanceFields;
68+
private ResolvedJavaField[] instanceFieldsWithSuper;
6769

6870
public BaseLayerType(String name, int baseLayerId, int modifiers, boolean isInterface, boolean isEnum, boolean isInitialized, boolean initializedAtBuildTime, boolean isLinked,
6971
String sourceFileName, ResolvedJavaType enclosingType, ResolvedJavaType componentType, ResolvedJavaType superClass, ResolvedJavaType[] interfaces, ResolvedJavaType objectType,
@@ -85,6 +87,14 @@ public BaseLayerType(String name, int baseLayerId, int modifiers, boolean isInte
8587
this.objectType = objectType;
8688
}
8789

90+
public void setInstanceFields(ResolvedJavaField[] instanceFields) {
91+
this.instanceFields = instanceFields;
92+
}
93+
94+
public void setInstanceFieldsWithSuper(ResolvedJavaField[] instanceFieldsWithSuper) {
95+
this.instanceFieldsWithSuper = instanceFieldsWithSuper;
96+
}
97+
8898
@Override
8999
public boolean isArray() {
90100
return name.charAt(0) == '[';
@@ -244,11 +254,7 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) {
244254

245255
@Override
246256
public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
247-
/*
248-
* For now, the base layer types have no fields. If they are needed, a BaseLayerField could
249-
* be created and put in an AnalysisField in a similar way to this BaseLayerType.
250-
*/
251-
return new ResolvedJavaField[0];
257+
return includeSuperclasses ? instanceFieldsWithSuper : instanceFields;
252258
}
253259

254260
@Override

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/AnnotationArrayValue.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ static AnnotationArrayValue extract(ByteBuffer buf, ConstantPool cp, Class<?> co
5151
return skip ? null : new AnnotationArrayValue(elements);
5252
}
5353

54-
AnnotationArrayValue(Class<?> elementType, Object[] values) {
55-
this.elements = new AnnotationMemberValue[values.length];
56-
for (int i = 0; i < values.length; ++i) {
57-
this.elements[i] = AnnotationMemberValue.from(elementType, values[i]);
54+
AnnotationArrayValue(Class<?> elementType, Object values) {
55+
int length = Array.getLength(values);
56+
this.elements = new AnnotationMemberValue[length];
57+
for (int i = 0; i < length; ++i) {
58+
this.elements[i] = AnnotationMemberValue.from(elementType, Array.get(values, i));
5859
}
5960
}
6061

0 commit comments

Comments
 (0)