Skip to content

Commit 8ad5cf7

Browse files
committed
[GR-69257] Cleanup field handling in points-to analysis
PullRequest: graal/21948
2 parents 0fbbfe1 + 8d2e7ef commit 8ad5cf7

22 files changed

+158
-143
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AnalysisObjectScanningObserver.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
3030
import com.oracle.graal.pointsto.flow.context.object.AnalysisObject;
3131
import com.oracle.graal.pointsto.meta.AnalysisField;
3232
import com.oracle.graal.pointsto.meta.AnalysisType;
33+
import com.oracle.graal.pointsto.meta.PointsToAnalysisField;
3334
import com.oracle.graal.pointsto.typestate.TypeState;
3435

3536
import jdk.vm.ci.meta.JavaConstant;
@@ -46,7 +47,7 @@ public AnalysisObjectScanningObserver(BigBang bb) {
4647
public boolean forRelocatedPointerFieldValue(JavaConstant receiver, AnalysisField field, JavaConstant fieldValue, ScanReason reason) {
4748
var changed = false;
4849
if (fieldValue.isNonNull()) {
49-
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver);
50+
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(((PointsToAnalysisField) field), receiver);
5051
changed = fieldTypeFlow.addState(getAnalysis(), TypeState.anyPrimitiveState());
5152
}
5253
if (!field.isWritten()) {
@@ -57,7 +58,7 @@ public boolean forRelocatedPointerFieldValue(JavaConstant receiver, AnalysisFiel
5758

5859
@Override
5960
public boolean forNullFieldValue(JavaConstant receiver, AnalysisField field, ScanReason reason) {
60-
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver);
61+
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(((PointsToAnalysisField) field), receiver);
6162
if (!fieldTypeFlow.getState().canBeNull()) {
6263
/* Signal that the field can contain null. */
6364
return fieldTypeFlow.addState(getAnalysis(), TypeState.forNull());
@@ -71,7 +72,7 @@ public boolean forNonNullFieldValue(JavaConstant receiver, AnalysisField field,
7172
AnalysisType fieldType = analysis.getMetaAccess().lookupJavaType(fieldValue);
7273

7374
/* Add the constant value object to the field's type flow. */
74-
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver);
75+
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(((PointsToAnalysisField) field), receiver);
7576
/* Add the new constant to the field's flow state. */
7677
return fieldTypeFlow.addState(analysis, bb.analysisPolicy().constantTypeState(analysis, fieldValue, fieldType));
7778
}
@@ -81,15 +82,15 @@ public boolean forPrimitiveFieldValue(JavaConstant receiver, AnalysisField field
8182
PointsToAnalysis analysis = getAnalysis();
8283

8384
/* Add the constant value object to the field's type flow. */
84-
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver);
85+
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(((PointsToAnalysisField) field), receiver);
8586
/* Add the new constant to the field's flow state. */
8687
return fieldTypeFlow.addState(analysis, TypeState.forPrimitiveConstant(analysis, fieldValue.asLong()));
8788
}
8889

8990
/**
9091
* Get the field type flow give a receiver.
9192
*/
92-
private FieldTypeFlow getFieldTypeFlow(AnalysisField field, JavaConstant receiver) {
93+
private FieldTypeFlow getFieldTypeFlow(PointsToAnalysisField field, JavaConstant receiver) {
9394
/* The field type flow is used to track the constant field value. */
9495
if (field.isStatic()) {
9596
/* If the field is static it comes from the originalRoots. */

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AnalysisPolicy.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -40,9 +40,9 @@
4040
import com.oracle.graal.pointsto.flow.TypeFlow;
4141
import com.oracle.graal.pointsto.flow.context.AnalysisContext;
4242
import com.oracle.graal.pointsto.flow.context.object.AnalysisObject;
43-
import com.oracle.graal.pointsto.meta.AnalysisField;
4443
import com.oracle.graal.pointsto.meta.AnalysisType;
4544
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
45+
import com.oracle.graal.pointsto.meta.PointsToAnalysisField;
4646
import com.oracle.graal.pointsto.meta.PointsToAnalysisMethod;
4747
import com.oracle.graal.pointsto.typestate.MultiTypeState;
4848
import com.oracle.graal.pointsto.typestate.SingleTypeState;
@@ -192,7 +192,7 @@ public int parsingContextMaxDepth() {
192192
*/
193193
public abstract void linkClonedObjects(PointsToAnalysis bb, TypeFlow<?> inputFlow, CloneTypeFlow cloneFlow, BytecodePosition source);
194194

195-
public abstract FieldTypeStore createFieldTypeStore(PointsToAnalysis bb, AnalysisObject object, AnalysisField field, AnalysisUniverse universe);
195+
public abstract FieldTypeStore createFieldTypeStore(PointsToAnalysis bb, AnalysisObject object, PointsToAnalysisField field, AnalysisUniverse universe);
196196

197197
public abstract ArrayElementsTypeStore createArrayElementsTypeStore(AnalysisObject object, AnalysisUniverse universe);
198198

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
import jdk.vm.ci.meta.ResolvedJavaField;
9292

9393
public abstract class PointsToAnalysis extends AbstractAnalysisEngine {
94-
/** The type of {@link java.lang.Object}. */
94+
/** The type of {@link Object}. */
9595
private final AnalysisType objectType;
9696
/**
9797
* Enables propagating primitive values interproceduraly using the typeflow graph. Only simple
@@ -103,7 +103,7 @@ public abstract class PointsToAnalysis extends AbstractAnalysisEngine {
103103
* Unsafe loads and stores are NOT modeled, because it would lead to merging of primitive and
104104
* objects states (all unsafe fields are merged into a single flow). Instead, all unsafe
105105
* accessed primitive fields are assigned the PrimitiveTypeState state and any unsafe read is
106-
* immediately represented as {@link com.oracle.graal.pointsto.flow.AnyPrimitiveSourceTypeFlow}.
106+
* immediately represented as {@link AnyPrimitiveSourceTypeFlow}.
107107
*/
108108
private final boolean trackPrimitiveValues;
109109
private final AnalysisType longType;
@@ -513,7 +513,7 @@ public AnalysisType addRootClass(Class<?> clazz, boolean addFields, boolean addA
513513
public AnalysisType addRootClass(AnalysisType type, boolean addFields, boolean addArrayClass) {
514514
type.registerAsReachable("root class");
515515
for (ResolvedJavaField javaField : type.getInstanceFields(false)) {
516-
AnalysisField field = (AnalysisField) javaField;
516+
var field = (PointsToAnalysisField) javaField;
517517
if (addFields) {
518518
field.registerAsAccessed("field of root class");
519519
}
@@ -533,7 +533,7 @@ public AnalysisType addRootClass(AnalysisType type, boolean addFields, boolean a
533533
public AnalysisType addRootField(Class<?> clazz, String fieldName) {
534534
AnalysisType type = addRootClass(clazz, false, false);
535535
for (ResolvedJavaField javaField : type.getInstanceFields(true)) {
536-
AnalysisField field = (AnalysisField) javaField;
536+
var field = (PointsToAnalysisField) javaField;
537537
if (field.getName().equals(fieldName)) {
538538
return addRootField(type, field);
539539
}
@@ -542,21 +542,22 @@ public AnalysisType addRootField(Class<?> clazz, String fieldName) {
542542
}
543543

544544
@Override
545-
public AnalysisType addRootField(AnalysisField field) {
545+
public AnalysisType addRootField(AnalysisField f) {
546+
var field = (PointsToAnalysisField) f;
546547
if (field.isStatic()) {
547548
return addRootStaticField(field);
548549
} else {
549550
return addRootField(field.getDeclaringClass(), field);
550551
}
551552
}
552553

553-
private AnalysisType addRootField(AnalysisType type, AnalysisField field) {
554+
private AnalysisType addRootField(AnalysisType type, PointsToAnalysisField field) {
554555
field.registerAsAccessed("root field");
555556
processRootField(type, field);
556557
return field.getType();
557558
}
558559

559-
private void processRootField(AnalysisType type, AnalysisField field) {
560+
private void processRootField(AnalysisType type, PointsToAnalysisField field) {
560561
JavaKind storageKind = field.getStorageKind();
561562
if (isSupportedJavaKind(storageKind)) {
562563
var fieldFlow = type.getContextInsensitiveAnalysisObject().getInstanceFieldFlow(this, field, true);
@@ -579,15 +580,15 @@ public AnalysisType addRootStaticField(Class<?> clazz, String fieldName) {
579580
Field reflectField;
580581
try {
581582
reflectField = clazz.getField(fieldName);
582-
AnalysisField field = metaAccess.lookupJavaField(reflectField);
583+
var field = (PointsToAnalysisField) metaAccess.lookupJavaField(reflectField);
583584
return addRootStaticField(field);
584585

585586
} catch (NoSuchFieldException e) {
586587
throw shouldNotReachHere("field not found: " + fieldName);
587588
}
588589
}
589590

590-
private AnalysisType addRootStaticField(AnalysisField field) {
591+
private AnalysisType addRootStaticField(PointsToAnalysisField field) {
591592
field.registerAsAccessed("static root field");
592593
JavaKind storageKind = field.getStorageKind();
593594
if (isSupportedJavaKind(storageKind)) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AccessFieldTypeFlow.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
2525
package com.oracle.graal.pointsto.flow;
2626

2727
import com.oracle.graal.pointsto.PointsToAnalysis;
28-
import com.oracle.graal.pointsto.meta.AnalysisField;
28+
import com.oracle.graal.pointsto.meta.PointsToAnalysisField;
2929
import com.oracle.graal.pointsto.typestate.TypeState;
3030

3131
import jdk.vm.ci.code.BytecodePosition;
@@ -34,9 +34,9 @@
3434
public abstract class AccessFieldTypeFlow extends TypeFlow<BytecodePosition> {
3535

3636
/** The field that this flow stores into or loads from. */
37-
protected final AnalysisField field;
37+
protected final PointsToAnalysisField field;
3838

39-
protected AccessFieldTypeFlow(BytecodePosition accessLocation, AnalysisField field) {
39+
protected AccessFieldTypeFlow(BytecodePosition accessLocation, PointsToAnalysisField field) {
4040
/* The declared type of a field access node is the field declared type. */
4141
super(accessLocation, filterUncheckedInterface(field.getType()));
4242
this.field = field;
@@ -47,7 +47,7 @@ protected AccessFieldTypeFlow(AccessFieldTypeFlow original, MethodFlowsGraph met
4747
this.field = original.field;
4848
}
4949

50-
public AnalysisField field() {
50+
public PointsToAnalysisField field() {
5151
return field;
5252
}
5353

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/LoadFieldTypeFlow.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
2626

2727
import com.oracle.graal.pointsto.PointsToAnalysis;
2828
import com.oracle.graal.pointsto.flow.context.object.AnalysisObject;
29-
import com.oracle.graal.pointsto.meta.AnalysisField;
29+
import com.oracle.graal.pointsto.meta.PointsToAnalysisField;
3030
import com.oracle.graal.pointsto.typestate.TypeState;
3131

3232
import jdk.vm.ci.code.BytecodePosition;
@@ -36,7 +36,7 @@
3636
*/
3737
public abstract class LoadFieldTypeFlow extends AccessFieldTypeFlow {
3838

39-
protected LoadFieldTypeFlow(BytecodePosition loadLocation, AnalysisField field) {
39+
protected LoadFieldTypeFlow(BytecodePosition loadLocation, PointsToAnalysisField field) {
4040
super(loadLocation, field);
4141
}
4242

@@ -48,7 +48,7 @@ public static class LoadStaticFieldTypeFlow extends LoadFieldTypeFlow {
4848

4949
private final FieldTypeFlow fieldFlow;
5050

51-
LoadStaticFieldTypeFlow(BytecodePosition loadLocation, AnalysisField field, FieldTypeFlow fieldFlow) {
51+
LoadStaticFieldTypeFlow(BytecodePosition loadLocation, PointsToAnalysisField field, FieldTypeFlow fieldFlow) {
5252
super(loadLocation, field);
5353
this.fieldFlow = fieldFlow;
5454

@@ -98,7 +98,7 @@ public static class LoadInstanceFieldTypeFlow extends LoadFieldTypeFlow {
9898
*/
9999
private TypeFlow<?> objectFlow;
100100

101-
LoadInstanceFieldTypeFlow(BytecodePosition loadLocation, AnalysisField field, TypeFlow<?> objectFlow) {
101+
LoadInstanceFieldTypeFlow(BytecodePosition loadLocation, PointsToAnalysisField field, TypeFlow<?> objectFlow) {
102102
super(loadLocation, field);
103103
this.objectFlow = objectFlow;
104104
}

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,7 @@
5555
import com.oracle.graal.pointsto.meta.AnalysisMethod;
5656
import com.oracle.graal.pointsto.meta.AnalysisType;
5757
import com.oracle.graal.pointsto.meta.HostedProviders;
58+
import com.oracle.graal.pointsto.meta.PointsToAnalysisField;
5859
import com.oracle.graal.pointsto.meta.PointsToAnalysisMethod;
5960
import com.oracle.graal.pointsto.phases.InlineBeforeAnalysis;
6061
import com.oracle.graal.pointsto.results.StrengthenGraphs;
@@ -298,7 +299,7 @@ public static void registerUsedElements(AbstractAnalysisEngine bb, StructuredGra
298299
if (!usePredicates) {
299300
type.registerAsInstantiated(AbstractAnalysisEngine.sourcePosition(node));
300301
for (var f : type.getInstanceFields(true)) {
301-
var field = (AnalysisField) f;
302+
var field = (PointsToAnalysisField) f;
302303
PointsToAnalysis pta = (PointsToAnalysis) bb;
303304
field.getInitialFlow().addState(pta, TypeState.defaultValueForKind(pta, field.getStorageKind()));
304305
}
@@ -1592,13 +1593,13 @@ protected void node(FixedNode n) {
15921593
state.add(node, newArrayBuilder);
15931594

15941595
} else if (n instanceof LoadFieldNode node) { // value = object.field
1595-
processLoadField(node, (AnalysisField) node.field(), node.object(), state);
1596+
processLoadField(node, (PointsToAnalysisField) node.field(), node.object(), state);
15961597
if (node.object() != null) {
15971598
processImplicitNonNull(node.object(), state);
15981599
}
15991600

16001601
} else if (n instanceof StoreFieldNode node) { // object.field = value
1601-
processStoreField(node, (AnalysisField) node.field(), node.object(), node.value(), node.value().getStackKind(), state);
1602+
processStoreField(node, (PointsToAnalysisField) node.field(), node.object(), node.value(), node.value().getStackKind(), state);
16021603
if (node.object() != null) {
16031604
processImplicitNonNull(node.object(), state);
16041605
}
@@ -1707,7 +1708,7 @@ private void modelUnsafeReadOnlyFlow(RawLoadNode node, ValueNode object, ValueNo
17071708
checkUnsafeOffset(object, offset);
17081709
if (object.getStackKind() == JavaKind.Object) {
17091710
if (offset instanceof FieldOffsetProvider fieldOffsetProvider) {
1710-
processLoadField(node, (AnalysisField) fieldOffsetProvider.getField(), object, state);
1711+
processLoadField(node, (PointsToAnalysisField) fieldOffsetProvider.getField(), object, state);
17111712
} else if (StampTool.isAlwaysArray(object)) {
17121713
processLoadIndexed(node, object, state);
17131714
} else {
@@ -1720,7 +1721,7 @@ private void modelUnsafeWriteOnlyFlow(ValueNode node, ValueNode object, ValueNod
17201721
checkUnsafeOffset(object, offset);
17211722
if (object.getStackKind() == JavaKind.Object) {
17221723
if (offset instanceof FieldOffsetProvider fieldOffsetProvider) {
1723-
processStoreField(node, (AnalysisField) fieldOffsetProvider.getField(), object, newValue, newValueKind, state);
1724+
processStoreField(node, (PointsToAnalysisField) fieldOffsetProvider.getField(), object, newValue, newValueKind, state);
17241725
} else if (StampTool.isAlwaysArray(object)) {
17251726
processStoreIndexed(node, object, newValue, newValueKind, state);
17261727
} else {
@@ -1733,7 +1734,7 @@ private void modelUnsafeReadAndWriteFlow(ValueNode node, ValueNode object, Value
17331734
checkUnsafeOffset(object, offset);
17341735
if (object.getStackKind() == JavaKind.Object) {
17351736
if (offset instanceof FieldOffsetProvider fieldOffsetProvider) {
1736-
var field = (AnalysisField) fieldOffsetProvider.getField();
1737+
var field = (PointsToAnalysisField) fieldOffsetProvider.getField();
17371738
processStoreField(node, field, object, newValue, newValueKind, state);
17381739
processLoadField(node, field, object, state);
17391740
} else if (StampTool.isAlwaysArray(object)) {
@@ -1990,12 +1991,12 @@ protected void processCommitAllocation(CommitAllocationNode commitAllocationNode
19901991
if (type.isArray()) {
19911992
processStoreIndexed(commitAllocationNode, object, value, value.getStackKind(), state);
19921993
} else {
1993-
AnalysisField field = (AnalysisField) ((VirtualInstanceNode) virtualObject).field(i);
1994+
var field = (PointsToAnalysisField) ((VirtualInstanceNode) virtualObject).field(i);
19941995
processStoreField(commitAllocationNode, field, object, value, value.getStackKind(), state);
19951996
}
19961997
} else {
19971998
if (!type.isArray()) {
1998-
AnalysisField field = (AnalysisField) ((VirtualInstanceNode) virtualObject).field(i);
1999+
var field = (PointsToAnalysisField) ((VirtualInstanceNode) virtualObject).field(i);
19992000
field.getInitialFlow().addState(bb, TypeState.defaultValueForKind(bb, field.getStorageKind()));
20002001
}
20012002
}
@@ -2023,7 +2024,7 @@ protected void processNewInstance(ValueNode node, AnalysisType type, TypeFlowsOf
20232024
state.add(node, newInstanceBuilder);
20242025
}
20252026

2026-
protected void processLoadField(ValueNode node, AnalysisField field, ValueNode object, TypeFlowsOfNodes state) {
2027+
protected void processLoadField(ValueNode node, PointsToAnalysisField field, ValueNode object, TypeFlowsOfNodes state) {
20272028
field.registerAsRead(AbstractAnalysisEngine.sourcePosition(node));
20282029

20292030
if (bb.isSupportedJavaKind(node.getStackKind())) {
@@ -2049,7 +2050,7 @@ protected void processLoadField(ValueNode node, AnalysisField field, ValueNode o
20492050
}
20502051
}
20512052

2052-
protected void processStoreField(ValueNode node, AnalysisField field, ValueNode object, ValueNode newValue, JavaKind newValueKind, TypeFlowsOfNodes state) {
2053+
protected void processStoreField(ValueNode node, PointsToAnalysisField field, ValueNode object, ValueNode newValue, JavaKind newValueKind, TypeFlowsOfNodes state) {
20532054
field.registerAsWritten(AbstractAnalysisEngine.sourcePosition(node));
20542055

20552056
if (bb.isSupportedJavaKind(newValueKind)) {

0 commit comments

Comments
 (0)