Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory improvements #363

Merged
merged 3 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading