Skip to content

Commit f38cabe

Browse files
Fixes #1625 issue by caching the field list and validation state in addition to the existing layoutInfo and fieldOrder caches.
1 parent 50b1cbf commit f38cabe

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

src/com/sun/jna/Structure.java

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ private static class NativeStringTracking {
157157
protected static final int CALCULATE_SIZE = -1;
158158
static final Map<Class<?>, LayoutInfo> layoutInfo = new WeakHashMap<>();
159159
static final Map<Class<?>, List<String>> fieldOrder = new WeakHashMap<>();
160+
static final Map<Class<?>, List<Field>> fieldList = new WeakHashMap<>();
161+
static final Map<Class<?>, Boolean> validationMap = new WeakHashMap<>();
160162

161163
// This field is accessed by native code
162164
private Pointer memory;
@@ -1015,22 +1017,26 @@ protected void sortFields(List<Field> fields, List<String> names) {
10151017
* this {@link Structure} class.
10161018
*/
10171019
protected List<Field> getFieldList() {
1018-
List<Field> flist = new ArrayList<>();
1019-
for (Class<?> cls = getClass();
1020-
!cls.equals(Structure.class);
1021-
cls = cls.getSuperclass()) {
1022-
List<Field> classFields = new ArrayList<>();
1023-
Field[] fields = cls.getDeclaredFields();
1024-
for (int i=0;i < fields.length;i++) {
1025-
int modifiers = fields[i].getModifiers();
1026-
if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
1027-
continue;
1020+
synchronized (fieldList) {
1021+
return fieldList.computeIfAbsent(getClass(), (c) -> {
1022+
List<Field> flist = new ArrayList<>();
1023+
List<Field> classFields = new ArrayList<>();
1024+
for (Class<?> cls = getClass();
1025+
!cls.equals(Structure.class);
1026+
cls = cls.getSuperclass()) {
1027+
for (Field field : cls.getDeclaredFields()) {
1028+
int modifiers = field.getModifiers();
1029+
if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
1030+
continue;
1031+
}
1032+
classFields.add(field);
1033+
}
1034+
flist.addAll(0, classFields);
1035+
classFields.clear();
10281036
}
1029-
classFields.add(fields[i]);
1030-
}
1031-
flist.addAll(0, classFields);
1037+
return flist;
1038+
});
10321039
}
1033-
return flist;
10341040
}
10351041

10361042
/** Cache field order per-class.
@@ -1039,12 +1045,7 @@ protected List<Field> getFieldList() {
10391045
private List<String> fieldOrder() {
10401046
Class<?> clazz = getClass();
10411047
synchronized(fieldOrder) {
1042-
List<String> list = fieldOrder.get(clazz);
1043-
if (list == null) {
1044-
list = getFieldOrder();
1045-
fieldOrder.put(clazz, list);
1046-
}
1047-
return list;
1048+
return fieldOrder.computeIfAbsent(clazz, (c) -> getFieldOrder());
10481049
}
10491050
}
10501051

@@ -1250,9 +1251,13 @@ private void validateField(String name, Class<?> type) {
12501251

12511252
/** ensure all fields are of valid type. */
12521253
private void validateFields() {
1253-
List<Field> fields = getFieldList();
1254-
for (Field f : fields) {
1255-
validateField(f.getName(), f.getType());
1254+
synchronized (validationMap) {
1255+
validationMap.computeIfAbsent(getClass(), (cls) -> {
1256+
for (Field f : getFieldList()) {
1257+
validateField(f.getName(), f.getType());
1258+
}
1259+
return true;
1260+
});
12561261
}
12571262
}
12581263

0 commit comments

Comments
 (0)