From 4104af6d61d6ac601a3bad2d8113906f767135da Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 23 Jul 1999 16:56:44 +0000 Subject: [PATCH] some speed improvements git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1127 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/bytecode/BytecodeInfo.java.in | 42 ++-- jode/jode/bytecode/GrowableConstantPool.java | 55 ++++-- jode/jode/obfuscator/ClassBundle.java.in | 23 ++- jode/jode/obfuscator/ClassIdentifier.java.in | 9 +- jode/jode/obfuscator/ConstantAnalyzer.java.in | 29 ++- jode/jode/obfuscator/LocalOptimizer.java.in | 48 ++++- .../jode/obfuscator/PackageIdentifier.java.in | 186 +++++------------- 7 files changed, 185 insertions(+), 207 deletions(-) diff --git a/jode/jode/bytecode/BytecodeInfo.java.in b/jode/jode/bytecode/BytecodeInfo.java.in index 10d9639..2c49837 100644 --- a/jode/jode/bytecode/BytecodeInfo.java.in +++ b/jode/jode/bytecode/BytecodeInfo.java.in @@ -50,6 +50,12 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { private Handler[] exceptionHandlers; private LocalVariableInfo[] lvt; private LineNumber[] lnt; + + /** + * A array of instructions, indexed by address. This array is only + * valid while reading the code. + */ + private Instruction[] instrs; private InstructionList instructions; @@ -66,7 +72,7 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { return instructionCount; } - private Instruction get0(int index) { + Instruction get0(int index) { Instruction instr = borderInstr; if (index < instructionCount / 2) { for (int i=0; i <= index; i++) @@ -84,6 +90,14 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { return get0(index); } + public boolean add(Object o) { + /* optimize add, since it is called many times by read() */ + instructionCount++; + borderInstr.prevByAddr.appendInstruction((Instruction) o, + BytecodeInfo.this); + return true; + } + public ListIterator listIterator(final int startIndex) { if (startIndex < 0 || startIndex > instructionCount) throw new IllegalArgumentException(); @@ -211,19 +225,9 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { int nameIndex = input.readUnsignedShort(); int typeIndex = input.readUnsignedShort(); int slot = input.readUnsignedShort(); - Instruction startInstr = null; - Instruction endInstr = null; + Instruction startInstr = instrs[start]; + Instruction endInstr = instrs[end]; - for (Iterator iter = instructions.iterator(); - iter.hasNext(); ) { - Instruction instr = (Instruction) iter.next(); - if (instr.getAddr() == start) - startInstr = instr; - if (instr.getNextAddr() == end) - endInstr = instr; - if (instr.getAddr() >= end) - break; - } if (startInstr == null || endInstr == null || nameIndex == 0 || typeIndex == 0 @@ -263,14 +267,7 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { for (int i = 0; i < count; i++) { lnt[i] = new LineNumber(); int start = input.readUnsignedShort(); - Instruction startInstr = null; - for (Iterator iter = instructions.iterator(); iter.hasNext(); ) { - Instruction instr = (Instruction) iter.next(); - if (instr.getAddr() == start) - startInstr = instr; - if (instr.getAddr() >= start) - break; - } + Instruction startInstr = instrs[start]; if (startInstr == null) { GlobalOptions.err.println ("Illegal entry, ignoring LineNumberTable table"); @@ -290,7 +287,7 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { maxLocals = input.readUnsignedShort(); instructions = new InstructionList(); int codeLength = input.readInt(); - Instruction[] instrs = new Instruction[codeLength]; + instrs = new Instruction[codeLength]; int[][] succAddrs = new int[codeLength][]; { int addr = 0; @@ -835,6 +832,7 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { } } readAttributes(cp, input, FULLINFO); + instrs = null; } public void dumpCode(java.io.PrintWriter output) { diff --git a/jode/jode/bytecode/GrowableConstantPool.java b/jode/jode/bytecode/GrowableConstantPool.java index 6d605ff..ed05930 100644 --- a/jode/jode/bytecode/GrowableConstantPool.java +++ b/jode/jode/bytecode/GrowableConstantPool.java @@ -31,6 +31,34 @@ public class GrowableConstantPool extends ConstantPool { Hashtable entryToIndex = new Hashtable(); boolean written; + /** + * This class is used as key to the entryToIndex hashtable + */ + private class Key { + int tag; + Object objData; + int intData; + + public Key(int tag, Object objData, int intData) { + this.tag = tag; + this.objData = objData; + this.intData = intData; + } + + public int hashCode() { + return tag ^ objData.hashCode() ^ intData; + } + + public boolean equals(Object o) { + if (o instanceof Key) { + Key k = (Key) o; + return tag == k.tag && intData == k.intData + && objData.equals(k.objData); + } + return false; + } + } + public GrowableConstantPool () { count = 1; tags = new int[128]; @@ -61,7 +89,7 @@ public class GrowableConstantPool extends ConstantPool { } private int putConstant(int tag, Object constant) { - String key = "" + (char)tag + constant; + Key key = new Key(tag, constant, 0); Integer index = (Integer) entryToIndex.get(key); if (index != null) return index.intValue(); @@ -75,7 +103,7 @@ public class GrowableConstantPool extends ConstantPool { } private int putLongConstant(int tag, Object constant) { - String key = "" + (char)tag + constant; + Key key = new Key(tag, constant, 0); Integer index = (Integer) entryToIndex.get(key); if (index != null) return index.intValue(); @@ -89,7 +117,8 @@ public class GrowableConstantPool extends ConstantPool { return newIndex; } - int putIndexed(String key, int tag, int index1, int index2) { + int putIndexed(int tag, Object obj1, int index1, int index2) { + Key key = new Key(tag, obj1, index2); Integer indexObj = (Integer) entryToIndex.get(key); if (indexObj != null) { /* Maybe this was a reserved, but not filled entry */ @@ -113,8 +142,7 @@ public class GrowableConstantPool extends ConstantPool { public int putClassName(String name) { name = name.replace('.','/'); TypeSignature.checkTypeSig("L"+name+";"); - return putIndexed(""+(char) CLASS + name, - CLASS, putUTF8(name), 0); + return putIndexed(CLASS, name, putUTF8(name), 0); } public int putClassType(String name) { @@ -123,14 +151,12 @@ public class GrowableConstantPool extends ConstantPool { name = name.substring(1, name.length()-1); else if (name.charAt(0) != '[') throw new IllegalArgumentException("wrong class type: "+name); - return putIndexed(""+(char) CLASS + name, - CLASS, putUTF8(name), 0); + return putIndexed(CLASS, name, putUTF8(name), 0); } public int putRef(int tag, Reference ref) { String className = ref.getClazz(); String typeSig = ref.getType(); - String nameAndType = ref.getName() + "/" + typeSig; if (tag == FIELDREF) TypeSignature.checkTypeSig(typeSig); else @@ -140,10 +166,9 @@ public class GrowableConstantPool extends ConstantPool { int classIndex = putClassType(className); int nameIndex = putUTF8(ref.getName()); int typeIndex = putUTF8(typeSig); - int nameTypeIndex = putIndexed("" + (char) NAMEANDTYPE + nameAndType, - NAMEANDTYPE, nameIndex, typeIndex); - return putIndexed("" + (char)tag + className + "/" + nameAndType, - tag, classIndex, nameTypeIndex); + int nameTypeIndex = putIndexed(NAMEANDTYPE, + ref.getName(), nameIndex, typeIndex); + return putIndexed(tag, className, classIndex, nameTypeIndex); } /** @@ -154,8 +179,7 @@ public class GrowableConstantPool extends ConstantPool { */ public int putConstant(Object c) { if (c instanceof String) { - return putIndexed("" + (char) STRING + c, - STRING, putUTF8((String) c), 0); + return putIndexed(STRING, c, putUTF8((String) c), 0); } else { int tag; if (c instanceof Integer) @@ -195,8 +219,7 @@ public class GrowableConstantPool extends ConstantPool { */ public int reserveConstant(Object c) { if (c instanceof String) { - return putIndexed("" + (char)STRING + c, - STRING, -1, 0); + return putIndexed(STRING, c, -1, 0); } else { return putConstant(c); } diff --git a/jode/jode/obfuscator/ClassBundle.java.in b/jode/jode/obfuscator/ClassBundle.java.in index 8aa1f71..9b03d03 100644 --- a/jode/jode/obfuscator/ClassBundle.java.in +++ b/jode/jode/obfuscator/ClassBundle.java.in @@ -66,7 +66,7 @@ public class ClassBundle implements OptionHandler { classPath = System.getProperty("java.class.path") .replace(File.pathSeparatorChar, SearchPath.pathSeparatorChar); destDir = "."; - basePackage = new PackageIdentifier(this, null, ""); + basePackage = new PackageIdentifier(this, null, "", ""); basePackage.setReachable(); basePackage.setPreserved(); } @@ -76,6 +76,8 @@ public class ClassBundle implements OptionHandler { ///#else private static final Map aliasesHash = new HashMap(); ///#endif + private static final Map clazzCache = new HashMap(); + private static final Map referenceCache = new HashMap(); public static void setStripOptions(Collection stripString) { } @@ -263,23 +265,34 @@ public class ClassBundle implements OptionHandler { return alias; } + public void addClassIdentifier(Identifier ident) { + } + public ClassIdentifier getClassIdentifier(String name) { + if (clazzCache.containsKey(name)) + return (ClassIdentifier) clazzCache.get(name); ClassIdentifier ident = (ClassIdentifier) basePackage.getIdentifier(name); + clazzCache.put(name, ident); return ident; } public Identifier getIdentifier(Reference ref) { + if (referenceCache.containsKey(ref)) + return (Identifier) referenceCache.get(ref); + String clName = ref.getClazz(); if (clName.charAt(0) == '[') /* Can't represent arrays */ return null; - ClassIdentifier ident = + ClassIdentifier clazzIdent = getClassIdentifier(clName.substring(1, clName.length()-1) .replace('/','.')); - if (ident == null) - return null; - return ident.getIdentifier(ref.getName(), ref.getType()); + Identifier ident = + clazzIdent == null ? null + : clazzIdent.getIdentifier(ref.getName(), ref.getType()); + referenceCache.put(ref, ident); + return ident; } public void reachableClass(String clazzName) { diff --git a/jode/jode/obfuscator/ClassIdentifier.java.in b/jode/jode/obfuscator/ClassIdentifier.java.in index 55251c6..2eeaf87 100644 --- a/jode/jode/obfuscator/ClassIdentifier.java.in +++ b/jode/jode/obfuscator/ClassIdentifier.java.in @@ -42,6 +42,7 @@ import java.io.IOException; public class ClassIdentifier extends Identifier { PackageIdentifier pack; String name; + String fullName; ClassInfo info; String superName; String[] ifaceNames; @@ -50,10 +51,11 @@ public class ClassIdentifier extends Identifier { List knownSubClasses = new LinkedList(); List virtualReachables = new LinkedList(); - public ClassIdentifier(PackageIdentifier pack, + public ClassIdentifier(PackageIdentifier pack, String fullName, String name, ClassInfo info) { super(name); this.pack = pack; + this.fullName = fullName; this.name = name; this.info = info; } @@ -712,10 +714,7 @@ public class ClassIdentifier extends Identifier { * @return the full qualified name, excluding trailing dot. */ public String getFullName() { - if (pack.parent == null) - return getName(); - else - return pack.getFullName() + "." + getName(); + return fullName; } /** diff --git a/jode/jode/obfuscator/ConstantAnalyzer.java.in b/jode/jode/obfuscator/ConstantAnalyzer.java.in index b482106..0051278 100644 --- a/jode/jode/obfuscator/ConstantAnalyzer.java.in +++ b/jode/jode/obfuscator/ConstantAnalyzer.java.in @@ -206,17 +206,23 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer { } } + private static class TodoQueue { + StackLocalInfo first; + } + private static class StackLocalInfo implements ConstantListener { ConstValue[] stack; ConstValue[] locals; Instruction instr; + StackLocalInfo nextOnQueue; + /** * The queue that should be notified, if the constant values of * this instruction changes. We put ourself on this queue in that * case. */ - Collection notifyQueue; + TodoQueue notifyQueue; public ConstValue copy(ConstValue value) { return (value == null) ? null : value.copy(); @@ -224,7 +230,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer { private StackLocalInfo(ConstValue[] stack, ConstValue[] locals, - Collection notifyQueue) { + TodoQueue notifyQueue) { this.stack = stack; this.locals = locals; this.notifyQueue = notifyQueue; @@ -232,7 +238,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer { public StackLocalInfo(int numLocals, boolean isStatic, String methodTypeSig, - Collection notifyQueue) { + TodoQueue notifyQueue) { String[] paramTypes = TypeSignature.getParameterTypes(methodTypeSig); @@ -250,7 +256,10 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer { } public final void enqueue() { - notifyQueue.add(this); + if (nextOnQueue == null) { + this.nextOnQueue = notifyQueue.first; + notifyQueue.first = this; + } } public void constantChanged() { @@ -1361,18 +1370,18 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer { this.bytecode = bytecode; if (constInfos == null) constInfos = new HashMap(); - Set modifiedQueue = new HashSet(); + TodoQueue modifiedQueue = new TodoQueue(); MethodInfo minfo = bytecode.getMethodInfo(); StackLocalInfo firstInfo = new StackLocalInfo (bytecode.getMaxLocals(), minfo.isStatic(), minfo.getType(), modifiedQueue); firstInfo.instr = (Instruction) bytecode.getInstructions().get(0); firstInfo.instr.setTmpInfo(firstInfo); - modifiedQueue.add(firstInfo); - while (!modifiedQueue.isEmpty()) { - Iterator iter = modifiedQueue.iterator(); - StackLocalInfo info = (StackLocalInfo) iter.next(); - iter.remove(); + firstInfo.enqueue(); + while (modifiedQueue.first != null) { + StackLocalInfo info = modifiedQueue.first; + modifiedQueue.first = info.nextOnQueue; + info.nextOnQueue = null; handleOpcode(info, methodIdent); } diff --git a/jode/jode/obfuscator/LocalOptimizer.java.in b/jode/jode/obfuscator/LocalOptimizer.java.in index 3d7bddc..a1b7063 100644 --- a/jode/jode/obfuscator/LocalOptimizer.java.in +++ b/jode/jode/obfuscator/LocalOptimizer.java.in @@ -135,11 +135,43 @@ public class LocalOptimizer implements Opcodes, CodeTransformer { } } + private static class TodoQueue { + public final InstrInfo LAST = new InstrInfo(); + InstrInfo first = LAST; + + public void add(InstrInfo info) { + if (info.nextTodo == null) { + /* only enqueue if not already on queue */ + info.nextTodo = first; + first = info; + } + } + + public boolean isEmpty() { + return first == LAST; + } + + public InstrInfo remove() { + if (first == LAST) + throw new NoSuchElementException(); + InstrInfo result = first; + first = result.nextTodo; + result.nextTodo = null; + return result; + } + } + /** * This class contains information for each instruction. */ - class InstrInfo { + static class InstrInfo { + /** + * The next changed InstrInfo, or null, if this instr info did + * not changed. + */ + InstrInfo nextTodo; + /** * The LocalInfo that this instruction manipulates, or null * if this is not an ret, iinc, load or store instruction. @@ -186,8 +218,8 @@ public class LocalOptimizer implements Opcodes, CodeTransformer { BytecodeInfo bc; + TodoQueue changedInfos; InstrInfo firstInfo; - Stack changedInfos; Hashtable instrInfos; boolean produceLVT; int maxlocals; @@ -236,7 +268,7 @@ public class LocalOptimizer implements Opcodes, CodeTransformer { if (preInfo.nextReads[i] == null) { preInfo.nextReads[i] = info.nextReads[i]; - changedInfos.push(preInfo); + changedInfos.add(preInfo); } else { preInfo.nextReads[i].local .combineInto(info.nextReads[i].local); @@ -328,7 +360,7 @@ public class LocalOptimizer implements Opcodes, CodeTransformer { /* Initialize the InstrInfos and LocalInfos */ - changedInfos = new Stack(); + changedInfos = new TodoQueue(); instrInfos = new Hashtable(); { InstrInfo info = firstInfo = new InstrInfo(); @@ -356,14 +388,14 @@ public class LocalOptimizer implements Opcodes, CodeTransformer { case opc_iinc: /* this is a load instruction */ info.nextReads[instr.getLocalSlot()] = info; - changedInfos.push(info); + changedInfos.add(info); break; case opc_ret: /* this is a ret instruction */ info.usedBySub = new BitSet(); info.nextReads[instr.getLocalSlot()] = info; - changedInfos.push(info); + changedInfos.add(info); break; case opc_lstore: case opc_dstore: @@ -380,7 +412,7 @@ public class LocalOptimizer implements Opcodes, CodeTransformer { /* find out which locals are the same. */ while (!changedInfos.isEmpty()) { - InstrInfo info = (InstrInfo) changedInfos.pop(); + InstrInfo info = changedInfos.remove(); Instruction instr = info.instr; /* Mark the local as used in all ret instructions */ @@ -393,7 +425,7 @@ public class LocalOptimizer implements Opcodes, CodeTransformer { && !retInfo.usedBySub.get(slot)) { retInfo.usedBySub.set(slot); if (retInfo.jsrTargetInfo != null) - changedInfos.push(retInfo.jsrTargetInfo); + changedInfos.add(retInfo.jsrTargetInfo); } } } diff --git a/jode/jode/obfuscator/PackageIdentifier.java.in b/jode/jode/obfuscator/PackageIdentifier.java.in index 78c1f71..3381779 100644 --- a/jode/jode/obfuscator/PackageIdentifier.java.in +++ b/jode/jode/obfuscator/PackageIdentifier.java.in @@ -37,16 +37,18 @@ public class PackageIdentifier extends Identifier { ClassBundle bundle; PackageIdentifier parent; String name; + String fullName; boolean loadOnDemand; Map loadedClasses; public PackageIdentifier(ClassBundle bundle, PackageIdentifier parent, - String name) { + String fullName, String name) { super(name); this.bundle = bundle; this.parent = parent; + this.fullName = fullName; this.name = name; this.loadedClasses = new HashMap(); } @@ -64,9 +66,8 @@ public class PackageIdentifier extends Identifier { return; loadOnDemand = true; if ((Main.stripping & Main.STRIP_UNREACH) == 0) { - String fullname = getFullName(); - if (fullname.length() > 0) - fullname += "."; + String fullNamePrefix = + (fullName.length() > 0) ? fullName + "." : ""; // Load all classes and packages now, so they don't get stripped Enumeration enum = @@ -75,21 +76,22 @@ public class PackageIdentifier extends Identifier { String subclazz = ((String)enum.nextElement()).intern(); if (loadedClasses.containsKey(subclazz)) continue; - String subFull = fullname + subclazz; + String subFull = (fullNamePrefix + subclazz).intern(); if (ClassInfo.isPackage(subFull)) { PackageIdentifier ident = new PackageIdentifier - (bundle, this, subclazz); + (bundle, this, subFull, subclazz); loadedClasses.put(subclazz, ident); ident.setLoadOnDemand(); } else { ClassIdentifier ident = new ClassIdentifier - (this, subclazz, ClassInfo.forName(subFull)); + (this, subFull, subclazz, ClassInfo.forName(subFull)); if (GlobalOptions.verboseLevel > 1) GlobalOptions.err.println("preloading Class " + subFull); loadedClasses.put(subclazz, ident); + bundle.addClassIdentifier(ident); ((ClassIdentifier) ident).initClass(); } } @@ -121,24 +123,24 @@ public class PackageIdentifier extends Identifier { if (index == -1) { Identifier ident = (Identifier) loadedClasses.get(name); if (ident == null) { - String fullname = getFullName(); - fullname = (fullname.length() > 0) - ? fullname + "."+ name - : name; - if (ClassInfo.isPackage(fullname)) { + String subFull = + (fullName.length() > 0) ? fullName + "."+ name : name; + subFull = subFull.intern(); + if (ClassInfo.isPackage(subFull)) { PackageIdentifier pack - = new PackageIdentifier(bundle, this, name); + = new PackageIdentifier(bundle, this, subFull, name); loadedClasses.put(name, pack); pack.setLoadOnDemand(); ident = pack; - } else if (!ClassInfo.exists(fullname)) { + } else if (!ClassInfo.exists(subFull)) { GlobalOptions.err.println("Warning: Can't find class " - + fullname); + + subFull); Thread.dumpStack(); } else { - ident = new ClassIdentifier(this, name, - ClassInfo.forName(fullname)); + ident = new ClassIdentifier(this, subFull, name, + ClassInfo.forName(subFull)); loadedClasses.put(name, ident); + bundle.addClassIdentifier(ident); ((ClassIdentifier) ident).initClass(); } } @@ -148,12 +150,12 @@ public class PackageIdentifier extends Identifier { PackageIdentifier pack = (PackageIdentifier) loadedClasses.get(subpack); if (pack == null) { - String fullname = getFullName(); - fullname = (fullname.length() > 0) - ? fullname + "."+ subpack : subpack; - if (ClassInfo.isPackage(fullname)) { + String subFull = (fullName.length() > 0) + ? fullName + "."+ subpack : subpack; + subFull = subFull.intern(); + if (ClassInfo.isPackage(subFull)) { pack = new PackageIdentifier(bundle, this, - subpack); + subFull, subpack); loadedClasses.put(subpack, pack); if (loadOnDemand) pack.setLoadOnDemand(); @@ -173,28 +175,28 @@ public class PackageIdentifier extends Identifier { Identifier ident = (Identifier) loadedClasses.get(component); if (ident == null) { component = component.intern(); - String fullname = getFullName(); - fullname = (fullname.length() > 0) - ? fullname + "." + component - : component; - if (ClassInfo.isPackage(fullname)) { + String subFull = (fullName.length() > 0) + ? fullName + "."+ component : component; + subFull = subFull.intern(); + if (ClassInfo.isPackage(subFull)) { ident = new PackageIdentifier(bundle, this, - component); + subFull, component); loadedClasses.put(component, ident); if (loadOnDemand) ((PackageIdentifier) ident).setLoadOnDemand(); - } else if (ClassInfo.exists(fullname)) { + } else if (ClassInfo.exists(subFull)) { if (GlobalOptions.verboseLevel > 1) - GlobalOptions.err.println("loading Class " +fullname); - ident = new ClassIdentifier(this, component, - ClassInfo.forName(fullname)); + GlobalOptions.err.println("loading Class " +subFull); + ident = new ClassIdentifier(this, subFull, component, + ClassInfo.forName(subFull)); if (loadOnDemand || matcher.matches(ident)) { loadedClasses.put(component, ident); + bundle.addClassIdentifier(ident); ((ClassIdentifier) ident).initClass(); } } else { GlobalOptions.err.println - ("Warning: Can't find class/package " + fullname); + ("Warning: Can't find class/package " + subFull); } } if (ident instanceof PackageIdentifier) { @@ -209,9 +211,8 @@ public class PackageIdentifier extends Identifier { ((PackageIdentifier) ident).loadMatchingClasses(matcher); } } else { - String fullname = getFullName(); - if (fullname.length() > 0) - fullname += "."; + String fullNamePrefix = + (fullName.length() > 0) ? fullName + "." : ""; /* Load all matching classes and packages */ Enumeration enum = ClassInfo.getClassesAndPackages(getFullName()); @@ -219,7 +220,7 @@ public class PackageIdentifier extends Identifier { String subclazz = ((String)enum.nextElement()).intern(); if (loadedClasses.containsKey(subclazz)) continue; - String subFull = fullname + subclazz; + String subFull = (fullNamePrefix + subclazz).intern(); if (matcher.matchesSub(this, subclazz)) { if (ClassInfo.isPackage(subFull)) { @@ -227,19 +228,21 @@ public class PackageIdentifier extends Identifier { GlobalOptions.err.println("loading Package " + subFull); PackageIdentifier ident = new PackageIdentifier - (bundle, this, subclazz); + (bundle, this, subFull, subclazz); loadedClasses.put(subclazz, ident); if (loadOnDemand || matcher.matches(ident)) ident.setLoadOnDemand(); } else { ClassIdentifier ident = new ClassIdentifier - (this, subclazz, ClassInfo.forName(subFull)); + (this, subFull, subclazz, + ClassInfo.forName(subFull)); if (loadOnDemand || matcher.matches(ident)) { if (GlobalOptions.verboseLevel > 1) GlobalOptions.err.println("loading Class " + subFull); loadedClasses.put(subclazz, ident); + bundle.addClassIdentifier(ident); ((ClassIdentifier) ident).initClass(); } } @@ -265,111 +268,12 @@ public class PackageIdentifier extends Identifier { loadMatchingClasses(preserveRule); super.applyPreserveRule(preserveRule); } -// public void preserveMatchingIdentifier(IdentifierMatcher matcher) { -// String component = matcher.getNextComponent(getFullName()); -// if (component != null) { -// String fullname = getFullName(); -// fullname = (fullname.length() > 0) -// ? fullname + "."+ component : component; -// Identifier ident = (Identifier) loadedClasses.get(component); -// if (ident == null) { -// if (!loadOnDemand) { -// GlobalOptions.err.println -// ("Warning: Didn't load package/class "+ fullname); -// return; -// } -// if (ClassInfo.isPackage(fullname)) { -// ident = new PackageIdentifier(bundle, this, -// component, loadOnDemand); -// loadedClasses.put(component, ident); -// } else if (ClassInfo.exists(fullname)) { -// ident = new ClassIdentifier(this, component, -// ClassInfo.forName(fullname)); -// loadedClasses.put(component, ident); -// ((ClassIdentifier) ident).initClass(); -// if (bundle.preserveRule != null) -// ident.applyPreserveRule(bundle.preserveRule); -// } else { -// GlobalOptions.err.println("Warning: Can't find class " -// + fullname); -// return; -// } -// } -// if (matcher.matches(fullname)) { -// if (GlobalOptions.verboseLevel > 1) -// GlobalOptions.err.println("preserving "+ident); -// ident.setPreserved(); -// } -// if (matcher.startsWith(fullname+".")) { -// if (ident instanceof PackageIdentifier) -// ((PackageIdentifier) ident) -// .preserveMatchingIdentifier(matcher); -// else -// ((ClassIdentifier) ident) -// .preserveMatchingIdentifier(matcher); -// } -// } else { -// String fullname = getFullName(); -// if (fullname.length() > 0) -// fullname += "."; -// if (loadOnDemand) { -// /* Load all matching classes and packages */ -// Enumeration enum = -// ClassInfo.getClassesAndPackages(getFullName()); -// while (enum.hasMoreElements()) { -// String subclazz = (String)enum.nextElement(); -// if (loadedClasses.containsKey(subclazz)) -// continue; -// String subFull = fullname + subclazz; - -// if (matcher.startsWith(subFull)) { -// if (ClassInfo.isPackage(subFull)) { -// System.err.println("is package: "+subFull); -// Identifier ident = new PackageIdentifier -// (bundle, this, subclazz, true); -// loadedClasses.put(subclazz, ident); -// } else { -// ClassIdentifier ident = new ClassIdentifier -// (this, subclazz, ClassInfo.forName(subFull)); -// loadedClasses.put(subclazz, ident); -// ((ClassIdentifier) ident).initClass(); -// if (bundle.preserveRule != null) -// ident.applyPreserveRule(bundle.preserveRule); -// } -// } -// } -// } -// for (Iterator i = loadedClasses.values().iterator(); -// i.hasNext(); ) { -// Identifier ident = (Identifier) i.next(); -// if (matcher.matches(ident.getFullName())) { -// if (GlobalOptions.verboseLevel > 1) -// GlobalOptions.err.println("Preserving "+ident); -// ident.setPreserved(); -// } -// if (matcher.startsWith(ident.getFullName()+".")) { -// if (ident instanceof PackageIdentifier) -// ((PackageIdentifier) ident) -// .preserveMatchingIdentifier(matcher); -// else -// ((ClassIdentifier) ident) -// .preserveMatchingIdentifier(matcher); -// } -// } -// } -// } /** * @return the full qualified name. */ public String getFullName() { - if (parent != null) { - if (parent.getFullName().length() > 0) - return parent.getFullName() + "." + getName(); - else - return getName(); - } else - return ""; + return fullName; } /** @@ -498,8 +402,8 @@ public class PackageIdentifier extends Identifier { && !ident.isReachable()) { if (GlobalOptions.verboseLevel > 4) GlobalOptions.err.println("Class/Package " - + ident.getFullName() - + " is not reachable"); + + ident.getFullName() + + " is not reachable"); continue; } if (ident instanceof PackageIdentifier)