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/11/19 17:36:11 UTC
svn commit: r719007 -
/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/
Author: sjanuary
Date: Wed Nov 19 08:36:11 2008
New Revision: 719007
URL: http://svn.apache.org/viewvc?rev=719007&view=rev
Log:
Ongoing pack200 development
Modified:
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java
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/BcBands.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPClass.java
harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.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/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/AttributeDefinitionBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java?rev=719007&r1=719006&r2=719007&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java Wed Nov 19 08:36:11 2008
@@ -30,6 +30,11 @@
*/
public class AttributeDefinitionBands extends BandSet {
+ public static final int CONTEXT_CLASS = 0;
+ public static final int CONTEXT_CODE = 3;
+ public static final int CONTEXT_FIELD = 1;
+ public static final int CONTEXT_METHOD = 2;
+
private final Map layouts = new HashMap();
private final SegmentHeader segmentHeader;
@@ -42,18 +47,22 @@
private final List attributeDefinitions = new ArrayList();
private final CpBands cpBands;
+ private final Segment segment;
- public AttributeDefinitionBands(SegmentHeader segmentHeader, CpBands cpBands) {
- this.segmentHeader = segmentHeader;
- this.cpBands = cpBands;
+ public AttributeDefinitionBands(Segment segment) {
+ this.segmentHeader = segment.getSegmentHeader();
+ this.cpBands = segment.getCpBands();
+ this.segment = segment;
}
public void finaliseBands() {
+ addSyntheticDefinitions();
segmentHeader.setAttribute_definition_count(classAttributes.keySet()
.size()
+ methodAttributes.keySet().size()
+ fieldAttributes.keySet().size()
- + codeAttributes.keySet().size());
+ + codeAttributes.keySet().size()
+ + attributeDefinitions.size());
if (classAttributes.keySet().size() > 7) {
segmentHeader.setHave_class_flags_hi(true);
}
@@ -73,31 +82,31 @@
if(classAttributes.size() > 7) {
availableClassIndices = addHighIndices(availableClassIndices);
}
- addAttributeDefinitions(classAttributes, availableClassIndices, 0);
+ addAttributeDefinitions(classAttributes, availableClassIndices, CONTEXT_CLASS);
int[] availableMethodIndices = new int[] {26, 27, 28, 29, 30, 31};
if(methodAttributes.size() > 6) {
availableMethodIndices = addHighIndices(availableMethodIndices);
}
- addAttributeDefinitions(methodAttributes, availableMethodIndices, 0);
+ addAttributeDefinitions(methodAttributes, availableMethodIndices, CONTEXT_METHOD);
int[] availableFieldIndices = new int[] {18, 23, 24, 25, 26, 27, 28, 29, 30, 31};
if(fieldAttributes.size() > 10) {
availableFieldIndices = addHighIndices(availableFieldIndices);
}
- addAttributeDefinitions(fieldAttributes, availableFieldIndices, 0);
+ addAttributeDefinitions(fieldAttributes, availableFieldIndices, CONTEXT_FIELD);
int[] availableCodeIndices = new int[] {17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
if(codeAttributes.size() > 15) {
availableCodeIndices = addHighIndices(availableCodeIndices);
}
- addAttributeDefinitions(codeAttributes, availableCodeIndices, 0);
+ addAttributeDefinitions(codeAttributes, availableCodeIndices, CONTEXT_CODE);
int[] attributeDefinitionHeader = new int[attributeDefinitions.size()];
int[] attributeDefinitionName = new int[attributeDefinitions.size()];
int[] attributeDefinitionLayout = new int[attributeDefinitions.size()];
for (int i = 0; i < attributeDefinitionLayout.length; i++) {
AttributeDefinition def = (AttributeDefinition) attributeDefinitions.get(i);
- attributeDefinitionHeader[i] = def.contextType | (def.index << 2);
- attributeDefinitionName[i] = cpBands.getCPUtf8(def.name).getIndex();
- attributeDefinitionLayout[i] = cpBands.getCPUtf8(def.layout).getIndex();
+ attributeDefinitionHeader[i] = def.contextType | (def.index + 1 << 2);
+ attributeDefinitionName[i] = def.name.getIndex();
+ attributeDefinitionLayout[i] = def.layout.getIndex();
}
out.write(encodeBandInt("attributeDefinitionHeader", attributeDefinitionHeader, Codec.BYTE1));
@@ -105,6 +114,25 @@
out.write(encodeBandInt("attributeDefinitionLayout", attributeDefinitionLayout, Codec.UNSIGNED5));
}
+ private void addSyntheticDefinitions() {
+ boolean anySytheticClasses = segment.getClassBands().isAnySyntheticClasses();
+ boolean anySyntheticMethods = segment.getClassBands().isAnySyntheticMethods();
+ boolean anySyntheticFields = segment.getClassBands().isAnySyntheticFields();
+ if(anySytheticClasses || anySyntheticMethods || anySyntheticFields) {
+ CPUTF8 syntheticUTF = cpBands.getCPUtf8("Synthetic");
+ CPUTF8 emptyUTF = cpBands.getCPUtf8("");
+ if(anySytheticClasses) {
+ attributeDefinitions.add(new AttributeDefinition(12, CONTEXT_CLASS, syntheticUTF, emptyUTF));
+ }
+ if(anySyntheticMethods) {
+ attributeDefinitions.add(new AttributeDefinition(12, CONTEXT_METHOD, syntheticUTF, emptyUTF));
+ }
+ if(anySyntheticFields) {
+ attributeDefinitions.add(new AttributeDefinition(12, CONTEXT_FIELD, syntheticUTF, emptyUTF));
+ }
+ }
+ }
+
private int[] addHighIndices(int[] availableIndices) {
int[] temp = new int[availableIndices.length + 32];
for (int i = 0; i < availableIndices.length; i++) {
@@ -125,7 +153,7 @@
String name = (String) iterator.next();
String layout = (String) layouts.get(name);
int index = availableIndices[i];
- attributeDefinitions.add(new AttributeDefinition(index, contextType, name, layout));
+ attributeDefinitions.add(new AttributeDefinition(index, contextType, cpBands.getCPUtf8(name), cpBands.getCPUtf8(layout)));
}
}
@@ -137,11 +165,11 @@
public int index;
public int contextType;
- public String name;
- public String layout;
+ public CPUTF8 name;
+ public CPUTF8 layout;
- public AttributeDefinition(int index, int contextType, String name,
- String layout) {
+ public AttributeDefinition(int index, int contextType, CPUTF8 name,
+ CPUTF8 layout) {
this.index = index;
this.contextType = contextType;
this.name = name;
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=719007&r1=719006&r2=719007&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 Wed Nov 19 08:36:11 2008
@@ -283,6 +283,9 @@
// }
long z = value;
if (isSigned()) {
+ if(z < Integer.MIN_VALUE) {
+ z += 4294967296L;
+ }
if (z < 0) {
z = (-z << s) - 1;
} else {
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=719007&r1=719006&r2=719007&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 Wed Nov 19 08:36:11 2008
@@ -154,27 +154,29 @@
bciRenumbering.add(i, new Integer(++renumberedOffset));
}
}
- if (renumberedOffset + 1 != bciRenumbering.size()) {
- throw new RuntimeException("Mistake made with renumbering");
- }
- for (int i = bcLabel.size() - 1; i >= 0; i--) {
- Object label = bcLabel.get(i);
- if (label instanceof Integer) {
- break;
- } else if (label instanceof Label) {
- bcLabel.remove(i);
- Integer offset = (Integer) labelsToOffsets.get(label);
- Integer relativeOffset = (Integer) bcLabelRelativeOffsets.get(i);
- bcLabel.add(i, new Integer(((Integer)bciRenumbering.get(offset.intValue())).intValue() - ((Integer)bciRenumbering.get(relativeOffset.intValue())).intValue()));
+ if (renumberedOffset != 0) {
+ if(renumberedOffset + 1 != bciRenumbering.size()) {
+ throw new RuntimeException("Mistake made with renumbering");
}
+ for (int i = bcLabel.size() - 1; i >= 0; i--) {
+ Object label = bcLabel.get(i);
+ if (label instanceof Integer) {
+ break;
+ } else if (label instanceof Label) {
+ bcLabel.remove(i);
+ Integer offset = (Integer) labelsToOffsets.get(label);
+ 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);
+ segment.getClassBands().doBciRenumbering(bciRenumbering,
+ labelsToOffsets);
+ bciRenumbering.clear();
+ labelsToOffsets.clear();
+ byteCodeOffset = 0;
+ renumberedOffset = 0;
}
- bcCodes.add(endMarker);
- segment.getClassBands().doBciRenumbering(bciRenumbering,
- labelsToOffsets);
- bciRenumbering.clear();
- labelsToOffsets.clear();
- byteCodeOffset = 0;
- renumberedOffset = 0;
}
public void visitLabel(Label label) {
@@ -299,6 +301,8 @@
} else if (constant instanceof CPClass) {
bcCodes.add(new Integer(236)); // cldc
bcClassRef.add(constant);
+ } else {
+ throw new RuntimeException("Constant should not be null");
}
} else {
byteCodeOffset += 2;
@@ -329,7 +333,7 @@
bcLabel.add(labels[i]);
bcLabelRelativeOffsets.add(new Integer(byteCodeOffset));
}
- int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - byteCodeOffset + 1;
+ int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - ((byteCodeOffset + 1) % 4);
byteCodeOffset += padding + 8 + 8 * keys.length;
updateRenumbering();
}
@@ -407,7 +411,7 @@
bcLabel.add(labels[i]);
bcLabelRelativeOffsets.add(new Integer(byteCodeOffset));
}
- int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - byteCodeOffset + 1;
+ int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - ((byteCodeOffset + 1) % 4);
byteCodeOffset+= (padding + 12 + 4 * labels.length);
updateRenumbering();
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPClass.java?rev=719007&r1=719006&r2=719007&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPClass.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPClass.java Wed Nov 19 08:36:11 2008
@@ -21,10 +21,19 @@
private final String className;
private final CPUTF8 utf8;
+ private final boolean isInnerClass;
public CPClass(CPUTF8 utf8) {
this.utf8 = utf8;
this.className = utf8.getUnderlyingString();
+ char[] chars = className.toCharArray();
+ for (int i = 0; i < chars.length; i++) {
+ if(chars[i] <= 0x2D) {
+ isInnerClass = true;
+ return;
+ }
+ }
+ isInnerClass = false;
}
public int compareTo(Object arg0) {
@@ -39,4 +48,8 @@
return utf8.getIndex();
}
+ public boolean isInnerClass() {
+ return isInnerClass;
+ }
+
}
Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java?rev=719007&r1=719006&r2=719007&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java Wed Nov 19 08:36:11 2008
@@ -48,15 +48,14 @@
return classes.size() - ((CPSignature) arg0).classes.size();
}
if (classes.size() > 0) {
- int classComp = 0;
for (int i = classes.size() - 1; i >=0; i--) {
CPClass cpClass = (CPClass) classes.get(i);
CPClass compareClass = (CPClass) ((CPSignature) arg0).classes
.get(i);
- classComp = classComp * 10 + cpClass.compareTo(compareClass);
- }
- if(classComp != 0) {
- return classComp;
+ int classComp = cpClass.compareTo(compareClass);
+ if(classComp != 0) {
+ return classComp;
+ }
}
}
return signature.compareTo(((CPSignature) arg0).signature);
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=719007&r1=719006&r2=719007&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 Wed Nov 19 08:36:11 2008
@@ -19,9 +19,14 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import org.apache.harmony.pack200.IcBands.IcTuple;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Label;
@@ -91,11 +96,18 @@
private final List tempMethodFlags = new ArrayList();
private final List tempMethodDesc = new ArrayList();
- public ClassBands(SegmentHeader header, CpBands cpBands,
- AttributeDefinitionBands attrBands, int numClasses) {
- this.header = header;
- this.cpBands = cpBands;
- this.attrBands = attrBands;
+ private boolean anySyntheticClasses = false;
+ private boolean anySyntheticFields = false;
+ private boolean anySyntheticMethods = false;
+ private final Segment segment;
+
+ private final Map classReferencesInnerClass = new HashMap();
+
+ public ClassBands(Segment segment, int numClasses) {
+ this.segment = segment;
+ this.header = segment.getSegmentHeader();
+ this.cpBands = segment.getCpBands();
+ this.attrBands = segment.getAttrBands();
class_this = new CPClass[numClasses];
class_super = new CPClass[numClasses];
class_interface_count = new int[numClasses];
@@ -114,6 +126,11 @@
private int index = 0;
private int numMethodArgs = 0;
+ private int[] class_InnerClasses_N;
+ private CPClass[] class_InnerClasses_RC;
+ private int[] class_InnerClasses_F;
+ private List classInnerClassesOuterRCN;
+ private List classInnerClassesNameRUN;
public void addClass(int major, int flags, String className,
String superName, String[] interfaces) {
@@ -126,6 +143,24 @@
}
major_versions[index] = major;
class_flags[index] = flags;
+ if(!anySyntheticClasses && ((flags & (1 << 12)) != 0)) {
+ cpBands.addCPUtf8("Synthetic");
+ anySyntheticClasses = true;
+ }
+ }
+
+ public void currentClassReferencesInnerClass(CPClass inner) {
+ if(!(index >= class_this.length)) {
+ CPClass currentClass = class_this[index];
+ if(currentClass != null && !currentClass.equals(inner)) {
+ Set referencedInnerClasses = (Set)classReferencesInnerClass.get(currentClass);
+ if(referencedInnerClasses == null) {
+ referencedInnerClasses = new HashSet();
+ classReferencesInnerClass.put(currentClass, referencedInnerClasses);
+ }
+ referencedInnerClasses.add(inner);
+ }
+ }
}
public void addField(int flags, String name, String desc, String signature,
@@ -141,6 +176,10 @@
fieldConstantValueKQ.add(cpBands.getConstant(value));
flags |= (1 << 17);
}
+ if(!anySyntheticFields && ((flags & (1 << 12)) != 0)) {
+ cpBands.addCPUtf8("Synthetic");
+ anySyntheticFields = true;
+ }
tempFieldFlags.add(new Long(flags));
}
@@ -188,20 +227,64 @@
removed++;
}
}
- }
- public void pack(OutputStream out) throws IOException, Pack200Exception {
- int[] classThis = new int[class_this.length];
- for (int i = 0; i < classThis.length; i++) {
- classThis[i] = class_this[i].getIndex();
+ // Compute any required IcLocals
+ List innerClassesN = new ArrayList();
+ List icLocal = new ArrayList();
+ Set keySet = classReferencesInnerClass.keySet();
+ for (int i = 0; i < class_this.length; i++) {
+ CPClass cpClass = class_this[i];
+ Set referencedInnerClasses = (Set) classReferencesInnerClass.get(cpClass);
+ if(referencedInnerClasses != null) {
+ int innerN = 0;
+ List innerClasses = segment.getIcBands().getInnerClassesForOuter(cpClass.toString());
+ if(innerClasses != null) {
+ for (Iterator iterator2 = innerClasses.iterator(); iterator2
+ .hasNext();) {
+ referencedInnerClasses.remove(((IcTuple)iterator2.next()).C);
+ }
+ }
+ for (Iterator iterator2 = referencedInnerClasses.iterator(); iterator2
+ .hasNext();) {
+ CPClass inner = (CPClass) iterator2.next();
+ IcTuple icTuple = segment.getIcBands().getIcTuple(inner);
+ if(icTuple != null) {
+ // should transmit an icLocal entry
+ icLocal.add(icTuple);
+ innerN++;
+ }
+ }
+ if(innerN != 0) {
+ innerClassesN.add(new Integer(innerN));
+ class_flags[i] |= (1 << 23);
+ }
+ }
}
- out.write(encodeBandInt("class_this", classThis, Codec.DELTA5));
-
- int[] classSuper = new int[class_super.length];
- for (int i = 0; i < classSuper.length; i++) {
- classSuper[i] = class_super[i].getIndex();
+ class_InnerClasses_N = listToArray(innerClassesN);
+ class_InnerClasses_RC = new CPClass[icLocal.size()];
+ class_InnerClasses_F = new int[icLocal.size()];
+ classInnerClassesOuterRCN = new ArrayList();
+ classInnerClassesNameRUN = new ArrayList();
+ for (int i = 0; i < class_InnerClasses_RC.length; i++) {
+ IcTuple icTuple = (IcTuple) icLocal.get(i);
+ class_InnerClasses_RC[i] = (icTuple.C);
+ if(icTuple.C2 == null && icTuple.N == null) {
+ class_InnerClasses_F[i] = 0;
+ } else {
+ if (icTuple.F == 0) {
+ class_InnerClasses_F[i] = 0x00010000;
+ } else {
+ class_InnerClasses_F[i] = icTuple.F;
+ }
+ classInnerClassesOuterRCN.add(icTuple.C2);
+ classInnerClassesNameRUN.add(icTuple.N);
+ }
}
- out.write(encodeBandInt("class_super", classSuper, Codec.DELTA5));
+ }
+
+ public void pack(OutputStream out) throws IOException, Pack200Exception {
+ out.write(encodeBandInt("class_this", getInts(class_this), Codec.DELTA5));
+ out.write(encodeBandInt("class_super", getInts(class_super), Codec.DELTA5));
out.write(encodeBandInt("class_interface_count", class_interface_count,
Codec.DELTA5));
@@ -217,9 +300,8 @@
}
}
}
- out
- .write(encodeBandInt("class_interface", classInterface,
- Codec.DELTA5));
+ out.write(encodeBandInt("class_interface", classInterface,
+ Codec.DELTA5));
out.write(encodeBandInt("class_field_count", class_field_count,
Codec.DELTA5));
out.write(encodeBandInt("class_method_count", class_method_count,
@@ -297,14 +379,27 @@
out.write(encodeBandInt("class_EnclosingMethod_RDN",
cpEntryOrNullListToArray(classEnclosingMethodDesc),
Codec.UNSIGNED5));
- out.write(encodeBandInt("classSignature",
+ out.write(encodeBandInt("class_Signature_RS",
cpEntryListToArray(classSignature), Codec.UNSIGNED5));
+ out.write(encodeBandInt("class_InnerClasses_N", class_InnerClasses_N, Codec.UNSIGNED5));
+ out.write(encodeBandInt("class_InnerClasses_RC", getInts(class_InnerClasses_RC), Codec.UNSIGNED5));
+ out.write(encodeBandInt("class_InnerClasses_F", class_InnerClasses_F, Codec.UNSIGNED5));
+ out.write(encodeBandInt("class_InnerClasses_outer_RCN", cpEntryOrNullListToArray(classInnerClassesOuterRCN), Codec.UNSIGNED5));
+ out.write(encodeBandInt("class_InnerClasses_name_RUN", cpEntryOrNullListToArray(classInnerClassesNameRUN), Codec.UNSIGNED5));
out.write(encodeBandInt("classFileVersionMinor",
listToArray(classFileVersionMinor), Codec.UNSIGNED5));
out.write(encodeBandInt("classFileVersionMajor",
listToArray(classFileVersionMajor), Codec.UNSIGNED5));
}
+ private int[] getInts(CPClass[] cpClasses) {
+ int[] ints = new int[cpClasses.length];
+ for (int i = 0; i < ints.length; i++) {
+ ints[i] = cpClasses[i].getIndex();
+ }
+ return ints;
+ }
+
private void writeCodeBands(OutputStream out) throws IOException,
Pack200Exception {
out.write(encodeBandInt("codeHeaders", codeHeaders, Codec.BYTE1));
@@ -388,8 +483,11 @@
flags |= (1 << 18);
}
tempMethodFlags.add(new Long(flags));
- codeHandlerCount.add(ZERO);
numMethodArgs = countArgs(desc);
+ if(!anySyntheticMethods && ((flags & (1 << 12)) != 0)) {
+ cpBands.addCPUtf8("Synthetic");
+ anySyntheticMethods = true;
+ }
}
protected static int countArgs(String descriptor) {
@@ -457,6 +555,9 @@
public void addSourceFile(String source) {
String implicitSourceFileName = class_this[index].toString();
+ if(implicitSourceFileName.indexOf('$') != -1) {
+ implicitSourceFileName = implicitSourceFileName.substring(0, implicitSourceFileName.indexOf('$'));
+ }
implicitSourceFileName = implicitSourceFileName
.substring(implicitSourceFileName.lastIndexOf('/') + 1)
+ ".java";
@@ -499,6 +600,7 @@
}
public void addCode() {
+ codeHandlerCount.add(ZERO);
codeFlags.add(new Long(0));
}
@@ -631,4 +733,16 @@
}
}
}
+
+ public boolean isAnySyntheticClasses() {
+ return anySyntheticClasses;
+ }
+
+ public boolean isAnySyntheticFields() {
+ return anySyntheticFields;
+ }
+
+ public boolean isAnySyntheticMethods() {
+ return anySyntheticMethods;
+ }
}
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=719007&r1=719006&r2=719007&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 Wed Nov 19 08:36:11 2008
@@ -27,6 +27,8 @@
import java.util.Set;
import java.util.TreeSet;
+import org.objectweb.asm.Type;
+
/**
* Pack200 Constant Pool Bands
*/
@@ -54,12 +56,17 @@
private final Map stringsToCpNameAndType = new HashMap();
private final Map stringsToCpClass = new HashMap();
private final Map stringsToCpSignature = new HashMap();
- private final Map stringsToCpMethodOrField = new HashMap();
+ private final Map stringsToCpMethod = new HashMap();
+ private final Map stringsToCpField = new HashMap();
+ private final Map stringsToCpIMethod = new HashMap();
private final Map objectsToCPConstant = new HashMap();
- public CpBands(SegmentHeader segmentHeader) {
- this.segmentHeader = segmentHeader;
+ private final Segment segment;
+
+ public CpBands(Segment segment) {
+ this.segmentHeader = segment.getSegmentHeader();
+ this.segment = segment;
defaultAttributeNames.add("AnnotationDefault");
defaultAttributeNames.add("RuntimeVisibleAnnotations");
defaultAttributeNames.add("RuntimeInvisibleAnnotations");
@@ -194,8 +201,8 @@
loBits[i] = (int) l;
i++;
}
- out.write(encodeBandInt("cp_Long_high", highBits, Codec.UDELTA5));
- out.write(encodeBandInt("cp_Long_low", loBits, Codec.DELTA5));
+ out.write(encodeBandInt("cp_Long_hi", highBits, Codec.UDELTA5));
+ out.write(encodeBandInt("cp_Long_lo", loBits, Codec.DELTA5));
}
private void writeCpDouble(OutputStream out) throws IOException,
@@ -210,8 +217,8 @@
loBits[i] = (int) l;
i++;
}
- out.write(encodeBandInt("cp_Double_high", highBits, Codec.UDELTA5));
- out.write(encodeBandInt("cp_Double_low", loBits, Codec.DELTA5));
+ out.write(encodeBandInt("cp_Double_hi", highBits, Codec.UDELTA5));
+ out.write(encodeBandInt("cp_Double_lo", loBits, Codec.DELTA5));
}
private void writeCpString(OutputStream out) throws IOException,
@@ -373,7 +380,7 @@
}
}
- private void addCPUtf8(String utf8) {
+ void addCPUtf8(String utf8) {
getCPUtf8(utf8);
}
@@ -453,6 +460,9 @@
cp_Class.add(cpClass);
stringsToCpClass.put(className, cpClass);
}
+ if(cpClass.isInnerClass()) {
+ segment.getClassBands().currentClassReferencesInnerClass(cpClass);
+ }
return cpClass;
}
@@ -475,13 +485,13 @@
public CPMethodOrField getCPField(CPClass cpClass, String name, String desc) {
String key = cpClass.toString() + ":" + name + ":" + desc;
- CPMethodOrField cpF = (CPMethodOrField) stringsToCpMethodOrField
+ CPMethodOrField cpF = (CPMethodOrField) stringsToCpField
.get(key);
if (cpF == null) {
CPNameAndType nAndT = getCPNameAndType(name, desc);
cpF = new CPMethodOrField(cpClass, nAndT);
cp_Field.add(cpF);
- stringsToCpMethodOrField.put(key, cpF);
+ stringsToCpField.put(key, cpF);
}
return cpF;
}
@@ -504,6 +514,9 @@
} else if (value instanceof String) {
constant = new CPString(getCPUtf8((String) value));
cp_String.add(constant);
+ } else if (value instanceof Type) {
+ constant = new CPClass(getCPUtf8(((Type) value).getClassName()));
+ cp_Class.add(constant);
}
objectsToCPConstant.put(value, constant);
}
@@ -512,13 +525,13 @@
public CPMethodOrField getCPMethod(CPClass cpClass, String name, String desc) {
String key = cpClass.toString() + ":" + name + ":" + desc;
- CPMethodOrField cpM = (CPMethodOrField) stringsToCpMethodOrField
+ CPMethodOrField cpM = (CPMethodOrField) stringsToCpMethod
.get(key);
if (cpM == null) {
CPNameAndType nAndT = getCPNameAndType(name, desc);
cpM = new CPMethodOrField(cpClass, nAndT);
cp_Method.add(cpM);
- stringsToCpMethodOrField.put(key, cpM);
+ stringsToCpMethod.put(key, cpM);
}
return cpM;
}
@@ -526,13 +539,13 @@
public CPMethodOrField getCPIMethod(CPClass cpClass, String name,
String desc) {
String key = cpClass.toString() + ":" + name + ":" + desc;
- CPMethodOrField cpIM = (CPMethodOrField) stringsToCpMethodOrField
+ CPMethodOrField cpIM = (CPMethodOrField) stringsToCpIMethod
.get(key);
if (cpIM == null) {
CPNameAndType nAndT = getCPNameAndType(name, desc);
cpIM = new CPMethodOrField(cpClass, nAndT);
cp_Imethod.add(cpIM);
- stringsToCpMethodOrField.put(key, cpIM);
+ stringsToCpIMethod.put(key, cpIM);
}
return cpIM;
}
@@ -551,12 +564,12 @@
public CPMethodOrField addCPMethod(CPClass cpClass, String name, String desc) {
String key = cpClass.toString() + ":" + name + ":" + desc;
- CPMethodOrField cpM = (CPMethodOrField) stringsToCpMethodOrField
+ CPMethodOrField cpM = (CPMethodOrField) stringsToCpMethod
.get(key);
if (cpM == null) {
CPNameAndType nAndT = getCPNameAndType(name, desc);
cpM = new CPMethodOrField(cpClass, nAndT);
- stringsToCpMethodOrField.put(key, cpM);
+ stringsToCpMethod.put(key, cpM);
cp_Method.add(cpM);
}
return cpM;
@@ -564,12 +577,12 @@
public CPMethodOrField addCPField(CPClass cpClass, String name, String desc) {
String key = cpClass.toString() + ":" + name + ":" + desc;
- CPMethodOrField cpF = (CPMethodOrField) stringsToCpMethodOrField
+ CPMethodOrField cpF = (CPMethodOrField) stringsToCpField
.get(key);
if (cpF == null) {
CPNameAndType nAndT = getCPNameAndType(name, desc);
cpF = new CPMethodOrField(cpClass, nAndT);
- stringsToCpMethodOrField.put(key, cpF);
+ stringsToCpField.put(key, cpF);
cp_Field.add(cpF);
}
return cpF;
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=719007&r1=719006&r2=719007&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 Wed Nov 19 08:36:11 2008
@@ -19,17 +19,22 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.TreeSet;
public class IcBands extends BandSet {
- private final Set innerClasses = new HashSet();
+ private final Set innerClasses = new TreeSet();
private final SegmentHeader segmentHeader;
private final CpBands cpBands;
private int bit16Count = 0;
+ private final Map outerToInner = new HashMap();
+
public IcBands(SegmentHeader segmentHeader, CpBands cpBands) {
this.segmentHeader = segmentHeader;
this.cpBands = cpBands;
@@ -66,17 +71,58 @@
public void addInnerClass(String name, String outerName, String innerName,
int flags) {
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++;
+ if(namesArePredictable(name, outerName, innerName)) {
+ IcTuple innerClass = new IcTuple(cpBands.getCPClass(name), flags, null, null);
+ addToMap(outerName, innerClass);
+ innerClasses.add(innerClass);
+ } else {
+ flags |= (1<<16);
+ IcTuple icTuple = new IcTuple(cpBands.getCPClass(name), flags, cpBands.getCPClass(outerName), cpBands.getCPUtf8(innerName));
+ boolean added = innerClasses.add(icTuple);
+ if(added) {
+ bit16Count++;
+ addToMap(outerName, icTuple);
+ }
}
} else {
- innerClasses.add(new IcTuple(cpBands.getCPClass(name), flags, cpBands.getCPClass(outerName), cpBands.getCPUtf8(innerName)));
+ IcTuple innerClass = new IcTuple(cpBands.getCPClass(name), flags, null, null);
+ addToMap(getOuter(name), innerClass);
+ innerClasses.add(innerClass);
}
}
- private class IcTuple {
+ public List getInnerClassesForOuter(String outerClassName) {
+ return (List) outerToInner.get(outerClassName);
+ }
+
+ private String getOuter(String name) {
+ return name.substring(0, name.lastIndexOf('$'));
+ }
+
+ private void addToMap(String outerName, IcTuple icTuple) {
+ List tuples = (List) outerToInner.get(outerName);
+ if(tuples == null) {
+ tuples = new ArrayList();
+ outerToInner.put(outerName, tuples);
+ tuples.add(icTuple);
+ } else {
+ for (Iterator iterator = tuples.iterator(); iterator.hasNext();) {
+ IcTuple icT = (IcTuple) iterator.next();
+ if(icTuple.equals(icT)) {
+ return;
+ }
+ }
+ tuples.add(icTuple);
+ }
+ }
+
+ private boolean namesArePredictable(String name, String outerName,
+ String innerName) {
+ // TODO: Could be multiple characters, not just $
+ return name.equals(outerName + '$' + innerName) && innerName.indexOf('$') == -1;
+ }
+
+ class IcTuple implements Comparable {
protected CPClass C; // this class
protected int F; // flags
@@ -93,7 +139,7 @@
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 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;
}
@@ -101,6 +147,25 @@
public int hashCode() {
return (C.hashCode() * 37) + F;
}
+
+ public String toString() {
+ return C.toString();
+ }
+
+ public int compareTo(Object arg0) {
+ return C.compareTo(((IcTuple)arg0).C);
+ }
+
+ }
+
+ public IcTuple getIcTuple(CPClass inner) {
+ for (Iterator iterator = innerClasses.iterator(); iterator.hasNext();) {
+ IcTuple icTuple = (IcTuple) iterator.next();
+ if(icTuple.C.equals(inner)) {
+ return icTuple;
+ }
+ }
+ return null;
}
}
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=719007&r1=719006&r2=719007&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 Wed Nov 19 08:36:11 2008
@@ -38,10 +38,6 @@
private BcBands bcBands;
private FileBands fileBands;
- // The current class - only to be used when processing the classes
- private String currentClass;
- private String superClass;
-
private final SegmentFieldVisitor fieldVisitor = new SegmentFieldVisitor();
private final SegmentMethodVisitor methodVisitor = new SegmentMethodVisitor();
private final SegmentAnnotationVisitor annotationVisitor = new SegmentAnnotationVisitor();
@@ -51,12 +47,10 @@
throws IOException, Pack200Exception {
segmentHeader = new SegmentHeader();
segmentHeader.setFile_count(files.size());
- cpBands = new CpBands(segmentHeader);
- attributeDefinitionBands = new AttributeDefinitionBands(segmentHeader,
- cpBands);
+ cpBands = new CpBands(this);
+ attributeDefinitionBands = new AttributeDefinitionBands(this);
icBands = new IcBands(segmentHeader, cpBands);
- classBands = new ClassBands(segmentHeader, cpBands,
- attributeDefinitionBands, classes.size());
+ classBands = new ClassBands(this, classes.size());
bcBands = new BcBands(cpBands, this);
fileBands = new FileBands(cpBands, segmentHeader, files);
@@ -90,8 +84,6 @@
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
- currentClass = name;
- superClass = superName;
bcBands.setCurrentClass(name);
bcBands.setSuperClass(superName);
segmentHeader.addMajorVersion(version);
@@ -299,4 +291,20 @@
public boolean lastConstantHadWideIndex() {
return currentClassReader.lastConstantHadWideIndex();
}
+
+ public CpBands getCpBands() {
+ return cpBands;
+ }
+
+ public SegmentHeader getSegmentHeader() {
+ return segmentHeader;
+ }
+
+ public AttributeDefinitionBands getAttrBands() {
+ return attributeDefinitionBands;
+ }
+
+ public IcBands getIcBands() {
+ return icBands;
+ }
}