Index: src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java =================================================================== --- src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java (revision 675615) +++ src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java (working copy) @@ -49,17 +49,24 @@ private boolean resolved; public ClassFileEntry add(ClassFileEntry entry) { - if (entry instanceof ConstantPoolEntry) { - if (!entriesContainsSet.contains(entry)) { - entriesContainsSet.add(entry); + return add(entry, false); + } + + public ClassFileEntry add(ClassFileEntry entry, boolean isAtStart) { + if (entry instanceof ConstantPoolEntry) { + if (entriesContainsSet.add(entry)) { entries.add(entry); } } else { - if (!othersContainsSet.contains(entry)) { - othersContainsSet.add(entry); + if (othersContainsSet.add(entry)) { others.add(entry); } } + + if (isAtStart) { + mustStartClassPool.add(entry); + } + return entry; } @@ -78,45 +85,26 @@ for (int classFileIndex = 0; classFileIndex < classFileEntries.size(); classFileIndex++) { ClassFileEntry entry = (ClassFileEntry) classFileEntries.get(classFileIndex); ClassFileEntry[] nestedEntries = entry.getNestedClassFileEntries(); - + + // If the entry is a bytecode that needs to start the + // class pool, add all the nestedEntries to the + // mustStartClassPool as well. + boolean isAtStart = (entry instanceof ByteCode) && ((ByteCode)entry).nestedMustStartClassPool(); + // Add all nestedEntries to the newEntries list for(int nestedEntriesIndex = 0; nestedEntriesIndex < nestedEntries.length; nestedEntriesIndex++) { - add(nestedEntries[nestedEntriesIndex]); + add(nestedEntries[nestedEntriesIndex], isAtStart); } - // If the entry is a bytecode that needs to start the - // class pool, add all the nestedEntries to the - // mustStartClassPool as well. - if(entry instanceof ByteCode) { - if(((ByteCode)entry).nestedMustStartClassPool()) { - for(int nestedEntriesIndex = 0; nestedEntriesIndex < nestedEntries.length; nestedEntriesIndex++) { - mustStartClassPool.add(nestedEntries[nestedEntriesIndex]); - } - } - } } } - 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 indexOf(ClassFileEntry entry) { if (!resolved) throw new IllegalStateException( "Constant pool is not yet resolved; this does not make any sense"); if (null == indexCache) { - initializeIndexCache(); + throw new IllegalStateException("Index cache is not initialized!"); } Integer entryIndex = ((Integer) indexCache.get(entry)); // If the entry isn't found, answer -1. Otherwise answer the entry. @@ -138,10 +126,12 @@ } public void resolve(Segment segment) { - initialSort(); - Iterator it; + initialSort(); + sortClassPool(); + resolved = true; - it = entries.iterator(); + + Iterator it = entries.iterator(); while (it.hasNext()) { ClassFileEntry entry = (ClassFileEntry) it.next(); entry.resolve(this); @@ -152,7 +142,7 @@ entry.resolve(this); } - sortClassPool(segment); + } private void initialSort() { @@ -216,15 +206,12 @@ return classesList; } - protected void sortClassPool(Segment segment) { + protected void sortClassPool() { // Now that everything has been resolved, do one // final sort of the class pool. This fixes up // references to objects which need to be at the // start of the class pool - // Since we resorted, need to initialize index cache - initializeIndexCache(); - Iterator it = entries.iterator(); ArrayList startOfPool = new ArrayList(); ArrayList finalSort = new ArrayList(); @@ -236,39 +223,43 @@ finalSort.add(nextEntry); } } + + // copy over and rebuild the cache + // + indexCache = new HashMap(); + int index = 0; + entries.clear(); Iterator itStart = startOfPool.iterator(); while (itStart.hasNext()) { ClassFileEntry entry = (ClassFileEntry) itStart.next(); - entries.add(entry); - if (entry instanceof CPLong || entry instanceof CPDouble) + indexCache.put(entry, new Integer(index)); + + if (entry instanceof CPLong || entry instanceof CPDouble) { entries.add(entry); // these get 2 slots because of their size + entries.add(entry); + index += 2; + } else { + entries.add(entry); + index += 1; + } } + it = finalSort.iterator(); while (it.hasNext()) { ClassFileEntry entry = (ClassFileEntry) it.next(); - entries.add(entry); - if (entry instanceof CPLong || entry instanceof CPDouble) + indexCache.put(entry, new Integer(index)); + + if (entry instanceof CPLong || entry instanceof CPDouble) { entries.add(entry); // these get 2 slots because of their size + entries.add(entry); + index += 2; + } else { + entries.add(entry); + index += 1; + } } - - // Since we re-sorted, 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. - it = entries.iterator(); - while (it.hasNext()) { - ClassFileEntry entry = (ClassFileEntry) it.next(); - entry.resolve(this); - } - // Also need to re-resolve the others. - it = others.iterator(); - while (it.hasNext()) { - ClassFileEntry entry = (ClassFileEntry) it.next(); - entry.resolve(this); - } + } public ClassFileEntry addWithNestedEntries(ClassFileEntry entry) {