You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sj...@apache.org on 2008/07/17 14:32:52 UTC

svn commit: r677568 - /harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java

Author: sjanuary
Date: Thu Jul 17 05:32:52 2008
New Revision: 677568

URL: http://svn.apache.org/viewvc?rev=677568&view=rev
Log:
Apply patch for HARMONY-5906 ([classlib][pack200][performance] ClassConstantPool optimizations)

Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java?rev=677568&r1=677567&r2=677568&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java Thu Jul 17 05:32:52 2008
@@ -50,64 +50,71 @@
 
     public ClassFileEntry add(ClassFileEntry entry) {
         if (entry instanceof ConstantPoolEntry) {
-            if (!entriesContainsSet.contains(entry)) {
-                entriesContainsSet.add(entry);
+            if (entriesContainsSet.add(entry)) {
                 entries.add(entry);
             }
         } else {
-            if (!othersContainsSet.contains(entry)) {
-                othersContainsSet.add(entry);
+            if (othersContainsSet.add(entry)) {
                 others.add(entry);
             }
         }
+
         return entry;
     }
 
     public void addNestedEntries() {
         boolean added = true;
-        while (added) {
+
+        // initial assignment
+        ArrayList parents = new ArrayList();
+        ArrayList children = new ArrayList();
+
+        // adding old entries
+        parents.addAll(entries);
+        parents.addAll(others);
+
+        // while there any parents to traverse and at least one change in target
+        // storage was made
+        while(added || parents.size() > 0) {
+
+            children.clear();
+
             int entriesOriginalSize = entries.size();
             int othersOriginalSize = others.size();
-            addNested(entries);
-            addNested(others);
-            added = !(entries.size() == entriesOriginalSize && others.size() == othersOriginalSize);
-        }
-    }
 
-    private void addNested(List classFileEntries) {
-        for (int classFileIndex = 0; classFileIndex < classFileEntries.size(); classFileIndex++) {
-            ClassFileEntry entry = (ClassFileEntry) classFileEntries.get(classFileIndex);
-            ClassFileEntry[] nestedEntries = entry.getNestedClassFileEntries();
-
-            // Add all nestedEntries to the newEntries list
-            for(int nestedEntriesIndex = 0; nestedEntriesIndex < nestedEntries.length; nestedEntriesIndex++) {
-                add(nestedEntries[nestedEntriesIndex]);
-            }
-
-            // 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]);
+            // get the parents' children and add them to buffer
+            // concurrently add parents to target storage
+            Iterator i = parents.iterator();
+            while(i.hasNext()) {
+                ClassFileEntry entry = (ClassFileEntry)i.next();
+
+                // traverse children
+                ClassFileEntry[] entryChildren = entry.getNestedClassFileEntries();
+                for(int c = 0; c < entryChildren.length; c++) {
+                    children.add(entryChildren[c]);
+                }
+
+                boolean isAtStart = (entry instanceof ByteCode)
+                        && ((ByteCode) entry).nestedMustStartClassPool();
+
+                if (isAtStart) {
+                    for (int c = 0; c < entryChildren.length; c++) {
+                        mustStartClassPool.add(entryChildren[c]);
                     }
                 }
-            }
-        }
-    }
 
-    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));
+                // add parent
+                add(entry);
             }
+
+            added = !(entries.size() == entriesOriginalSize && others.size() == othersOriginalSize);
+
+            // parents are not needed anymore
+            // children now become parents
+            parents.clear();
+            parents.addAll(children);
+
+
         }
     }
 
@@ -116,7 +123,7 @@
             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.
@@ -139,9 +146,11 @@
 
     public void resolve(Segment segment) {
         initialSort();
-        Iterator it;
+        sortClassPool();
+
         resolved = true;
-        it = entries.iterator();
+
+        Iterator it = entries.iterator();
         while (it.hasNext()) {
             ClassFileEntry entry = (ClassFileEntry) it.next();
             entry.resolve(this);
@@ -152,7 +161,7 @@
             entry.resolve(this);
         }
 
-        sortClassPool(segment);
+
     }
 
     private void initialSort() {
@@ -216,15 +225,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 +242,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) {