Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java
41161 views
/*1* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324package sun.jvm.hotspot.oops;2526import java.io.*;27import java.util.*;28import sun.jvm.hotspot.debugger.*;29import sun.jvm.hotspot.classfile.*;30import sun.jvm.hotspot.runtime.*;31import sun.jvm.hotspot.types.*;32import sun.jvm.hotspot.utilities.Observable;33import sun.jvm.hotspot.utilities.Observer;3435public class Klass extends Metadata implements ClassConstants {36static {37VM.registerVMInitializedObserver(new Observer() {38public void update(Observable o, Object data) {39initialize(VM.getVM().getTypeDataBase());40}41});42}4344// anon-enum constants for _layout_helper.45public static int LH_INSTANCE_SLOW_PATH_BIT;46public static int LH_LOG2_ELEMENT_SIZE_SHIFT;47public static int LH_ELEMENT_TYPE_SHIFT;48public static int LH_HEADER_SIZE_SHIFT;49public static int LH_ARRAY_TAG_SHIFT;50public static int LH_ARRAY_TAG_TYPE_VALUE;51public static int LH_ARRAY_TAG_OBJ_VALUE;5253private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {54Type type = db.lookupType("Klass");55javaMirrorFieldOffset = type.getField("_java_mirror").getOffset();56superField = new MetadataField(type.getAddressField("_super"), 0);57layoutHelper = new IntField(type.getJIntField("_layout_helper"), 0);58name = type.getAddressField("_name");59accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0);60try {61traceIDField = type.getField("_trace_id");62} catch(Exception e) {63}64subklass = new MetadataField(type.getAddressField("_subklass"), 0);65nextSibling = new MetadataField(type.getAddressField("_next_sibling"), 0);66nextLink = new MetadataField(type.getAddressField("_next_link"), 0);67vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), 0);68classLoaderData = type.getAddressField("_class_loader_data");6970LH_INSTANCE_SLOW_PATH_BIT = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue();71LH_LOG2_ELEMENT_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_log2_element_size_shift").intValue();72LH_ELEMENT_TYPE_SHIFT = db.lookupIntConstant("Klass::_lh_element_type_shift").intValue();73LH_HEADER_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_header_size_shift").intValue();74LH_ARRAY_TAG_SHIFT = db.lookupIntConstant("Klass::_lh_array_tag_shift").intValue();75LH_ARRAY_TAG_TYPE_VALUE = db.lookupIntConstant("Klass::_lh_array_tag_type_value").intValue();76LH_ARRAY_TAG_OBJ_VALUE = db.lookupIntConstant("Klass::_lh_array_tag_obj_value").intValue();77}787980public Klass(Address addr) {81super(addr);82}8384// jvmdi support - see also class_status in VM code85public int getClassStatus() {86return 0; // overridden in derived classes87}8889public boolean isKlass() { return true; }90public boolean isArrayKlass() { return false; }9192// Fields93private static long javaMirrorFieldOffset;94private static MetadataField superField;95private static IntField layoutHelper;96private static AddressField name;97private static CIntField accessFlags;98private static MetadataField subklass;99private static MetadataField nextSibling;100private static MetadataField nextLink;101private static sun.jvm.hotspot.types.Field traceIDField;102private static CIntField vtableLen;103private static AddressField classLoaderData;104105protected Symbol getSymbol(AddressField field) {106return Symbol.create(addr.getAddressAt(field.getOffset()));107}108109// Accessors for declared fields110public Instance getJavaMirror() {111Address addr = getAddress().addOffsetTo(javaMirrorFieldOffset);112VMOopHandle vmOopHandle = VMObjectFactory.newObject(VMOopHandle.class, addr);113return vmOopHandle.resolve();114}115public Klass getSuper() { return (Klass) superField.getValue(this); }116public Klass getJavaSuper() { return null; }117public int getLayoutHelper() { return (int) layoutHelper.getValue(this); }118public Symbol getName() { return getSymbol(name); }119public long getAccessFlags() { return accessFlags.getValue(this); }120// Convenience routine121public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); }122public Klass getSubklassKlass() { return (Klass) subklass.getValue(this); }123public Klass getNextSiblingKlass() { return (Klass) nextSibling.getValue(this); }124public Klass getNextLinkKlass() { return (Klass) nextLink.getValue(this); }125public long getVtableLen() { return vtableLen.getValue(this); }126127public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }128public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }129130public long traceID() {131if (traceIDField == null) return 0;132return traceIDField.getJLong(addr);133}134135// computed access flags - takes care of inner classes etc.136// This is closer to actual source level than getAccessFlags() etc.137public long computeModifierFlags() {138return 0L; // Unless overridden, modifier_flags is 0.139}140141// same as JVM_GetClassModifiers142public final long getClassModifiers() {143// unlike the VM counterpart we never have to deal with primitive type,144// because we operator on Klass and not an instance of java.lang.Class.145long flags = computeModifierFlags();146if (isSuper()) {147flags |= JVM_ACC_SUPER;148}149return flags;150}151152// subclass check153public boolean isSubclassOf(Klass k) {154if (k != null) {155Klass t = this;156// Run up the super chain and check157while (t != null) {158if (t.equals(k)) return true;159t = t.getSuper();160}161}162return false;163}164165// subtype check166public boolean isSubtypeOf(Klass k) {167return computeSubtypeOf(k);168}169170boolean computeSubtypeOf(Klass k) {171return isSubclassOf(k);172}173174// Find LCA (Least Common Ancester) in class heirarchy175public Klass lca( Klass k2 ) {176Klass k1 = this;177while ( true ) {178if ( k1.isSubtypeOf(k2) ) return k2;179if ( k2.isSubtypeOf(k1) ) return k1;180k1 = k1.getSuper();181k2 = k2.getSuper();182}183}184185public void printValueOn(PrintStream tty) {186tty.print("Klass");187}188189public void iterateFields(MetadataVisitor visitor) {190// visitor.doOop(javaMirror, true);191visitor.doMetadata(superField, true);192visitor.doInt(layoutHelper, true);193// visitor.doOop(name, true);194visitor.doCInt(accessFlags, true);195visitor.doMetadata(subklass, true);196visitor.doMetadata(nextSibling, true);197visitor.doCInt(vtableLen, true);198}199200public long getObjectSize() {201throw new RuntimeException("should not reach here");202}203204/** Array class with specific rank */205public Klass arrayKlass(int rank) { return arrayKlassImpl(false, rank); }206/** Array class with this klass as element type */207public Klass arrayKlass() { return arrayKlassImpl(false); }208/** These will return null instead of allocating on the heap */209public Klass arrayKlassOrNull(int rank) { return arrayKlassImpl(true, rank); }210public Klass arrayKlassOrNull() { return arrayKlassImpl(true); }211212public Klass arrayKlassImpl(boolean orNull, int rank) {213throw new RuntimeException("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");214}215216public Klass arrayKlassImpl(boolean orNull) {217throw new RuntimeException("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");218}219220// This returns the name in the form java/lang/String which isn't really a signature221// The subclasses override this to produce the correct form, eg222// Ljava/lang/String; For ArrayKlasses getName itself is the signature.223public String signature() { return getName().asString(); }224225// Convenience routines226public boolean isPublic() { return getAccessFlagsObj().isPublic(); }227public boolean isFinal() { return getAccessFlagsObj().isFinal(); }228public boolean isInterface() { return getAccessFlagsObj().isInterface(); }229public boolean isAbstract() { return getAccessFlagsObj().isAbstract(); }230public boolean isSuper() { return getAccessFlagsObj().isSuper(); }231public boolean isSynthetic() { return getAccessFlagsObj().isSynthetic(); }232public boolean hasFinalizer() { return getAccessFlagsObj().hasFinalizer(); }233public boolean isCloneable() { return getAccessFlagsObj().isCloneable(); }234public boolean hasVanillaConstructor() { return getAccessFlagsObj().hasVanillaConstructor(); }235public boolean hasMirandaMethods () { return getAccessFlagsObj().hasMirandaMethods(); }236}237238239