diff --git a/core/src/main/java/org/jboss/jandex/MethodInternal.java b/core/src/main/java/org/jboss/jandex/MethodInternal.java index 55970e1d..9725afd2 100644 --- a/core/src/main/java/org/jboss/jandex/MethodInternal.java +++ b/core/src/main/java/org/jboss/jandex/MethodInternal.java @@ -18,6 +18,7 @@ package org.jboss.jandex; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -31,7 +32,7 @@ final class MethodInternal { static final NameAndParameterComponentComparator NAME_AND_PARAMETER_COMPONENT_COMPARATOR = new NameAndParameterComponentComparator(); static final byte[][] EMPTY_PARAMETER_NAMES = new byte[0][]; - static class NameAndParameterComponentComparator implements Comparator { + private static final class NameAndParameterComponentComparator implements Comparator { private int compare(byte[] left, byte[] right) { for (int i = 0, j = 0; i < left.length && j < right.length; i++, j++) { int a = (left[i] & 0xff); @@ -74,16 +75,21 @@ public int compare(MethodInternal instance, MethodInternal instance2) { } } + // contains fields that are only seldom used, to make the `MethodInternal` class smaller + private static final class ExtraInfo { + Type receiverType; + Type[] typeParameters; + AnnotationValue defaultValue; + AnnotationInstance[] annotations; + } + private byte[] name; private byte[][] parameterNames; private Type[] parameterTypes; private Type returnType; private Type[] exceptions; - private Type receiverType; - private Type[] typeParameters; - private AnnotationInstance[] annotations; - private AnnotationValue defaultValue; private short flags; + private ExtraInfo extra; private final Type[] descriptorParameterTypes; @@ -105,11 +111,31 @@ public int compare(MethodInternal instance, MethodInternal instance2) { this.parameterTypes = parameterTypes.length == 0 ? Type.EMPTY_ARRAY : parameterTypes; this.returnType = returnType; this.flags = flags; - this.annotations = annotations; this.exceptions = exceptions; - this.typeParameters = typeParameters; - this.receiverType = receiverType; - this.defaultValue = defaultValue; + if (annotations != null && annotations.length > 0) { + if (extra == null) { + extra = new ExtraInfo(); + } + extra.annotations = annotations; + } + if (typeParameters != null && typeParameters.length > 0) { + if (extra == null) { + extra = new ExtraInfo(); + } + extra.typeParameters = typeParameters; + } + if (receiverType != null) { + if (extra == null) { + extra = new ExtraInfo(); + } + extra.receiverType = receiverType; + } + if (defaultValue != null) { + if (extra == null) { + extra = new ExtraInfo(); + } + extra.defaultValue = defaultValue; + } this.descriptorParameterTypes = this.parameterTypes; } @@ -125,10 +151,14 @@ public boolean equals(Object o) { MethodInternal methodInternal = (MethodInternal) o; + if (extra != null && methodInternal.extra == null || extra == null && methodInternal.extra != null) { + return false; + } + if (flags != methodInternal.flags) { return false; } - if (!Arrays.equals(annotations, methodInternal.annotations)) { + if (extra != null && !Arrays.equals(extra.annotations, methodInternal.extra.annotations)) { return false; } if (!Arrays.equals(exceptions, methodInternal.exceptions)) { @@ -146,16 +176,21 @@ public boolean equals(Object o) { if (!Arrays.equals(descriptorParameterTypes, methodInternal.descriptorParameterTypes)) { return false; } - if (receiverType != null ? !receiverType.equals(methodInternal.receiverType) : methodInternal.receiverType != null) { + if (extra != null && (extra.receiverType != null ? !extra.receiverType.equals(methodInternal.extra.receiverType) + : methodInternal.extra.receiverType != null)) { return false; } if (!returnType.equals(methodInternal.returnType)) { return false; } - if (defaultValue != null ? !defaultValue.equals(methodInternal.defaultValue) : methodInternal.defaultValue != null) { + if (extra != null && (extra.defaultValue != null ? !extra.defaultValue.equals(methodInternal.extra.defaultValue) + : methodInternal.extra.defaultValue != null)) { return false; } - return Arrays.equals(typeParameters, methodInternal.typeParameters); + if (extra != null && !Arrays.equals(extra.typeParameters, methodInternal.extra.typeParameters)) { + return false; + } + return true; } @Override @@ -166,11 +201,11 @@ public int hashCode() { result = 31 * result + Arrays.hashCode(descriptorParameterTypes); result = 31 * result + returnType.hashCode(); result = 31 * result + Arrays.hashCode(exceptions); - result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0); - result = 31 * result + Arrays.hashCode(typeParameters); - result = 31 * result + Arrays.hashCode(annotations); + result = 31 * result + (extra != null && extra.receiverType != null ? extra.receiverType.hashCode() : 0); + result = 31 * result + (extra != null ? Arrays.hashCode(extra.typeParameters) : 0); + result = 31 * result + (extra != null ? Arrays.hashCode(extra.annotations) : 0); + result = 31 * result + (extra != null && extra.defaultValue != null ? extra.defaultValue.hashCode() : 0); result = 31 * result + (int) flags; - result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0); return result; } @@ -184,10 +219,14 @@ boolean internEquals(Object o) { MethodInternal methodInternal = (MethodInternal) o; + if (extra != null && methodInternal.extra == null || extra == null && methodInternal.extra != null) { + return false; + } + if (flags != methodInternal.flags) { return false; } - if (!Arrays.equals(annotations, methodInternal.annotations)) { + if (extra != null && !Arrays.equals(extra.annotations, methodInternal.extra.annotations)) { return false; } if (!TypeInterning.arrayEquals(exceptions, methodInternal.exceptions)) { @@ -205,17 +244,21 @@ boolean internEquals(Object o) { if (!TypeInterning.arrayEquals(descriptorParameterTypes, methodInternal.descriptorParameterTypes)) { return false; } - if (receiverType != null ? !receiverType.internEquals(methodInternal.receiverType) - : methodInternal.receiverType != null) { + if (extra != null && (extra.receiverType != null ? !extra.receiverType.internEquals(methodInternal.extra.receiverType) + : methodInternal.extra.receiverType != null)) { return false; } if (!returnType.internEquals(methodInternal.returnType)) { return false; } - if (defaultValue != null ? !defaultValue.equals(methodInternal.defaultValue) : methodInternal.defaultValue != null) { + if (extra != null && (extra.defaultValue != null ? !extra.defaultValue.equals(methodInternal.extra.defaultValue) + : methodInternal.extra.defaultValue != null)) { + return false; + } + if (extra != null && !TypeInterning.arrayEquals(extra.typeParameters, methodInternal.extra.typeParameters)) { return false; } - return TypeInterning.arrayEquals(typeParameters, methodInternal.typeParameters); + return true; } int internHashCode() { @@ -225,11 +268,11 @@ int internHashCode() { result = 31 * result + TypeInterning.arrayHashCode(descriptorParameterTypes); result = 31 * result + returnType.internHashCode(); result = 31 * result + TypeInterning.arrayHashCode(exceptions); - result = 31 * result + (receiverType != null ? receiverType.internHashCode() : 0); - result = 31 * result + TypeInterning.arrayHashCode(typeParameters); - result = 31 * result + Arrays.hashCode(annotations); + result = 31 * result + (extra != null && extra.receiverType != null ? extra.receiverType.internHashCode() : 0); + result = 31 * result + (extra != null ? TypeInterning.arrayHashCode(extra.typeParameters) : 0); + result = 31 * result + (extra != null ? Arrays.hashCode(extra.annotations) : 0); + result = 31 * result + (extra != null && extra.defaultValue != null ? extra.defaultValue.hashCode() : 0); result = 31 * result + (int) flags; - result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0); return result; } @@ -284,8 +327,8 @@ final Type returnType() { } final Type receiverType(ClassInfo clazz) { - if (receiverType != null) { - return receiverType; + if (extra != null && extra.receiverType != null) { + return extra.receiverType; } // don't assign the `receiverType` field here! receiver type declaration is only useful @@ -302,7 +345,7 @@ final Type receiverType(ClassInfo clazz) { } final Type receiverTypeField() { - return receiverType; + return extra != null ? extra.receiverType : null; } final List exceptions() { @@ -315,19 +358,21 @@ final Type[] exceptionArray() { final List typeParameters() { // type parameters are always `TypeVariable` - return new ImmutableArrayList(typeParameters); + return extra != null && extra.typeParameters != null ? new ImmutableArrayList(extra.typeParameters) + : Collections.emptyList(); } final List annotations() { - return new ImmutableArrayList<>(annotations); + return extra != null && extra.annotations != null ? new ImmutableArrayList<>(extra.annotations) + : Collections.emptyList(); } final AnnotationInstance[] annotationArray() { - return annotations; + return extra != null && extra.annotations != null ? extra.annotations : AnnotationInstance.EMPTY_ARRAY; } final AnnotationInstance annotation(DotName name) { - return AnnotationInstance.binarySearch(annotations, name); + return extra != null && extra.annotations != null ? AnnotationInstance.binarySearch(extra.annotations, name) : null; } final boolean hasAnnotation(DotName name) { @@ -335,11 +380,11 @@ final boolean hasAnnotation(DotName name) { } final Type[] typeParameterArray() { - return typeParameters; + return extra != null && extra.typeParameters != null ? extra.typeParameters : Type.EMPTY_ARRAY; } final AnnotationValue defaultValue() { - return defaultValue; + return extra != null ? extra.defaultValue : null; } final short flags() { @@ -351,8 +396,8 @@ public String toString() { StringBuilder builder = new StringBuilder(); String name = name(); builder.append(returnType.toString(true)).append(' ').append(name).append('('); - if (receiverType != null) { - builder.append(receiverType.toString(true)).append(" this"); + if (extra != null && extra.receiverType != null) { + builder.append(extra.receiverType.toString(true)).append(" this"); if (parameterTypes.length > 0) { builder.append(", "); } @@ -384,7 +429,10 @@ public String toString() { void setTypeParameters(Type[] typeParameters) { if (typeParameters.length > 0) { - this.typeParameters = typeParameters; + if (extra == null) { + extra = new ExtraInfo(); + } + extra.typeParameters = typeParameters; } } @@ -405,17 +453,26 @@ void setExceptions(Type[] exceptions) { } void setReceiverType(Type receiverType) { - this.receiverType = receiverType; + if (extra == null) { + extra = new ExtraInfo(); + } + extra.receiverType = receiverType; } void setAnnotations(List annotations) { - if (annotations.size() > 0) { - this.annotations = annotations.toArray(new AnnotationInstance[annotations.size()]); - Arrays.sort(this.annotations, AnnotationInstance.NAME_COMPARATOR); + if (!annotations.isEmpty()) { + if (extra == null) { + extra = new ExtraInfo(); + } + extra.annotations = annotations.toArray(new AnnotationInstance[0]); + Arrays.sort(extra.annotations, AnnotationInstance.NAME_COMPARATOR); } } void setDefaultValue(AnnotationValue defaultValue) { - this.defaultValue = defaultValue; + if (extra == null) { + extra = new ExtraInfo(); + } + extra.defaultValue = defaultValue; } }