Skip to content

Commit 54b86b3

Browse files
committed
Simplify root fields registration.
1 parent c523e33 commit 54b86b3

File tree

3 files changed

+24
-93
lines changed

3 files changed

+24
-93
lines changed

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

Lines changed: 14 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,9 @@
2525
package com.oracle.graal.pointsto;
2626

2727
import static com.oracle.graal.pointsto.meta.AnalysisUniverse.ESTIMATED_NUMBER_OF_TYPES;
28-
import static jdk.vm.ci.common.JVMCIError.shouldNotReachHere;
2928

3029
import java.io.PrintWriter;
3130
import java.lang.reflect.Executable;
32-
import java.lang.reflect.Field;
3331
import java.util.ArrayList;
3432
import java.util.Collections;
3533
import java.util.Comparator;
@@ -47,7 +45,6 @@
4745
import com.oracle.graal.pointsto.constraints.UnsupportedFeatures;
4846
import com.oracle.graal.pointsto.flow.AlwaysEnabledPredicateFlow;
4947
import com.oracle.graal.pointsto.flow.AnyPrimitiveSourceTypeFlow;
50-
import com.oracle.graal.pointsto.flow.FieldTypeFlow;
5148
import com.oracle.graal.pointsto.flow.FormalParamTypeFlow;
5249
import com.oracle.graal.pointsto.flow.InvokeTypeFlow;
5350
import com.oracle.graal.pointsto.flow.MethodFlowsGraph;
@@ -77,6 +74,7 @@
7774
import com.oracle.svm.common.meta.MultiMethod;
7875
import com.oracle.svm.util.AnnotationUtil;
7976
import com.oracle.svm.util.ClassUtil;
77+
import com.oracle.svm.util.JVMCIReflectionUtil;
8078

8179
import jdk.graal.compiler.api.replacements.Fold;
8280
import jdk.graal.compiler.api.replacements.SnippetReflectionProvider;
@@ -266,26 +264,9 @@ public void forceUnsafeUpdate() {
266264
}
267265

