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/08/27 10:41:24 UTC

svn commit: r689413 - in /harmony/enhanced/classlib/trunk/modules/pack200/src: main/java/org/apache/harmony/unpack200/ main/java/org/apache/harmony/unpack200/bytecode/ test/java/org/apache/harmony/unpack200/tests/ test/java/org/apache/harmony/unpack200...

Author: sjanuary
Date: Wed Aug 27 01:41:24 2008
New Revision: 689413

URL: http://svn.apache.org/viewvc?rev=689413&view=rev
Log:
Apply patch for HARMONY-5930 ([classlib][pack200][performance] IcBands.getRelevantIcTuples rewrite)

Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/ClassBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/CpBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcTuple.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/bytecode/ClassConstantPool.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ICTupleTest.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/bytecode/ConstantPoolTest.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/ClassBands.java?rev=689413&r1=689412&r2=689413&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/ClassBands.java Wed Aug 27 01:41:24 2008
@@ -685,7 +685,7 @@
                     }
 
                     IcTuple icTuple = new IcTuple(icTupleC, icTupleF,
-                            icTupleC2, icTupleN, icTupleCIndex, icTupleC2Index, icTupleNIndex);
+                            icTupleC2, icTupleN, icTupleCIndex, icTupleC2Index, icTupleNIndex, j);
                     icLocal[i][j] = icTuple;
                 }
                 innerClassIndex++;

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/CpBands.java?rev=689413&r1=689412&r2=689413&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/CpBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/CpBands.java Wed Aug 27 01:41:24 2008
@@ -86,8 +86,8 @@
     private Map mapClass;
     private Map mapDescriptor;
     private Map mapUTF8;
-    
-// TODO: Not used 
+
+// TODO: Not used
 //    private Map mapSignature;
 
     private int intOffset;

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcBands.java?rev=689413&r1=689412&r2=689413&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcBands.java Wed Aug 27 01:41:24 2008
@@ -19,14 +19,19 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.harmony.pack200.Codec;
 import org.apache.harmony.pack200.Pack200Exception;
 import org.apache.harmony.unpack200.bytecode.CPClass;
 import org.apache.harmony.unpack200.bytecode.ClassConstantPool;
+import org.apache.harmony.unpack200.bytecode.ConstantPoolEntry;
 
 /**
  * Inner Class Bands
@@ -39,6 +44,9 @@
 
     private final String[] cpClass;
 
+    private Map thisClassToTuple;
+    private Map outerClassToTuples;
+
     /**
      * @param segment
      */
@@ -101,12 +109,43 @@
                 nIndex = icNameInts[index] - 1;
                 index++;
             }
-            icAll[i] = new IcTuple(icTupleC, icTupleF, icTupleC2, icTupleN, cIndex, c2Index, nIndex);
+            icAll[i] = new IcTuple(icTupleC, icTupleF, icTupleC2, icTupleN, cIndex, c2Index, nIndex, i);
         }
     }
 
     public void unpack() throws IOException, Pack200Exception {
-
+    	IcTuple[] allTuples = getIcTuples();
+    	thisClassToTuple = new HashMap(allTuples.length);
+    	outerClassToTuples = new HashMap(allTuples.length);
+    	for(int index = 0; index < allTuples.length; index++) {
+
+    		IcTuple tuple = allTuples[index];
+
+    		// generate mapping thisClassString -> IcTuple
+    		//  presumably this relation is 1:1
+    		//
+    		Object result = thisClassToTuple.put(tuple.thisClassString(), tuple);
+    		if (result != null) {
+    			throw new Error("Collision detected in <thisClassString, IcTuple> mapping. " +
+    					"There are at least two inner clases with the same name.");
+    		}
+
+    		// generate mapping outerClassString -> IcTuple
+    		//  this relation is 1:M
+
+            // If it's not anon and the outer is not anon, it could be relevant
+    		if (!tuple.isAnonymous() && !tuple.outerIsAnonymous()) {
+
+    			// add tuple to corresponding bucket
+    			String key = tuple.outerClassString();
+    			List bucket = (List)outerClassToTuples.get(key);
+    			if (bucket == null) {
+    				bucket = new ArrayList();
+    				outerClassToTuples.put(key, bucket);
+    			}
+    			bucket.add(tuple);
+    		}
+    	}
     }
 
 
