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/10/17 11:44:08 UTC

svn commit: r705535 - in /harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200: BHSDCodec.java BandSet.java BcBands.java CPInt.java CPLong.java ClassBands.java CodecEncoding.java CpBands.java IcBands.java Segment.java

Author: sjanuary
Date: Fri Oct 17 02:44:07 2008
New Revision: 705535

URL: http://svn.apache.org/viewvc?rev=705535&view=rev
Log:
Progress on pack200

Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPInt.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPLong.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java Fri Oct 17 02:44:07 2008
@@ -115,7 +115,7 @@
     /**
      * radix^i powers
      */
-    private long[] powers;
+    private final long[] powers;
 
     /**
      * Constructs an unsigned, non-delta Codec with the given B and H values.
@@ -276,10 +276,11 @@
         if (isDelta()) {
             value -= last;
         }
-        if (!encodes(value)) {
-            throw new Pack200Exception("The codec " + toString()
-                    + " does not encode the value " + value);
-        }
+        // TODO: Do we need this?  this implementation isn't right because of integer overflow...
+//        if (!encodes(value)) {
+//            throw new Pack200Exception("The codec " + toString()
+//                   + " does not encode the value " + value);
+//        }
         long z = value;
         if (isSigned()) {
             if (z < 0) {
@@ -440,4 +441,16 @@
     public int getL() {
         return l;
     }
+
+    public boolean equals(Object o) {
+        if(!(o instanceof BHSDCodec)) {
+            return false;
+        }
+        BHSDCodec codec = (BHSDCodec) o;
+        return codec.b == b && codec.h == h && codec.s == s && codec.d == d;
+    }
+
+    public int hashCode() {
+        return ((b* 37 + h) * 37 + s) * 37 + d;
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java Fri Oct 17 02:44:07 2008
@@ -33,9 +33,34 @@
         return codec.encode(value);
     }
 
-    public byte[] encodeBandInt(String name, int[] ints, Codec defaultCodec) throws Pack200Exception {
+    public byte[] encodeBandInt(String name, int[] ints, BHSDCodec defaultCodec) throws Pack200Exception {
         // TODO non-default codecs
-        return defaultCodec.encode(ints);
+        if(ints.length > 0) {
+            System.out.println("encoding " + name + ", size = " + ints.length);
+            int first = ints[0];
+            if(defaultCodec.getB() != 1) {
+                if (defaultCodec.isSigned() && first >= -256 && first <= -1) {
+                    int specifier = -1 - CodecEncoding.getSpecifierForDefaultCodec(defaultCodec);
+                    byte[] specifierEncoded = defaultCodec.encode(new int[] {specifier});
+                    byte[] rest = defaultCodec.encode(ints);
+                    byte[] band = new byte[specifierEncoded.length + rest.length];
+                    System.arraycopy(specifierEncoded, 0, band, 0, specifierEncoded.length);
+                    System.arraycopy(rest, 0, band, specifierEncoded.length, rest.length);
+                    return band;
+                } else if (!defaultCodec.isSigned() && first >= defaultCodec.getL()
+                        && first <= defaultCodec.getL() + 255) {
+                    int specifier = CodecEncoding.getSpecifierForDefaultCodec(defaultCodec) + defaultCodec.getL();
+                    byte[] specifierEncoded = defaultCodec.encode(new int[] {specifier});
+                    byte[] rest = defaultCodec.encode(ints);
+                    byte[] band = new byte[specifierEncoded.length + rest.length];
+                    System.arraycopy(specifierEncoded, 0, band, 0, specifierEncoded.length);
+                    System.arraycopy(rest, 0, band, specifierEncoded.length, rest.length);
+                    return band;
+                }
+            }
+            return defaultCodec.encode(ints);
+        }
+        return new byte[0];
     }
 
     public boolean isPredictableSourceFileName(String className, String sourceFileName) {
@@ -95,6 +120,9 @@
         int[] array = new int[list.size()];
         for (int i = 0; i < array.length; i++) {
             array[i] = ((ConstantPoolEntry)list.get(i)).getIndex();
+            if(array[i] < 0) {
+                throw new RuntimeException("Index should be > 0");
+            }
         }
         return array;
     }
@@ -104,6 +132,9 @@
         for (int j = 0; j < array.length; j++) {
             ConstantPoolEntry cpEntry = (ConstantPoolEntry) theList.get(j);
             array[j] = cpEntry == null ? 0 : cpEntry.getIndex() + 1;
+            if(cpEntry != null && cpEntry.getIndex() < 0) {
+                throw new RuntimeException("Index should be > 0");
+            }
         }
         return array;
     }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java Fri Oct 17 02:44:07 2008
@@ -75,6 +75,7 @@
     private final Map labelsToOffsets = new HashMap();
     private int byteCodeOffset;
     private int renumberedOffset;
+    private final List bcLabelRelativeOffsets = new ArrayList();
 
     public void setCurrentClass(String name) {
         currentClass = name;
@@ -163,7 +164,8 @@
             } else if (label instanceof Label) {
                 bcLabel.remove(i);
                 Integer offset = (Integer) labelsToOffsets.get(label);
-                bcLabel.add(i, bciRenumbering.get(offset.intValue()));
+                Integer relativeOffset = (Integer) bcLabelRelativeOffsets.get(i);
+                bcLabel.add(i, new Integer(((Integer)bciRenumbering.get(offset.intValue())).intValue() - ((Integer)bciRenumbering.get(relativeOffset.intValue())).intValue()));
             }
         }
         bcCodes.add(endMarker);
@@ -186,7 +188,7 @@
         boolean aload_0 = false;
         if (bcCodes.size() > 0
                 && ((Integer) bcCodes.get(bcCodes.size() - 1)).equals(ALOAD_0)) {
-            bcCodes.remove(bcCodes.size());
+            bcCodes.remove(bcCodes.size() - 1);
             aload_0 = true;
         }
         CPMethodOrField cpField = cpBands.getCPField(owner, name, desc);
@@ -234,7 +236,7 @@
             byteCodeOffset += 3;
             bcCodes.add(IINC);
             bcLocal.add(new Integer(var));
-            bcByte.add(new Integer(increment));
+            bcByte.add(new Integer(increment & 0xFF));
         }
         updateRenumbering();
     }
@@ -260,17 +262,18 @@
         case 16: // bipush
         case 188: // newarray
             bcCodes.add(new Integer(opcode));
-            bcByte.add(new Integer(operand));
+            bcByte.add(new Integer(operand & 0xFF));
             byteCodeOffset += 2;
         }
         updateRenumbering();
     }
 
     public void visitJumpInsn(int opcode, Label label) {
-        byteCodeOffset += 3;
-        updateRenumbering();
         bcCodes.add(new Integer(opcode));
         bcLabel.add(label);
+        bcLabelRelativeOffsets.add(new Integer(byteCodeOffset));
+        byteCodeOffset += 3;
+        updateRenumbering();
     }
 
     public void visitLdcInsn(Object cst) {
@@ -317,16 +320,18 @@
     }
 
     public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - byteCodeOffset + 1;
-        byteCodeOffset += padding + 8 + 8 * keys.length;
-        updateRenumbering();
         bcCodes.add(LOOKUPSWITCH);
         bcLabel.add(dflt);
+        bcLabelRelativeOffsets.add(new Integer(byteCodeOffset));
         bcCaseCount.add(new Integer(keys.length));
         for (int i = 0; i < labels.length; i++) {
             bcCaseValue.add(new Integer(keys[i]));
             bcLabel.add(labels[i]);
+            bcLabelRelativeOffsets.add(new Integer(byteCodeOffset));
         }
+        int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - byteCodeOffset + 1;
+        byteCodeOffset += padding + 8 + 8 * keys.length;
+        updateRenumbering();
     }
 
     public void visitMethodInsn(int opcode, String owner, String name,
@@ -387,22 +392,24 @@
         updateRenumbering();
         bcCodes.add(MULTIANEWARRAY);
         bcClassRef.add(cpBands.getCPClass(desc));
-        bcByte.add(new Integer(dimensions));
+        bcByte.add(new Integer(dimensions & 0xFF));
     }
 
     public void visitTableSwitchInsn(int min, int max, Label dflt,
             Label[] labels) {
-        int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - byteCodeOffset + 1;
-        byteCodeOffset+= (padding + 12 + 4 * labels.length);
-        updateRenumbering();
         bcCodes.add(TABLESWITCH);
         bcLabel.add(dflt);
+        bcLabelRelativeOffsets.add(new Integer(byteCodeOffset));
         bcCaseValue.add(new Integer(min));
         int count = labels.length;
         bcCaseCount.add(new Integer(count));
         for (int i = 0; i < count; i++) {
             bcLabel.add(labels[i]);
+            bcLabelRelativeOffsets.add(new Integer(byteCodeOffset));
         }
+        int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - byteCodeOffset + 1;
+        byteCodeOffset+= (padding + 12 + 4 * labels.length);
+        updateRenumbering();
     }
 
     public void visitTypeInsn(int opcode, String type) {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPInt.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPInt.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPInt.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPInt.java Fri Oct 17 02:44:07 2008
@@ -19,14 +19,20 @@
 
 public class CPInt extends CPConstant {
 
-    private int theInt;
+    private final int theInt;
 
     public CPInt(int theInt) {
         this.theInt = theInt;
     }
 
     public int compareTo(Object obj) {
-        return theInt - ((CPInt)obj).theInt;
+        if(theInt > ((CPInt)obj).theInt) {
+            return 1;
+        } else if (theInt == ((CPInt)obj).theInt) {
+            return 0;
+        } else {
+            return -1;
+        }
     }
 
     public int getInt() {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPLong.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPLong.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPLong.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPLong.java Fri Oct 17 02:44:07 2008
@@ -19,18 +19,28 @@
 
 public class CPLong extends CPConstant {
 
-    private long theLong;
+    private final long theLong;
 
     public CPLong(long theLong) {
         this.theLong = theLong;
     }
 
     public int compareTo(Object obj) {
-        return (int) (theLong - ((CPLong)obj).theLong);
+        if(theLong > ((CPLong)obj).theLong) {
+            return 1;
+        } else if (theLong == ((CPLong)obj).theLong) {
+            return 0;
+        } else {
+            return -1;
+        }
     }
 
     public long getLong() {
         return theLong;
     }
 
+    public String toString() {
+        return "" + theLong;
+    }
+
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Fri Oct 17 02:44:07 2008
@@ -291,6 +291,12 @@
                 Codec.UNSIGNED5, header.have_class_flags_hi()));
         out.write(encodeBandInt("classSourceFile",
                 cpEntryOrNullListToArray(classSourceFile), Codec.UNSIGNED5));
+        out.write(encodeBandInt("class_enclosing_method_RC",
+                 cpEntryListToArray(classEnclosingMethodClass),
+                 Codec.UNSIGNED5));
+        out.write(encodeBandInt("class_EnclosingMethod_RDN",
+                cpEntryOrNullListToArray(classEnclosingMethodDesc),
+                Codec.UNSIGNED5));
         out.write(encodeBandInt("classSignature",
                 cpEntryListToArray(classSignature), Codec.UNSIGNED5));
         out.write(encodeBandInt("classFileVersionMinor",
@@ -497,13 +503,6 @@
     }
 
     public void addHandler(Label start, Label end, Label handler, String type) {
-        Long latestMethodFlag = (Long) tempMethodFlags.get(tempMethodFlags
-                .size() - 1);
-        if ((latestMethodFlag.longValue() & (1 << 18)) == 0) {
-            tempMethodFlags.remove(tempMethodFlags.size() - 1);
-            tempMethodFlags.add(new Long(latestMethodFlag.intValue()
-                    | (1 << 18)));
-        }
         Integer handlers = (Integer) codeHandlerCount.remove(codeHandlerCount
                 .size() - 1);
         codeHandlerCount.add(new Integer(handlers.intValue() + 1));
@@ -571,12 +570,18 @@
     public void doBciRenumbering(List bciRenumbering, Map labelsToOffsets) {
         renumberBci(codeLineNumberTableBciP, bciRenumbering, labelsToOffsets);
         renumberBci(codeLocalVariableTableBciP, bciRenumbering, labelsToOffsets);
-        renumberBci(codeLocalVariableTableSpanO, bciRenumbering,
-                labelsToOffsets);
+        renumberOffsetBci(codeLocalVariableTableBciP,
+                codeLocalVariableTableSpanO, bciRenumbering, labelsToOffsets);
         renumberBci(codeLocalVariableTypeTableBciP, bciRenumbering,
                 labelsToOffsets);
-        renumberBci(codeLocalVariableTypeTableSpanO, bciRenumbering,
+        renumberOffsetBci(codeLocalVariableTypeTableBciP,
+                codeLocalVariableTypeTableSpanO, bciRenumbering,
                 labelsToOffsets);
+        renumberBci(codeHandlerStartP, bciRenumbering, labelsToOffsets);
+        renumberOffsetBci(codeHandlerStartP, codeHandlerEndPO,
+                bciRenumbering, labelsToOffsets);
+        renumberDoubleOffsetBci(codeHandlerStartP, codeHandlerEndPO, codeHandlerCatchPO,
+                bciRenumbering, labelsToOffsets);
     }
 
     private void renumberBci(List list, List bciRenumbering, Map labelsToOffsets) {
@@ -586,8 +591,43 @@
                 break;
             } else if (label instanceof Label) {
                 list.remove(i);
-                Integer offset = (Integer) labelsToOffsets.get(label);
-                list.add(i, bciRenumbering.get(offset.intValue()));
+                Integer bytecodeIndex = (Integer) labelsToOffsets.get(label);
+                list.add(i, bciRenumbering.get(bytecodeIndex.intValue()));
+            }
+        }
+    }
+
+    private void renumberOffsetBci(List relative, List list,
+            List bciRenumbering, Map labelsToOffsets) {
+        for (int i = list.size() - 1; i >= 0; i--) {
+            Object label = list.get(i);
+            if (label instanceof Integer) {
+                break;
+            } else if (label instanceof Label) {
+                list.remove(i);
+                Integer bytecodeIndex = (Integer) labelsToOffsets.get(label);
+                Integer renumberedOffset = new Integer(((Integer) bciRenumbering
+                        .get(bytecodeIndex.intValue())).intValue()
+                        - ((Integer) relative.get(i)).intValue());
+                list.add(i, renumberedOffset);
+            }
+        }
+    }
+
+    private void renumberDoubleOffsetBci(List relative, List firstOffset, List list,
+            List bciRenumbering, Map labelsToOffsets) {
+        // TODO: There's probably a nicer way of doing this...
+        for (int i = list.size() - 1; i >= 0; i--) {
+            Object label = list.get(i);
+            if (label instanceof Integer) {
+                break;
+            } else if (label instanceof Label) {
+                list.remove(i);
+                Integer bytecodeIndex = (Integer) labelsToOffsets.get(label);
+                Integer renumberedOffset = new Integer(((Integer) bciRenumbering
+                        .get(bytecodeIndex.intValue())).intValue()
+                        - ((Integer) relative.get(i)).intValue() - ((Integer) firstOffset.get(i)).intValue());
+                list.add(i, renumberedOffset);
             }
         }
     }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java Fri Oct 17 02:44:07 2008
@@ -19,6 +19,8 @@
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
 
 
 /**
@@ -91,6 +93,9 @@
             new BHSDCodec(4, 240, 1, 1), new BHSDCodec(4, 248, 0, 1),
             new BHSDCodec(4, 248, 1, 1) };
 
+    private static Map canonicalCodecsToSpecifiers;
+
+
     /**
      * Returns the codec specified by the given value byte and optional byte
      * header. If the value is >=116, then bytes may be consumed from the
@@ -208,4 +213,14 @@
                     + ") found");
         }
     }
+
+    public static int getSpecifierForDefaultCodec(BHSDCodec defaultCodec) {
+        if(canonicalCodecsToSpecifiers == null) {
+            canonicalCodecsToSpecifiers = new HashMap();
+            for (int i = 0; i < canonicalCodec.length; i++) {
+                canonicalCodecsToSpecifiers.put(canonicalCodec[i], new Integer(i));
+            }
+        }
+        return ((Integer)canonicalCodecsToSpecifiers.get(defaultCodec)).intValue();
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Fri Oct 17 02:44:07 2008
@@ -366,8 +366,10 @@
     private void removeCpUtf8(String string) {
         CPUTF8 utf8 = (CPUTF8) stringsToCpUtf8.get(string);
         if (utf8 != null) {
-            stringsToCpUtf8.remove(string);
-            cp_Utf8.remove(utf8);
+            if(stringsToCpClass.get(string) == null) { // don't remove if strings are also in cpclass
+                stringsToCpUtf8.remove(string);
+                cp_Utf8.remove(utf8);
+            }
         }
     }
 
@@ -376,6 +378,9 @@
     }
 
     public CPUTF8 getCPUtf8(String utf8) {
+        if(utf8 == null) {
+            return null;
+        }
         CPUTF8 cpUtf8 = (CPUTF8) stringsToCpUtf8.get(utf8);
         if (cpUtf8 == null) {
             cpUtf8 = new CPUTF8(utf8);
@@ -437,6 +442,9 @@
     }
 
     public CPClass getCPClass(String className) {
+        if(className == null) {
+            return null;
+        }
         className = className.replace('.', '/');
         CPClass cpClass = (CPClass) stringsToCpClass.get(className);
         if (cpClass == null) {
@@ -473,6 +481,7 @@
             CPNameAndType nAndT = getCPNameAndType(name, desc);
             cpF = new CPMethodOrField(cpClass, nAndT);
             cp_Field.add(cpF);
+            stringsToCpMethodOrField.put(key, cpF);
         }
         return cpF;
     }
@@ -509,6 +518,7 @@
             CPNameAndType nAndT = getCPNameAndType(name, desc);
             cpM = new CPMethodOrField(cpClass, nAndT);
             cp_Method.add(cpM);
+            stringsToCpMethodOrField.put(key, cpM);
         }
         return cpM;
     }
@@ -522,6 +532,7 @@
             CPNameAndType nAndT = getCPNameAndType(name, desc);
             cpIM = new CPMethodOrField(cpClass, nAndT);
             cp_Imethod.add(cpIM);
+            stringsToCpMethodOrField.put(key, cpIM);
         }
         return cpIM;
     }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java Fri Oct 17 02:44:07 2008
@@ -16,32 +16,91 @@
  */
 package org.apache.harmony.pack200;
 
