1 /* 2 * Copyright 2000-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any 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 Oop 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"), Oop.getHeaderSize()); 54 superField = new OopField(type.getOopField("_super"), Oop.getHeaderSize()); 55 layoutHelper = new IntField(type.getJIntField("_layout_helper"), Oop.getHeaderSize()); 56 name = new OopField(type.getOopField("_name"), Oop.getHeaderSize()); 57 accessFlags = new CIntField(type.getCIntegerField("_access_flags"), Oop.getHeaderSize()); 58 subklass = new OopField(type.getOopField("_subklass"), Oop.getHeaderSize()); 59 nextSibling = new OopField(type.getOopField("_next_sibling"), Oop.getHeaderSize()); 60 allocCount = new CIntField(type.getCIntegerField("_alloc_count"), Oop.getHeaderSize()); 61 62 LH_INSTANCE_SLOW_PATH_BIT = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue(); 63 LH_LOG2_ELEMENT_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_log2_element_size_shift").intValue(); 64 LH_ELEMENT_TYPE_SHIFT = db.lookupIntConstant("Klass::_lh_element_type_shift").intValue(); 65 LH_HEADER_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_header_size_shift").intValue(); 66 LH_ARRAY_TAG_SHIFT = db.lookupIntConstant("Klass::_lh_array_tag_shift").intValue(); 67 LH_ARRAY_TAG_TYPE_VALUE = db.lookupIntConstant("Klass::_lh_array_tag_type_value").intValue(); 68 LH_ARRAY_TAG_OBJ_VALUE = db.lookupIntConstant("Klass::_lh_array_tag_obj_value").intValue(); 69 } 70 71 Klass(OopHandle handle, ObjectHeap heap) { 72 super(handle, heap); 73 } 74 75 // jvmdi support - see also class_status in VM code 76 public int getClassStatus() { 77 return 0; // overridden in derived classes 78 } 79 80 public boolean isKlass() { return true; } 81 82 // Fields 83 private static OopField javaMirror; 84 private static OopField superField; 85 private static IntField layoutHelper; 86 private static OopField name; 87 private static CIntField accessFlags; 88 private static OopField subklass; 89 private static OopField nextSibling; 90 private static CIntField allocCount; 91 92 // Accessors for declared fields 93 public Instance getJavaMirror() { return (Instance) javaMirror.getValue(this); } 94 public Klass getSuper() { return (Klass) superField.getValue(this); } 95 public Klass getJavaSuper() { return null; } 96 public int getLayoutHelper() { return (int) layoutHelper.getValue(this); } 97 public Symbol getName() { return (Symbol) name.getValue(this); } 98 public long getAccessFlags() { return accessFlags.getValue(this); } 99 // Convenience routine 100 public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); } 101 public Klass getSubklassKlass() { return (Klass) subklass.getValue(this); } 102 public Klass getNextSiblingKlass() { return (Klass) nextSibling.getValue(this); } 103 public long getAllocCount() { return allocCount.getValue(this); } 104 105 // computed access flags - takes care of inner classes etc. 106 // This is closer to actual source level than getAccessFlags() etc. 107 public long computeModifierFlags() { 108 return 0L; // Unless overridden, modifier_flags is 0. 109 } 110 111 // same as JVM_GetClassModifiers 112 public final long getClassModifiers() { 113 // unlike the VM counterpart we never have to deal with primitive type, 114 // because we operator on Klass and not an instance of java.lang.Class. 115 long flags = computeModifierFlags(); 116 if (isSuper()) { 117 flags |= JVM_ACC_SUPER; 118 } 119 return flags; 120 } 121 122 // subclass check 123 public boolean isSubclassOf(Klass k) { 124 if (k != null) { 125 Klass t = this; 126 // Run up the super chain and check 127 while (t != null) { 128 if (t.equals(k)) return true; 129 t = t.getSuper(); 130 } 131 } 132 return false; 133 } 134 135 // subtype check 136 public boolean isSubtypeOf(Klass k) { 137 return computeSubtypeOf(k); 138 } 139 140 boolean computeSubtypeOf(Klass k) { 141 return isSubclassOf(k); 142 } 143 144 // Find LCA (Least Common Ancester) in class heirarchy 145 public Klass lca( Klass k2 ) { 146 Klass k1 = this; 147 while ( true ) { 148 if ( k1.isSubtypeOf(k2) ) return k2; 149 if ( k2.isSubtypeOf(k1) ) return k1; 150 k1 = k1.getSuper(); 151 k2 = k2.getSuper(); 152 } 153 } 154 155 public void printValueOn(PrintStream tty) { 156 tty.print("Klass"); 157 } 158 159 public void iterateFields(OopVisitor visitor, boolean doVMFields) { 160 super.iterateFields(visitor, doVMFields); 161 if (doVMFields) { 162 visitor.doOop(javaMirror, true); 163 visitor.doOop(superField, true); 164 visitor.doInt(layoutHelper, true); 165 visitor.doOop(name, true); 166 visitor.doCInt(accessFlags, true); 167 visitor.doOop(subklass, true); 168 visitor.doOop(nextSibling, true); 169 visitor.doCInt(allocCount, true); 170 } 171 } 172 173 public long getObjectSize() { 174 System.out.println("should not reach here"); 175 return 0; 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 }