@@ -127,38 +166,32 @@
     public IcTuple[] getRelevantIcTuples(String className, ClassConstantPool cp) {
         Set relevantTuplesContains = new HashSet();
         List relevantTuples = new ArrayList();
-        IcTuple[] allTuples = getIcTuples();
-        int allTuplesSize = allTuples.length;
-        for (int index = 0; index < allTuplesSize; index++) {
-            if (allTuples[index].shouldAddToRelevantForClassName(className)) {
-                relevantTuplesContains.add(allTuples[index]);
-                relevantTuples.add(allTuples[index]);
-            }
-        }
 
-        List classPoolClasses = cp.allClasses();
-        boolean changed = true;
+        List relevantCandidates = (List) outerClassToTuples.get(className);
+		if (relevantCandidates != null) {
+			for (int index = 0; index < relevantCandidates.size(); index++) {
+				IcTuple tuple = (IcTuple) relevantCandidates.get(index);
+				relevantTuplesContains.add(tuple);
+				relevantTuples.add(tuple);
+			}
+		}
+
+        List entries = cp.entries();
+
         // For every class constant in both ic_this_class and cp,
         // add it to ic_relevant. Repeat until no more
         // changes to ic_relevant.
 
-        while (changed) {
-            changed = false;
-            for (int allTupleIndex = 0; allTupleIndex < allTuplesSize; allTupleIndex++) {
-                for(int cpcIndex = 0; cpcIndex < classPoolClasses.size(); cpcIndex++) {
-                    CPClass classInPool = (CPClass) classPoolClasses.get(cpcIndex);
-                    String poolClassName = classInPool.name;
-                    if (poolClassName.equals(allTuples[allTupleIndex]
-                            .thisClassString())) {
-                        // If the tuple isn't already in there, then add it
-                        if (relevantTuplesContains.add(allTuples[allTupleIndex])) {
-                            relevantTuples.add(allTuples[allTupleIndex]);
-                            changed = true;
-                        }
-                    }
-                }
-            }
-        }
+		for (int eIndex = 0; eIndex < entries.size(); eIndex++) {
+			ConstantPoolEntry entry = (ConstantPoolEntry) entries.get(eIndex);
+			if (entry instanceof CPClass) {
+				CPClass clazz = (CPClass) entry;
+				IcTuple relevant = (IcTuple) thisClassToTuple.get(clazz.name);
+				if (relevant != null && relevantTuplesContains.add(relevant)) {
+					relevantTuples.add(relevant);
+				}
+			}
+		}
 
         // Not part of spec: fix up by adding to relevantTuples the parents
         // of inner classes which are themselves inner classes.
@@ -166,49 +199,51 @@
         // added
         // as well.
 
-        boolean changedFixup = true;
-        ArrayList tuplesToAdd = new ArrayList();
-        while (changedFixup) {
-            changedFixup = false;
-            for (int index = 0; index < relevantTuples.size(); index++) {
-                IcTuple aRelevantTuple = (IcTuple) relevantTuples.get(index);
-                for (int allTupleIndex = 0; allTupleIndex < allTuplesSize; allTupleIndex++) {
-                    if (aRelevantTuple.outerClassString().equals(
-                            allTuples[allTupleIndex].thisClassString())) {
-                        if (!aRelevantTuple.outerIsAnonymous()) {
-                            tuplesToAdd.add(allTuples[allTupleIndex]);
-                        }
-                    }
-                }
-            }
-            if (tuplesToAdd.size() > 0) {
-                for(int index = 0; index < tuplesToAdd.size(); index++) {
-                    IcTuple tuple = (IcTuple) tuplesToAdd.get(index);
-                    if (relevantTuplesContains.add(tuple)) {
-                        changedFixup = true;
-                        relevantTuples.add(tuple);
-                    }
-                }
-                tuplesToAdd = new ArrayList();
-            }
-        }
+		ArrayList tuplesToScan = new ArrayList(relevantTuples);
+		ArrayList tuplesToAdd = new ArrayList();
+
+		while (tuplesToScan.size() > 0) {
+
+			tuplesToAdd.clear();
+			for (int index = 0; index < tuplesToScan.size(); index++) {
+				IcTuple aRelevantTuple = (IcTuple) tuplesToScan.get(index);
+				IcTuple relevant = (IcTuple) thisClassToTuple
+						.get(aRelevantTuple.outerClassString());
+				if (relevant != null && !aRelevantTuple.outerIsAnonymous()) {
+					tuplesToAdd.add(relevant);
+				}
+			}
+
+			tuplesToScan.clear();
+			for (int index = 0; index < tuplesToAdd.size(); index++) {
+				IcTuple tuple = (IcTuple) tuplesToAdd.get(index);
+				if (relevantTuplesContains.add(tuple)) {
+					relevantTuples.add(tuple);
+					tuplesToScan.add(tuple);
+				}
+			}
+
+		}
+
         // End not part of the spec. Ugh.
 
         // Now order the result as a subsequence of ic_all
-        IcTuple[] orderedRelevantTuples = new IcTuple[relevantTuples.size()];
-        int orderedRelevantIndex = 0;
-        for (int index = 0; index < allTuplesSize; index++) {
-            if (relevantTuplesContains.contains(allTuples[index])) {
-                orderedRelevantTuples[orderedRelevantIndex] = allTuples[index];
-                orderedRelevantIndex++;
-            }
-        }
-        if (orderedRelevantIndex != orderedRelevantTuples.length) {
-            // This should never happen. If it does, we have a
-            // logic error in the ordering code.
-            throw new Error("Missing a tuple when ordering them");
-        }
-        return orderedRelevantTuples;
+		Collections.sort(relevantTuples, new Comparator() {
+
+			public int compare(Object arg0, Object arg1) {
+				Integer index1 = new Integer(((IcTuple)arg0).getTupleIndex());
+				Integer index2 = new Integer(((IcTuple)arg1).getTupleIndex());
+				return index1.compareTo(index2);
+			}
+
+		});
+
+		IcTuple[] relevantTuplesArray = new IcTuple[relevantTuples.size()];
+		for(int i = 0; i < relevantTuplesArray.length; i++) {
+			relevantTuplesArray[i] = (IcTuple)relevantTuples.get(i);
+		}
+
+        return relevantTuplesArray;
     }
 
 }
