Skip to content

Commit 19a2d4a

Browse files
thomaswuecstancu
authored andcommitted
Simplify and speed up lookup of fields in AnalysisType.
1 parent 448b0de commit 19a2d4a

File tree

2 files changed

+66
-35
lines changed

2 files changed

+66
-35
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151

5252
public abstract class AnalysisField extends AnalysisElement implements WrappedJavaField, OriginalFieldProvider {
5353

54+
static final AnalysisField[] EMPTY_ARRAY = new AnalysisField[0];
55+
5456
private static final AtomicReferenceFieldUpdater<AnalysisField, Object> isAccessedUpdater = AtomicReferenceFieldUpdater
5557
.newUpdater(AnalysisField.class, Object.class, "isAccessed");
5658

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

Lines changed: 64 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,64 +1170,93 @@ public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expec
11701170
*/
11711171
private volatile ResolvedJavaField[] instanceFieldsWithSuper;
11721172
private volatile ResolvedJavaField[] instanceFieldsWithoutSuper;
1173+
private volatile ResolvedJavaField[] staticFields;
11731174

11741175
/**
1175-
* Note that although this returns a ResolvedJavaField[], all instance fields are of type
1176-
* AnalysisField and can be cast to AnalysisField without problem.
1176+
* Note that although this returns a {@code ResolvedJavaField[]}, all instance fields are of
1177+
* type {@link AnalysisField} and can be cast to AnalysisField without problem.
11771178
*/
11781179
@Override
11791180
public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
1180-
ResolvedJavaField[] result = includeSuperclasses ? instanceFieldsWithSuper : instanceFieldsWithoutSuper;
1181-
if (result != null) {
1182-
return result;
1183-
} else {
1184-
return initializeInstanceFields(includeSuperclasses);
1181+
return includeSuperclasses ? getInstanceFieldsWithSuper() : getInstanceFieldsWithoutSuper();
1182+
}
1183+
1184+
private ResolvedJavaField[] getInstanceFieldsWithoutSuper() {
1185+
if (instanceFieldsWithoutSuper == null) {
1186+
if (isArray() || isInterface() || isPrimitive()) {
1187+
instanceFieldsWithoutSuper = AnalysisField.EMPTY_ARRAY;
1188+
} else {
1189+
instanceFieldsWithoutSuper = convertFields(wrapped.getInstanceFields(false), false);
1190+
}
11851191
}
1192+
return instanceFieldsWithoutSuper;
11861193
}
11871194

1188-
private ResolvedJavaField[] initializeInstanceFields(boolean includeSuperclasses) {
1189-
List<ResolvedJavaField> list = new ArrayList<>();
1190-
if (includeSuperclasses && getSuperclass() != null) {
1191-
list.addAll(Arrays.asList(getSuperclass().getInstanceFields(true)));
1195+
private ResolvedJavaField[] getInstanceFieldsWithSuper() {
1196+
if (instanceFieldsWithSuper == null) {
1197+
if (isArray() || isInterface() || isPrimitive()) {
1198+
instanceFieldsWithSuper = AnalysisField.EMPTY_ARRAY;
1199+
} else {
1200+
ResolvedJavaField[] instanceFields = getInstanceFieldsWithoutSuper();
1201+
if (getSuperclass() == null) {
1202+
instanceFieldsWithSuper = instanceFields;
1203+
} else {
1204+
ResolvedJavaField[] superInstanceFields = getSuperclass().getInstanceFields(true);
1205+
ResolvedJavaField[] result = Arrays.copyOf(superInstanceFields, superInstanceFields.length + instanceFields.length);
1206+
System.arraycopy(instanceFields, 0, result, superInstanceFields.length, instanceFields.length);
1207+
for (int index = 0; index < instanceFields.length; ++index) {
1208+
((AnalysisField) instanceFields[index]).setPosition(superInstanceFields.length + index);
1209+
}
1210+
instanceFieldsWithSuper = result;
1211+
}
1212+
}
11921213
}
1193-
ResolvedJavaField[] result = convertFields(wrapped.getInstanceFields(false), list, includeSuperclasses);
1194-
if (includeSuperclasses) {
1195-
instanceFieldsWithSuper = result;
1196-
} else {
1197-
instanceFieldsWithoutSuper = result;
1214+
return instanceFieldsWithSuper;
1215+
}
1216+
1217+
/**
1218+
* Note that although this returns a ResolvedJavaField[], all instance fields are of type
1219+
* AnalysisField and can be cast to AnalysisField without problem.
1220+
*/
1221+
@Override
1222+
public ResolvedJavaField[] getStaticFields() {
1223+
if (staticFields == null) {
1224+
if (isArray() || isPrimitive()) {
1225+
staticFields = AnalysisField.EMPTY_ARRAY;
1226+
} else {
1227+
staticFields = convertFields(wrapped.getStaticFields(), true);
1228+
}
11981229
}
1199-
return result;
1230+
return staticFields;
12001231
}
12011232

1202-
private ResolvedJavaField[] convertFields(ResolvedJavaField[] originals, List<ResolvedJavaField> list, boolean listIncludesSuperClassesFields) {
1233+
/**
1234+
* Converts the given array of hosted {@link ResolvedJavaField}s into an array of
1235+
* {@link AnalysisField}s. The resulting array is compact and contains only convertible fields,
1236+
* i.e., if looking up the field in the {@link AnalysisUniverse} is not supported then the field
1237+
* is skipped.
1238+
*/
1239+
private ResolvedJavaField[] convertFields(ResolvedJavaField[] originals, boolean setPosition) {
1240+
ResolvedJavaField[] result = new ResolvedJavaField[originals.length];
1241+
int index = 0;
12031242
for (ResolvedJavaField original : originals) {
12041243
if (!original.isInternal() && universe.hostVM.platformSupported(original)) {
12051244
try {
1206-
AnalysisField aField = universe.lookup(original);
1207-
if (aField != null) {
1208-
if (listIncludesSuperClassesFields || aField.isStatic()) {
1209-
/*
1210-
* If the list includes the super classes fields, register the position.
1211-
*/
1212-
aField.setPosition(list.size());
1245+
AnalysisField field = universe.lookup(original);
1246+
if (field != null) {
1247+
if (setPosition) {
1248+
field.setPosition(index);
12131249
}
1214-
list.add(aField);
1250+
result[index++] = field;
12151251
}
12161252
} catch (UnsupportedFeatureException ex) {
12171253
// Ignore deleted fields and fields of deleted types.
12181254
}
12191255
}
12201256
}
1221-
return list.toArray(new ResolvedJavaField[list.size()]);
1222-
}
12231257

1224-
/**
1225-
* Note that although this returns a ResolvedJavaField[], all instance fields are of type
1226-
* AnalysisField and can be casted to AnalysisField without problem.
1227-
*/
1228-
@Override
1229-
public ResolvedJavaField[] getStaticFields() {
1230-
return convertFields(wrapped.getStaticFields(), new ArrayList<>(), false);
1258+
// Trim array if some fields could not be converted.
1259+
return index == result.length ? result : Arrays.copyOf(result, index);
12311260
}
12321261

12331262
@Override

0 commit comments

Comments
 (0)