34 // nmethods (native methods) are the compiled code versions of Java methods. 35 // 36 // An nmethod contains: 37 // - header (the nmethod structure) 38 // [Relocation] 39 // - relocation information 40 // - constant part (doubles, longs and floats used in nmethod) 41 // - oop table 42 // [Code] 43 // - code body 44 // - exception handler 45 // - stub code 46 // [Debugging information] 47 // - oop array 48 // - data array 49 // - pcs 50 // [Exception handler table] 51 // - handler entry point array 52 // [Implicit Null Pointer exception table] 53 // - implicit null table array 54 55 class nmethod : public CompiledMethod { 56 friend class VMStructs; 57 friend class JVMCIVMStructs; 58 friend class NMethodSweeper; 59 friend class CodeCache; // scavengable oops 60 private: 61 62 // Shared fields for all nmethod's 63 int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method 64 jmethodID _jmethod_id; // Cache of method()->jmethod_id() 65 66 #if INCLUDE_JVMCI 67 // A weak reference to an InstalledCode object associated with 68 // this nmethod. 69 jweak _jvmci_installed_code; 70 71 // A weak reference to a SpeculationLog object associated with 72 // this nmethod. 73 jweak _speculation_log; 74 75 // Determines whether this nmethod is unloaded when the 76 // referent in _jvmci_installed_code is cleared. This 77 // will be false if the referent is initialized to a 78 // HotSpotNMethod object whose isDefault field is true. 79 // That is, installed code other than a "default" 80 // HotSpotNMethod causes nmethod unloading. 81 // This field is ignored once _jvmci_installed_code is NULL. 82 bool _jvmci_installed_code_triggers_invalidation; 83 #endif 84 85 // To support simple linked-list chaining of nmethods: 86 nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head 87 88 static nmethod* volatile _oops_do_mark_nmethods; 89 nmethod* volatile _oops_do_mark_link; 90 91 // offsets for entry points 92 address _entry_point; // entry point with class check 93 address _verified_entry_point; // entry point without class check 94 address _osr_entry_point; // entry point for on stack replacement 95 96 // Offsets for different nmethod parts 97 int _exception_offset; 98 // Offset of the unwind handler if it exists 99 int _unwind_handler_offset; 100 101 int _consts_offset; 102 int _stub_offset; 103 int _oops_offset; // offset to where embedded oop table begins (inside data) 104 int _metadata_offset; // embedded meta data table 105 int _scopes_data_offset; 106 int _scopes_pcs_offset; 107 int _dependencies_offset; 108 int _handler_table_offset; 109 int _nul_chk_table_offset; 110 int _nmethod_end_offset; 111 112 int code_offset() const { return (address) code_begin() - header_begin(); } 113 114 // location in frame (offset for sp) that deopt can store the original 115 // pc during a deopt. 116 int _orig_pc_offset; 117 118 int _compile_id; // which compilation made this nmethod 119 int _comp_level; // compilation level 120 121 // protected by CodeCache_lock 122 bool _has_flushed_dependencies; // Used for maintenance of dependencies (CodeCache_lock) 123 124 // used by jvmti to track if an unload event has been posted for this nmethod. 125 bool _unload_reported; 126 127 // Protected by Patching_lock 128 volatile signed char _state; // {not_installed, in_use, not_entrant, zombie, unloaded} 129 190 OopMapSet* oop_maps); 191 192 // Creation support 193 nmethod(Method* method, 194 CompilerType type, 195 int nmethod_size, 196 int compile_id, 197 int entry_bci, 198 CodeOffsets* offsets, 199 int orig_pc_offset, 200 DebugInformationRecorder *recorder, 201 Dependencies* dependencies, 202 CodeBuffer *code_buffer, 203 int frame_size, 204 OopMapSet* oop_maps, 205 ExceptionHandlerTable* handler_table, 206 ImplicitExceptionTable* nul_chk_table, 207 AbstractCompiler* compiler, 208 int comp_level 209 #if INCLUDE_JVMCI 210 , jweak installed_code, 211 jweak speculation_log 212 #endif 213 ); 214 215 // helper methods 216 void* operator new(size_t size, int nmethod_size, int comp_level) throw(); 217 218 const char* reloc_string_for(u_char* begin, u_char* end); 219 // Returns true if this thread changed the state of the nmethod or 220 // false if another thread performed the transition. 221 bool make_not_entrant_or_zombie(int state); 222 bool make_entrant() { Unimplemented(); return false; } 223 void inc_decompile_count(); 224 225 // Inform external interfaces that a compiled method has been unloaded 226 void post_compiled_method_unload(); 227 228 // Initailize fields to their default values 229 void init_defaults(); 230 231 // Offsets 234 235 address header_end() const { return (address) header_begin() + header_size(); } 236 237 public: 238 // create nmethod with entry_bci 239 static nmethod* new_nmethod(const methodHandle& method, 240 int compile_id, 241 int entry_bci, 242 CodeOffsets* offsets, 243 int orig_pc_offset, 244 DebugInformationRecorder* recorder, 245 Dependencies* dependencies, 246 CodeBuffer *code_buffer, 247 int frame_size, 248 OopMapSet* oop_maps, 249 ExceptionHandlerTable* handler_table, 250 ImplicitExceptionTable* nul_chk_table, 251 AbstractCompiler* compiler, 252 int comp_level 253 #if INCLUDE_JVMCI 254 , jweak installed_code = NULL, 255 jweak speculation_log = NULL 256 #endif 257 ); 258 259 // Only used for unit tests. 260 nmethod() 261 : CompiledMethod(), 262 _is_unloading_state(0), 263 _native_receiver_sp_offset(in_ByteSize(-1)), 264 _native_basic_lock_sp_offset(in_ByteSize(-1)) {} 265 266 267 static nmethod* new_native_nmethod(const methodHandle& method, 268 int compile_id, 269 CodeBuffer *code_buffer, 270 int vep_offset, 271 int frame_complete, 272 int frame_size, 273 ByteSize receiver_sp_offset, 274 ByteSize basic_lock_sp_offset, 275 OopMapSet* oop_maps); 282 address consts_begin () const { return header_begin() + _consts_offset ; } 283 address consts_end () const { return code_begin() ; } 284 address stub_begin () const { return header_begin() + _stub_offset ; } 285 address stub_end () const { return header_begin() + _oops_offset ; } 286 address exception_begin () const { return header_begin() + _exception_offset ; } 287 address unwind_handler_begin () const { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : NULL; } 288 oop* oops_begin () const { return (oop*) (header_begin() + _oops_offset) ; } 289 oop* oops_end () const { return (oop*) (header_begin() + _metadata_offset) ; } 290 291 Metadata** metadata_begin () const { return (Metadata**) (header_begin() + _metadata_offset) ; } 292 Metadata** metadata_end () const { return (Metadata**) _scopes_data_begin; } 293 294 address scopes_data_end () const { return header_begin() + _scopes_pcs_offset ; } 295 PcDesc* scopes_pcs_begin () const { return (PcDesc*)(header_begin() + _scopes_pcs_offset ); } 296 PcDesc* scopes_pcs_end () const { return (PcDesc*)(header_begin() + _dependencies_offset) ; } 297 address dependencies_begin () const { return header_begin() + _dependencies_offset ; } 298 address dependencies_end () const { return header_begin() + _handler_table_offset ; } 299 address handler_table_begin () const { return header_begin() + _handler_table_offset ; } 300 address handler_table_end () const { return header_begin() + _nul_chk_table_offset ; } 301 address nul_chk_table_begin () const { return header_begin() + _nul_chk_table_offset ; } 302 address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; } 303 304 // Sizes 305 int oops_size () const { return (address) oops_end () - (address) oops_begin (); } 306 int metadata_size () const { return (address) metadata_end () - (address) metadata_begin (); } 307 int dependencies_size () const { return dependencies_end () - dependencies_begin (); } 308 309 int oops_count() const { assert(oops_size() % oopSize == 0, ""); return (oops_size() / oopSize) + 1; } 310 int metadata_count() const { assert(metadata_size() % wordSize == 0, ""); return (metadata_size() / wordSize) + 1; } 311 312 int total_size () const; 313 314 void dec_hotness_counter() { _hotness_counter--; } 315 void set_hotness_counter(int val) { _hotness_counter = val; } 316 int hotness_counter() const { return _hotness_counter; } 317 318 // Containment 319 bool oops_contains (oop* addr) const { return oops_begin () <= addr && addr < oops_end (); } 320 bool metadata_contains (Metadata** addr) const { return metadata_begin () <= addr && addr < metadata_end (); } 321 bool scopes_data_contains (address addr) const { return scopes_data_begin () <= addr && addr < scopes_data_end (); } 322 bool scopes_pcs_contains (PcDesc* addr) const { return scopes_pcs_begin () <= addr && addr < scopes_pcs_end (); } 323 324 // entry points 325 address entry_point() const { return _entry_point; } // normal entry point 326 address verified_entry_point() const { return _verified_entry_point; } // if klass is correct 327 429 // Only NMethodSweeper class is expected to use this. NMethodSweeper is not 430 // expected to use any other private methods/data in this class. 431 432 protected: 433 void flush(); 434 435 public: 436 // When true is returned, it is unsafe to remove this nmethod even if 437 // it is a zombie, since the VM or the ServiceThread might still be 438 // using it. 439 bool is_locked_by_vm() const { return _lock_count >0; } 440 441 // See comment at definition of _last_seen_on_stack 442 void mark_as_seen_on_stack(); 443 bool can_convert_to_zombie(); 444 445 // Evolution support. We make old (discarded) compiled methods point to new Method*s. 446 void set_method(Method* method) { _method = method; } 447 448 #if INCLUDE_JVMCI 449 // Gets the InstalledCode object associated with this nmethod 450 // which may be NULL if this nmethod was not compiled by JVMCI 451 // or the weak reference has been cleared. 452 oop jvmci_installed_code(); 453 454 // Copies the value of the name field in the InstalledCode 455 // object (if any) associated with this nmethod into buf. 456 // Returns the value of buf if it was updated otherwise NULL. 457 char* jvmci_installed_code_name(char* buf, size_t buflen) const; 458 459 // Updates the state of the InstalledCode (if any) associated with 460 // this nmethod based on the current value of _state. 461 void maybe_invalidate_installed_code(); 462 463 // Deoptimizes the nmethod (if any) in the address field of a given 464 // InstalledCode object. The address field is zeroed upon return. 465 static void invalidate_installed_code(Handle installed_code, TRAPS); 466 467 // Gets the SpeculationLog object associated with this nmethod 468 // which may be NULL if this nmethod was not compiled by JVMCI 469 // or the weak reference has been cleared. 470 oop speculation_log(); 471 472 private: 473 // Deletes the weak reference (if any) to the InstalledCode object 474 // associated with this nmethod. 475 void clear_jvmci_installed_code(); 476 477 // Deletes the weak reference (if any) to the SpeculationLog object 478 // associated with this nmethod. 479 void clear_speculation_log(); 480 481 public: 482 #endif 483 484 public: 485 void oops_do(OopClosure* f) { oops_do(f, false); } 486 void oops_do(OopClosure* f, bool allow_zombie); 487 488 bool test_set_oops_do_mark(); 489 static void oops_do_marking_prologue(); 490 static void oops_do_marking_epilogue(); 491 static bool oops_do_marking_is_active() { return _oops_do_mark_nmethods != NULL; } 492 bool test_oops_do_mark() { return _oops_do_mark_link != NULL; } 493 494 private: 495 ScopeDesc* scope_desc_in(address begin, address end); 496 497 address* orig_pc_addr(const frame* fr); 498 499 public: 500 // copying of debugging information 501 void copy_scopes_pcs(PcDesc* pcs, int count); | 34 // nmethods (native methods) are the compiled code versions of Java methods. 35 // 36 // An nmethod contains: 37 // - header (the nmethod structure) 38 // [Relocation] 39 // - relocation information 40 // - constant part (doubles, longs and floats used in nmethod) 41 // - oop table 42 // [Code] 43 // - code body 44 // - exception handler 45 // - stub code 46 // [Debugging information] 47 // - oop array 48 // - data array 49 // - pcs 50 // [Exception handler table] 51 // - handler entry point array 52 // [Implicit Null Pointer exception table] 53 // - implicit null table array 54 // [Speculations] 55 // - encoded speculations array 56 // [JVMCINMethodData] 57 // - meta data for JVMCI compiled nmethod 58 59 #if INCLUDE_JVMCI 60 class FailedSpeculation; 61 class JVMCINMethodData; 62 #endif 63 64 class nmethod : public CompiledMethod { 65 friend class VMStructs; 66 friend class JVMCIVMStructs; 67 friend class NMethodSweeper; 68 friend class CodeCache; // scavengable oops 69 friend class JVMCINMethodData; 70 private: 71 72 // Shared fields for all nmethod's 73 int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method 74 jmethodID _jmethod_id; // Cache of method()->jmethod_id() 75 76 // To support simple linked-list chaining of nmethods: 77 nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head 78 79 static nmethod* volatile _oops_do_mark_nmethods; 80 nmethod* volatile _oops_do_mark_link; 81 82 // offsets for entry points 83 address _entry_point; // entry point with class check 84 address _verified_entry_point; // entry point without class check 85 address _osr_entry_point; // entry point for on stack replacement 86 87 // Offsets for different nmethod parts 88 int _exception_offset; 89 // Offset of the unwind handler if it exists 90 int _unwind_handler_offset; 91 92 int _consts_offset; 93 int _stub_offset; 94 int _oops_offset; // offset to where embedded oop table begins (inside data) 95 int _metadata_offset; // embedded meta data table 96 int _scopes_data_offset; 97 int _scopes_pcs_offset; 98 int _dependencies_offset; 99 int _handler_table_offset; 100 int _nul_chk_table_offset; 101 #if INCLUDE_JVMCI 102 int _speculations_offset; 103 int _jvmci_data_offset; 104 #endif 105 int _nmethod_end_offset; 106 107 int code_offset() const { return (address) code_begin() - header_begin(); } 108 109 // location in frame (offset for sp) that deopt can store the original 110 // pc during a deopt. 111 int _orig_pc_offset; 112 113 int _compile_id; // which compilation made this nmethod 114 int _comp_level; // compilation level 115 116 // protected by CodeCache_lock 117 bool _has_flushed_dependencies; // Used for maintenance of dependencies (CodeCache_lock) 118 119 // used by jvmti to track if an unload event has been posted for this nmethod. 120 bool _unload_reported; 121 122 // Protected by Patching_lock 123 volatile signed char _state; // {not_installed, in_use, not_entrant, zombie, unloaded} 124 185 OopMapSet* oop_maps); 186 187 // Creation support 188 nmethod(Method* method, 189 CompilerType type, 190 int nmethod_size, 191 int compile_id, 192 int entry_bci, 193 CodeOffsets* offsets, 194 int orig_pc_offset, 195 DebugInformationRecorder *recorder, 196 Dependencies* dependencies, 197 CodeBuffer *code_buffer, 198 int frame_size, 199 OopMapSet* oop_maps, 200 ExceptionHandlerTable* handler_table, 201 ImplicitExceptionTable* nul_chk_table, 202 AbstractCompiler* compiler, 203 int comp_level 204 #if INCLUDE_JVMCI 205 , char* speculations, 206 int speculations_len, 207 int jvmci_data_size 208 #endif 209 ); 210 211 // helper methods 212 void* operator new(size_t size, int nmethod_size, int comp_level) throw(); 213 214 const char* reloc_string_for(u_char* begin, u_char* end); 215 // Returns true if this thread changed the state of the nmethod or 216 // false if another thread performed the transition. 217 bool make_not_entrant_or_zombie(int state); 218 bool make_entrant() { Unimplemented(); return false; } 219 void inc_decompile_count(); 220 221 // Inform external interfaces that a compiled method has been unloaded 222 void post_compiled_method_unload(); 223 224 // Initailize fields to their default values 225 void init_defaults(); 226 227 // Offsets 230 231 address header_end() const { return (address) header_begin() + header_size(); } 232 233 public: 234 // create nmethod with entry_bci 235 static nmethod* new_nmethod(const methodHandle& method, 236 int compile_id, 237 int entry_bci, 238 CodeOffsets* offsets, 239 int orig_pc_offset, 240 DebugInformationRecorder* recorder, 241 Dependencies* dependencies, 242 CodeBuffer *code_buffer, 243 int frame_size, 244 OopMapSet* oop_maps, 245 ExceptionHandlerTable* handler_table, 246 ImplicitExceptionTable* nul_chk_table, 247 AbstractCompiler* compiler, 248 int comp_level 249 #if INCLUDE_JVMCI 250 , char* speculations = NULL, 251 int speculations_len = 0, 252 int nmethod_mirror_index = -1, 253 const char* nmethod_mirror_name = NULL, 254 FailedSpeculation** failed_speculations = NULL 255 #endif 256 ); 257 258 // Only used for unit tests. 259 nmethod() 260 : CompiledMethod(), 261 _is_unloading_state(0), 262 _native_receiver_sp_offset(in_ByteSize(-1)), 263 _native_basic_lock_sp_offset(in_ByteSize(-1)) {} 264 265 266 static nmethod* new_native_nmethod(const methodHandle& method, 267 int compile_id, 268 CodeBuffer *code_buffer, 269 int vep_offset, 270 int frame_complete, 271 int frame_size, 272 ByteSize receiver_sp_offset, 273 ByteSize basic_lock_sp_offset, 274 OopMapSet* oop_maps); 281 address consts_begin () const { return header_begin() + _consts_offset ; } 282 address consts_end () const { return code_begin() ; } 283 address stub_begin () const { return header_begin() + _stub_offset ; } 284 address stub_end () const { return header_begin() + _oops_offset ; } 285 address exception_begin () const { return header_begin() + _exception_offset ; } 286 address unwind_handler_begin () const { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : NULL; } 287 oop* oops_begin () const { return (oop*) (header_begin() + _oops_offset) ; } 288 oop* oops_end () const { return (oop*) (header_begin() + _metadata_offset) ; } 289 290 Metadata** metadata_begin () const { return (Metadata**) (header_begin() + _metadata_offset) ; } 291 Metadata** metadata_end () const { return (Metadata**) _scopes_data_begin; } 292 293 address scopes_data_end () const { return header_begin() + _scopes_pcs_offset ; } 294 PcDesc* scopes_pcs_begin () const { return (PcDesc*)(header_begin() + _scopes_pcs_offset ); } 295 PcDesc* scopes_pcs_end () const { return (PcDesc*)(header_begin() + _dependencies_offset) ; } 296 address dependencies_begin () const { return header_begin() + _dependencies_offset ; } 297 address dependencies_end () const { return header_begin() + _handler_table_offset ; } 298 address handler_table_begin () const { return header_begin() + _handler_table_offset ; } 299 address handler_table_end () const { return header_begin() + _nul_chk_table_offset ; } 300 address nul_chk_table_begin () const { return header_begin() + _nul_chk_table_offset ; } 301 #if INCLUDE_JVMCI 302 address nul_chk_table_end () const { return header_begin() + _speculations_offset ; } 303 address speculations_begin () const { return header_begin() + _speculations_offset ; } 304 address speculations_end () const { return header_begin() + _jvmci_data_offset ; } 305 address jvmci_data_begin () const { return header_begin() + _jvmci_data_offset ; } 306 address jvmci_data_end () const { return header_begin() + _nmethod_end_offset ; } 307 #else 308 address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; } 309 #endif 310 311 // Sizes 312 int oops_size () const { return (address) oops_end () - (address) oops_begin (); } 313 int metadata_size () const { return (address) metadata_end () - (address) metadata_begin (); } 314 int dependencies_size () const { return dependencies_end () - dependencies_begin (); } 315 #if INCLUDE_JVMCI 316 int speculations_size () const { return speculations_end () - speculations_begin (); } 317 int jvmci_data_size () const { return jvmci_data_end () - jvmci_data_begin (); } 318 #endif 319 320 int oops_count() const { assert(oops_size() % oopSize == 0, ""); return (oops_size() / oopSize) + 1; } 321 int metadata_count() const { assert(metadata_size() % wordSize == 0, ""); return (metadata_size() / wordSize) + 1; } 322 323 int total_size () const; 324 325 void dec_hotness_counter() { _hotness_counter--; } 326 void set_hotness_counter(int val) { _hotness_counter = val; } 327 int hotness_counter() const { return _hotness_counter; } 328 329 // Containment 330 bool oops_contains (oop* addr) const { return oops_begin () <= addr && addr < oops_end (); } 331 bool metadata_contains (Metadata** addr) const { return metadata_begin () <= addr && addr < metadata_end (); } 332 bool scopes_data_contains (address addr) const { return scopes_data_begin () <= addr && addr < scopes_data_end (); } 333 bool scopes_pcs_contains (PcDesc* addr) const { return scopes_pcs_begin () <= addr && addr < scopes_pcs_end (); } 334 335 // entry points 336 address entry_point() const { return _entry_point; } // normal entry point 337 address verified_entry_point() const { return _verified_entry_point; } // if klass is correct 338 440 // Only NMethodSweeper class is expected to use this. NMethodSweeper is not 441 // expected to use any other private methods/data in this class. 442 443 protected: 444 void flush(); 445 446 public: 447 // When true is returned, it is unsafe to remove this nmethod even if 448 // it is a zombie, since the VM or the ServiceThread might still be 449 // using it. 450 bool is_locked_by_vm() const { return _lock_count >0; } 451 452 // See comment at definition of _last_seen_on_stack 453 void mark_as_seen_on_stack(); 454 bool can_convert_to_zombie(); 455 456 // Evolution support. We make old (discarded) compiled methods point to new Method*s. 457 void set_method(Method* method) { _method = method; } 458 459 #if INCLUDE_JVMCI 460 // Gets the JVMCI name of this nmethod. 461 const char* jvmci_name(); 462 463 // Records the pending failed speculation in the 464 // JVMCI speculation log associated with this nmethod. 465 void update_speculation(JavaThread* thread); 466 467 // Gets the data specific to a JVMCI compiled method. 468 // This returns a non-NULL value iff this nmethod was 469 // compiled by the JVMCI compiler. 470 JVMCINMethodData* jvmci_nmethod_data() const { 471 return jvmci_data_size() == 0 ? NULL : (JVMCINMethodData*) jvmci_data_begin(); 472 } 473 #endif 474 475 public: 476 void oops_do(OopClosure* f) { oops_do(f, false); } 477 void oops_do(OopClosure* f, bool allow_zombie); 478 479 bool test_set_oops_do_mark(); 480 static void oops_do_marking_prologue(); 481 static void oops_do_marking_epilogue(); 482 static bool oops_do_marking_is_active() { return _oops_do_mark_nmethods != NULL; } 483 bool test_oops_do_mark() { return _oops_do_mark_link != NULL; } 484 485 private: 486 ScopeDesc* scope_desc_in(address begin, address end); 487 488 address* orig_pc_addr(const frame* fr); 489 490 public: 491 // copying of debugging information 492 void copy_scopes_pcs(PcDesc* pcs, int count); |