\ No newline at end of file

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcTuple.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcTuple.java?rev=689413&r1=689412&r2=689413&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcTuple.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/IcTuple.java Wed Aug 27 01:41:24 2008
@@ -31,6 +31,7 @@
     private final int cIndex;
     private final int c2Index;
     private final int nIndex;
+    private final int tIndex;
 
     /**
      *
@@ -42,7 +43,7 @@
      * @param c2Index the index of C2 in cpClass, or -1 if C2 is null
      * @param nIndex the index of N in cpUTF8, or -1 if N is null
      */
-    public IcTuple(String C, int F, String C2, String N, int cIndex, int c2Index, int nIndex) {
+    public IcTuple(String C, int F, String C2, String N, int cIndex, int c2Index, int nIndex, int tIndex) {
         this.C = C;
         this.F = F;
         this.C2 = C2;
@@ -50,6 +51,7 @@
         this.cIndex = cIndex;
         this.c2Index = c2Index;
         this.nIndex = nIndex;
+        this.tIndex = tIndex;
         if (null == N) {
             predictSimple = true;
         }
@@ -60,7 +62,7 @@
     }
 
     public IcTuple(String C, int F, int cIndex) {
-        this(C, F, null, null, cIndex, -1, -1);
+        this(C, F, null, null, cIndex, -1, -1, -1);
     }
 
     public static final int NESTED_CLASS_FLAG = 0x00010000;
@@ -176,22 +178,6 @@
         return false;
     }
 
