changeset 2723:cb315dc80374

7092278: "jmap -finalizerinfo" throws "sun.jvm.hotspot.utilities.AssertionFailure: invalid cp index 0 137" Reviewed-by: kvn
author never
date Thu, 29 Sep 2011 09:53:56 -0700
parents a92cdbac8b9e
children 098acdf97f09
files agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java agent/src/share/classes/sun/jvm/hotspot/runtime/vmSymbols.java agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java src/share/vm/classfile/vmSymbols.hpp src/share/vm/runtime/vmStructs.cpp
diffstat 5 files changed, 132 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Mon Sep 26 10:24:05 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu Sep 29 09:53:56 2011 -0700
@@ -44,14 +44,14 @@
   }
 
   // field offset constants
-  public static int ACCESS_FLAGS_OFFSET;
-  public static int NAME_INDEX_OFFSET;
-  public static int SIGNATURE_INDEX_OFFSET;
-  public static int INITVAL_INDEX_OFFSET;
-  public static int LOW_OFFSET;
-  public static int HIGH_OFFSET;
-  public static int GENERIC_SIGNATURE_INDEX_OFFSET;
-  public static int FIELD_SLOTS;
+  private static int ACCESS_FLAGS_OFFSET;
+  private static int NAME_INDEX_OFFSET;
+  private static int SIGNATURE_INDEX_OFFSET;
+  private static int INITVAL_INDEX_OFFSET;
+  private static int LOW_OFFSET;
+  private static int HIGH_OFFSET;
+  private static int GENERIC_SIGNATURE_INDEX_OFFSET;
+  private static int FIELD_SLOTS;
   public static int IMPLEMENTORS_LIMIT;
 
   // ClassState constants
@@ -122,6 +122,13 @@
 
   InstanceKlass(OopHandle handle, ObjectHeap heap) {
     super(handle, heap);
+    if (getJavaFieldsCount() != getAllFieldsCount()) {
+      // Exercise the injected field logic
+      for (int i = getJavaFieldsCount(); i < getAllFieldsCount(); i++) {
+        getFieldName(i);
+        getFieldSignature(i);
+      }
+    }
   }
 
   private static OopField  arrayKlasses;
@@ -253,24 +260,51 @@
     return getFields().getShortAt(index * FIELD_SLOTS + ACCESS_FLAGS_OFFSET);
   }
 
+  public short getFieldNameIndex(int index) {
+    if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;");
+    return getFields().getShortAt(index * FIELD_SLOTS + NAME_INDEX_OFFSET);
+  }
+
   public Symbol getFieldName(int index) {
     int nameIndex = getFields().getShortAt(index * FIELD_SLOTS + NAME_INDEX_OFFSET);
-    return getConstants().getSymbolAt(nameIndex);
+    if (index < getJavaFieldsCount()) {
+      return getConstants().getSymbolAt(nameIndex);
+    } else {
+      return vmSymbols.symbolAt(nameIndex);
+    }
+  }
+
+  public short getFieldSignatureIndex(int index) {
+    if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;");
+    return getFields().getShortAt(index * FIELD_SLOTS + SIGNATURE_INDEX_OFFSET);
   }
 
   public Symbol getFieldSignature(int index) {
     int signatureIndex = getFields().getShortAt(index * FIELD_SLOTS + SIGNATURE_INDEX_OFFSET);
-    return getConstants().getSymbolAt(signatureIndex);
+    if (index < getJavaFieldsCount()) {
+      return getConstants().getSymbolAt(signatureIndex);
+    } else {
+      return vmSymbols.symbolAt(signatureIndex);
+    }
+  }
+
+  public short getFieldGenericSignatureIndex(int index) {
+    return getFields().getShortAt(index * FIELD_SLOTS + GENERIC_SIGNATURE_INDEX_OFFSET);
   }
 
   public Symbol getFieldGenericSignature(int index) {
-    short genericSignatureIndex = getFields().getShortAt(index * FIELD_SLOTS + GENERIC_SIGNATURE_INDEX_OFFSET);
+    short genericSignatureIndex = getFieldGenericSignatureIndex(index);
     if (genericSignatureIndex != 0)  {
       return getConstants().getSymbolAt(genericSignatureIndex);
     }
     return null;
   }
 
