From a9744fe1e9aad2d7222d036dc463d874f0a1d153 Mon Sep 17 00:00:00 2001 From: aclement Date: Mon, 16 Oct 2006 14:25:35 +0000 Subject: [PATCH] pr133532 fix: promoted compact representation to top level type - fixed memory leak when classes deleted --- .../ajdt/internal/core/builder/AjState.java | 155 ++++-------------- 1 file changed, 36 insertions(+), 119 deletions(-) diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java index 2cff1298f..24baedad5 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java @@ -40,15 +40,14 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryField; import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryMethod; +import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers; import org.aspectj.org.eclipse.jdt.internal.core.builder.ReferenceCollection; import org.aspectj.org.eclipse.jdt.internal.core.builder.StringSet; import org.aspectj.util.FileUtil; import org.aspectj.weaver.BCException; import org.aspectj.weaver.IWeaver; -import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; -import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.bcel.BcelWeaver; import org.aspectj.weaver.bcel.BcelWorld; import org.aspectj.weaver.bcel.UnwovenClassFile; @@ -162,6 +161,9 @@ public class AjState { private List/*String*/ resources = new ArrayList(); private List/*String*/ aspectNames; + // these are references created on a particular compile run - when looping round in + // addAffectedSourceFiles(), if some have been created then we look at which source files + // touch upon those and get them recompiled. private ArrayList/**/ qualifiedStrings; private ArrayList/**/ simpleStrings; @@ -278,6 +280,13 @@ public class AjState { if (stateListener!=null) stateListener.detectedAspectDeleted(aDeletedFile); return false; } + List/*ClassFile*/ classes = (List)fullyQualifiedTypeNamesResultingFromCompilationUnit.get(aDeletedFile); + if (classes!=null) { + for (Iterator iterator = classes.iterator(); iterator.hasNext();) { + ClassFile element = (ClassFile) iterator.next(); + resolvedTypeStructuresFromLastBuild.remove(element.fullyQualifiedTypeName); + } + } } return true; } @@ -617,6 +626,7 @@ public class AjState { return ucf; } + public void noteResult(InterimCompilationResult result) { if (!maybeIncremental()) { return; @@ -770,7 +780,7 @@ public class AjState { if (!rType.isMissing()) { try { ClassFileReader reader = new ClassFileReader(thisTime.getBytes(), null); - this.resolvedTypeStructuresFromLastBuild.put(thisTime.getClassName(),new CompactStructureRepresentation(reader)); + this.resolvedTypeStructuresFromLastBuild.put(thisTime.getClassName(),new CompactTypeStructureRepresentation(reader)); } catch (ClassFormatException cfe) { throw new BCException("Unexpected problem processing class",cfe); } @@ -778,12 +788,12 @@ public class AjState { return; } - CompactStructureRepresentation existingStructure = (CompactStructureRepresentation) this.resolvedTypeStructuresFromLastBuild.get(thisTime.getClassName()); + CompactTypeStructureRepresentation existingStructure = (CompactTypeStructureRepresentation) this.resolvedTypeStructuresFromLastBuild.get(thisTime.getClassName()); ResolvedType newResolvedType = world.resolve(thisTime.getClassName()); if (!newResolvedType.isMissing()) { try { ClassFileReader reader = new ClassFileReader(thisTime.getBytes(), null); - this.resolvedTypeStructuresFromLastBuild.put(thisTime.getClassName(),new CompactStructureRepresentation(reader)); + this.resolvedTypeStructuresFromLastBuild.put(thisTime.getClassName(),new CompactTypeStructureRepresentation(reader)); } catch (ClassFormatException cfe) { throw new BCException("Unexpected problem processing class",cfe); } @@ -833,7 +843,7 @@ public class AjState { * @param existingType * @return */ - private boolean hasStructuralChanges(ClassFileReader reader, CompactStructureRepresentation existingType) { + private boolean hasStructuralChanges(ClassFileReader reader, CompactTypeStructureRepresentation existingType) { if (existingType == null) { return true; } @@ -869,9 +879,9 @@ public class AjState { } // fields - MemberStructure[] existingFields = existingType.fields; +// CompactMemberStructureRepresentation[] existingFields = existingType.fields; IBinaryField[] newFields = reader.getFields(); - if (newFields == null) { newFields = new IBinaryField[0]; } + if (newFields == null) { newFields = CompactTypeStructureRepresentation.NoField; } // all redundant for now ... could be an optimization at some point... // remove any ajc$XXX fields from those we compare with @@ -884,17 +894,18 @@ public class AjState { // nonGenFields.add(field); // //} // } - if (newFields.length != existingFields.length) return true; + IBinaryField[] existingFs = existingType.binFields; + if (newFields.length != existingFs.length) return true; new_field_loop: for (int i = 0; i < newFields.length; i++) { IBinaryField field = newFields[i]; char[] fieldName = field.getName(); - for (int j = 0; j < existingFields.length; j++) { - if (CharOperation.equals(existingFields[j].name,fieldName)) { - if (!modifiersEqual(field.getModifiers(),existingFields[j].modifiers)) { + for (int j = 0; j < existingFs.length; j++) { + if (CharOperation.equals(existingFs[j].getName(),fieldName)) { + if (!modifiersEqual(field.getModifiers(),existingFs[j].getModifiers())) { return true; } - if (!CharOperation.equals(existingFields[j].signature,field.getTypeName())) { + if (!CharOperation.equals(existingFs[j].getTypeName(),field.getTypeName())) { return true; } continue new_field_loop; @@ -904,9 +915,9 @@ public class AjState { } // methods - MemberStructure[] existingMethods = existingType.methods; +// CompactMemberStructureRepresentation[] existingMethods = existingType.methods; IBinaryMethod[] newMethods = reader.getMethods(); - if (newMethods == null) { newMethods = new IBinaryMethod[0]; } + if (newMethods == null) { newMethods = CompactTypeStructureRepresentation.NoMethod; } // all redundant for now ... could be an optimization at some point... @@ -944,15 +955,16 @@ public class AjState { // nonGenMethods.add(method); //// } // } - if (newMethods.length != existingMethods.length) return true; + IBinaryMethod[] existingMs = existingType.binMethods; + if (newMethods.length != existingMs.length) return true; new_method_loop: for (int i = 0; i < newMethods.length; i++) { IBinaryMethod method = newMethods[i]; char[] methodName = method.getSelector(); - for (int j = 0; j < existingMethods.length; j++) { - if (CharOperation.equals(existingMethods[j].name,methodName)) { + for (int j = 0; j < existingMs.length; j++) { + if (CharOperation.equals(existingMs[j].getSelector(),methodName)) { // candidate match - if (!CharOperation.equals(method.getMethodDescriptor(),existingMethods[j].signature)) { + if (!CharOperation.equals(method.getMethodDescriptor(),existingMs[j].getMethodDescriptor())) { // ok, the descriptors don't match, but is this a funky ctor on a non-static inner // type? // boolean mightBeOK = @@ -973,7 +985,7 @@ public class AjState { continue; // might be overloading } else { // matching sigs - if (!modifiersEqual(method.getModifiers(),existingMethods[j].modifiers)) { + if (!modifiersEqual(method.getModifiers(),existingMs[j].getModifiers())) { return true; } continue new_method_loop; @@ -1230,105 +1242,6 @@ public class AjState { } } - private static class CompactStructureRepresentation { - - char[] className; - int modifiers; - char[] genericSignature; - char[] superclassName; - char[][] interfaces; - MemberStructure[] fields; - MemberStructure[] methods; - - public CompactStructureRepresentation(ClassFileReader cfr) { - this.className = cfr.getName(); // slashes... - this.modifiers = cfr.getModifiers(); - this.genericSignature = cfr.getGenericSignature(); -// if (this.genericSignature.length == 0) { -// this.genericSignature = null; -// } - this.superclassName = cfr.getSuperclassName(); // slashes... - interfaces = cfr.getInterfaceNames(); - - - - IBinaryField[] rFields = cfr.getFields(); - this.fields = new MemberStructure[rFields==null?0:rFields.length]; - if (rFields!=null) { - for (int i = 0; i < rFields.length; i++) { - this.fields[i] = new MemberStructure(); - this.fields[i].name = rFields[i].getName(); - this.fields[i].modifiers = rFields[i].getModifiers(); - this.fields[i].signature = rFields[i].getTypeName(); - } - } - - IBinaryMethod[] rMethods = cfr.getMethods(); - this.methods = new MemberStructure[rMethods==null?0:rMethods.length]; - if (rMethods!=null) { - for (int i = 0; i < rMethods.length; i++) { - this.methods[i] = new MemberStructure(); - this.methods[i].name = rMethods[i].getSelector(); - this.methods[i].modifiers = rMethods[i].getModifiers(); - // StringBuffer sig = new StringBuffer(); - // sig.append("("); - // UnresolvedType[] pTypes = rMethods[i].getMethodDescriptor(); - // for (int j = 0; j < pTypes.length; j++) { - // sig.append(pTypes[j].getSignature()); - // } - // sig.append(")"); - // sig.append(rMethods[i].getReturnType().getSignature()); - this.methods[i].signature =rMethods[i].getMethodDescriptor();// sig.toString().toCharArray(); - } - } - } - - public CompactStructureRepresentation(ResolvedType forType) { - this.className = forType.getName().replace('.','/').toCharArray(); - this.modifiers = forType.getModifiers(); - this.genericSignature = forType.getGenericSignature().toCharArray(); - if (this.genericSignature.length == 0) { - this.genericSignature = null; - } - this.superclassName = forType.getSuperclass().getName().replace('.','/').toCharArray(); - ResolvedType[] rTypes = forType.getDeclaredInterfaces(); - this.interfaces = new char[rTypes.length][]; - for (int i = 0; i < rTypes.length; i++) { - this.interfaces[i] = rTypes[i].getName().replace('.','/').toCharArray(); - } - ResolvedMember[] rFields = forType.getDeclaredFields(); - this.fields = new MemberStructure[rFields.length]; - for (int i = 0; i < rFields.length; i++) { - this.fields[i] = new MemberStructure(); - this.fields[i].name = rFields[i].getName().toCharArray(); - this.fields[i].modifiers = rFields[i].getModifiers(); - this.fields[i].signature = rFields[i].getReturnType().getSignature().toCharArray(); - } - ResolvedMember[] rMethods = forType.getDeclaredMethods(); - this.methods = new MemberStructure[rMethods.length]; - for (int i = 0; i < rMethods.length; i++) { - this.methods[i] = new MemberStructure(); - this.methods[i].name = rMethods[i].getName().toCharArray(); - this.methods[i].modifiers = rMethods[i].getModifiers(); - StringBuffer sig = new StringBuffer(); - sig.append("("); - UnresolvedType[] pTypes = rMethods[i].getParameterTypes(); - for (int j = 0; j < pTypes.length; j++) { - sig.append(pTypes[j].getSignature()); - } - sig.append(")"); - sig.append(rMethods[i].getReturnType().getSignature()); - this.methods[i].signature = sig.toString().toCharArray(); - } - } - } - - private static class MemberStructure { - char[] name; - int modifiers; - char[] signature; - } - public void wipeAllKnowledge() { buildManager.state = null; buildManager.setStructureModel(null); @@ -1350,4 +1263,8 @@ public class AjState { public IStateListener getListener() { return stateListener; } + + public IBinaryType checkPreviousBuild(String name) { + return (IBinaryType)resolvedTypeStructuresFromLastBuild.get(name); + } } -- 2.39.5