-    public boolean shouldAddToRelevantForClassName(String className) {
-        // If the outerClassString of the tuple doesn't match the
-        // class name of the class we're looking through, don't
-        // consider it relevant.
-        if (!outerClassString().equals(className)) {
-            return false;
-        }
-        // If it's not anon and the outer is not anon, it's relevant
-        if (!isAnonymous() && !outerIsAnonymous()) {
-            return true;
-        }
-
-        // Otherwise it's not relevant.
-        return false;
-    }
-
     private void initializeClassStrings() {
         if (initialized) {
             return;
@@ -344,6 +330,10 @@
         return N;
     }
 
+    public int getTupleIndex() {
+    	return tIndex;
+    }
+
     public String realOuterClassString() {
         int firstDollarPosition = cachedOuterClassString.indexOf('$');
         if (firstDollarPosition <= 0) {

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=689413&r1=689412&r2=689413&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 Wed Aug 27 01:41:24 2008
@@ -17,6 +17,7 @@
 package org.apache.harmony.unpack200.bytecode;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -202,24 +203,8 @@
         entries.addAll(cpClassesNotInCpAll);
     }
 
-    /**
-     * Answer the collection of CPClasses currently held by the ClassPoolSet.
-     * This is used to calculate relevant classes when generating the set of
-     * relevant inner classes (ic_relevant())
-     *
-     * @return ArrayList collection of all classes.
-     *
-     * NOTE: when this list is answered, the classes may not yet be resolved.
-     */
-    public List allClasses() {
-        List classesList = new ArrayList(entries.size());
-        for(int i = 0; i < entries.size(); i++) {
-            ConstantPoolEntry entry = (ConstantPoolEntry) entries.get(i);
-            if (entry instanceof CPClass) {
-                classesList.add(entry);
-            }
-        }
-        return classesList;
+    public List entries() {
+    	return Collections.unmodifiableList(entries);
     }
 
     protected void sortClassPool() {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ICTupleTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ICTupleTest.java?rev=689413&r1=689412&r2=689413&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ICTupleTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ICTupleTest.java Wed Aug 27 01:41:24 2008
@@ -25,39 +25,39 @@
     public void testPredictedClassTupleParsing() {
         IcTuple tuple = new IcTuple(
                 "orw/SimpleHelloWorld$SimpleHelloWorldInner", 0, null, null,
-                -1, -1, -1);
+                -1, -1, -1, -1);
         assertEquals("SimpleHelloWorldInner", tuple.simpleClassName());
         assertEquals("orw/SimpleHelloWorld", tuple.outerClassString());
 
         tuple = new IcTuple("java/util/AbstractList$2$Local", 0, null, null,
-                -1, -1, -1);
+                -1, -1, -1, -1);
         assertEquals("Local", tuple.simpleClassName());
         assertEquals("java/util/AbstractList$2", tuple.outerClassString());
 
         tuple = new IcTuple("java/util/AbstractList#2#Local", 0, null, null,
-                -1, -1, -1);
+                -1, -1, -1, -1);
         assertEquals("Local", tuple.simpleClassName());
         assertEquals("java/util/AbstractList$2", tuple.outerClassString());
 
         tuple = new IcTuple("java/util/AbstractList$1", 0, null, null, -1, -1,
-                -1);
+                -1, -1);
         assertEquals("1", tuple.simpleClassName());
         assertEquals("java/util/AbstractList", tuple.outerClassString());
     }
 
     public void testExplicitClassTupleParsing() {
         IcTuple tuple = new IcTuple("Foo$$2$Local", IcTuple.NESTED_CLASS_FLAG,
-                null, "$2$Local", -1, -1, -1);
+                null, "$2$Local", -1, -1, -1, -1);
         assertEquals("$2$Local", tuple.simpleClassName());
         assertEquals("Foo$$2", tuple.outerClassString());
 
         tuple = new IcTuple("Red$Herring", IcTuple.NESTED_CLASS_FLAG,
-                "Red$Herring", null, -1, -1, -1);
+                "Red$Herring", null, -1, -1, -1, -1);
         assertEquals("Herring", tuple.simpleClassName());
         assertEquals("Red$Herring", tuple.outerClassString());
 
         tuple = new IcTuple("X$1$Q", IcTuple.NESTED_CLASS_FLAG, "X$1", "Q", -1,
-                -1, -1);
+                -1, -1, -1);
         assertEquals("Q", tuple.simpleClassName());
         assertEquals("X$1", tuple.outerClassString());
     }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/bytecode/ConstantPoolTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/bytecode/ConstantPoolTest.java?rev=689413&r1=689412&r2=689413&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/bytecode/ConstantPoolTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/bytecode/ConstantPoolTest.java Wed Aug 27 01:41:24 2008
@@ -61,9 +61,9 @@
         assertTrue(pool.indexOf(u1) > 0);
     }
 
-    public void testAllClasses() {
+    public void testEntries() {
         pool.add(new CPClass(new CPUTF8("RandomClass", 1), 10));
         pool.add(new CPClass(new CPUTF8("RandomClass2", 2), 20));
-        assertEquals(2, pool.allClasses().size());
+        assertEquals(2, pool.entries().size());
     }
 }