1/*
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25package sun.jvm.hotspot.ci;
26
27import java.io.*;
28import java.util.*;
29import sun.jvm.hotspot.debugger.*;
30import sun.jvm.hotspot.memory.SystemDictionary;
31import sun.jvm.hotspot.runtime.*;
32import sun.jvm.hotspot.oops.*;
33import sun.jvm.hotspot.types.Type;
34import sun.jvm.hotspot.types.TypeDataBase;
35import sun.jvm.hotspot.types.WrongTypeException;
36
37public class ciInstanceKlass extends ciKlass {
38  static {
39    VM.registerVMInitializedObserver(new Observer() {
40        public void update(Observable o, Object data) {
41          initialize(VM.getVM().getTypeDataBase());
42        }
43      });
44  }
45
46  private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
47    Type type      = db.lookupType("ciInstanceKlass");
48    initStateField = new CIntField(type.getCIntegerField("_init_state"), 0);
49    isSharedField = new CIntField(type.getCIntegerField("_is_shared"), 0);
50    CLASS_STATE_LINKED = db.lookupIntConstant("InstanceKlass::linked").intValue();
51    CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("InstanceKlass::fully_initialized").intValue();
52  }
53
54  private static CIntField initStateField;
55  private static CIntField isSharedField;
56  private static int CLASS_STATE_LINKED;
57  private static int CLASS_STATE_FULLY_INITIALIZED;
58
59  public ciInstanceKlass(Address addr) {
60    super(addr);
61  }
62
63  public int initState() {
64    int initState = (int)initStateField.getValue(getAddress());
65    if (isShared() && initState < CLASS_STATE_LINKED) {
66      InstanceKlass ik = (InstanceKlass)getMetadata();
67      initState = ik.getInitStateAsInt();
68    }
69    return initState;
70  }
71
72  public boolean isShared() {
73    return isSharedField.getValue(getAddress()) != 0;
74  }
75
76  public boolean isLinked() {
77    return initState() >= CLASS_STATE_LINKED;
78  }
79
80  public boolean isInitialized() {
81    return initState() == CLASS_STATE_FULLY_INITIALIZED;
82  }
83
84  public void dumpReplayData(PrintStream out) {
85    InstanceKlass ik = (InstanceKlass)getMetadata();
86    ConstantPool cp = ik.getConstants();
87
88    // Try to record related loaded classes
89    Klass sub = ik.getSubklassKlass();
90    while (sub != null) {
91      if (sub instanceof InstanceKlass) {
92        out.println("instanceKlass " + sub.getName().asString());
93      }
94      sub = sub.getNextSiblingKlass();
95    }
96
97    final int length = (int) cp.getLength();
98    out.print("ciInstanceKlass " + name() + " " + (isLinked() ? 1 : 0) + " " + (isInitialized() ? 1 : 0) + " " + length);
99    for (int index = 1; index < length; index++) {
100      out.print(" " + cp.getTags().at(index));
101    }
102    out.println();
103    if (isInitialized()) {
104      Field[] staticFields = ik.getStaticFields();
105      for (int i = 0; i < staticFields.length; i++) {
106        Field f = staticFields[i];
107        Oop mirror = ik.getJavaMirror();
108        if (f.isFinal() && !f.hasInitialValue()) {
109          out.print("staticfield " + name() + " " +
110                    OopUtilities.escapeString(f.getID().getName()) + " " +
111                    f.getFieldType().getSignature().asString() + " ");
112          if (f instanceof ByteField) {
113            ByteField bf = (ByteField)f;
114            out.println(bf.getValue(mirror));
115          } else if (f instanceof BooleanField) {
116            BooleanField bf = (BooleanField)f;
117            out.println(bf.getValue(mirror) ? 1 : 0);
118          } else if (f instanceof ShortField) {
119            ShortField bf = (ShortField)f;
120            out.println(bf.getValue(mirror));
121          } else if (f instanceof CharField) {
122            CharField bf = (CharField)f;
123            out.println(bf.getValue(mirror) & 0xffff);
124          } else if (f instanceof IntField) {
125            IntField bf = (IntField)f;
126            out.println(bf.getValue(mirror));
127          } else  if (f instanceof LongField) {
128            LongField bf = (LongField)f;
129            out.println(bf.getValue(mirror));
130          } else if (f instanceof FloatField) {
131            FloatField bf = (FloatField)f;
132            out.println(Float.floatToRawIntBits(bf.getValue(mirror)));
133          } else if (f instanceof DoubleField) {
134            DoubleField bf = (DoubleField)f;
135            out.println(Double.doubleToRawLongBits(bf.getValue(mirror)));
136          } else if (f instanceof OopField) {
137            OopField bf = (OopField)f;
138            Oop value = bf.getValue(mirror);
139            if (value == null) {
140              out.println("null");
141            } else if (value.isInstance()) {
142              Instance inst = (Instance)value;
143              if (inst.isA(SystemDictionary.getStringKlass())) {
144                out.println("\"" + OopUtilities.stringOopToEscapedString(inst) + "\"");
145              } else {
146                out.println(inst.getKlass().getName().asString());
147              }
148            } else if (value.isObjArray()) {
149              ObjArray oa = (ObjArray)value;
150              Klass ek = (ObjArrayKlass)oa.getKlass();
151              out.println(oa.getLength() + " " + ek.getName().asString());
152            } else if (value.isTypeArray()) {
153              TypeArray ta = (TypeArray)value;
154              out.println(ta.getLength());
155            } else {
156              out.println(value);
157            }
158          }
159        }
160      }
161    }
162  }
163}
164