7092278: "jmap -finalizerinfo" throws "sun.jvm.hotspot.utilities.AssertionFailure: invalid cp index 0 137"
Reviewed-by: kvn
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Mon Sep 26 10:24:05 2011 -0700
+++ b/hotspot/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/hotspot/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/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Mon Sep 26 10:24:05 2011 -0700
+++ b/hotspot/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/hotspot/src/share/vm/classfile/vmSymbols.hpp Mon Sep 26 10:24:05 2011 -0700
+++ b/hotspot/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/hotspot/src/share/vm/runtime/vmStructs.cpp Mon Sep 26 10:24:05 2011 -0700
+++ b/hotspot/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 */ \
/********************************/ \