6826261: class file dumping from SA is broken
authornever
Fri, 03 Apr 2009 18:51:31 -0700
changeset 2529 9dfd3cb5648f
parent 2528 feeff04a3129
child 2530 8e437991f5c0
6826261: class file dumping from SA is broken Reviewed-by: kvn, jcoomes
hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java	Fri Apr 03 13:33:32 2009 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java	Fri Apr 03 18:51:31 2009 -0700
@@ -142,34 +142,35 @@
     // from jvm.h
 
     public static final long JVM_RECOGNIZED_CLASS_MODIFIERS   = (JVM_ACC_PUBLIC |
-                                        JVM_ACC_FINAL |
-                                        JVM_ACC_SUPER |
-                                        JVM_ACC_INTERFACE |
-                                        JVM_ACC_ABSTRACT |
-                                        JVM_ACC_ANNOTATION |
-                                        JVM_ACC_SYNTHETIC);
+                                                                 JVM_ACC_FINAL |
+                                                                 JVM_ACC_SUPER |
+                                                                 JVM_ACC_INTERFACE |
+                                                                 JVM_ACC_ABSTRACT |
+                                                                 JVM_ACC_ANNOTATION |
+                                                                 JVM_ACC_ENUM |
+                                                                 JVM_ACC_SYNTHETIC);
 
 
     public static final long JVM_RECOGNIZED_FIELD_MODIFIERS  = (JVM_ACC_PUBLIC |
-                                        JVM_ACC_PRIVATE |
-                                        JVM_ACC_PROTECTED |
-                                        JVM_ACC_STATIC |
-                                        JVM_ACC_FINAL |
-                                        JVM_ACC_VOLATILE |
-                                        JVM_ACC_TRANSIENT |
-                                        JVM_ACC_ENUM |
-                                        JVM_ACC_SYNTHETIC);
+                                                                JVM_ACC_PRIVATE |
+                                                                JVM_ACC_PROTECTED |
+                                                                JVM_ACC_STATIC |
+                                                                JVM_ACC_FINAL |
+                                                                JVM_ACC_VOLATILE |
+                                                                JVM_ACC_TRANSIENT |
+                                                                JVM_ACC_ENUM |
+                                                                JVM_ACC_SYNTHETIC);
 
     public static final long JVM_RECOGNIZED_METHOD_MODIFIERS  = (JVM_ACC_PUBLIC |
-                                         JVM_ACC_PRIVATE |
-                                         JVM_ACC_PROTECTED |
-                                         JVM_ACC_STATIC |
-                                         JVM_ACC_FINAL |
-                                         JVM_ACC_SYNCHRONIZED |
-                                         JVM_ACC_BRIDGE |
-                                         JVM_ACC_VARARGS |
-                                         JVM_ACC_NATIVE |
-                                         JVM_ACC_ABSTRACT |
-                                         JVM_ACC_STRICT |
-                                         JVM_ACC_SYNTHETIC);
+                                                                 JVM_ACC_PRIVATE |
+                                                                 JVM_ACC_PROTECTED |
+                                                                 JVM_ACC_STATIC |
+                                                                 JVM_ACC_FINAL |
+                                                                 JVM_ACC_SYNCHRONIZED |
+                                                                 JVM_ACC_BRIDGE |
+                                                                 JVM_ACC_VARARGS |
+                                                                 JVM_ACC_NATIVE |
+                                                                 JVM_ACC_ABSTRACT |
+                                                                 JVM_ACC_STRICT |
+                                                                 JVM_ACC_SYNTHETIC);
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java	Fri Apr 03 13:33:32 2009 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java	Fri Apr 03 18:51:31 2009 -0700
@@ -89,29 +89,6 @@
             // update the code buffer hotspot specific bytecode with the jvm 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;
             switch (bytecode) {
                 // bytecodes with ConstantPoolCache index
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java	Fri Apr 03 13:33:32 2009 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java	Fri Apr 03 18:51:31 2009 -0700
@@ -59,8 +59,14 @@
             SystemDictionary dict = VM.getVM().getSystemDictionary();
             dict.classesDo(new SystemDictionary.ClassVisitor() {
                     public void visit(Klass k) {
-                        if (k instanceof InstanceKlass)
-                            dumpKlass((InstanceKlass) k);
+                        if (k instanceof InstanceKlass) {
+                            try {
+                                dumpKlass((InstanceKlass) k);
+                            } catch (Exception e) {
+                                System.out.println(k.getName().asString());
+                                e.printStackTrace();
+                            }
+                        }
                     }
                 });
         }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Fri Apr 03 13:33:32 2009 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Fri Apr 03 18:51:31 2009 -0700
@@ -40,7 +40,6 @@
     protected InstanceKlass     klass;
     protected DataOutputStream  dos;
     protected ConstantPool      cpool;
-    protected boolean           is15Format;
 
     // Map between class name to index of type CONSTANT_Class
     protected Map               classToIndex = new HashMap();
@@ -73,7 +72,6 @@
         klass = kls;
         dos = new DataOutputStream(os);
         cpool = klass.getConstants();
-        is15Format = is15ClassFile();
     }
 
     public void write() throws IOException {
@@ -82,7 +80,7 @@
         // write magic
         dos.writeInt(0xCAFEBABE);
 
-        writeVersion(is15Format);
+        writeVersion();
         writeConstantPool();
         writeClassAccessFlags();
         writeThisClass();
@@ -96,43 +94,14 @@
         dos.flush();
     }
 
