提交 ecf5dcd6 编写于 作者: N never

6826261: class file dumping from SA is broken

Reviewed-by: kvn, jcoomes
上级 c1041b91
...@@ -147,6 +147,7 @@ public interface ClassConstants ...@@ -147,6 +147,7 @@ public interface ClassConstants
JVM_ACC_INTERFACE | JVM_ACC_INTERFACE |
JVM_ACC_ABSTRACT | JVM_ACC_ABSTRACT |
JVM_ACC_ANNOTATION | JVM_ACC_ANNOTATION |
JVM_ACC_ENUM |
JVM_ACC_SYNTHETIC); JVM_ACC_SYNTHETIC);
......
...@@ -89,29 +89,6 @@ public class ByteCodeRewriter ...@@ -89,29 +89,6 @@ public class ByteCodeRewriter
// update the code buffer hotspot specific bytecode with the jvm bytecode // update the code buffer hotspot specific bytecode with the jvm bytecode
code[bci] = (byte) (0xFF & bytecode); code[bci] = (byte) (0xFF & bytecode);
// RewriteFrequentPairs
if(hotspotcode == Bytecodes._fast_iaccess_0 ||
hotspotcode == Bytecodes._fast_aaccess_0 ||
hotspotcode == Bytecodes._fast_faccess_0) {
// rewrite next bytecode as _getfield
bci++;
code[bci] = (byte) (0xFF & Bytecodes._getfield);
bytecode = Bytecodes._getfield;
hotspotcode = Bytecodes._getfield;
} else if (hotspotcode == Bytecodes._fast_iload2) {
// rewrite next bytecode as _iload
bci++;
code[bci] = (byte) (0xFF & Bytecodes._iload);
bytecode = Bytecodes._iload;
hotspotcode = Bytecodes._iload;
} else if (hotspotcode == Bytecodes._fast_icaload) {
// rewrite next bytecode as _caload
bci++;
code[bci] = (byte) (0xFF & Bytecodes._caload);
bytecode = Bytecodes._caload;
bytecode = Bytecodes._caload;
}
short cpoolIndex = 0; short cpoolIndex = 0;
switch (bytecode) { switch (bytecode) {
// bytecodes with ConstantPoolCache index // bytecodes with ConstantPoolCache index
......
...@@ -59,8 +59,14 @@ public class ClassDump extends Tool { ...@@ -59,8 +59,14 @@ public class ClassDump extends Tool {
SystemDictionary dict = VM.getVM().getSystemDictionary(); SystemDictionary dict = VM.getVM().getSystemDictionary();
dict.classesDo(new SystemDictionary.ClassVisitor() { dict.classesDo(new SystemDictionary.ClassVisitor() {
public void visit(Klass k) { public void visit(Klass k) {
if (k instanceof InstanceKlass) if (k instanceof InstanceKlass) {
try {
dumpKlass((InstanceKlass) k); dumpKlass((InstanceKlass) k);
} catch (Exception e) {
System.out.println(k.getName().asString());
e.printStackTrace();
}
}
} }
}); });
} }
......
...@@ -40,7 +40,6 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -40,7 +40,6 @@ public class ClassWriter implements /* imports */ ClassConstants
protected InstanceKlass klass; protected InstanceKlass klass;
protected DataOutputStream dos; protected DataOutputStream dos;
protected ConstantPool cpool; protected ConstantPool cpool;
protected boolean is15Format;
// Map between class name to index of type CONSTANT_Class // Map between class name to index of type CONSTANT_Class
protected Map classToIndex = new HashMap(); protected Map classToIndex = new HashMap();
...@@ -73,7 +72,6 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -73,7 +72,6 @@ public class ClassWriter implements /* imports */ ClassConstants
klass = kls; klass = kls;
dos = new DataOutputStream(os); dos = new DataOutputStream(os);
cpool = klass.getConstants(); cpool = klass.getConstants();
is15Format = is15ClassFile();
} }
public void write() throws IOException { public void write() throws IOException {
...@@ -82,7 +80,7 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -82,7 +80,7 @@ public class ClassWriter implements /* imports */ ClassConstants
// write magic // write magic
dos.writeInt(0xCAFEBABE); dos.writeInt(0xCAFEBABE);
writeVersion(is15Format); writeVersion();
writeConstantPool(); writeConstantPool();
writeClassAccessFlags(); writeClassAccessFlags();
writeThisClass(); writeThisClass();
...@@ -96,43 +94,14 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -96,43 +94,14 @@ public class ClassWriter implements /* imports */ ClassConstants
dos.flush(); dos.flush();
} }
protected boolean is15ClassFile() { protected void writeVersion() throws IOException {
// if klass has generic signature, then it is 1.5 class file. dos.writeShort((short)klass.minorVersion());
if (klass.getGenericSignature() != null) { dos.writeShort((short)klass.majorVersion());
return true;
} }
// if atleast one method has generic signature protected void writeIndex(int index) throws IOException {
// , then we have 1.5 class file. if (index == 0) throw new InternalError();
ObjArray methods = klass.getMethods(); dos.writeShort(index);
final int numMethods = (int) methods.getLength();
for (int m = 0; m < numMethods; m++) {
Method curMethod = (Method) methods.getObjAt(m);
if (curMethod.getGenericSignature() != null) {
return true;
}
}
// if atleast one field has non-zero generic signature index, then we have
// 1.5 class file
TypeArray fields = klass.getFields();
final int numFields = (int) fields.getLength();
for (int f = 0; f < numFields; f += InstanceKlass.NEXT_OFFSET) {
short genSigIndex = fields.getShortAt(f + InstanceKlass.GENERIC_SIGNATURE_INDEX_OFFSET);
if (genSigIndex != (short)0) return true;
}
return false;
}
protected void writeVersion(boolean is15Format) throws IOException {
if (is15Format) {
dos.writeShort(MINOR_VERSION);
dos.writeShort(MAJOR_VERSION);
} else {
dos.writeShort(MINOR_VERSION_OLD);
dos.writeShort(MAJOR_VERSION_OLD);
}
} }
protected void writeConstantPool() throws IOException { protected void writeConstantPool() throws IOException {
...@@ -392,8 +361,8 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -392,8 +361,8 @@ public class ClassWriter implements /* imports */ ClassConstants
if (DEBUG) debugMessage("\tfield name = " + nameIndex + ", signature = " + signatureIndex); if (DEBUG) debugMessage("\tfield name = " + nameIndex + ", signature = " + signatureIndex);
short fieldAttributeCount = 0; short fieldAttributeCount = 0;
boolean isSyn = isSynthetic(accessFlags); boolean hasSyn = hasSyntheticAttribute(accessFlags);
if (isSyn) if (hasSyn)
fieldAttributeCount++; fieldAttributeCount++;
short initvalIndex = fields.getShortAt(index + InstanceKlass.INITVAL_INDEX_OFFSET); short initvalIndex = fields.getShortAt(index + InstanceKlass.INITVAL_INDEX_OFFSET);
...@@ -407,18 +376,18 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -407,18 +376,18 @@ public class ClassWriter implements /* imports */ ClassConstants
dos.writeShort(fieldAttributeCount); dos.writeShort(fieldAttributeCount);
// write synthetic, if applicable // write synthetic, if applicable
if (isSyn) if (hasSyn)
writeSynthetic(); writeSynthetic();
if (initvalIndex != 0) { if (initvalIndex != 0) {
dos.writeShort(_constantValueIndex); writeIndex(_constantValueIndex);
dos.writeInt(2); dos.writeInt(2);
dos.writeShort(initvalIndex); dos.writeShort(initvalIndex);
if (DEBUG) debugMessage("\tfield init value = " + initvalIndex); if (DEBUG) debugMessage("\tfield init value = " + initvalIndex);
} }
if (genSigIndex != 0) { if (genSigIndex != 0) {
dos.writeShort(_signatureIndex); writeIndex(_signatureIndex);
dos.writeInt(2); dos.writeInt(2);
dos.writeShort(genSigIndex); dos.writeShort(genSigIndex);
if (DEBUG) debugMessage("\tfield generic signature index " + genSigIndex); if (DEBUG) debugMessage("\tfield generic signature index " + genSigIndex);
...@@ -430,8 +399,13 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -430,8 +399,13 @@ public class ClassWriter implements /* imports */ ClassConstants
return (accessFlags & (short) JVM_ACC_SYNTHETIC) != 0; return (accessFlags & (short) JVM_ACC_SYNTHETIC) != 0;
} }
protected boolean hasSyntheticAttribute(short accessFlags) {
// Check if flags have the attribute and if the constant pool contains an entry for it.
return isSynthetic(accessFlags) && _syntheticIndex != 0;
}
protected void writeSynthetic() throws IOException { protected void writeSynthetic() throws IOException {
dos.writeShort(_syntheticIndex); writeIndex(_syntheticIndex);
dos.writeInt(0); dos.writeInt(0);
} }
...@@ -459,8 +433,8 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -459,8 +433,8 @@ public class ClassWriter implements /* imports */ ClassConstants
short methodAttributeCount = 0; short methodAttributeCount = 0;
final boolean isSyn = isSynthetic((short)accessFlags); final boolean hasSyn = hasSyntheticAttribute((short)accessFlags);
if (isSyn) if (hasSyn)
methodAttributeCount++; methodAttributeCount++;
final boolean hasCheckedExceptions = m.hasCheckedExceptions(); final boolean hasCheckedExceptions = m.hasCheckedExceptions();
...@@ -478,27 +452,11 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -478,27 +452,11 @@ public class ClassWriter implements /* imports */ ClassConstants
dos.writeShort(methodAttributeCount); dos.writeShort(methodAttributeCount);
if (DEBUG) debugMessage("\tmethod attribute count = " + methodAttributeCount); if (DEBUG) debugMessage("\tmethod attribute count = " + methodAttributeCount);
if (isSyn) { if (hasSyn) {
if (DEBUG) debugMessage("\tmethod is synthetic"); if (DEBUG) debugMessage("\tmethod is synthetic");
writeSynthetic(); writeSynthetic();
} }
if (hasCheckedExceptions) {
CheckedExceptionElement[] exceptions = m.getCheckedExceptions();
dos.writeShort(_exceptionsIndex);
int attrSize = 2 /* number_of_exceptions */ +
exceptions.length * 2 /* exception_index */;
dos.writeInt(attrSize);
dos.writeShort(exceptions.length);
if (DEBUG) debugMessage("\tmethod has " + exceptions.length
+ " checked exception(s)");
for (int e = 0; e < exceptions.length; e++) {
short cpIndex = (short) exceptions[e].getClassCPIndex();
dos.writeShort(cpIndex);
}
}
if (isCodeAvailable) { if (isCodeAvailable) {
byte[] code = m.getByteCode(); byte[] code = m.getByteCode();
short codeAttrCount = 0; short codeAttrCount = 0;
...@@ -574,7 +532,7 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -574,7 +532,7 @@ public class ClassWriter implements /* imports */ ClassConstants
// start writing Code // start writing Code
dos.writeShort(_codeIndex); writeIndex(_codeIndex);
dos.writeInt(codeSize); dos.writeInt(codeSize);
if (DEBUG) debugMessage("\tcode attribute length = " + codeSize); if (DEBUG) debugMessage("\tcode attribute length = " + codeSize);
...@@ -608,7 +566,7 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -608,7 +566,7 @@ public class ClassWriter implements /* imports */ ClassConstants
// write LineNumberTable, if available. // write LineNumberTable, if available.
if (hasLineNumberTable) { if (hasLineNumberTable) {
dos.writeShort(_lineNumberTableIndex); writeIndex(_lineNumberTableIndex);
dos.writeInt(lineNumberAttrLen); dos.writeInt(lineNumberAttrLen);
dos.writeShort((short) lineNumberTable.length); dos.writeShort((short) lineNumberTable.length);
for (int l = 0; l < lineNumberTable.length; l++) { for (int l = 0; l < lineNumberTable.length; l++) {
...@@ -619,7 +577,7 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -619,7 +577,7 @@ public class ClassWriter implements /* imports */ ClassConstants
// write LocalVariableTable, if available. // write LocalVariableTable, if available.
if (hasLocalVariableTable) { if (hasLocalVariableTable) {
dos.writeShort((short) _localVariableTableIndex); writeIndex((short) _localVariableTableIndex);
dos.writeInt(localVarAttrLen); dos.writeInt(localVarAttrLen);
dos.writeShort((short) localVariableTable.length); dos.writeShort((short) localVariableTable.length);
for (int l = 0; l < localVariableTable.length; l++) { for (int l = 0; l < localVariableTable.length; l++) {
...@@ -632,6 +590,22 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -632,6 +590,22 @@ public class ClassWriter implements /* imports */ ClassConstants
} }
} }
if (hasCheckedExceptions) {
CheckedExceptionElement[] exceptions = m.getCheckedExceptions();
writeIndex(_exceptionsIndex);
int attrSize = 2 /* number_of_exceptions */ +
exceptions.length * 2 /* exception_index */;
dos.writeInt(attrSize);
dos.writeShort(exceptions.length);
if (DEBUG) debugMessage("\tmethod has " + exceptions.length
+ " checked exception(s)");
for (int e = 0; e < exceptions.length; e++) {
short cpIndex = (short) exceptions[e].getClassCPIndex();
dos.writeShort(cpIndex);
}
}
if (isGeneric) { if (isGeneric) {
writeGenericSignature(m.getGenericSignature().asString()); writeGenericSignature(m.getGenericSignature().asString());
} }
...@@ -643,7 +617,7 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -643,7 +617,7 @@ public class ClassWriter implements /* imports */ ClassConstants
} }
protected void writeGenericSignature(String signature) throws IOException { protected void writeGenericSignature(String signature) throws IOException {
dos.writeShort(_signatureIndex); writeIndex(_signatureIndex);
if (DEBUG) debugMessage("signature attribute = " + _signatureIndex); if (DEBUG) debugMessage("signature attribute = " + _signatureIndex);
dos.writeInt(2); dos.writeInt(2);
Short index = (Short) utf8ToIndex.get(signature); Short index = (Short) utf8ToIndex.get(signature);
...@@ -653,12 +627,12 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -653,12 +627,12 @@ public class ClassWriter implements /* imports */ ClassConstants
protected void writeClassAttributes() throws IOException { protected void writeClassAttributes() throws IOException {
final long flags = klass.getAccessFlags(); final long flags = klass.getAccessFlags();
final boolean isSyn = isSynthetic((short) flags); final boolean hasSyn = hasSyntheticAttribute((short) flags);
// check for source file // check for source file
short classAttributeCount = 0; short classAttributeCount = 0;
if (isSyn) if (hasSyn)
classAttributeCount++; classAttributeCount++;
Symbol sourceFileName = klass.getSourceFileName(); Symbol sourceFileName = klass.getSourceFileName();
...@@ -677,12 +651,12 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -677,12 +651,12 @@ public class ClassWriter implements /* imports */ ClassConstants
dos.writeShort(classAttributeCount); dos.writeShort(classAttributeCount);
if (DEBUG) debugMessage("class attribute count = " + classAttributeCount); if (DEBUG) debugMessage("class attribute count = " + classAttributeCount);
if (isSyn) if (hasSyn)
writeSynthetic(); writeSynthetic();
// write SourceFile, if any // write SourceFile, if any
if (sourceFileName != null) { if (sourceFileName != null) {
dos.writeShort(_sourceFileIndex); writeIndex(_sourceFileIndex);
if (DEBUG) debugMessage("source file attribute = " + _sourceFileIndex); if (DEBUG) debugMessage("source file attribute = " + _sourceFileIndex);
dos.writeInt(2); dos.writeInt(2);
Short index = (Short) utf8ToIndex.get(sourceFileName.asString()); Short index = (Short) utf8ToIndex.get(sourceFileName.asString());
...@@ -697,7 +671,7 @@ public class ClassWriter implements /* imports */ ClassConstants ...@@ -697,7 +671,7 @@ public class ClassWriter implements /* imports */ ClassConstants
// write inner classes, if any // write inner classes, if any
if (numInnerClasses != 0) { if (numInnerClasses != 0) {
dos.writeShort(_innerClassesIndex); writeIndex(_innerClassesIndex);
final int innerAttrLen = 2 /* number_of_inner_classes */ + final int innerAttrLen = 2 /* number_of_inner_classes */ +
numInnerClasses * ( numInnerClasses * (
2 /* inner_class_info_index */ + 2 /* inner_class_info_index */ +
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册