+  public short getFieldInitialValueIndex(int index) {
+    if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;");
+    return getFields().getShortAt(index * FIELD_SLOTS + INITVAL_INDEX_OFFSET);
+  }
+
   public int getFieldOffset(int index) {
     TypeArray fields = getFields();
     return VM.getVM().buildIntFromShorts(fields.getShortAt(index * FIELD_SLOTS + LOW_OFFSET),
@@ -288,7 +322,7 @@
   public Klass     getImplementor(int i)    { return (Klass)        implementors[i].getValue(this); }
   public TypeArray getFields()              { return (TypeArray)    fields.getValue(this); }
   public int       getJavaFieldsCount()     { return                (int) javaFieldsCount.getValue(this); }
-  public int       getAllFieldsCount()      { return                (int)getFields().getLength(); }
+  public int       getAllFieldsCount()      { return                (int)getFields().getLength() / FIELD_SLOTS; }
   public ConstantPool getConstants()        { return (ConstantPool) constants.getValue(this); }
   public Oop       getClassLoader()         { return                classLoader.getValue(this); }
   public Oop       getProtectionDomain()    { return                protectionDomain.getValue(this); }
@@ -511,7 +545,6 @@
   }
 
   void iterateStaticFieldsInternal(OopVisitor visitor) {
-    TypeArray fields = getFields();
     int length = getJavaFieldsCount();
     for (int index = 0; index < length; index++) {
       short accessFlags    = getFieldAccessFlags(index);
@@ -541,8 +574,6 @@
     if (getSuper() != null) {
       ((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
     }
-    TypeArray fields = getFields();
-
     int length = getJavaFieldsCount();
     for (int index = 0; index < length; index++) {
       short accessFlags    = getFieldAccessFlags(index);
@@ -556,9 +587,7 @@
 
   /** Field access by name. */
   public Field findLocalField(Symbol name, Symbol sig) {
-    TypeArray fields = getFields();
-    int length = (int) fields.getLength();
-    ConstantPool cp = getConstants();
+    int length = getJavaFieldsCount();
     for (int i = 0; i < length; i++) {
       Symbol f_name = getFieldName(i);
       Symbol f_sig  = getFieldSignature(i);
@@ -648,8 +677,6 @@
     public List getImmediateFields() {
         // A list of Fields for each field declared in this class/interface,
         // not including inherited fields.
-        TypeArray fields = getFields();
-
         int length = getJavaFieldsCount();
         List immediateFields = new ArrayList(length);
         for (int index = 0; index < length; index++) {
@@ -839,7 +866,6 @@
 
   // Creates new field from index in fields TypeArray
   private Field newField(int index) {
-    TypeArray fields = getFields();
     FieldType type = new FieldType(getFieldSignature(index));
     if (type.isOop()) {
      if (VM.getVM().isCompressedOopsEnabled()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/vmSymbols.java	Thu Sep 29 09:53:56 2011 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.memory.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+
+public class vmSymbols {
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static Address symbolsAddress;
+  private static int FIRST_SID;
+  private static int SID_LIMIT;
+
+  private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+    Type type            = db.lookupType("vmSymbols");
+    symbolsAddress       = type.getAddressField("_symbols[0]").getStaticFieldAddress();
+    FIRST_SID            = db.lookupIntConstant("vmSymbols::FIRST_SID");
+    SID_LIMIT            = db.lookupIntConstant("vmSymbols::SID_LIMIT");
+  }
+
+  public static Symbol symbolAt(int id) {
+    if (id < FIRST_SID || id >= SID_LIMIT) throw new IndexOutOfBoundsException("bad SID " + id);
+    return Symbol.create(symbolsAddress.getAddressAt(id * VM.getVM().getAddressSize()));
+  }
+}
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Mon Sep 26 10:24:05 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Thu Sep 29 09:53:56 2011 -0700
@@ -379,23 +379,21 @@
     }
 
     protected void writeFields() throws IOException {
-        TypeArray fields = klass.getFields();
         final int length = klass.getJavaFieldsCount();
 
         // write number of fields
-        dos.writeShort((short) (length / InstanceKlass.FIELD_SLOTS) );
+        dos.writeShort((short) length);
 
-        if (DEBUG) debugMessage("number of fields = "
-                                + length/InstanceKlass.FIELD_SLOTS);
+        if (DEBUG) debugMessage("number of fields = " + length);
 
-        for (int index = 0; index < length; index += InstanceKlass.FIELD_SLOTS) {
-            short accessFlags    = fields.getShortAt(index + InstanceKlass.ACCESS_FLAGS_OFFSET);
+        for (int index = 0; index < length; index++) {
+            short accessFlags    = klass.getFieldAccessFlags(index);
             dos.writeShort(accessFlags & (short) JVM_RECOGNIZED_FIELD_MODIFIERS);
 
-            short nameIndex    = fields.getShortAt(index + InstanceKlass.NAME_INDEX_OFFSET);
+            short nameIndex    = klass.getFieldNameIndex(index);
             dos.writeShort(nameIndex);
 
-            short signatureIndex = fields.getShortAt(index + InstanceKlass.SIGNATURE_INDEX_OFFSET);
+            short signatureIndex = klass.getFieldSignatureIndex(index);
             dos.writeShort(signatureIndex);
             if (DEBUG) debugMessage("\tfield name = " + nameIndex + ", signature = " + signatureIndex);
 
@@ -404,11 +402,11 @@
             if (hasSyn)
                 fieldAttributeCount++;
 
-            short initvalIndex = fields.getShortAt(index + InstanceKlass.INITVAL_INDEX_OFFSET);
+            short initvalIndex = klass.getFieldInitialValueIndex(index);
             if (initvalIndex != 0)
                 fieldAttributeCount++;
 
-            short genSigIndex = fields.getShortAt(index + InstanceKlass.GENERIC_SIGNATURE_INDEX_OFFSET);
+            short genSigIndex = klass.getFieldGenericSignatureIndex(index);
             if (genSigIndex != 0)
                 fieldAttributeCount++;
 
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Sep 26 10:24:05 2011 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Sep 29 09:53:56 2011 -0700
@@ -967,7 +967,8 @@
 // Class vmSymbols
 
 class vmSymbols: AllStatic {
- friend class vmIntrinsics;
+  friend class vmIntrinsics;
+  friend class VMStructs;
  public:
   // enum for figuring positions and size of array holding Symbol*s
   enum SID {
--- a/src/share/vm/runtime/vmStructs.cpp	Mon Sep 26 10:24:05 2011 -0700
+++ b/src/share/vm/runtime/vmStructs.cpp	Thu Sep 29 09:53:56 2011 -0700
@@ -703,6 +703,12 @@
       static_field(SystemDictionary,            _box_klasses[0],                               klassOop)                             \
       static_field(SystemDictionary,            _java_system_loader,                           oop)                                  \
                                                                                                                                      \
+  /*************/                                                                                                                    \
+  /* vmSymbols */                                                                                                                    \
+  /*************/                                                                                                                    \
+                                                                                                                                     \
+      static_field(vmSymbols,                   _symbols[0],                                  Symbol*)                               \
+                                                                                                                                     \
   /*******************/                                                                                                              \
   /* HashtableBucket */                                                                                                              \
   /*******************/                                                                                                              \
@@ -1548,6 +1554,7 @@
     declare_type(LoaderConstraintEntry, HashtableEntry<klassOop>)         \
   declare_toplevel_type(HashtableBucket)                                  \
   declare_toplevel_type(SystemDictionary)                                 \
+  declare_toplevel_type(vmSymbols)                                        \
   declare_toplevel_type(ProtectionDomainEntry)                            \
                                                                           \
   declare_toplevel_type(GenericGrowableArray)                             \
@@ -2530,6 +2537,13 @@
   X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset))      \
   declare_constant(frame::pc_return_offset)                               \
                                                                           \
+  /*************/                                                         \
+  /* vmSymbols */                                                         \
+  /*************/                                                         \
+                                                                          \
+  declare_constant(vmSymbols::FIRST_SID)                                  \
+  declare_constant(vmSymbols::SID_LIMIT)                                  \
+                                                                          \
   /********************************/                                      \
   /* Calling convention constants */                                      \
   /********************************/                                      \