You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2008/01/14 18:26:23 UTC

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

Author: tellison
Date: Mon Jan 14 09:26:18 2008
New Revision: 611862

URL: http://svn.apache.org/viewvc?rev=611862&view=rev
Log:
Apply patch HARMONY-5382 ([classlib][pack200] Class constant pool sort order, instruction set fixes)

Added:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassPoolSet.java   (with props)
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NarrowClassRefForm.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassFileEntry.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ClassRefForm.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/bytecode/ConstantPoolTest.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java?rev=611862&r1=611861&r2=611862&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPNameAndType.java Mon Jan 14 09:26:18 2008
@@ -54,10 +54,9 @@
 		}
 		this.domain = ClassConstantPool.DOMAIN_NAMEANDTYPE;
 		this.name = new CPUTF8(nameString, ClassConstantPool.DOMAIN_NORMALASCIIZ);
-		if((nameString.equals("<init>")) || (nameString.equals("<clinit>")) || nativeDescriptor ) {
-		    // Signatures for init methods are stored with the init methods.
-		    // Not sure why. Similarly, native signatures are stored
-		    // there as well.
+		if( nativeDescriptor ) {
+		    // Native signatures are stored in DOMAIN_NORMALASCIIZ, not
+		    // DOMAIN_SIGNATUREASCIIZ for some reason.
 		    descriptorDomain = ClassConstantPool.DOMAIN_NORMALASCIIZ;
 		} else {
 		    descriptorDomain = ClassConstantPool.DOMAIN_SIGNATUREASCIIZ;
@@ -132,4 +131,43 @@
 	public int invokeInterfaceCount() {
 	    return 1 + SegmentUtils.countInvokeInterfaceArgs(descriptor.underlyingString());
 	}
+	
+
+    /* (non-Javadoc)
+     * @see org.apache.harmony.pack200.bytecode.ConstantPoolEntry#comparisonString()
+     */
+    public String comparisonString() {
+        // First come those things which don't have an
+        // associated signature. Then come the native signatures, 
+        // then finally the class signatures.
+        // TODO: I think Character.MAX_VALUE is no longer the
+        // biggest character, what with the weird codepage thing
+        // going on. How to sort these things so that even if
+        // they're in some oddball codepage they'll still end
+        // up sorted correctly?
+        String descriptorString = descriptor.underlyingString();
+        StringBuffer comparisonBuffer = new StringBuffer();
+        if((descriptorString.indexOf("(")) == -1) {
+            // it's a variable reference
+            comparisonBuffer.append(descriptor.underlyingString());
+        } else {
+            // it's a signature. Append something that will
+            // make the comparison buffer bigger than all
+            // non-signature references.
+            comparisonBuffer.append(Character.MAX_VALUE);
+            // do the natives first
+            if(descriptorString.length() <= 4) {
+                // it's a native signature
+                comparisonBuffer.append(descriptor.underlyingString());
+            } else {
+                // it's a non-native signature. Append something
+                // that will make the comparison buffer bigger
+                // than all native signature references.
+                comparisonBuffer.append(Character.MAX_VALUE);
+                comparisonBuffer.append(descriptor.underlyingString());
+            }
+        }
+        comparisonBuffer.append(name.underlyingString());
+        return comparisonBuffer.toString();
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java?rev=611862&r1=611861&r2=611862&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPRef.java Mon Jan 14 09:26:18 2008
@@ -77,6 +77,37 @@
 		classNameIndex = pool.indexOf(className);
 	}
 
+   public String comparisonString() {
+        // This one is tricky. The sorting appears to be
+        // done based on the indices of the method descriptor
+        // and class name in the classpool *after* sorting them.
+       
+       // If we haven't yet been resolved, just do a normal
+       // compare (so things like .contains() work).
+        if(!isResolved()) {
+            return super.comparisonString();
+        }
+        
+        // If we get here, the receiver has been resolved; there
+        // is a different sort order.
+        StringBuffer result = new StringBuffer();
+        // Pad all numbers to 6 digits so they sort correctly.
+        int padLength = 6;
+        int classIndexLength = ("" + classNameIndex).length();
+        int nameAndTypeIndexLength = ("" + nameAndTypeIndex).length();
+        
+        for(int index=0; index < (padLength - classIndexLength); index++) {
+            result.append('0');
+        }
+        result.append("" + classNameIndex);
+        result.append(":");
+        for(int index=0; index < (padLength - nameAndTypeIndexLength); index++) {
+            result.append('0');
+        }
+        result.append("" + nameAndTypeIndex);
+        return result.toString();
+    }
+
 	public String toString() {
 		String type;
 		if (getTag() == ConstantPoolEntry.CP_Fieldref) {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java?rev=611862&r1=611861&r2=611862&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPUTF8.java Mon Jan 14 09:26:18 2008
@@ -29,7 +29,6 @@
 		this.domain = domain;
 	}
 
-	
 	public boolean equals(Object obj) {
 		if (this == obj)
 			return true;
@@ -45,7 +44,6 @@
 			return false;
 		return true;
 	}
-
 	
 	public int hashCode() {
 		final int PRIME = 31;
@@ -80,20 +78,36 @@
 	}
 	
 	public String comparisonString() {
-	    String returnValue = utf8;
-	    if(utf8.endsWith(";")) {
-	        StringBuffer alphaChars = new StringBuffer();
-	        StringBuffer extraChars = new StringBuffer();
-	        extraChars.append((char)0xFFFF);
-	        for(int index=0; index < utf8.length(); index++) {
-	            if( (utf8.charAt(index) == '(') || (utf8.charAt(index) == ')') || (utf8.charAt(index) == '[') || (utf8.charAt(index) == ']') ) {
-	                extraChars.append(utf8.charAt(index));
-	            } else {
-	                alphaChars.append(utf8.charAt(index));
-	            }
-	        }
-	        returnValue = alphaChars.toString() + extraChars.toString();
-	    }
-	    return returnValue;
+	    // Should use either normalComparisonString or signatureComparisonString.
+	    // If we get here, that might indicate an error.
+	    throw new Error("Should use specific kinds of comparisonString() on CPUTF8s");
 	}
+
+	public String normalComparisonString() {
+        return utf8;
+    }
+
+    public String signatureComparisonString() {
+        StringBuffer alphaChars = new StringBuffer();
+        StringBuffer extraChars = new StringBuffer();
+        if(utf8.length() > 0){
+            if(utf8.charAt(0) == '(') {
+                // Things with return values (which apparently
+                // always begin with '(') sort after things
+                // without return values.
+                // TODO: need a better way for this - possibly in the comparator?
+                alphaChars.append(Character.MAX_VALUE);
+            }
+        }
+        // TODO: need a better way for this - possibly in the comparator?
+        extraChars.append(Character.MAX_VALUE);
+        for(int index=0; index < utf8.length(); index++) {
+            if( (utf8.charAt(index) == '(') || (utf8.charAt(index) == ')') || (utf8.charAt(index) == '[') || (utf8.charAt(index) == ']') ) {
+                extraChars.append(utf8.charAt(index));
+            } else {
+                alphaChars.append(utf8.charAt(index));
+            }
+        }
+        return(alphaChars.toString() + extraChars.toString());
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java?rev=611862&r1=611861&r2=611862&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassConstantPool.java Mon Jan 14 09:26:18 2008
@@ -81,9 +81,10 @@
     public static int DOMAIN_FIELD = 10;
     public static int DOMAIN_METHOD = 11;
     public static int DOMAIN_ATTRIBUTEASCIIZ = 12;
+    public static int NUM_DOMAINS = DOMAIN_ATTRIBUTEASCIIZ + 1;
 
-    protected SortedSet sortedEntries = new TreeSet(new PoolComparator());
-    
+//    protected SortedSet sortedEntries = new TreeSet(new PoolComparator());
+    protected ClassPoolSet classPoolSet = new ClassPoolSet();
 	public String toString() {
 		return entries.toString();
 	}
@@ -100,44 +101,17 @@
 // This is a handy way to see what's adding a ClassFileEntry - set a breakpoint on the print 
 //	    if(entry instanceof CPUTF8) {
 //	        System.out.println("AAH:" + ((CPUTF8)entry).comparisonString());
-//	        if (((CPUTF8)entry).comparisonString().matches("Ljava.*")) {
+//	        if (((CPUTF8)entry).underlyingString().matches("Code")) {
 //	            System.out.println("Adding");
 //	        }
 //	    }
 		if (entry instanceof ConstantPoolEntry) {
+            classPoolSet.add(entry);
 			if (!entries.contains(entry)) {
 				entries.add(entry);
-				sortedEntries.add(entry);
 				// TODO This will be a bugger when they're sorted.
 				if (entry instanceof CPLong ||entry instanceof CPDouble)
 					entries.add(entry); //these get 2 slots because of their size
-			} else {
-			    // TODO: This is awful. If I'm presented with
-			    // an entry that has a lower domain than the
-			    // current entry but is otherwise the same,
-			    // change its domain and rebalance the tree.
-			    // And by "rebalance" I mean destroy and recreate
-			    // the tree.
-			    Iterator iterator = sortedEntries.iterator();
-			    boolean replaceTree = false;
-			    SortedSet newSortedSet = new TreeSet(new PoolComparator());
-			    while(iterator.hasNext()) {
-			        ConstantPoolEntry storedEntry = (ConstantPoolEntry)iterator.next();
-			        if(storedEntry.equals(entry)) {
-			            if(storedEntry.getDomain() > ((ConstantPoolEntry)entry).getDomain()) {
-			                // need to blow away the tree.
-			                replaceTree = true;
-			                newSortedSet.add(entry);
-			            } else {
-			                newSortedSet.add(storedEntry);
-			            }
-			        } else {
-			            newSortedSet.add(storedEntry);
-			        }
-			        if(replaceTree) {
-			            sortedEntries = newSortedSet;
-			        }
-			    }
 			}
 		} else {
 			if (!others.contains(entry))
@@ -177,42 +151,15 @@
 		// In an ideal world, you wouldn't actually add to it unless you're
 		// sure.
         entries = new ArrayList();
-//      entries.addAll(sortedEntries);
-      Iterator sortedIterator = sortedEntries.iterator();
+      Iterator sortedIterator = classPoolSet.iterator();
       while(sortedIterator.hasNext()) {
           ConstantPoolEntry entry = (ConstantPoolEntry)sortedIterator.next();
           entries.add(entry);
+          // need to do this both here and in the sort below
+          // so the indices are correct.
           if (entry instanceof CPLong ||entry instanceof CPDouble)
               entries.add(entry); //these get 2 slots because of their size
       }
-//		HashMap sortMap = new HashMap();
-//		List cpAll = null;
-//		// TODO: HACK - this is a 1.5 api.
-//		// Need to do the right thing and do it with 1.4 API.
-//		try {
-//			cpAll = Arrays.asList(segment.getConstantPool().getCpAll());
-//		} catch (Pack200Exception ex) {
-//			ex.printStackTrace();
-//		}
-//		Iterator it = entries.iterator();
-//		while(it.hasNext()) {
-//			ClassFileEntry entry = (ClassFileEntry) it.next();
-//			int indexInCpAll = cpAll.indexOf(entry);
-//			if(indexInCpAll > 0) {
-//				sortMap.put(new Integer(indexInCpAll), entry);
-//			} else {
-//				sortMap.put(new Integer(99999), entry);
-//			}
-//		}
-//		ArrayList sortedList = new ArrayList();
-//		for(int index=0; index < 99999; index++) {
-//			if(sortMap.containsKey(new Integer(index))) {
-//				sortedList.add((ClassFileEntry)sortMap.get(new Integer(index)));
-//			}
-//		}
-//		for(int xindex=0; xindex < sortedList.size(); xindex++) {
-//			SegmentUtils.debug(sortedList.get(xindex).toString());
-//		}
 		resolve();
 	}
 	
@@ -227,7 +174,25 @@
 		while (it.hasNext()) {
 			ClassFileEntry entry = (ClassFileEntry) it.next();
 			entry.resolve(this);
-		}		
+		}
+		
+		// Now that everything has been resolved, do one
+		// final sort of the class pool. This fixes up
+		// references, which are sorted by index in the
+		// class pool.
+		it = entries.iterator();
+		ClassPoolSet finalSort = new ClassPoolSet();
+		while(it.hasNext()) {
+		    finalSort.add(it.next());
+		}
+		it = finalSort.iterator();
+		entries = new ArrayList();
+		while(it.hasNext()) {
+		    ClassFileEntry entry = (ClassFileEntry) it.next();
+		    entries.add(entry);
+	        if (entry instanceof CPLong ||entry instanceof CPDouble)
+	            entries.add(entry); //these get 2 slots because of their size
+		}
 	}
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassFileEntry.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassFileEntry.java?rev=611862&r1=611861&r2=611862&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassFileEntry.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassFileEntry.java Mon Jan 14 09:26:18 2008
@@ -42,6 +42,10 @@
 		resolved = true;
 	}
 
+	protected boolean isResolved() {
+	    return resolved;
+	}
+	
 	public abstract String toString();
 
 	public final void write(DataOutputStream dos) throws IOException {

Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassPoolSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassPoolSet.java?rev=611862&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassPoolSet.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassPoolSet.java Mon Jan 14 09:26:18 2008
@@ -0,0 +1,233 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.harmony.pack200.bytecode;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeSet;
+
+/**
+ * This class implements the special set (which is aware of
+ * domains) used when generating ClassConstantPools.
+ */
+public class ClassPoolSet {
+
+    class GeneralComparator implements Comparator {
+        /* (non-Javadoc)
+         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+         */
+        public int compare(Object o1, Object o2) {            
+            if(o1.equals(o2)) {
+                return 0;
+            }
+            return o1.getClass().getName().compareTo(o2.getClass().getName());
+        }
+    }
+
+    class PoolComparator extends GeneralComparator {
+        /* (non-Javadoc)
+         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+         */
+        public int compare(Object o1, Object o2) {
+            int classCompare = super.compare(o1, o2);
+            if(classCompare != 0) {
+                return classCompare;
+            }
+            // If we compare anything other than ConstantPoolEntries
+            // with this comparator, it is an error.
+            ConstantPoolEntry cpe1 = (ConstantPoolEntry)o1;
+            ConstantPoolEntry cpe2 = (ConstantPoolEntry)o2;
+            
+            // Domains must be the same, need to compare
+            // based on comparisonString.
+            String compare1 = cpe1.comparisonString();
+            String compare2 = cpe2.comparisonString();
+            return compare1.compareTo(compare2);
+        }
+    }
+
+    class SignatureAsciizComparator extends GeneralComparator {
+        /* (non-Javadoc)
+         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+         */
+        public int compare(Object o1, Object o2) {
+            int classCompare = super.compare(o1, o2);
+            if(classCompare != 0) {
+                return classCompare;
+            }
+            
+            // Now that we've reached this point, we're
+            // comparing objects of the same class. Since
+            // they have the same class, we can make the
+            // statement that they're UTF8s, since only
+            // UTF8s will be added to a TreeSet with
+            // the SignatureAsciizComparator.
+            CPUTF8 cpe1 = (CPUTF8)o1;
+            CPUTF8 cpe2 = (CPUTF8)o2;
+
+            String compare1 = cpe1.signatureComparisonString();
+            String compare2 = cpe2.signatureComparisonString();
+            return compare1.compareTo(compare2);
+        }
+    }
+
+    class NormalAsciizComparator extends GeneralComparator {
+        /* (non-Javadoc)
+         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+         */
+        public int compare(Object o1, Object o2) {
+            int classCompare = super.compare(o1, o2);
+            if(classCompare != 0) {
+                return classCompare;
+            }
+            
+            // Now that we've reached this point, we're
+            // comparing objects of the same class. Since
+            // they have the same class, we can make the
+            // statement that they're UTF8s, since only
+            // UTF8s will be added to a TreeSet with
+            // the NormalAsciizComparator.
+            CPUTF8 cpe1 = (CPUTF8)o1;
+            CPUTF8 cpe2 = (CPUTF8)o2;
+
+            String compare1 = cpe1.normalComparisonString();
+            String compare2 = cpe2.normalComparisonString();
+            return compare1.compareTo(compare2);
+        }
+    }
+
+    protected Comparator[] comparators = new Comparator[ClassConstantPool.NUM_DOMAINS];
+    protected TreeSet[] sets = new TreeSet[ClassConstantPool.NUM_DOMAINS];
+
+    public ClassPoolSet() {
+        // These are the comparators in numeric order.
+        comparators[ClassConstantPool.DOMAIN_UNDEFINED] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_INTEGER] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_FLOAT] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_STRING] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_NORMALASCIIZ] = new NormalAsciizComparator();
+        comparators[ClassConstantPool.DOMAIN_LONG] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_DOUBLE] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_CLASSREF] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_SIGNATUREASCIIZ] = new SignatureAsciizComparator();
+        comparators[ClassConstantPool.DOMAIN_NAMEANDTYPE] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_FIELD] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_METHOD] = new PoolComparator();
+        comparators[ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ] = new NormalAsciizComparator();
+        
+        for(int index=0; index < ClassConstantPool.NUM_DOMAINS; index++) {
+            sets[index] = new TreeSet(comparators[index]);
+        }
+    }
+    
+    
+    /**
+     * Answer the index of the first set which contains the entry
+     * passed in as the parameter.
+     * @param entry ConstantPoolEntry to test for (with .contains())
+     * @return int index of the first set containing the entry
+     */
+    protected int findFirstSetContaining(ConstantPoolEntry entry) {
+        for(int index=0; index < ClassConstantPool.NUM_DOMAINS; index++) {
+            if(sets[index].contains(entry)) {
+                return index;
+            }
+        }
+        return -1;
+    }
+    
+    /**
+     * @param set
+     * @param testEntry
+     * @return
+     */
+    protected ConstantPoolEntry getStoredEntry(int set, ConstantPoolEntry testEntry) {
+        TreeSet searchSet = sets[set];
+        Iterator iterator = searchSet.iterator();
+        while(iterator.hasNext()) {
+            ConstantPoolEntry storedEntry = (ConstantPoolEntry)iterator.next();
+            if(0 == (comparators[set].compare(storedEntry, testEntry))) {
+                return storedEntry;
+            }
+        }
+        // Not found. Should not happen.
+        throw new Error("Tried to find a stored entry which wasn't in the set");
+    }
+
+    /**
+     * Add the parameter to the receiver. If the parameter
+     * already exists in a higher precedence domain, answer
+     * that. If the parameter exists in a lower precedence
+     * domain, remove it from the lower domain and add it to
+     * the higher one.
+     * 
+     * @param entry ConstantPoolEntry to add
+     * @return ConstantPoolEntry from the domain where it's stored
+     */
+    public ConstantPoolEntry add(Object entry) {
+        ConstantPoolEntry cpEntry = (ConstantPoolEntry)entry;
+        int entryDomain = cpEntry.getDomain();
+        int currentStoredDomain = findFirstSetContaining(cpEntry);
+        
+        if(currentStoredDomain < 0) {
+            // Entry is not currently stored; just store it.
+            sets[entryDomain].add(cpEntry);
+            return cpEntry;
+        }
+        
+        if(currentStoredDomain <= entryDomain) {
+            // Entry is either already in this place
+            // or in a higher-precedence (numerically lower)
+            // domain; answer the value in the stored
+            // domain.
+            return getStoredEntry(currentStoredDomain, cpEntry);
+        }
+        
+        // Entry is in a lower-precedence (numerically higher)
+        // domain. Need to remove it from the lower-precedence
+        // domain and add it to the higher precedence domain.
+        sets[currentStoredDomain].remove(cpEntry);
+        sets[entryDomain].add(cpEntry);
+        return cpEntry;
+    }
+
+
+    public Iterator iterator() {
+        return partialIterator(ClassConstantPool.DOMAIN_INTEGER, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ);
+    }
+
+    /**
+     * Answer an iterator which iterates over the sets
+     * from sets[start] to sets[stop] only.
+     * @param start int the first set over which iteration will occur.
+     * @param stop int the last set over which iteration will occur
+     * @return Iterator
+     */
+    public Iterator partialIterator(int start, int stop) {
+        // Make sure there's nothing in the undefined domain
+        if(sets[ClassConstantPool.DOMAIN_UNDEFINED].size() > 0) {
+            throw new Error("Trying to get iterator but have undefined elements");
+        }
+        List someElements = new ArrayList();
+        for(int index=start; index <= stop; index++) {
+            someElements.addAll(sets[index]);
+        }
+        return someElements.iterator();        
+    }
+}

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ClassPoolSet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java?rev=611862&r1=611861&r2=611862&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ConstantPoolEntry.java Mon Jan 14 09:26:18 2008
@@ -59,7 +59,7 @@
 	protected int domain = ClassConstantPool.DOMAIN_UNDEFINED;
 	public static int creationOrderCount = 100;
 	public String comparisonString() {
-	    return "" + creationOrder;
+	    return toString();
 	}
 	public int creationOrder = -1;
 	ConstantPoolEntry(byte tag) {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java?rev=611862&r1=611861&r2=611862&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ByteCodeForm.java Mon Jan 14 09:26:18 2008
@@ -291,16 +291,16 @@
         byteCodeArray[224] = new SuperFieldRefForm(224, "aload_0_putstatic_super", new int[] {42, 179, -1, -1});
         byteCodeArray[225] = new SuperFieldRefForm(225, "aload_0_getfield_super", new int[] {42, 180, -1, -1});
         byteCodeArray[226] = new SuperFieldRefForm(226, "aload_0_putfield_super", new int[] {42, 181, -1, -1});
-        byteCodeArray[227] = new SuperFieldRefForm(227, "aload_0_invokevirtual_super", new int[] {42, 182, -1, -1});
-        byteCodeArray[228] = new SuperFieldRefForm(228, "aload_0_invokespecial_super", new int[] {42, 183, -1, -1});
-        byteCodeArray[229] = new SuperFieldRefForm(229, "aload_0_invokestatic_super", new int[] {42, 184, -1, -1});
+        byteCodeArray[227] = new SuperMethodRefForm(227, "aload_0_invokevirtual_super", new int[] {42, 182, -1, -1});
+        byteCodeArray[228] = new SuperMethodRefForm(228, "aload_0_invokespecial_super", new int[] {42, 183, -1, -1});
+        byteCodeArray[229] = new SuperMethodRefForm(229, "aload_0_invokestatic_super", new int[] {42, 184, -1, -1});
         byteCodeArray[230] = new ThisInitMethodRefForm(230, "invokespecial_this_init", new int[] {183, -1, -1});
         byteCodeArray[231] = new SuperInitMethodRefForm(231, "invokespecial_super_init", new int[] {183, -1, -1});
         byteCodeArray[232] = new NewInitMethodRefForm(232, "invokespecial_new_init", new int[] {183, -1, -1});
-        byteCodeArray[233] = new ClassRefForm(233, "cldc", new int[] {18, -1}); 
+        byteCodeArray[233] = new NarrowClassRefForm(233, "cldc", new int[] {18, -1}); 
         byteCodeArray[234] = new IntRefForm(234, "ildc", new int[] {18, -1});
         byteCodeArray[235] = new FloatRefForm(235, "fldc", new int[] {18, -1});
-        byteCodeArray[236] = new ClassRefForm(236, "cldc_w", new int[] {19, -1, -1}, WIDENED);
+        byteCodeArray[236] = new NarrowClassRefForm(236, "cldc_w", new int[] {19, -1, -1}, WIDENED);
         byteCodeArray[237] = new IntRefForm(237, "ildc_w", new int[] {19, -1, -1}, WIDENED);
         byteCodeArray[238] = new FloatRefForm(238, "fldc_w", new int[] {19, -1, -1}, WIDENED);
         byteCodeArray[239] = new DoubleForm(239, "dldc2_w", new int[] {20, -1, -1});

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ClassRefForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ClassRefForm.java?rev=611862&r1=611861&r2=611862&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ClassRefForm.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/ClassRefForm.java Mon Jan 14 09:26:18 2008
@@ -16,7 +16,10 @@
  */
 package org.apache.harmony.pack200.bytecode.forms;
 
+import org.apache.harmony.pack200.Pack200Exception;
 import org.apache.harmony.pack200.SegmentConstantPool;
+import org.apache.harmony.pack200.bytecode.ByteCode;
+import org.apache.harmony.pack200.bytecode.ClassFileEntry;
 import org.apache.harmony.pack200.bytecode.OperandManager;
 
 /**
@@ -53,5 +56,4 @@
     protected int getPoolID() {
         return SegmentConstantPool.CP_CLASS;
     }
-
 }

Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NarrowClassRefForm.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NarrowClassRefForm.java?rev=611862&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NarrowClassRefForm.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NarrowClassRefForm.java Mon Jan 14 09:26:18 2008
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.harmony.pack200.bytecode.forms;
+
+import org.apache.harmony.pack200.Pack200Exception;
+import org.apache.harmony.pack200.bytecode.ByteCode;
+import org.apache.harmony.pack200.bytecode.OperandManager;
+
+/**
+ * This class is used for representations of cldc and
+ * cldc_w. In these cases, a narrow class ref has one
+ * byte and a wide class ref has two bytes.
+ */
+public class NarrowClassRefForm extends ClassRefForm {
+
+    public NarrowClassRefForm(int opcode, String name, int[] rewrite) {
+        super(opcode, name, rewrite);
+    }
+
+    public NarrowClassRefForm(int opcode, String name, int[] rewrite,
+            boolean widened) {
+        super(opcode, name, rewrite, widened);
+     }
+
+    protected void setNestedEntries(ByteCode byteCode, OperandManager operandManager, int offset) throws Pack200Exception {
+        super.setNestedEntries(byteCode, operandManager, offset);
+        if(!widened) {
+            byteCode.setNestedPositions(new int[][] {{0,1}});
+        }
+    }
+}

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/forms/NarrowClassRefForm.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/bytecode/ConstantPoolTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/bytecode/ConstantPoolTest.java?rev=611862&r1=611861&r2=611862&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/bytecode/ConstantPoolTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/bytecode/ConstantPoolTest.java Mon Jan 14 09:26:18 2008
@@ -29,8 +29,8 @@
 		pool = new ClassConstantPool();
 	}
 	public void testDuplicateUTF8() {
-		CPUTF8 u1 = new CPUTF8("thing", ClassConstantPool.DOMAIN_UNDEFINED);
-		CPUTF8 u2 = new CPUTF8("thing", ClassConstantPool.DOMAIN_UNDEFINED);
+		CPUTF8 u1 = new CPUTF8("thing", ClassConstantPool.DOMAIN_NORMALASCIIZ);
+		CPUTF8 u2 = new CPUTF8("thing", ClassConstantPool.DOMAIN_NORMALASCIIZ);
 		pool.add(u1);
 		pool.add(u2);
 		assertEquals(1,pool.size());
@@ -44,8 +44,8 @@
 		assertEquals(2,pool.size());
 	}
 	public void testIndex() {
-		pool.add(new CPUTF8("OtherThing", ClassConstantPool.DOMAIN_UNDEFINED));
-		CPUTF8 u1 = new CPUTF8("thing", ClassConstantPool.DOMAIN_UNDEFINED);
+		pool.add(new CPUTF8("OtherThing", ClassConstantPool.DOMAIN_NORMALASCIIZ));
+		CPUTF8 u1 = new CPUTF8("thing", ClassConstantPool.DOMAIN_NORMALASCIIZ);
 		pool.add(u1);
 		pool.resolve();
 		assertTrue(pool.indexOf(u1) > 0);