Skip to content

Commit

Permalink
Merge pull request #363 from Ladicek/memory-improvements
Browse files Browse the repository at this point in the history
Memory improvements
  • Loading branch information
Ladicek authored May 7, 2024
2 parents d4005a4 + 261a828 commit 5723b37
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 133 deletions.
124 changes: 89 additions & 35 deletions core/src/main/java/org/jboss/jandex/ClassInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,15 @@ public final class ClassInfo implements Declaration, Descriptor, GenericSignatur

// Not final to allow lazy initialization, immutable once published
private short flags;
private boolean hasNoArgsConstructor;
private Type[] interfaceTypes;
private Type superClassType;
private Type[] typeParameters;
private MethodInternal[] methods;
private FieldInternal[] fields;
private RecordComponentInternal[] recordComponents;
private byte[] methodPositions = EMPTY_POSITIONS;
private byte[] fieldPositions = EMPTY_POSITIONS;
private byte[] recordComponentPositions = EMPTY_POSITIONS;
private boolean hasNoArgsConstructor;
private NestingInfo nestingInfo;
private Set<DotName> memberClasses;
private ExtraInfo extra;

/** Describes the form of nesting used by a class */
public enum NestingType {
Expand All @@ -93,16 +90,19 @@ public enum NestingType {
ANONYMOUS
}

// contains fields that are only seldom used, to make the `ClassInfo` class smaller
private static final class ExtraInfo {
private Type[] typeParameters;
private RecordComponentInternal[] recordComponents;
private byte[] recordComponentPositions = EMPTY_POSITIONS;
private Set<DotName> memberClasses;
private ModuleInfo module;
}

private static final class NestingInfo {
private DotName enclosingClass;
private String simpleName;
private EnclosingMethodInfo enclosingMethod;

// non-null if the class is in fact a module descriptor
// this field would naturally belong to ClassInfo, but is present here
// to make the ClassInfo object smaller in the most common case:
// non-nested class that is not a module descriptor
private ModuleInfo module;
}

/**
Expand Down Expand Up @@ -187,7 +187,6 @@ public String toString() {
this.flags = flags;
this.interfaceTypes = interfaceTypes.length == 0 ? Type.EMPTY_ARRAY : interfaceTypes;
this.hasNoArgsConstructor = hasNoArgsConstructor;
this.typeParameters = Type.EMPTY_ARRAY;
this.methods = MethodInternal.EMPTY_ARRAY;
this.fields = FieldInternal.EMPTY_ARRAY;
}
Expand Down Expand Up @@ -853,12 +852,16 @@ final byte[] fieldPositionArray() {
* @return the record component
*/
public final RecordComponentInfo recordComponent(String name) {
if (extra == null || extra.recordComponents == null) {
return null;
}

RecordComponentInternal key = new RecordComponentInternal(Utils.toUTF8(name), VoidType.VOID);
int i = Arrays.binarySearch(recordComponents, key, RecordComponentInternal.NAME_COMPARATOR);
int i = Arrays.binarySearch(extra.recordComponents, key, RecordComponentInternal.NAME_COMPARATOR);
if (i < 0) {
return null;
}
return new RecordComponentInfo(this, recordComponents[i]);
return new RecordComponentInfo(this, extra.recordComponents[i]);
}

/**
Expand All @@ -868,7 +871,11 @@ public final RecordComponentInfo recordComponent(String name) {
* @return a list of record components
*/
public final List<RecordComponentInfo> recordComponents() {
return new RecordComponentInfoGenerator(this, recordComponents, EMPTY_POSITIONS);
if (extra == null || extra.recordComponents == null) {
return Collections.emptyList();
}

return new RecordComponentInfoGenerator(this, extra.recordComponents, EMPTY_POSITIONS);
}

/**
Expand All @@ -885,15 +892,19 @@ public final List<RecordComponentInfo> recordComponents() {
* @since 2.4
*/
public final List<RecordComponentInfo> unsortedRecordComponents() {
return new RecordComponentInfoGenerator(this, recordComponents, recordComponentPositions);
if (extra == null || extra.recordComponents == null) {
return Collections.emptyList();
}

return new RecordComponentInfoGenerator(this, extra.recordComponents, extra.recordComponentPositions);
}

final RecordComponentInternal[] recordComponentArray() {
return recordComponents;
return extra != null && extra.recordComponents != null ? extra.recordComponents : RecordComponentInternal.EMPTY_ARRAY;
}

final byte[] recordComponentPositionArray() {
return recordComponentPositions;
return extra != null && extra.recordComponentPositions != null ? extra.recordComponentPositions : EMPTY_POSITIONS;
}

/**
Expand Down Expand Up @@ -1003,12 +1014,20 @@ public final Type superClassType() {
* @return immutable list of generic type parameters of this class
*/
public final List<TypeVariable> typeParameters() {
if (extra == null || extra.typeParameters == null) {
return Collections.emptyList();
}

// type parameters are always `TypeVariable`
return new ImmutableArrayList(typeParameters);
return new ImmutableArrayList(extra.typeParameters);
}

final Type[] typeParameterArray() {
return typeParameters;
if (extra == null || extra.typeParameters == null) {
return Type.EMPTY_ARRAY;
}

return extra.typeParameters;
}

/**
Expand Down Expand Up @@ -1040,7 +1059,7 @@ public final boolean hasNoArgsConstructor() {
* @return the nesting type of this class
*/
public NestingType nestingType() {
if (nestingInfo == null || nestingInfo.module != null) {
if (nestingInfo == null) {
return NestingType.TOP_LEVEL;
} else if (nestingInfo.enclosingClass != null) {
return NestingType.INNER;
Expand Down Expand Up @@ -1099,10 +1118,10 @@ public EnclosingMethodInfo enclosingMethod() {
* @return immutable set of names of this class's member classes, never {@code null}
*/
public Set<DotName> memberClasses() {
if (memberClasses == null) {
if (extra == null || extra.memberClasses == null) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(memberClasses);
return Collections.unmodifiableSet(extra.memberClasses);
}

/**
Expand All @@ -1111,7 +1130,7 @@ public Set<DotName> memberClasses() {
* @return the module descriptor for module classes, otherwise {@code null}
*/
public ModuleInfo module() {
return nestingInfo != null ? nestingInfo.module : null;
return extra != null ? extra.module : null;
}

/**
Expand Down Expand Up @@ -1252,31 +1271,50 @@ void setMethods(List<MethodInfo> methods, NameTable names) {
}

void setRecordComponentArray(RecordComponentInternal[] recordComponents) {
this.recordComponents = recordComponents;
if (recordComponents.length == 0) {
return;
}

if (extra == null) {
extra = new ExtraInfo();
}

extra.recordComponents = recordComponents;
}

void setRecordComponentPositionArray(byte[] recordComponentPositions) {
this.recordComponentPositions = recordComponentPositions;
if (recordComponentPositions.length == 0) {
return;
}

if (extra == null) {
extra = new ExtraInfo();
}

extra.recordComponentPositions = recordComponentPositions;
}

void setRecordComponents(List<RecordComponentInfo> recordComponents, NameTable names) {
final int size = recordComponents.size();

if (size == 0) {
this.recordComponents = RecordComponentInternal.EMPTY_ARRAY;
return;
}

this.recordComponents = new RecordComponentInternal[size];
if (extra == null) {
extra = new ExtraInfo();
}

extra.recordComponents = new RecordComponentInternal[size];

for (int i = 0; i < size; i++) {
RecordComponentInfo recordComponentInfo = recordComponents.get(i);
RecordComponentInternal internal = names.intern(recordComponentInfo.recordComponentInternal());
recordComponentInfo.setRecordComponentInternal(internal);
this.recordComponents[i] = internal;
extra.recordComponents[i] = internal;
}

this.recordComponentPositions = sortAndGetPositions(this.recordComponents, RecordComponentInternal.NAME_COMPARATOR,
extra.recordComponentPositions = sortAndGetPositions(extra.recordComponents, RecordComponentInternal.NAME_COMPARATOR,
names);
}

Expand Down Expand Up @@ -1330,7 +1368,15 @@ void setInterfaceTypes(Type[] interfaceTypes) {
}

void setTypeParameters(Type[] typeParameters) {
this.typeParameters = typeParameters.length == 0 ? Type.EMPTY_ARRAY : typeParameters;
if (typeParameters.length == 0) {
return;
}

if (extra == null) {
extra = new ExtraInfo();
}

extra.typeParameters = typeParameters;
}

void setInnerClassInfo(DotName enclosingClass, String simpleName, boolean knownInnerClass) {
Expand All @@ -1351,7 +1397,15 @@ void setInnerClassInfo(DotName enclosingClass, String simpleName, boolean knownI
}

void setMemberClasses(Set<DotName> memberClasses) {
this.memberClasses = memberClasses;
if (memberClasses == null || memberClasses.isEmpty()) {
return;
}

if (extra == null) {
extra = new ExtraInfo();
}

extra.memberClasses = memberClasses;
}

void setEnclosingMethod(EnclosingMethodInfo enclosingMethod) {
Expand All @@ -1371,11 +1425,11 @@ void setModule(ModuleInfo module) {
return;
}

if (nestingInfo == null) {
nestingInfo = new NestingInfo();
if (extra == null) {
extra = new ExtraInfo();
}

nestingInfo.module = module;
extra.module = module;
}

void setFlags(short flags) {
Expand Down
Loading

0 comments on commit 5723b37

Please sign in to comment.