From 68345435e559bb2ab50b149b17f2c1d4127228d6 Mon Sep 17 00:00:00 2001 From: never Date: Thu, 29 Sep 2011 09:53:56 -0700 Subject: [PATCH] 7092278: "jmap -finalizerinfo" throws "sun.jvm.hotspot.utilities.AssertionFailure: invalid cp index 0 137" Reviewed-by: kvn --- .../sun/jvm/hotspot/oops/InstanceKlass.java | 68 +++++++++++++------ .../sun/jvm/hotspot/runtime/vmSymbols.java | 61 +++++++++++++++++ .../jvm/hotspot/tools/jcore/ClassWriter.java | 18 +++-- src/share/vm/classfile/vmSymbols.hpp | 3 +- src/share/vm/runtime/vmStructs.cpp | 14 ++++ 5 files changed, 132 insertions(+), 32 deletions(-) create mode 100644 agent/src/share/classes/sun/jvm/hotspot/runtime/vmSymbols.java diff --git a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java index 9ff98e2aa..87de9700d 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @@ -44,14 +44,14 @@ public class InstanceKlass extends Klass { } // 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 @@ public class InstanceKlass extends Klass { 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 @@ public class InstanceKlass extends Klass { 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 class InstanceKlass extends Klass { 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 @@ public class InstanceKlass extends Klass { } 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 @@ public class InstanceKlass extends Klass { 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 @@ public class InstanceKlass extends Klass { /** 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 class InstanceKlass extends Klass { 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 @@ public class InstanceKlass extends Klass { // 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()) { diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/vmSymbols.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/vmSymbols.java new file mode 100644 index 000000000..650f61242 --- /dev/null +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/vmSymbols.java @@ -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())); + } +} diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java index f5e5837e1..f4e3d7c93 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java @@ -379,23 +379,21 @@ public class ClassWriter implements /* imports */ ClassConstants } 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 @@ public class ClassWriter implements /* imports */ ClassConstants 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++; diff --git a/src/share/vm/classfile/vmSymbols.hpp b/src/share/vm/classfile/vmSymbols.hpp index a5c5781fe..16652e5ef 100644 --- a/src/share/vm/classfile/vmSymbols.hpp +++ b/src/share/vm/classfile/vmSymbols.hpp @@ -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 { diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp index e89c2f1ff..0ce636f8e 100644 --- a/src/share/vm/runtime/vmStructs.cpp +++ b/src/share/vm/runtime/vmStructs.cpp @@ -703,6 +703,12 @@ static inline uint64_t cast_uint64_t(size_t x) 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 @@ static inline uint64_t cast_uint64_t(size_t x) declare_type(LoaderConstraintEntry, HashtableEntry) \ declare_toplevel_type(HashtableBucket) \ declare_toplevel_type(SystemDictionary) \ + declare_toplevel_type(vmSymbols) \ declare_toplevel_type(ProtectionDomainEntry) \ \ declare_toplevel_type(GenericGrowableArray) \ @@ -2530,6 +2537,13 @@ static inline uint64_t cast_uint64_t(size_t x) 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 */ \ /********************************/ \ -- GitLab