268266
@Override
269-
public void registerAsJNIAccessed(AnalysisField f, boolean writable) {
270-
PointsToAnalysisField field = (PointsToAnalysisField) f;
271-
// Same as addRootField() and addRootStaticField():
272-
// create type flows for any subtype of the field's declared type
273-
TypeFlow<?> declaredTypeFlow = field.getType().getTypeFlow(this, true);
274-
if (isSupportedJavaKind(field.getStorageKind())) {
275-
if (field.isStatic()) {
276-
if (field.getStorageKind().isObject()) {
277-
declaredTypeFlow.addUse(this, field.getStaticFieldFlow());
278-
} else {
279-
field.saturatePrimitiveField();
280-
}
281-
} else {
282-
FieldTypeFlow instanceFieldFlow = field.getDeclaringClass().getContextInsensitiveAnalysisObject().getInstanceFieldFlow(this, field, writable);
283-
if (field.getStorageKind().isObject()) {
284-
declaredTypeFlow.addUse(this, instanceFieldFlow);
285-
} else {
286-
field.saturatePrimitiveField();
287-
}
288-
}
267+
public void registerAsJNIAccessed(AnalysisField field, boolean writable) {
268+
if (writable && isSupportedJavaKind(field.getStorageKind())) {
269+
field.injectDeclaredType();
289270
}
290271
}
291272

@@ -519,7 +500,7 @@ public AnalysisType addRootClass(AnalysisType type, boolean addFields, boolean a
519500
if (addFields) {
520501
field.registerAsAccessed("field of root class");
521502
}
522-
processRootField(type, field);
503+
processRootField(field);
523504
}
524505
if (type.getSuperclass() != null) {
525506
addRootClass(type.getSuperclass(), addFields, addArrayClass);
@@ -531,77 +512,23 @@ public AnalysisType addRootClass(AnalysisType type, boolean addFields, boolean a
531512
}
532513

533514
@Override
534-
@SuppressWarnings("try")
535515
public AnalysisType addRootField(Class<?> clazz, String fieldName) {
536-
AnalysisType type = addRootClass(clazz, false, false);
537-
for (ResolvedJavaField javaField : type.getInstanceFields(true)) {
538-
var field = (PointsToAnalysisField) javaField;
539-
if (field.getName().equals(fieldName)) {
540-
return addRootField(type, field);
541-
}
542-
}
543-
throw shouldNotReachHere("field not found: " + fieldName);
516+
AnalysisType type = metaAccess.lookupJavaType(clazz);
517+
addRootClass(type, false, false);
518+
return addRootField((AnalysisField) JVMCIReflectionUtil.getDeclaredField(type, fieldName));
544519
}
545520

546521
@Override
547-
public AnalysisType addRootField(AnalysisField f) {
548-
var field = (PointsToAnalysisField) f;
549-
if (field.isStatic()) {
550-
return addRootStaticField(field);
551-
} else {
552-
return addRootField(field.getDeclaringClass(), field);
553-
}
554-
}
555-
556-
private AnalysisType addRootField(AnalysisType type, PointsToAnalysisField field) {
557-
field.registerAsAccessed("root field");
558-
processRootField(type, field);
522+
public AnalysisType addRootField(AnalysisField field) {
523+
field.registerAsAccessed((field.isStatic() ? "static" : "instance") + " root field");
524+
processRootField(field);
559525
return field.getType();
560526
}
561527

562-
private void processRootField(AnalysisType type, PointsToAnalysisField field) {
563-
JavaKind storageKind = field.getStorageKind();
564-
if (isSupportedJavaKind(storageKind)) {
565-
var fieldFlow = type.getContextInsensitiveAnalysisObject().getInstanceFieldFlow(this, field, true);
566-
if (storageKind.isObject()) {
567-
/*
568-
* For system classes any instantiated (sub)type of the declared field type can be
569-
* written to the field flow.
570-
*/
571-
TypeFlow<?> fieldDeclaredTypeFlow = field.getType().getTypeFlow(this, true);
572-
fieldDeclaredTypeFlow.addUse(this, fieldFlow);
573-
} else {
574-
fieldFlow.addState(this, TypeState.anyPrimitiveState());
575-
}
576-
}
577-
}
578-
579-
@SuppressWarnings({"try", "unused"})
580-
public AnalysisType addRootStaticField(Class<?> clazz, String fieldName) {
581-
addRootClass(clazz, false, false);
582-
Field reflectField;
583-
try {
584-
reflectField = clazz.getField(fieldName);
585-
var field = (PointsToAnalysisField) metaAccess.lookupJavaField(reflectField);
586-
return addRootStaticField(field);
587-
588-
} catch (NoSuchFieldException e) {
589-
throw shouldNotReachHere("field not found: " + fieldName);
590-
}
591-
}
592-
593-
private AnalysisType addRootStaticField(PointsToAnalysisField field) {
594-
field.registerAsAccessed("static root field");
595-
JavaKind storageKind = field.getStorageKind();
596-
if (isSupportedJavaKind(storageKind)) {
597-
if (storageKind.isObject()) {
598-
TypeFlow<?> fieldFlow = field.getType().getTypeFlow(this, true);
599-
fieldFlow.addUse(this, field.getStaticFieldFlow());
600-
} else {
601-
field.getStaticFieldFlow().addState(this, TypeState.anyPrimitiveState());
602-
}
528+
private void processRootField(AnalysisField field) {
529+
if (isSupportedJavaKind(field.getStorageKind())) {
530+
field.injectDeclaredType();
603531
}
604-
return field.getType();
605532
}
606533

607534
@Override

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/PointsToCustomTypeFieldHandler.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ public PointsToCustomTypeFieldHandler(BigBang bb, AnalysisMetaAccess metaAccess)
4040
}
4141

4242
/**
43-
* Inject custom types for an analysis field. These fields usually have lazily computed values
44-
* which are not available during analysis.
43+
* Inject custom types in the analysis field type state. This utility is used for:
44+
* <ul>
45+
* <li>root fields - whose state is forced to be that of the declared type</li>
46+
* <li>unsafe accessed fields - whose state is conservatively also the declared type</li>
47+
* <li>lazily computed fields - for which writes are not visible during analysis</li>
48+
* <ul/>
4549
*/
4650
@Override
4751
public void injectFieldTypes(AnalysisField aField, List<AnalysisType> customTypes, boolean canBeNull) {
@@ -73,11 +77,11 @@ public void injectFieldTypes(AnalysisField aField, List<AnalysisType> customType
7377
fieldComponentType.getTypeFlow(analysis, false).addUse(analysis, elementsFlow);
7478

7579
/*
76-
* In the current implementation it is not necessary to do it it recursively for
80+
* In the current implementation it is not necessary to do it recursively for
7781
* multidimensional arrays since we don't model individual array elements, so
7882
* from the point of view of the static analysis the field's array elements
79-
* value is non null (in the case of a n-dimensional array that value is another
80-
* array, n-1 dimensional).
83+
* value is non-null (in the case of an n-dimensional array that value is
84+
* another array, n-1 dimensional).
8185
*/
8286
}
8387
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ private void addField(Field reflField, boolean preserved, boolean writable, Duri
513513
JNIAccessibleClass jniClass = addClass(reflField.getDeclaringClass(), preserved, access);
514514
AnalysisField field = access.getMetaAccess().lookupJavaField(reflField);
515515
jniClass.addOrUpdateField(field.getName(), preserved, _ -> new JNIAccessibleField(jniClass, field.getJavaKind(), field.getModifiers(), preserved));
516-
field.registerAsRead("it is registered for as JNI accessed");
516+
field.registerAsRead("it is registered as JNI accessed");
517517
if (writable) {
518518
field.registerAsWritten("it is registered as JNI writable");
519519
AnalysisType fieldType = field.getType();

0 commit comments

Comments
 (0)