+import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 public class IcBands extends BandSet {
 
-    private final List innerClasses = new ArrayList();
+    private final Set innerClasses = new HashSet();
     private final SegmentHeader segmentHeader;
+    private final CpBands cpBands;
+    private int bit16Count = 0;
 
-    public IcBands(SegmentHeader segmentHeader) {
+    public IcBands(SegmentHeader segmentHeader, CpBands cpBands) {
         this.segmentHeader = segmentHeader;
+        this.cpBands = cpBands;
     }
 
     public void finaliseBands() {
         segmentHeader.setIc_count(innerClasses.size());
     }
 
-    public void pack(OutputStream out) {
-        // TODO Auto-generated method stub
-
+    public void pack(OutputStream out) throws IOException, Pack200Exception {
+        int[] ic_this_class = new int[innerClasses.size()];
+        int[] ic_flags = new int[innerClasses.size()];
+        int[] ic_outer_class = new int[bit16Count];
+        int[] ic_name = new int[bit16Count];
+
+        int index2 = 0;
+        List innerClassesList = new ArrayList(innerClasses);
+        for (int i = 0; i < ic_this_class.length; i++) {
+            IcTuple icTuple = (IcTuple) innerClassesList.get(i);
+            ic_this_class[i] = icTuple.C.getIndex();
+            ic_flags[i] = icTuple.F;
+            if((icTuple.F & (1<<16)) != 0) {
+                ic_outer_class[index2] = icTuple.C2 == null ? 0 : icTuple.C2.getIndex() + 1;
+                ic_name[index2] = icTuple.N == null ? 0 : icTuple.N.getIndex() + 1;
+                index2++;
+            }
+        }
+        out.write(encodeBandInt("ic_this_class", ic_this_class, Codec.UDELTA5));
+        out.write(encodeBandInt("ic_flags", ic_flags, Codec.UNSIGNED5));
+        out.write(encodeBandInt("ic_outer_class", ic_outer_class, Codec.DELTA5));
+        out.write(encodeBandInt("ic_name", ic_name, Codec.DELTA5));
     }
 
     public void addInnerClass(String name, String outerName, String innerName,
             int flags) {
-        // TODO Auto-generated method stub
+        if(outerName != null || innerName != null) {
+            flags |= (1<<16);
+            boolean added = innerClasses.add(new IcTuple(cpBands.getCPClass(name), flags, cpBands.getCPClass(outerName), cpBands.getCPUtf8(innerName)));
+            if(added) {
+                bit16Count++;
+            }
+        } else {
+            innerClasses.add(new IcTuple(cpBands.getCPClass(name), flags, cpBands.getCPClass(outerName), cpBands.getCPUtf8(innerName)));
+        }
+    }
+
+    private class IcTuple {
 
+        protected CPClass C; // this class
+        protected int F; // flags
+        protected CPClass C2; // outer class
+        protected CPUTF8 N; // name
+
+        public IcTuple(CPClass C, int F, CPClass C2, CPUTF8 N) {
+            this.C = C;
+            this.F = F;
+            this.C2 = C2;
+            this.N = N;
+        }
+
+        public boolean equals(Object o) {
+            if(o instanceof IcTuple) {
+                IcTuple icT = (IcTuple)o;
+                return C.equals(icT.C) && F == icT.F && C2 != null ? C2.equals(icT.C2) : icT.C2 == null && N != null ? N.equals(icT.N) : icT.N == null;
+            }
+            return false;
+        }
+
+        public int hashCode() {
+            return (C.hashCode() * 37) + F;
+        }
     }
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=705535&r1=705534&r2=705535&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java Fri Oct 17 02:44:07 2008
@@ -55,7 +55,7 @@
         cpBands = new CpBands(segmentHeader);
         attributeDefinitionBands = new AttributeDefinitionBands(segmentHeader,
                 cpBands);
-        icBands = new IcBands(segmentHeader);
+        icBands = new IcBands(segmentHeader, cpBands);
         classBands = new ClassBands(segmentHeader, cpBands,
                 attributeDefinitionBands, classes.size());
         bcBands = new BcBands(cpBands, this);
@@ -92,7 +92,6 @@
 
     public void visit(int version, int access, String name, String signature,
             String superName, String[] interfaces) {
-        System.out.println("visit " + name + " " + version + " " + access);
         currentClass = name;
         superClass = superName;
         bcBands.setCurrentClass(name);
@@ -115,7 +114,6 @@
     }
 
     public void visitAttribute(Attribute arg0) {
-        System.out.println("visitAttribute");
     }
 
     public void visitInnerClass(String name, String outerName,