View Javadoc
1   /*
2    * Copyright (c) 2000, 2013, 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  
25  package sun.jvm.hotspot.oops;
26  
27  import java.io.*;
28  import java.util.*;
29  import sun.jvm.hotspot.debugger.*;
30  import sun.jvm.hotspot.runtime.*;
31  import sun.jvm.hotspot.types.*;
32  
33  public class Klass extends Metadata implements ClassConstants {
34    static {
35      VM.registerVMInitializedObserver(new Observer() {
36          public void update(Observable o, Object data) {
37            initialize(VM.getVM().getTypeDataBase());
38          }
39        });
40    }
41  
42    // anon-enum constants for _layout_helper.
43    public static int LH_INSTANCE_SLOW_PATH_BIT;
44    public static int LH_LOG2_ELEMENT_SIZE_SHIFT;
45    public static int LH_ELEMENT_TYPE_SHIFT;
46    public static int LH_HEADER_SIZE_SHIFT;
47    public static int LH_ARRAY_TAG_SHIFT;
48    public static int LH_ARRAY_TAG_TYPE_VALUE;
49    public static int LH_ARRAY_TAG_OBJ_VALUE;
50  
51    private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
52      Type type    = db.lookupType("Klass");
53      javaMirror   = new OopField(type.getOopField("_java_mirror"), 0);
54      superField   = new MetadataField(type.getAddressField("_super"), 0);
55      layoutHelper = new IntField(type.getJIntField("_layout_helper"), 0);
56      name         = type.getAddressField("_name");
57      accessFlags  = new CIntField(type.getCIntegerField("_access_flags"), 0);
58      subklass     = new MetadataField(type.getAddressField("_subklass"), 0);
59      nextSibling  = new MetadataField(type.getAddressField("_next_sibling"), 0);
60  
61      LH_INSTANCE_SLOW_PATH_BIT  = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue();
62      LH_LOG2_ELEMENT_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_log2_element_size_shift").intValue();
63      LH_ELEMENT_TYPE_SHIFT      = db.lookupIntConstant("Klass::_lh_element_type_shift").intValue();
64      LH_HEADER_SIZE_SHIFT       = db.lookupIntConstant("Klass::_lh_header_size_shift").intValue();
65      LH_ARRAY_TAG_SHIFT         = db.lookupIntConstant("Klass::_lh_array_tag_shift").intValue();
66      LH_ARRAY_TAG_TYPE_VALUE    = db.lookupIntConstant("Klass::_lh_array_tag_type_value").intValue();
67      LH_ARRAY_TAG_OBJ_VALUE     = db.lookupIntConstant("Klass::_lh_array_tag_obj_value").intValue();
68    }
69  
70    public Klass(Address addr) {
71      super(addr);
72    }
73  
74    // jvmdi support - see also class_status in VM code
75    public int getClassStatus() {
76      return 0; // overridden in derived classes
77    }
78  
79    public boolean isKlass()             { return true; }
80  
81    // Fields
82    private static OopField  javaMirror;
83    private static MetadataField  superField;
84    private static IntField layoutHelper;
85    private static AddressField  name;
86    private static CIntField accessFlags;
87    private static MetadataField  subklass;
88    private static MetadataField  nextSibling;
89  
90    private Address getValue(AddressField field) {
91      return addr.getAddressAt(field.getOffset());
92    }
93  
94    protected Symbol getSymbol(AddressField field) {
95      return Symbol.create(addr.getAddressAt(field.getOffset()));
96    }
97  
98    // Accessors for declared fields
99    public Instance getJavaMirror()       { return (Instance) javaMirror.getValue(this);   }
100   public Klass    getSuper()            { return (Klass)    superField.getValue(this);   }
101   public Klass    getJavaSuper()        { return null;  }
102   public int      getLayoutHelper()     { return (int)           layoutHelper.getValue(this); }
103   public Symbol   getName()             { return getSymbol(name); }
104   public long     getAccessFlags()      { return            accessFlags.getValue(this);  }
105   // Convenience routine
106   public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags());      }
107   public Klass    getSubklassKlass()    { return (Klass)    subklass.getValue(this);     }
108   public Klass    getNextSiblingKlass() { return (Klass)    nextSibling.getValue(this);  }
109 
110   // computed access flags - takes care of inner classes etc.
111   // This is closer to actual source level than getAccessFlags() etc.
112   public long computeModifierFlags() {
113     return 0L; // Unless overridden, modifier_flags is 0.
114   }
115 
116   // same as JVM_GetClassModifiers
117   public final long getClassModifiers() {
118     // unlike the VM counterpart we never have to deal with primitive type,
119     // because we operator on Klass and not an instance of java.lang.Class.
120     long flags = computeModifierFlags();
121     if (isSuper()) {
122        flags |= JVM_ACC_SUPER;
123     }
124     return flags;
125   }
126 
127   // subclass check
128   public boolean isSubclassOf(Klass k) {
129     if (k != null) {
130       Klass t = this;
131       // Run up the super chain and check
132       while (t != null) {
133         if (t.equals(k)) return true;
134         t = t.getSuper();
135       }
136     }
137     return false;
138   }
139 
140   // subtype check
141   public boolean isSubtypeOf(Klass k) {
142     return computeSubtypeOf(k);
143   }
144 
145   boolean computeSubtypeOf(Klass k) {
146     return isSubclassOf(k);
147   }
148 
149   // Find LCA (Least Common Ancester) in class heirarchy
150   public Klass lca( Klass k2 ) {
151     Klass k1 = this;
152     while ( true ) {
153       if ( k1.isSubtypeOf(k2) ) return k2;
154       if ( k2.isSubtypeOf(k1) ) return k1;
155       k1 = k1.getSuper();
156       k2 = k2.getSuper();
157     }
158   }
159 
160   public void printValueOn(PrintStream tty) {
161     tty.print("Klass");
162   }
163 
164   public void iterateFields(MetadataVisitor visitor) {
165       visitor.doOop(javaMirror, true);
166     visitor.doMetadata(superField, true);
167       visitor.doInt(layoutHelper, true);
168       // visitor.doOop(name, true);
169       visitor.doCInt(accessFlags, true);
170     visitor.doMetadata(subklass, true);
171     visitor.doMetadata(nextSibling, true);
172     }
173 
174   public long getObjectSize() {
175     throw new RuntimeException("should not reach here");
176   }
177 
178   /** Array class with specific rank */
179   public Klass arrayKlass(int rank)       { return arrayKlassImpl(false, rank); }
180   /** Array class with this klass as element type */
181   public Klass arrayKlass()               { return arrayKlassImpl(false);       }
182   /** These will return null instead of allocating on the heap */
183   public Klass arrayKlassOrNull(int rank) { return arrayKlassImpl(true, rank);  }
184   public Klass arrayKlassOrNull()         { return arrayKlassImpl(true);        }
185 
186   public Klass arrayKlassImpl(boolean orNull, int rank) {
187     throw new RuntimeException("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");
188   }
189 
190   public Klass arrayKlassImpl(boolean orNull) {
191     throw new RuntimeException("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");
192   }
193 
194   // This returns the name in the form java/lang/String which isn't really a signature
195   // The subclasses override this to produce the correct form, eg
196   //   Ljava/lang/String; For ArrayKlasses getName itself is the signature.
197   public String signature() { return getName().asString(); }
198 
199   // Convenience routines
200   public boolean isPublic()                 { return getAccessFlagsObj().isPublic(); }
201   public boolean isFinal()                  { return getAccessFlagsObj().isFinal(); }
202   public boolean isInterface()              { return getAccessFlagsObj().isInterface(); }
203   public boolean isAbstract()               { return getAccessFlagsObj().isAbstract(); }
204   public boolean isSuper()                  { return getAccessFlagsObj().isSuper(); }
205   public boolean isSynthetic()              { return getAccessFlagsObj().isSynthetic(); }
206   public boolean hasFinalizer()             { return getAccessFlagsObj().hasFinalizer(); }
207   public boolean isCloneable()              { return getAccessFlagsObj().isCloneable(); }
208   public boolean hasVanillaConstructor()    { return getAccessFlagsObj().hasVanillaConstructor(); }
209   public boolean hasMirandaMethods ()       { return getAccessFlagsObj().hasMirandaMethods(); }
210 }