Skip to content

Commit

Permalink
Fixes #1625 issue by caching the field list and validation state in a…
Browse files Browse the repository at this point in the history
…ddition to the existing layoutInfo and fieldOrder caches.
  • Loading branch information
brettwooldridge committed Sep 20, 2024
1 parent 50b1cbf commit f38cabe
Showing 1 changed file with 28 additions and 23 deletions.
51 changes: 28 additions & 23 deletions src/com/sun/jna/Structure.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ private static class NativeStringTracking {
protected static final int CALCULATE_SIZE = -1;
static final Map<Class<?>, LayoutInfo> layoutInfo = new WeakHashMap<>();
static final Map<Class<?>, List<String>> fieldOrder = new WeakHashMap<>();
static final Map<Class<?>, List<Field>> fieldList = new WeakHashMap<>();
static final Map<Class<?>, Boolean> validationMap = new WeakHashMap<>();

// This field is accessed by native code
private Pointer memory;
Expand Down Expand Up @@ -1015,22 +1017,26 @@ protected void sortFields(List<Field> fields, List<String> names) {
* this {@link Structure} class.
*/
protected List<Field> getFieldList() {
List<Field> flist = new ArrayList<>();
for (Class<?> cls = getClass();
!cls.equals(Structure.class);
cls = cls.getSuperclass()) {
List<Field> classFields = new ArrayList<>();
Field[] fields = cls.getDeclaredFields();
for (int i=0;i < fields.length;i++) {
int modifiers = fields[i].getModifiers();
if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
continue;
synchronized (fieldList) {
return fieldList.computeIfAbsent(getClass(), (c) -> {
List<Field> flist = new ArrayList<>();
List<Field> classFields = new ArrayList<>();
for (Class<?> cls = getClass();
!cls.equals(Structure.class);
cls = cls.getSuperclass()) {
for (Field field : cls.getDeclaredFields()) {
int modifiers = field.getModifiers();
if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
continue;
}
classFields.add(field);
}
flist.addAll(0, classFields);
classFields.clear();
}
classFields.add(fields[i]);
}
flist.addAll(0, classFields);
return flist;
});
}
return flist;
}

/** Cache field order per-class.
Expand All @@ -1039,12 +1045,7 @@ protected List<Field> getFieldList() {
private List<String> fieldOrder() {
Class<?> clazz = getClass();
synchronized(fieldOrder) {
List<String> list = fieldOrder.get(clazz);
if (list == null) {
list = getFieldOrder();
fieldOrder.put(clazz, list);
}
return list;
return fieldOrder.computeIfAbsent(clazz, (c) -> getFieldOrder());
}
}

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

/** ensure all fields are of valid type. */
private void validateFields() {
List<Field> fields = getFieldList();
for (Field f : fields) {
validateField(f.getName(), f.getType());
synchronized (validationMap) {
validationMap.computeIfAbsent(getClass(), (cls) -> {
for (Field f : getFieldList()) {
validateField(f.getName(), f.getType());
}
return true;
});
}
}

Expand Down

0 comments on commit f38cabe

Please sign in to comment.