Index: main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java =================================================================== --- main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java (revision 643198) +++ main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java (working copy) @@ -58,9 +58,16 @@ protected int domain = ClassConstantPool.DOMAIN_UNDEFINED; private static int creationOrderCount = 100; + + protected String cachedConstantPoolComparisonString = null; + public String comparisonString() { - return toString(); + if(cachedConstantPoolComparisonString == null) { + cachedConstantPoolComparisonString = toString(); + } + return cachedConstantPoolComparisonString; } + public int creationOrder = -1; ConstantPoolEntry(byte tag) { this.tag = tag; Index: main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java =================================================================== --- main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java (revision 643198) +++ main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java (working copy) @@ -17,12 +17,13 @@ package org.apache.harmony.pack200.bytecode; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; -import org.apache.harmony.pack200.Pack200Exception; import org.apache.harmony.pack200.Segment; -import org.apache.harmony.pack200.SegmentUtils; public class ClassConstantPool { @@ -45,13 +46,17 @@ // protected SortedSet sortedEntries = new TreeSet(new PoolComparator()); protected ClassPoolSet classPoolSet = new ClassPoolSet(); + protected HashSet entriesContainsSet = new HashSet(); + protected HashSet othersContainsSet = new HashSet(); + + protected Map indexCache = null; + public String toString() { return entries.toString(); } - private final List others = new ArrayList(); + private List others = new ArrayList(500); + private List entries = new ArrayList(500); - private List entries = new ArrayList(); - private boolean resolved; public ClassFileEntry add(ClassFileEntry entry) { @@ -74,14 +79,20 @@ // } // } if (entry instanceof ConstantPoolEntry) { - if (!entries.contains(entry)) { +// if (!entries.contains(entry)) { + if (!entriesContainsSet.contains(entry)) { + entriesContainsSet.add(entry); entries.add(entry); if (entry instanceof CPLong ||entry instanceof CPDouble) entries.add(entry); //these get 2 slots because of their size } } else { - if (!others.contains(entry)) +// if (!others.contains(entry)) + if (!othersContainsSet.contains(entry)) { + othersContainsSet.add(entry); others.add(entry); + } + } ClassFileEntry[] nestedEntries = entry.getNestedClassFileEntries(); for (int i = 0; i < nestedEntries.length; i++) { @@ -90,7 +101,21 @@ return entry; } - public int indexOf(ClassFileEntry entry) { + protected void initializeIndexCache() { + indexCache = new HashMap(); + for(int index=0; index < entries.size(); index++) { + ClassFileEntry indexEntry = (ClassFileEntry)entries.get(index); + if(indexCache.containsKey(indexEntry)) { + // key is already in there - do nothing + // This will happen if a long or double + // is the entry - they take up 2 slots. + } else { + indexCache.put(indexEntry, new Integer(index)); + } + } + } + + public int indexOfOld(ClassFileEntry entry) { if (!resolved) throw new IllegalStateException("Constant pool is not yet resolved; this does not make any sense"); int entryIndex = entries.indexOf(entry); @@ -101,6 +126,34 @@ return -1; } + public int indexOf(ClassFileEntry entry) { + if (!resolved) + throw new IllegalStateException("Constant pool is not yet resolved; this does not make any sense"); + if(null == indexCache) { + initializeIndexCache(); + } + Integer entryIndex = ((Integer)indexCache.get(entry)); + // If the entry isn't found, answer -1. Otherwise answer the entry. + if(entryIndex != null) { + return entryIndex.intValue() + 1; + } + return -1; + } + +// public int indexOf(ClassFileEntry entry) { +// int oldEntry = indexOfOld(entry); +// int newEntry = indexOfNew(entry); +// if(oldEntry != newEntry) { +// throw new Error("Mismatch"); +// ClassFileEntry oldEntryValue = (ClassFileEntry)entries.get(oldEntry); +// ClassFileEntry newEntryValue = (ClassFileEntry)entries.get(newEntry); +// System.out.println("Entry index mismatch "); +// System.out.println(" old style value " + oldEntry + "=" + oldEntryValue); +// System.out.println(" new style value " + newEntry + "=" + newEntryValue); +// } +// return newEntry; +// } + public int size() { return entries.size(); } @@ -117,7 +170,7 @@ while(it.hasNext()) { classPoolSet.add(it.next()); } - entries = new ArrayList(); + entries = new ArrayList(entries.size()); Iterator sortedIterator = classPoolSet.iterator(); while(sortedIterator.hasNext()) { ConstantPoolEntry entry = (ConstantPoolEntry)sortedIterator.next(); @@ -147,6 +200,10 @@ // final sort of the class pool. This fixes up // references, which are sorted by index in the // class pool. + + // Since we resorted, need to initialize index cache + initializeIndexCache(); + it = entries.iterator(); ClassPoolSet startOfPool = new ClassPoolSet(); ClassPoolSet finalSort = new ClassPoolSet(); @@ -158,7 +215,7 @@ finalSort.add(nextEntry); } } - entries = new ArrayList(); + entries = new ArrayList(entries.size()); Iterator itStart = startOfPool.iterator(); while(itStart.hasNext()) { ClassFileEntry entry = (ClassFileEntry) itStart.next(); @@ -174,6 +231,9 @@ entries.add(entry); //these get 2 slots because of their size } + // Since we resorted, need to initialize index cache + initializeIndexCache(); + // Now that the indices have been re-sorted, need // to re-resolve to update references. This should // not add any new entries this time through. Index: main/java/org/apache/harmony/pack200/bytecode/CPRef.java =================================================================== --- main/java/org/apache/harmony/pack200/bytecode/CPRef.java (revision 643198) +++ main/java/org/apache/harmony/pack200/bytecode/CPRef.java (working copy) @@ -41,6 +41,9 @@ return false; if (getClass() != obj.getClass()) return false; + if (this.hashCode() != obj.hashCode()) { + return false; + } final CPRef other = (CPRef) obj; if (className == null) { if (other.className != null) Index: main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java =================================================================== --- main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java (revision 643198) +++ main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java (working copy) @@ -31,6 +31,8 @@ transient int nameIndex; + protected String cachedComparisonString = null; + public CPNameAndType(CPUTF8 name, CPUTF8 descriptor, int domain) { super(ConstantPoolEntry.CP_NameAndType); this.name = name; @@ -118,6 +120,9 @@ // going on. How to sort these things so that even if // they're in some oddball codepage they'll still end // up sorted correctly? + if(cachedComparisonString != null) { + return cachedComparisonString; + } String descriptorString = descriptor.underlyingString(); StringBuffer comparisonBuffer = new StringBuffer(); if((descriptorString.indexOf("(")) == -1) { @@ -141,6 +146,7 @@ } } comparisonBuffer.append(name.underlyingString()); - return comparisonBuffer.toString(); + cachedComparisonString = comparisonBuffer.toString(); + return cachedComparisonString; } } \ No newline at end of file