-    protected boolean is15ClassFile() {
-        // if klass has generic signature, then it is 1.5  class file.
-        if (klass.getGenericSignature() != null) {
-           return true;
-        }
-
-        // if atleast one method has generic signature
-        // , then we have 1.5 class file.
-        ObjArray methods = klass.getMethods();
-        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() throws IOException {
+        dos.writeShort((short)klass.minorVersion());
+        dos.writeShort((short)klass.majorVersion());
     }
 
-    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 writeIndex(int index) throws IOException {
+        if (index == 0) throw new InternalError();
+        dos.writeShort(index);
     }
 
     protected void writeConstantPool() throws IOException {
@@ -392,8 +361,8 @@
             if (DEBUG) debugMessage("\tfield name = " + nameIndex + ", signature = " + signatureIndex);
 
             short fieldAttributeCount = 0;
-            boolean isSyn = isSynthetic(accessFlags);
-            if (isSyn)
+            boolean hasSyn = hasSyntheticAttribute(accessFlags);
+            if (hasSyn)
                 fieldAttributeCount++;
 
             short initvalIndex = fields.getShortAt(index + InstanceKlass.INITVAL_INDEX_OFFSET);
@@ -407,18 +376,18 @@
             dos.writeShort(fieldAttributeCount);
 
             // write synthetic, if applicable
-            if (isSyn)
+            if (hasSyn)
                 writeSynthetic();
 
             if (initvalIndex != 0) {
-                dos.writeShort(_constantValueIndex);
+                writeIndex(_constantValueIndex);
                 dos.writeInt(2);
                 dos.writeShort(initvalIndex);
                 if (DEBUG) debugMessage("\tfield init value = " + initvalIndex);
             }
 
             if (genSigIndex != 0) {
-                dos.writeShort(_signatureIndex);
+                writeIndex(_signatureIndex);
                 dos.writeInt(2);
                 dos.writeShort(genSigIndex);
                 if (DEBUG) debugMessage("\tfield generic signature index " + genSigIndex);
@@ -430,8 +399,13 @@
         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 {
-        dos.writeShort(_syntheticIndex);
+        writeIndex(_syntheticIndex);
         dos.writeInt(0);
     }
 
@@ -459,8 +433,8 @@
 
         short methodAttributeCount = 0;
 
-        final boolean isSyn = isSynthetic((short)accessFlags);
-        if (isSyn)
+        final boolean hasSyn = hasSyntheticAttribute((short)accessFlags);
+        if (hasSyn)
             methodAttributeCount++;
 
         final boolean hasCheckedExceptions = m.hasCheckedExceptions();
@@ -478,27 +452,11 @@
         dos.writeShort(methodAttributeCount);
         if (DEBUG) debugMessage("\tmethod attribute count = " + methodAttributeCount);
 
-        if (isSyn) {
+        if (hasSyn) {
             if (DEBUG) debugMessage("\tmethod is synthetic");
             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) {
             byte[] code = m.getByteCode();
             short codeAttrCount = 0;
@@ -574,7 +532,7 @@
 
             // start writing Code
 
-            dos.writeShort(_codeIndex);
+            writeIndex(_codeIndex);
 
             dos.writeInt(codeSize);
             if (DEBUG) debugMessage("\tcode attribute length = " + codeSize);
@@ -608,7 +566,7 @@
 
             // write LineNumberTable, if available.
             if (hasLineNumberTable) {
-                dos.writeShort(_lineNumberTableIndex);
+                writeIndex(_lineNumberTableIndex);
                 dos.writeInt(lineNumberAttrLen);
                 dos.writeShort((short) lineNumberTable.length);
                 for (int l = 0; l < lineNumberTable.length; l++) {
@@ -619,7 +577,7 @@
 
             // write LocalVariableTable, if available.
             if (hasLocalVariableTable) {
-                dos.writeShort((short) _localVariableTableIndex);
+                writeIndex((short) _localVariableTableIndex);
                 dos.writeInt(localVarAttrLen);
                 dos.writeShort((short) localVariableTable.length);
                 for (int l = 0; l < localVariableTable.length; l++) {
@@ -632,6 +590,22 @@
             }
         }
 
+        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) {
            writeGenericSignature(m.getGenericSignature().asString());
         }
@@ -643,7 +617,7 @@
     }
 
     protected void writeGenericSignature(String signature) throws IOException {
-        dos.writeShort(_signatureIndex);
+        writeIndex(_signatureIndex);
         if (DEBUG) debugMessage("signature attribute = " + _signatureIndex);
         dos.writeInt(2);
         Short index = (Short) utf8ToIndex.get(signature);
@@ -653,12 +627,12 @@
 
     protected void writeClassAttributes() throws IOException {
         final long flags = klass.getAccessFlags();
-        final boolean isSyn = isSynthetic((short) flags);
+        final boolean hasSyn = hasSyntheticAttribute((short) flags);
 
         // check for source file
         short classAttributeCount = 0;
 
-        if (isSyn)
+        if (hasSyn)
             classAttributeCount++;
 
         Symbol sourceFileName = klass.getSourceFileName();
@@ -677,12 +651,12 @@
         dos.writeShort(classAttributeCount);
         if (DEBUG) debugMessage("class attribute count = " + classAttributeCount);
 
-        if (isSyn)
+        if (hasSyn)
             writeSynthetic();
 
         // write SourceFile, if any
         if (sourceFileName != null) {
-            dos.writeShort(_sourceFileIndex);
+            writeIndex(_sourceFileIndex);
             if (DEBUG) debugMessage("source file attribute = " + _sourceFileIndex);
             dos.writeInt(2);
             Short index = (Short) utf8ToIndex.get(sourceFileName.asString());
@@ -697,7 +671,7 @@
 
         // write inner classes, if any
         if (numInnerClasses != 0) {
-            dos.writeShort(_innerClassesIndex);
+            writeIndex(_innerClassesIndex);
             final int innerAttrLen = 2 /* number_of_inner_classes */ +
                                      numInnerClasses * (
                                                  2 /* inner_class_info_index */ +