21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.code; 26 27 import java.io.*; 28 import java.util.*; 29 import sun.jvm.hotspot.debugger.*; 30 import sun.jvm.hotspot.oops.*; 31 import sun.jvm.hotspot.runtime.*; 32 import sun.jvm.hotspot.types.*; 33 import sun.jvm.hotspot.utilities.*; 34 35 public class NMethod extends CompiledMethod { 36 private static long pcDescSize; 37 /** != InvocationEntryBci if this nmethod is an on-stack replacement method */ 38 private static CIntegerField entryBCIField; 39 /** To support simple linked-list chaining of nmethods */ 40 private static AddressField osrLinkField; 41 private static AddressField scavengeRootLinkField; 42 private static JByteField scavengeRootStateField; 43 44 /** Offsets for different nmethod parts */ 45 private static CIntegerField exceptionOffsetField; 46 private static CIntegerField origPCOffsetField; 47 private static CIntegerField stubOffsetField; 48 private static CIntegerField oopsOffsetField; 49 private static CIntegerField metadataOffsetField; 50 private static CIntegerField scopesPCsOffsetField; 51 private static CIntegerField dependenciesOffsetField; 52 private static CIntegerField handlerTableOffsetField; 53 private static CIntegerField nulChkTableOffsetField; 54 private static CIntegerField nmethodEndOffsetField; 55 56 /** Offsets for entry points */ 57 /** Entry point with class check */ 58 private static AddressField entryPointField; 59 /** Entry point without class check */ 60 private static AddressField verifiedEntryPointField; 61 /** Entry point for on stack replacement */ 62 private static AddressField osrEntryPointField; 71 stack. An not_entrant method can be removed when there is no 72 more activations, i.e., when the _stack_traversal_mark is less than 73 current sweep traversal index. */ 74 private static CIntegerField stackTraversalMarkField; 75 76 private static CIntegerField compLevelField; 77 78 static { 79 VM.registerVMInitializedObserver(new Observer() { 80 public void update(Observable o, Object data) { 81 initialize(VM.getVM().getTypeDataBase()); 82 } 83 }); 84 } 85 86 private static void initialize(TypeDataBase db) { 87 Type type = db.lookupType("nmethod"); 88 89 entryBCIField = type.getCIntegerField("_entry_bci"); 90 osrLinkField = type.getAddressField("_osr_link"); 91 scavengeRootLinkField = type.getAddressField("_scavenge_root_link"); 92 scavengeRootStateField = type.getJByteField("_scavenge_root_state"); 93 94 exceptionOffsetField = type.getCIntegerField("_exception_offset"); 95 origPCOffsetField = type.getCIntegerField("_orig_pc_offset"); 96 stubOffsetField = type.getCIntegerField("_stub_offset"); 97 oopsOffsetField = type.getCIntegerField("_oops_offset"); 98 metadataOffsetField = type.getCIntegerField("_metadata_offset"); 99 scopesPCsOffsetField = type.getCIntegerField("_scopes_pcs_offset"); 100 dependenciesOffsetField = type.getCIntegerField("_dependencies_offset"); 101 handlerTableOffsetField = type.getCIntegerField("_handler_table_offset"); 102 nulChkTableOffsetField = type.getCIntegerField("_nul_chk_table_offset"); 103 nmethodEndOffsetField = type.getCIntegerField("_nmethod_end_offset"); 104 entryPointField = type.getAddressField("_entry_point"); 105 verifiedEntryPointField = type.getAddressField("_verified_entry_point"); 106 osrEntryPointField = type.getAddressField("_osr_entry_point"); 107 lockCountField = type.getJIntField("_lock_count"); 108 stackTraversalMarkField = type.getCIntegerField("_stack_traversal_mark"); 109 compLevelField = type.getCIntegerField("_comp_level"); 110 pcDescSize = db.lookupType("PcDesc").getSize(); 111 } 112 232 // public int age(); 233 // public boolean isMarkedForDeoptimization(); 234 // public boolean isMarkedForUnloading(); 235 // public int level(); 236 // public int version(); 237 238 // FIXME: add mutators for above 239 // FIXME: add exception cache access? 240 241 /** On-stack replacement support */ 242 // FIXME: add mutators 243 public int getOSREntryBCI() { 244 if (Assert.ASSERTS_ENABLED) { 245 Assert.that(getEntryBCI() != VM.getVM().getInvocationEntryBCI(), "wrong kind of nmethod"); 246 } 247 return getEntryBCI(); 248 } 249 250 public NMethod getOSRLink() { 251 return (NMethod) VMObjectFactory.newObject(NMethod.class, osrLinkField.getValue(addr)); 252 } 253 254 public NMethod getScavengeRootLink() { 255 return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootLinkField.getValue(addr)); 256 } 257 258 public int getScavengeRootState() { 259 return (int) scavengeRootStateField.getValue(addr); 260 } 261 262 // MethodHandle 263 public boolean isMethodHandleReturn(Address returnPc) { 264 // Hard to read a bit fields from Java and it's only there for performance 265 // so just go directly to the PCDesc 266 // if (!hasMethodHandleInvokes()) return false; 267 PCDesc pd = getPCDescAt(returnPc); 268 if (pd == null) 269 return false; 270 return pd.isMethodHandleInvoke(); 271 } 272 273 // Deopt 274 // Return true is the PC is one would expect if the frame is being deopted. 275 public boolean isDeoptPc (Address pc) { return isDeoptEntry(pc) || isDeoptMhEntry(pc); } 276 public boolean isDeoptEntry (Address pc) { return pc == deoptHandlerBegin(); } 277 public boolean isDeoptMhEntry (Address pc) { return pc == deoptMhHandlerBegin(); } 278 279 /** Tells whether frames described by this nmethod can be | 21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.code; 26 27 import java.io.*; 28 import java.util.*; 29 import sun.jvm.hotspot.debugger.*; 30 import sun.jvm.hotspot.oops.*; 31 import sun.jvm.hotspot.runtime.*; 32 import sun.jvm.hotspot.types.*; 33 import sun.jvm.hotspot.utilities.*; 34 35 public class NMethod extends CompiledMethod { 36 private static long pcDescSize; 37 /** != InvocationEntryBci if this nmethod is an on-stack replacement method */ 38 private static CIntegerField entryBCIField; 39 /** To support simple linked-list chaining of nmethods */ 40 private static AddressField osrLinkField; 41 42 /** Offsets for different nmethod parts */ 43 private static CIntegerField exceptionOffsetField; 44 private static CIntegerField origPCOffsetField; 45 private static CIntegerField stubOffsetField; 46 private static CIntegerField oopsOffsetField; 47 private static CIntegerField metadataOffsetField; 48 private static CIntegerField scopesPCsOffsetField; 49 private static CIntegerField dependenciesOffsetField; 50 private static CIntegerField handlerTableOffsetField; 51 private static CIntegerField nulChkTableOffsetField; 52 private static CIntegerField nmethodEndOffsetField; 53 54 /** Offsets for entry points */ 55 /** Entry point with class check */ 56 private static AddressField entryPointField; 57 /** Entry point without class check */ 58 private static AddressField verifiedEntryPointField; 59 /** Entry point for on stack replacement */ 60 private static AddressField osrEntryPointField; 69 stack. An not_entrant method can be removed when there is no 70 more activations, i.e., when the _stack_traversal_mark is less than 71 current sweep traversal index. */ 72 private static CIntegerField stackTraversalMarkField; 73 74 private static CIntegerField compLevelField; 75 76 static { 77 VM.registerVMInitializedObserver(new Observer() { 78 public void update(Observable o, Object data) { 79 initialize(VM.getVM().getTypeDataBase()); 80 } 81 }); 82 } 83 84 private static void initialize(TypeDataBase db) { 85 Type type = db.lookupType("nmethod"); 86 87 entryBCIField = type.getCIntegerField("_entry_bci"); 88 osrLinkField = type.getAddressField("_osr_link"); 89 90 exceptionOffsetField = type.getCIntegerField("_exception_offset"); 91 origPCOffsetField = type.getCIntegerField("_orig_pc_offset"); 92 stubOffsetField = type.getCIntegerField("_stub_offset"); 93 oopsOffsetField = type.getCIntegerField("_oops_offset"); 94 metadataOffsetField = type.getCIntegerField("_metadata_offset"); 95 scopesPCsOffsetField = type.getCIntegerField("_scopes_pcs_offset"); 96 dependenciesOffsetField = type.getCIntegerField("_dependencies_offset"); 97 handlerTableOffsetField = type.getCIntegerField("_handler_table_offset"); 98 nulChkTableOffsetField = type.getCIntegerField("_nul_chk_table_offset"); 99 nmethodEndOffsetField = type.getCIntegerField("_nmethod_end_offset"); 100 entryPointField = type.getAddressField("_entry_point"); 101 verifiedEntryPointField = type.getAddressField("_verified_entry_point"); 102 osrEntryPointField = type.getAddressField("_osr_entry_point"); 103 lockCountField = type.getJIntField("_lock_count"); 104 stackTraversalMarkField = type.getCIntegerField("_stack_traversal_mark"); 105 compLevelField = type.getCIntegerField("_comp_level"); 106 pcDescSize = db.lookupType("PcDesc").getSize(); 107 } 108 228 // public int age(); 229 // public boolean isMarkedForDeoptimization(); 230 // public boolean isMarkedForUnloading(); 231 // public int level(); 232 // public int version(); 233 234 // FIXME: add mutators for above 235 // FIXME: add exception cache access? 236 237 /** On-stack replacement support */ 238 // FIXME: add mutators 239 public int getOSREntryBCI() { 240 if (Assert.ASSERTS_ENABLED) { 241 Assert.that(getEntryBCI() != VM.getVM().getInvocationEntryBCI(), "wrong kind of nmethod"); 242 } 243 return getEntryBCI(); 244 } 245 246 public NMethod getOSRLink() { 247 return (NMethod) VMObjectFactory.newObject(NMethod.class, osrLinkField.getValue(addr)); 248 } 249 250 // MethodHandle 251 public boolean isMethodHandleReturn(Address returnPc) { 252 // Hard to read a bit fields from Java and it's only there for performance 253 // so just go directly to the PCDesc 254 // if (!hasMethodHandleInvokes()) return false; 255 PCDesc pd = getPCDescAt(returnPc); 256 if (pd == null) 257 return false; 258 return pd.isMethodHandleInvoke(); 259 } 260 261 // Deopt 262 // Return true is the PC is one would expect if the frame is being deopted. 263 public boolean isDeoptPc (Address pc) { return isDeoptEntry(pc) || isDeoptMhEntry(pc); } 264 public boolean isDeoptEntry (Address pc) { return pc == deoptHandlerBegin(); } 265 public boolean isDeoptMhEntry (Address pc) { return pc == deoptMhHandlerBegin(); } 266 267 /** Tells whether frames described by this nmethod can be |