51
51
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .IDENTITY_HASH_CODE_TAG ;
52
52
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .ID_TAG ;
53
53
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 ;
54
56
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .INSTANCE_TAG ;
55
57
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .INTERFACES_TAG ;
56
58
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .INTRINSIC_TAG ;
66
68
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .IS_INVOKED ;
67
69
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .IS_LINKED_TAG ;
68
70
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .IS_REACHABLE ;
71
+ import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .IS_STATIC_TAG ;
69
72
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .IS_SYNTHETIC_TAG ;
70
73
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .IS_UNSAFE_ALLOCATED ;
71
74
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .IS_VAR_ARGS_TAG ;
84
87
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .PARENT_CONSTANT_INDEX_TAG ;
85
88
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .POSITION_TAG ;
86
89
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .PRIMITIVE_ARRAY_TAG ;
87
- import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .RETURN_TYPE_TAG ;
88
90
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .RELOCATED_CONSTANT_TAG ;
91
+ import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .RETURN_TYPE_TAG ;
89
92
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .SIMULATED_TAG ;
90
93
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .SOURCE_FILE_NAME_TAG ;
91
94
import static com .oracle .graal .pointsto .heap .ImageLayerSnapshotUtil .STRENGTHENED_GRAPH_TAG ;
98
101
99
102
import java .io .IOException ;
100
103
import java .io .PrintWriter ;
104
+ import java .lang .annotation .Annotation ;
105
+ import java .lang .reflect .AnnotatedElement ;
101
106
import java .lang .reflect .Executable ;
102
107
import java .lang .reflect .Field ;
103
108
import java .nio .ByteBuffer ;
@@ -208,7 +213,6 @@ public ImageLayerWriter() {
208
213
this (true );
209
214
}
210
215
211
- @ SuppressWarnings ({"this-escape" , "unused" })
212
216
public ImageLayerWriter (boolean useSharedLayerGraphs ) {
213
217
this .useSharedLayerGraphs = useSharedLayerGraphs ;
214
218
this .useSharedLayerStrengthenedGraphs = false ;
@@ -278,12 +282,6 @@ public void persistAnalysisInfo() {
278
282
jsonMap .put (NEXT_METHOD_ID_TAG , aUniverse .getNextMethodId ());
279
283
jsonMap .put (NEXT_FIELD_ID_TAG , aUniverse .getNextFieldId ());
280
284
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
- */
287
285
for (AnalysisType type : aUniverse .getTypes ().stream ().filter (AnalysisType ::isTrackedAcrossLayers ).toList ()) {
288
286
checkTypeStability (type );
289
287
persistType (type );
@@ -312,6 +310,16 @@ public void persistAnalysisInfo() {
312
310
jsonMap .put (CONSTANTS_TO_RELINK_TAG , constantsToRelink );
313
311
}
314
312
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
+
315
323
/**
316
324
* A hook used to persist more general information about the base layer not accessible in
317
325
* pointsto.
@@ -338,6 +346,15 @@ protected void persistType(AnalysisType type) {
338
346
*/
339
347
persistType (superclass );
340
348
}
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
+
341
358
EconomicMap <String , Object > typeMap = EconomicMap .create ();
342
359
343
360
persistType (type , typeMap );
@@ -364,8 +381,17 @@ protected void persistType(AnalysisType type, EconomicMap<String, Object> typeMa
364
381
typeMap .put (IS_INITIALIZED_TAG , type .isInitialized ());
365
382
typeMap .put (IS_LINKED_TAG , type .isLinked ());
366
383
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
+ */
369
395
}
370
396
if (type .isArray ()) {
371
397
typeMap .put (COMPONENT_TYPE_TAG , type .getComponentType ().getId ());
@@ -374,7 +400,9 @@ protected void persistType(AnalysisType type, EconomicMap<String, Object> typeMa
374
400
typeMap .put (SUPER_CLASS_TAG , type .getSuperclass ().getId ());
375
401
}
376
402
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 );
378
406
379
407
typeMap .put (IS_INSTANTIATED , type .isInstantiated ());
380
408
typeMap .put (IS_UNSAFE_ALLOCATED , type .isUnsafeAllocated ());
@@ -410,6 +438,9 @@ protected void persistMethod(AnalysisMethod method, EconomicMap<String, Object>
410
438
methodMap .put (ARGUMENTS_TAG , Arrays .stream (executable .getParameterTypes ()).map (Class ::getName ).toList ());
411
439
methodMap .put (CLASS_NAME_TAG , executable .getDeclaringClass ().getName ());
412
440
}
441
+
442
+ persistType (method .getSignature ().getReturnType ());
443
+
413
444
methodMap .put (TID_TAG , method .getDeclaringClass ().getId ());
414
445
methodMap .put (ARGUMENT_IDS_TAG , method .getSignature ().toParameterList (null ).stream ().map (AnalysisType ::getId ).toList ());
415
446
methodMap .put (ID_TAG , method .getId ());
@@ -429,7 +460,7 @@ protected void persistMethod(AnalysisMethod method, EconomicMap<String, Object>
429
460
if (intrinsicMethod != null ) {
430
461
methodMap .put (METHOD_HANDLE_INTRINSIC_TAG , intrinsicMethod .name ());
431
462
}
432
- methodMap . put ( ANNOTATIONS_TAG , Arrays . stream ( AnnotationAccess . getAnnotationTypes ( method )). map ( Class :: getName ). toList () );
463
+ persistAnnotations ( method , methodMap );
433
464
434
465
methodMap .put (IS_VIRTUAL_ROOT_METHOD , method .isVirtualRootMethod ());
435
466
methodMap .put (IS_DIRECT_ROOT_METHOD , method .isDirectRootMethod ());
@@ -524,11 +555,13 @@ protected void persistField(AnalysisField field) {
524
555
if (originalField != null && !originalField .getDeclaringClass ().equals (field .getDeclaringClass ().getJavaClass ())) {
525
556
fieldMap .put (CLASS_NAME_TAG , originalField .getDeclaringClass ().getName ());
526
557
}
558
+ fieldMap .put (IS_STATIC_TAG , field .isStatic ());
527
559
fieldMap .put (IS_INTERNAL_TAG , field .isInternal ());
560
+ fieldMap .put (IS_SYNTHETIC_TAG , field .isSynthetic ());
528
561
fieldMap .put (FIELD_TYPE_TAG , field .getType ().getId ());
529
562
fieldMap .put (MODIFIERS_TAG , field .getModifiers ());
530
563
fieldMap .put (POSITION_TAG , field .getPosition ());
531
- fieldMap . put ( ANNOTATIONS_TAG , Arrays . stream ( AnnotationAccess . getAnnotationTypes ( field )). map ( Class :: getName ). toList () );
564
+ persistAnnotations ( field , fieldMap );
532
565
533
566
String tid = String .valueOf (field .getDeclaringClass ().getId ());
534
567
fieldsMap .computeIfAbsent (tid , key -> new ConcurrentHashMap <>()).put (field .getName (), fieldMap );
0 commit comments