Fri, 03 Apr 2009 18:51:31 -0700
6826261: class file dumping from SA is broken
Reviewed-by: kvn, jcoomes
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Fri Apr 03 13:33:32 2009 -0700 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Fri Apr 03 18:51:31 2009 -0700 1.3 @@ -142,34 +142,35 @@ 1.4 // from jvm.h 1.5 1.6 public static final long JVM_RECOGNIZED_CLASS_MODIFIERS = (JVM_ACC_PUBLIC | 1.7 - JVM_ACC_FINAL | 1.8 - JVM_ACC_SUPER | 1.9 - JVM_ACC_INTERFACE | 1.10 - JVM_ACC_ABSTRACT | 1.11 - JVM_ACC_ANNOTATION | 1.12 - JVM_ACC_SYNTHETIC); 1.13 + JVM_ACC_FINAL | 1.14 + JVM_ACC_SUPER | 1.15 + JVM_ACC_INTERFACE | 1.16 + JVM_ACC_ABSTRACT | 1.17 + JVM_ACC_ANNOTATION | 1.18 + JVM_ACC_ENUM | 1.19 + JVM_ACC_SYNTHETIC); 1.20 1.21 1.22 public static final long JVM_RECOGNIZED_FIELD_MODIFIERS = (JVM_ACC_PUBLIC | 1.23 - JVM_ACC_PRIVATE | 1.24 - JVM_ACC_PROTECTED | 1.25 - JVM_ACC_STATIC | 1.26 - JVM_ACC_FINAL | 1.27 - JVM_ACC_VOLATILE | 1.28 - JVM_ACC_TRANSIENT | 1.29 - JVM_ACC_ENUM | 1.30 - JVM_ACC_SYNTHETIC); 1.31 + JVM_ACC_PRIVATE | 1.32 + JVM_ACC_PROTECTED | 1.33 + JVM_ACC_STATIC | 1.34 + JVM_ACC_FINAL | 1.35 + JVM_ACC_VOLATILE | 1.36 + JVM_ACC_TRANSIENT | 1.37 + JVM_ACC_ENUM | 1.38 + JVM_ACC_SYNTHETIC); 1.39 1.40 public static final long JVM_RECOGNIZED_METHOD_MODIFIERS = (JVM_ACC_PUBLIC | 1.41 - JVM_ACC_PRIVATE | 1.42 - JVM_ACC_PROTECTED | 1.43 - JVM_ACC_STATIC | 1.44 - JVM_ACC_FINAL | 1.45 - JVM_ACC_SYNCHRONIZED | 1.46 - JVM_ACC_BRIDGE | 1.47 - JVM_ACC_VARARGS | 1.48 - JVM_ACC_NATIVE | 1.49 - JVM_ACC_ABSTRACT | 1.50 - JVM_ACC_STRICT | 1.51 - JVM_ACC_SYNTHETIC); 1.52 + JVM_ACC_PRIVATE | 1.53 + JVM_ACC_PROTECTED | 1.54 + JVM_ACC_STATIC | 1.55 + JVM_ACC_FINAL | 1.56 + JVM_ACC_SYNCHRONIZED | 1.57 + JVM_ACC_BRIDGE | 1.58 + JVM_ACC_VARARGS | 1.59 + JVM_ACC_NATIVE | 1.60 + JVM_ACC_ABSTRACT | 1.61 + JVM_ACC_STRICT | 1.62 + JVM_ACC_SYNTHETIC); 1.63 }
2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java Fri Apr 03 13:33:32 2009 -0700 2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java Fri Apr 03 18:51:31 2009 -0700 2.3 @@ -89,29 +89,6 @@ 2.4 // update the code buffer hotspot specific bytecode with the jvm bytecode 2.5 code[bci] = (byte) (0xFF & bytecode); 2.6 2.7 - // RewriteFrequentPairs 2.8 - if(hotspotcode == Bytecodes._fast_iaccess_0 || 2.9 - hotspotcode == Bytecodes._fast_aaccess_0 || 2.10 - hotspotcode == Bytecodes._fast_faccess_0) { 2.11 - // rewrite next bytecode as _getfield 2.12 - bci++; 2.13 - code[bci] = (byte) (0xFF & Bytecodes._getfield); 2.14 - bytecode = Bytecodes._getfield; 2.15 - hotspotcode = Bytecodes._getfield; 2.16 - } else if (hotspotcode == Bytecodes._fast_iload2) { 2.17 - // rewrite next bytecode as _iload 2.18 - bci++; 2.19 - code[bci] = (byte) (0xFF & Bytecodes._iload); 2.20 - bytecode = Bytecodes._iload; 2.21 - hotspotcode = Bytecodes._iload; 2.22 - } else if (hotspotcode == Bytecodes._fast_icaload) { 2.23 - // rewrite next bytecode as _caload 2.24 - bci++; 2.25 - code[bci] = (byte) (0xFF & Bytecodes._caload); 2.26 - bytecode = Bytecodes._caload; 2.27 - bytecode = Bytecodes._caload; 2.28 - } 2.29 - 2.30 short cpoolIndex = 0; 2.31 switch (bytecode) { 2.32 // bytecodes with ConstantPoolCache index
3.1 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Fri Apr 03 13:33:32 2009 -0700 3.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Fri Apr 03 18:51:31 2009 -0700 3.3 @@ -59,8 +59,14 @@ 3.4 SystemDictionary dict = VM.getVM().getSystemDictionary(); 3.5 dict.classesDo(new SystemDictionary.ClassVisitor() { 3.6 public void visit(Klass k) { 3.7 - if (k instanceof InstanceKlass) 3.8 - dumpKlass((InstanceKlass) k); 3.9 + if (k instanceof InstanceKlass) { 3.10 + try { 3.11 + dumpKlass((InstanceKlass) k); 3.12 + } catch (Exception e) { 3.13 + System.out.println(k.getName().asString()); 3.14 + e.printStackTrace(); 3.15 + } 3.16 + } 3.17 } 3.18 }); 3.19 }
4.1 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Fri Apr 03 13:33:32 2009 -0700 4.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Fri Apr 03 18:51:31 2009 -0700 4.3 @@ -40,7 +40,6 @@ 4.4 protected InstanceKlass klass; 4.5 protected DataOutputStream dos; 4.6 protected ConstantPool cpool; 4.7 - protected boolean is15Format; 4.8 4.9 // Map between class name to index of type CONSTANT_Class 4.10 protected Map classToIndex = new HashMap(); 4.11 @@ -73,7 +72,6 @@ 4.12 klass = kls; 4.13 dos = new DataOutputStream(os); 4.14 cpool = klass.getConstants(); 4.15 - is15Format = is15ClassFile(); 4.16 } 4.17 4.18 public void write() throws IOException { 4.19 @@ -82,7 +80,7 @@ 4.20 // write magic 4.21 dos.writeInt(0xCAFEBABE); 4.22 4.23 - writeVersion(is15Format); 4.24 + writeVersion(); 4.25 writeConstantPool(); 4.26 writeClassAccessFlags(); 4.27 writeThisClass(); 4.28 @@ -96,43 +94,14 @@ 4.29 dos.flush(); 4.30 } 4.31 4.32 - protected boolean is15ClassFile() { 4.33 - // if klass has generic signature, then it is 1.5 class file. 4.34 - if (klass.getGenericSignature() != null) { 4.35 - return true; 4.36 - } 4.37 - 4.38 - // if atleast one method has generic signature 4.39 - // , then we have 1.5 class file. 4.40 - ObjArray methods = klass.getMethods(); 4.41 - final int numMethods = (int) methods.getLength(); 4.42 - for (int m = 0; m < numMethods; m++) { 4.43 - Method curMethod = (Method) methods.getObjAt(m); 4.44 - if (curMethod.getGenericSignature() != null) { 4.45 - return true; 4.46 - } 4.47 - } 4.48 - 4.49 - // if atleast one field has non-zero generic signature index, then we have 4.50 - // 1.5 class file 4.51 - TypeArray fields = klass.getFields(); 4.52 - final int numFields = (int) fields.getLength(); 4.53 - for (int f = 0; f < numFields; f += InstanceKlass.NEXT_OFFSET) { 4.54 - short genSigIndex = fields.getShortAt(f + InstanceKlass.GENERIC_SIGNATURE_INDEX_OFFSET); 4.55 - if (genSigIndex != (short)0) return true; 4.56 - } 4.57 - 4.58 - return false; 4.59 + protected void writeVersion() throws IOException { 4.60 + dos.writeShort((short)klass.minorVersion()); 4.61 + dos.writeShort((short)klass.majorVersion()); 4.62 } 4.63 4.64 - protected void writeVersion(boolean is15Format) throws IOException { 4.65 - if (is15Format) { 4.66 - dos.writeShort(MINOR_VERSION); 4.67 - dos.writeShort(MAJOR_VERSION); 4.68 - } else { 4.69 - dos.writeShort(MINOR_VERSION_OLD); 4.70 - dos.writeShort(MAJOR_VERSION_OLD); 4.71 - } 4.72 + protected void writeIndex(int index) throws IOException { 4.73 + if (index == 0) throw new InternalError(); 4.74 + dos.writeShort(index); 4.75 } 4.76 4.77 protected void writeConstantPool() throws IOException { 4.78 @@ -392,8 +361,8 @@ 4.79 if (DEBUG) debugMessage("\tfield name = " + nameIndex + ", signature = " + signatureIndex); 4.80 4.81 short fieldAttributeCount = 0; 4.82 - boolean isSyn = isSynthetic(accessFlags); 4.83 - if (isSyn) 4.84 + boolean hasSyn = hasSyntheticAttribute(accessFlags); 4.85 + if (hasSyn) 4.86 fieldAttributeCount++; 4.87 4.88 short initvalIndex = fields.getShortAt(index + InstanceKlass.INITVAL_INDEX_OFFSET); 4.89 @@ -407,18 +376,18 @@ 4.90 dos.writeShort(fieldAttributeCount); 4.91 4.92 // write synthetic, if applicable 4.93 - if (isSyn) 4.94 + if (hasSyn) 4.95 writeSynthetic(); 4.96 4.97 if (initvalIndex != 0) { 4.98 - dos.writeShort(_constantValueIndex); 4.99 + writeIndex(_constantValueIndex); 4.100 dos.writeInt(2); 4.101 dos.writeShort(initvalIndex); 4.102 if (DEBUG) debugMessage("\tfield init value = " + initvalIndex); 4.103 } 4.104 4.105 if (genSigIndex != 0) { 4.106 - dos.writeShort(_signatureIndex); 4.107 + writeIndex(_signatureIndex); 4.108 dos.writeInt(2); 4.109 dos.writeShort(genSigIndex); 4.110 if (DEBUG) debugMessage("\tfield generic signature index " + genSigIndex); 4.111 @@ -430,8 +399,13 @@ 4.112 return (accessFlags & (short) JVM_ACC_SYNTHETIC) != 0; 4.113 } 4.114 4.115 + protected boolean hasSyntheticAttribute(short accessFlags) { 4.116 + // Check if flags have the attribute and if the constant pool contains an entry for it. 4.117 + return isSynthetic(accessFlags) && _syntheticIndex != 0; 4.118 + } 4.119 + 4.120 protected void writeSynthetic() throws IOException { 4.121 - dos.writeShort(_syntheticIndex); 4.122 + writeIndex(_syntheticIndex); 4.123 dos.writeInt(0); 4.124 } 4.125 4.126 @@ -459,8 +433,8 @@ 4.127 4.128 short methodAttributeCount = 0; 4.129 4.130 - final boolean isSyn = isSynthetic((short)accessFlags); 4.131 - if (isSyn) 4.132 + final boolean hasSyn = hasSyntheticAttribute((short)accessFlags); 4.133 + if (hasSyn) 4.134 methodAttributeCount++; 4.135 4.136 final boolean hasCheckedExceptions = m.hasCheckedExceptions(); 4.137 @@ -478,27 +452,11 @@ 4.138 dos.writeShort(methodAttributeCount); 4.139 if (DEBUG) debugMessage("\tmethod attribute count = " + methodAttributeCount); 4.140 4.141 - if (isSyn) { 4.142 + if (hasSyn) { 4.143 if (DEBUG) debugMessage("\tmethod is synthetic"); 4.144 writeSynthetic(); 4.145 } 4.146 4.147 - if (hasCheckedExceptions) { 4.148 - CheckedExceptionElement[] exceptions = m.getCheckedExceptions(); 4.149 - dos.writeShort(_exceptionsIndex); 4.150 - 4.151 - int attrSize = 2 /* number_of_exceptions */ + 4.152 - exceptions.length * 2 /* exception_index */; 4.153 - dos.writeInt(attrSize); 4.154 - dos.writeShort(exceptions.length); 4.155 - if (DEBUG) debugMessage("\tmethod has " + exceptions.length 4.156 - + " checked exception(s)"); 4.157 - for (int e = 0; e < exceptions.length; e++) { 4.158 - short cpIndex = (short) exceptions[e].getClassCPIndex(); 4.159 - dos.writeShort(cpIndex); 4.160 - } 4.161 - } 4.162 - 4.163 if (isCodeAvailable) { 4.164 byte[] code = m.getByteCode(); 4.165 short codeAttrCount = 0; 4.166 @@ -574,7 +532,7 @@ 4.167 4.168 // start writing Code 4.169 4.170 - dos.writeShort(_codeIndex); 4.171 + writeIndex(_codeIndex); 4.172 4.173 dos.writeInt(codeSize); 4.174 if (DEBUG) debugMessage("\tcode attribute length = " + codeSize); 4.175 @@ -608,7 +566,7 @@ 4.176 4.177 // write LineNumberTable, if available. 4.178 if (hasLineNumberTable) { 4.179 - dos.writeShort(_lineNumberTableIndex); 4.180 + writeIndex(_lineNumberTableIndex); 4.181 dos.writeInt(lineNumberAttrLen); 4.182 dos.writeShort((short) lineNumberTable.length); 4.183 for (int l = 0; l < lineNumberTable.length; l++) { 4.184 @@ -619,7 +577,7 @@ 4.185 4.186 // write LocalVariableTable, if available. 4.187 if (hasLocalVariableTable) { 4.188 - dos.writeShort((short) _localVariableTableIndex); 4.189 + writeIndex((short) _localVariableTableIndex); 4.190 dos.writeInt(localVarAttrLen); 4.191 dos.writeShort((short) localVariableTable.length); 4.192 for (int l = 0; l < localVariableTable.length; l++) { 4.193 @@ -632,6 +590,22 @@ 4.194 } 4.195 } 4.196 4.197 + if (hasCheckedExceptions) { 4.198 + CheckedExceptionElement[] exceptions = m.getCheckedExceptions(); 4.199 + writeIndex(_exceptionsIndex); 4.200 + 4.201 + int attrSize = 2 /* number_of_exceptions */ + 4.202 + exceptions.length * 2 /* exception_index */; 4.203 + dos.writeInt(attrSize); 4.204 + dos.writeShort(exceptions.length); 4.205 + if (DEBUG) debugMessage("\tmethod has " + exceptions.length 4.206 + + " checked exception(s)"); 4.207 + for (int e = 0; e < exceptions.length; e++) { 4.208 + short cpIndex = (short) exceptions[e].getClassCPIndex(); 4.209 + dos.writeShort(cpIndex); 4.210 + } 4.211 + } 4.212 + 4.213 if (isGeneric) { 4.214 writeGenericSignature(m.getGenericSignature().asString()); 4.215 } 4.216 @@ -643,7 +617,7 @@ 4.217 } 4.218 4.219 protected void writeGenericSignature(String signature) throws IOException { 4.220 - dos.writeShort(_signatureIndex); 4.221 + writeIndex(_signatureIndex); 4.222 if (DEBUG) debugMessage("signature attribute = " + _signatureIndex); 4.223 dos.writeInt(2); 4.224 Short index = (Short) utf8ToIndex.get(signature); 4.225 @@ -653,12 +627,12 @@ 4.226 4.227 protected void writeClassAttributes() throws IOException { 4.228 final long flags = klass.getAccessFlags(); 4.229 - final boolean isSyn = isSynthetic((short) flags); 4.230 + final boolean hasSyn = hasSyntheticAttribute((short) flags); 4.231 4.232 // check for source file 4.233 short classAttributeCount = 0; 4.234 4.235 - if (isSyn) 4.236 + if (hasSyn) 4.237 classAttributeCount++; 4.238 4.239 Symbol sourceFileName = klass.getSourceFileName(); 4.240 @@ -677,12 +651,12 @@ 4.241 dos.writeShort(classAttributeCount); 4.242 if (DEBUG) debugMessage("class attribute count = " + classAttributeCount); 4.243 4.244 - if (isSyn) 4.245 + if (hasSyn) 4.246 writeSynthetic(); 4.247 4.248 // write SourceFile, if any 4.249 if (sourceFileName != null) { 4.250 - dos.writeShort(_sourceFileIndex); 4.251 + writeIndex(_sourceFileIndex); 4.252 if (DEBUG) debugMessage("source file attribute = " + _sourceFileIndex); 4.253 dos.writeInt(2); 4.254 Short index = (Short) utf8ToIndex.get(sourceFileName.asString()); 4.255 @@ -697,7 +671,7 @@ 4.256 4.257 // write inner classes, if any 4.258 if (numInnerClasses != 0) { 4.259 - dos.writeShort(_innerClassesIndex); 4.260 + writeIndex(_innerClassesIndex); 4.261 final int innerAttrLen = 2 /* number_of_inner_classes */ + 4.262 numInnerClasses * ( 4.263 2 /* inner_class_info_index */ +