| /* |
| * Copyright (c) 2011, 2012, 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.ci; |
| |
| import java.io.*; |
| import java.util.*; |
| import sun.jvm.hotspot.debugger.*; |
| import sun.jvm.hotspot.memory.SystemDictionary; |
| import sun.jvm.hotspot.runtime.*; |
| import sun.jvm.hotspot.oops.*; |
| import sun.jvm.hotspot.types.Type; |
| import sun.jvm.hotspot.types.TypeDataBase; |
| import sun.jvm.hotspot.types.WrongTypeException; |
| |
| public class ciInstanceKlass extends ciKlass { |
| static { |
| VM.registerVMInitializedObserver(new Observer() { |
| public void update(Observable o, Object data) { |
| initialize(VM.getVM().getTypeDataBase()); |
| } |
| }); |
| } |
| |
| private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { |
| Type type = db.lookupType("ciInstanceKlass"); |
| initStateField = new CIntField(type.getCIntegerField("_init_state"), 0); |
| isSharedField = new CIntField(type.getCIntegerField("_is_shared"), 0); |
| CLASS_STATE_LINKED = db.lookupIntConstant("InstanceKlass::linked").intValue(); |
| CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("InstanceKlass::fully_initialized").intValue(); |
| } |
| |
| private static CIntField initStateField; |
| private static CIntField isSharedField; |
| private static int CLASS_STATE_LINKED; |
| private static int CLASS_STATE_FULLY_INITIALIZED; |
| |
| public ciInstanceKlass(Address addr) { |
| super(addr); |
| } |
| |
| public int initState() { |
| int initState = (int)initStateField.getValue(getAddress()); |
| if (isShared() && initState < CLASS_STATE_LINKED) { |
| InstanceKlass ik = (InstanceKlass)getMetadata(); |
| initState = ik.getInitStateAsInt(); |
| } |
| return initState; |
| } |
| |
| public boolean isShared() { |
| return isSharedField.getValue(getAddress()) != 0; |
| } |
| |
| public boolean isLinked() { |
| return initState() >= CLASS_STATE_LINKED; |
| } |
| |
| public boolean isInitialized() { |
| return initState() == CLASS_STATE_FULLY_INITIALIZED; |
| } |
| |
| public void dumpReplayData(PrintStream out) { |
| InstanceKlass ik = (InstanceKlass)getMetadata(); |
| ConstantPool cp = ik.getConstants(); |
| |
| // Try to record related loaded classes |
| Klass sub = ik.getSubklassKlass(); |
| while (sub != null) { |
| if (sub instanceof InstanceKlass) { |
| out.println("instanceKlass " + sub.getName().asString()); |
| } |
| sub = sub.getNextSiblingKlass(); |
| } |
| |
| final int length = (int) cp.getLength(); |
| out.print("ciInstanceKlass " + name() + " " + (isLinked() ? 1 : 0) + " " + (isInitialized() ? 1 : 0) + " " + length); |
| for (int index = 1; index < length; index++) { |
| out.print(" " + cp.getTags().at(index)); |
| } |
| out.println(); |
| if (isInitialized()) { |
| Field[] staticFields = ik.getStaticFields(); |
| for (int i = 0; i < staticFields.length; i++) { |
| Field f = staticFields[i]; |
| Oop mirror = ik.getJavaMirror(); |
| if (f.isFinal() && !f.hasInitialValue()) { |
| out.print("staticfield " + name() + " " + |
| OopUtilities.escapeString(f.getID().getName()) + " " + |
| f.getFieldType().getSignature().asString() + " "); |
| if (f instanceof ByteField) { |
| ByteField bf = (ByteField)f; |
| out.println(bf.getValue(mirror)); |
| } else if (f instanceof BooleanField) { |
| BooleanField bf = (BooleanField)f; |
| out.println(bf.getValue(mirror) ? 1 : 0); |
| } else if (f instanceof ShortField) { |
| ShortField bf = (ShortField)f; |
| out.println(bf.getValue(mirror)); |
| } else if (f instanceof CharField) { |
| CharField bf = (CharField)f; |
| out.println(bf.getValue(mirror) & 0xffff); |
| } else if (f instanceof IntField) { |
| IntField bf = (IntField)f; |
| out.println(bf.getValue(mirror)); |
| } else if (f instanceof LongField) { |
| LongField bf = (LongField)f; |
| out.println(bf.getValue(mirror)); |
| } else if (f instanceof FloatField) { |
| FloatField bf = (FloatField)f; |
| out.println(Float.floatToRawIntBits(bf.getValue(mirror))); |
| } else if (f instanceof DoubleField) { |
| DoubleField bf = (DoubleField)f; |
| out.println(Double.doubleToRawLongBits(bf.getValue(mirror))); |
| } else if (f instanceof OopField) { |
| OopField bf = (OopField)f; |
| Oop value = bf.getValue(mirror); |
| if (value == null) { |
| out.println("null"); |
| } else if (value.isInstance()) { |
| Instance inst = (Instance)value; |
| if (inst.isA(SystemDictionary.getStringKlass())) { |
| out.println("\"" + OopUtilities.stringOopToEscapedString(inst) + "\""); |
| } else { |
| out.println(inst.getKlass().getName().asString()); |
| } |
| } else if (value.isObjArray()) { |
| ObjArray oa = (ObjArray)value; |
| Klass ek = (ObjArrayKlass)oa.getKlass(); |
| out.println(oa.getLength() + " " + ek.getName().asString()); |
| } else if (value.isTypeArray()) { |
| TypeArray ta = (TypeArray)value; |
| out.println(ta.getLength()); |
| } else { |
| out.println(value); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |