From 39d47ebd9e084c354e729aebb3cd08a7819306d1 Mon Sep 17 00:00:00 2001 From: aclement Date: Mon, 16 Nov 2009 21:05:58 +0000 Subject: [PATCH] weak refs to cached interface set --- .../src/org/aspectj/weaver/MemberImpl.java | 98 +++++++++---------- .../src/org/aspectj/weaver/ReferenceType.java | 44 +++++---- 2 files changed, 67 insertions(+), 75 deletions(-) diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java b/org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java index 553fed430..e10174a26 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java @@ -27,8 +27,8 @@ public class MemberImpl implements Member { protected UnresolvedType returnType; protected UnresolvedType declaringType; protected UnresolvedType[] parameterTypes; - private final String signature; - private String paramSignature; + private final String erasedSignature; // eg. (Ljava/util/Set;V)Ljava/lang/String; + private String paramSignature; // eg. (Ljava/util/Set;V) // no return type // OPTIMIZE move out of the member! private boolean reportedCantFindDeclaringType = false; @@ -39,25 +39,28 @@ public class MemberImpl implements Member { */ private JoinPointSignatureIterator joinPointSignatures = null; - public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, String name, String signature) { + /** + * Construct a MemberImpl using an erased signature for the parameters and return type (member method/ctor) or type (member field) + */ + public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, String name, String erasedSignature) { this.kind = kind; this.declaringType = declaringType; this.modifiers = modifiers; this.name = name; - this.signature = signature; + this.erasedSignature = erasedSignature; if (kind == FIELD) { - this.returnType = UnresolvedType.forSignature(signature); + this.returnType = UnresolvedType.forSignature(erasedSignature); this.parameterTypes = UnresolvedType.NONE; } else { - Object[] returnAndParams = signatureToTypes(signature, false); + Object[] returnAndParams = signatureToTypes(erasedSignature); this.returnType = (UnresolvedType) returnAndParams[0]; this.parameterTypes = (UnresolvedType[]) returnAndParams[1]; - // always safe not to do this ?!? - // String oldsig=new String(signature); - // signature = typesToSignature(returnType,parameterTypes,true); } } + /** + * Construct a MemberImpl using real type information for the parameters and return type (member method/ctor) or type (member field) + */ public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name, UnresolvedType[] parameterTypes) { this.kind = kind; @@ -67,10 +70,22 @@ public class MemberImpl implements Member { this.name = name; this.parameterTypes = parameterTypes; if (kind == FIELD) { - this.signature = returnType.getErasureSignature(); + this.erasedSignature = returnType.getErasureSignature(); } else { - this.signature = typesToSignature(returnType, parameterTypes, true); + this.erasedSignature = typesToSignature(returnType, parameterTypes, true); + + // Check parameter recovery by collapsing types to the string then rebuilding them from that + // this will check we are capable of having WeakRefs to the parameter types +// String nonErasedSignature = getParameterSignature()+getReturnType().getSignature(); +// Object[] returnAndParams = signatureToTypes(nonErasedSignature); +// UnresolvedType[] recoveredParams = (UnresolvedType[]) returnAndParams[1]; +// for (int jj=0;jj - * - *
-	 *   UnresolvedType.signatureToTypes("()[Z")[0].equals(Type.forSignature("[Z"))
-	 *   UnresolvedType.signatureToTypes("(JJ)I")[1]
-	 *      .equals(UnresolvedType.forSignatures(new String[] {"J", "J"}))
-	 * 
- * - * - * - * @param signature the JVM bytecode method signature string we want to break apart - * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types. + * Build a signature based on the return type and parameter types. For example: "(Ljava/util/Set;)V" + * or "(Ljava/util/Set;)V". The latter form shows what happens when the generics are erased */ - // OPTIMIZE move static util methods out into a memberutils class - public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean useRawTypes) { - StringBuffer buf = new StringBuffer(); + public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean eraseGenerics) { + StringBuilder buf = new StringBuilder(); buf.append("("); - for (int i = 0, len = paramTypes.length; i < len; i++) { - if (paramTypes[i].isParameterizedType() && useRawTypes) { - buf.append(paramTypes[i].getErasureSignature()); - } else if (paramTypes[i].isTypeVariableReference() && useRawTypes) { - buf.append(paramTypes[i].getErasureSignature()); + for (UnresolvedType paramType: paramTypes) { + if (eraseGenerics && (paramType.isParameterizedType() || paramType.isTypeVariableReference())) { + buf.append(paramType.getErasureSignature()); } else { - buf.append(paramTypes[i].getSignature()); + buf.append(paramType.getSignature()); } } buf.append(")"); - if (returnType.isParameterizedType() && useRawTypes) { - buf.append(returnType.getErasureSignature()); - } else if (returnType.isTypeVariableReference() && useRawTypes) { - buf.append(returnType.getErasureSignature()); + if (eraseGenerics && (returnType.isParameterizedType() || returnType.isTypeVariableReference())) { + buf.append(returnType.getErasureSignature()); } else { buf.append(returnType.getSignature()); } @@ -150,10 +146,10 @@ public class MemberImpl implements Member { * * * - * @param signature the JVM bytecode method signature string we want to break apart + * @param erasedSignature the JVM bytecode method signature string we want to break apart * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types. */ - private static Object[] signatureToTypes(String sig, boolean keepParameterizationInfo) { + private static Object[] signatureToTypes(String sig) { boolean hasParameters = sig.charAt(1) != ')'; if (hasParameters) { List l = new ArrayList(); @@ -204,7 +200,7 @@ public class MemberImpl implements Member { } else if (c == 'T') { // assumed 'reference' to a type // variable, so just "Tname;" int nextSemicolon = sig.indexOf(';', start); - String nextbit = sig.substring(start, nextSemicolon); + String nextbit = sig.substring(start, nextSemicolon+1); l.add(UnresolvedType.forSignature(nextbit)); i = nextSemicolon + 1; } else { @@ -226,16 +222,10 @@ public class MemberImpl implements Member { return field(declaring, mods, UnresolvedType.forSignature(signature), name); } - // public static Member field(UnresolvedType declaring, int mods, String - // name, UnresolvedType type) { - // return new MemberImpl(FIELD, declaring, mods, type, name, - // UnresolvedType.NONE); - // } // OPTIMIZE do we need to call this? unless necessary the signatureToTypes() - // call smacks of laziness on the behalf of the caller - // of this method + // call smacks of laziness on the behalf of the caller of this method public static MemberImpl method(UnresolvedType declaring, int mods, String name, String signature) { - Object[] pair = signatureToTypes(signature, false); + Object[] pair = signatureToTypes(signature); return method(declaring, mods, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]); } @@ -250,7 +240,7 @@ public class MemberImpl implements Member { } public static Member pointcut(UnresolvedType declaring, String name, String signature) { - Object[] pair = signatureToTypes(signature, false); + Object[] pair = signatureToTypes(signature); return pointcut(declaring, 0, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]); } @@ -261,7 +251,7 @@ public class MemberImpl implements Member { public static MemberImpl method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) { return new MemberImpl( // ??? this calls a method - name.equals("") ? CONSTRUCTOR : METHOD, declTy, mods, rTy, name, paramTys); + name.equals("") ? CONSTRUCTOR : METHOD, declTy, mods, rTy, name, paramTys); } private static Member pointcut(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) { @@ -369,7 +359,7 @@ public class MemberImpl implements Member { } public String getSignature() { - return signature; + return erasedSignature; } public int getArity() { diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java b/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java index 5155c495b..3fe97a4b6 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java @@ -50,7 +50,7 @@ public class ReferenceType extends ResolvedType { ResolvedMember[] parameterizedMethods = null; ResolvedMember[] parameterizedFields = null; ResolvedMember[] parameterizedPointcuts = null; - ResolvedType[] parameterizedInterfaces = null; + WeakReference parameterizedInterfaces = new WeakReference(null); Collection parameterizedDeclares = null; Collection parameterizedTypeMungers = null; @@ -603,8 +603,9 @@ public class ReferenceType extends ResolvedType { */ @Override public ResolvedType[] getDeclaredInterfaces() { - if (parameterizedInterfaces != null) { - return parameterizedInterfaces; + ResolvedType[] interfaces = parameterizedInterfaces.get(); + if (interfaces != null) { + return interfaces; } ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces(); if (newInterfaces != null) { @@ -617,41 +618,42 @@ public class ReferenceType extends ResolvedType { if (isParameterizedType()) { // UnresolvedType[] paramTypes = // getTypesForMemberParameterization(); - parameterizedInterfaces = new ResolvedType[delegateInterfaces.length]; + interfaces = new ResolvedType[delegateInterfaces.length]; for (int i = 0; i < delegateInterfaces.length; i++) { // We may have to sub/super set the set of parametertypes if the // implemented interface // needs more or less than this type does. (pr124803/pr125080) if (delegateInterfaces[i].isParameterizedType()) { - parameterizedInterfaces[i] = delegateInterfaces[i].parameterize(getMemberParameterizationMap()).resolve(world); + interfaces[i] = delegateInterfaces[i].parameterize(getMemberParameterizationMap()).resolve(world); } else { - parameterizedInterfaces[i] = delegateInterfaces[i]; + interfaces[i] = delegateInterfaces[i]; } } - return parameterizedInterfaces; + parameterizedInterfaces = new WeakReference(interfaces); + return interfaces; } else if (isRawType()) { UnresolvedType[] paramTypes = getTypesForMemberParameterization(); - parameterizedInterfaces = new ResolvedType[delegateInterfaces.length]; - for (int i = 0; i < parameterizedInterfaces.length; i++) { - parameterizedInterfaces[i] = delegateInterfaces[i]; - if (parameterizedInterfaces[i].isGenericType()) { + interfaces = new ResolvedType[delegateInterfaces.length]; + for (int i = 0,max=interfaces.length; i < max; i++) { + interfaces[i] = delegateInterfaces[i]; + if (interfaces[i].isGenericType()) { // a generic supertype of a raw type is replaced by its raw // equivalent - parameterizedInterfaces[i] = parameterizedInterfaces[i].getRawType().resolve(getWorld()); - } else if (parameterizedInterfaces[i].isParameterizedType()) { + interfaces[i] = interfaces[i].getRawType().resolve(getWorld()); + } else if (interfaces[i].isParameterizedType()) { // a parameterized supertype collapses any type vars to // their upper bounds - UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(parameterizedInterfaces[i], paramTypes); - parameterizedInterfaces[i] = parameterizedInterfaces[i].parameterizedWith(toUseForParameterization); + UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(interfaces[i], paramTypes); + interfaces[i] = interfaces[i].parameterizedWith(toUseForParameterization); } } - return parameterizedInterfaces; + parameterizedInterfaces = new WeakReference(interfaces); + return interfaces; } if (delegate.isCacheable()) { - parameterizedInterfaces = delegateInterfaces; + parameterizedInterfaces = new WeakReference(delegateInterfaces); } - return delegateInterfaces; } @@ -932,7 +934,7 @@ public class ReferenceType extends ResolvedType { private void clearParameterizationCaches() { parameterizedFields = null; - parameterizedInterfaces = null; + parameterizedInterfaces.clear(); parameterizedMethods = null; parameterizedPointcuts = null; superclassReference = new WeakReference(null); @@ -1025,7 +1027,7 @@ public class ReferenceType extends ResolvedType { annotationTypes = null; newSuperclass = null; newInterfaces = null; - parameterizedInterfaces = null; + parameterizedInterfaces.clear(); superclassReference = new WeakReference(null); } @@ -1052,7 +1054,7 @@ public class ReferenceType extends ResolvedType { newNewInterfaces[0] = newParent; newInterfaces = newNewInterfaces; } - parameterizedInterfaces = null;// invalidate cached info + parameterizedInterfaces.clear(); } } } \ No newline at end of file -- 2.39.5