123 class xmlStream; |
123 class xmlStream; |
124 |
124 |
125 class nmethod : public CodeBlob { |
125 class nmethod : public CodeBlob { |
126 friend class VMStructs; |
126 friend class VMStructs; |
127 friend class NMethodSweeper; |
127 friend class NMethodSweeper; |
|
128 friend class CodeCache; // non-perm oops |
128 private: |
129 private: |
129 // Shared fields for all nmethod's |
130 // Shared fields for all nmethod's |
130 static int _zombie_instruction_size; |
131 static int _zombie_instruction_size; |
131 |
132 |
132 methodOop _method; |
133 methodOop _method; |
133 int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method |
134 int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method |
134 |
135 |
135 nmethod* _link; // To support simple linked-list chaining of nmethods |
136 // To support simple linked-list chaining of nmethods: |
|
137 nmethod* _osr_link; // from instanceKlass::osr_nmethods_head |
|
138 nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods |
|
139 |
|
140 static nmethod* volatile _oops_do_mark_nmethods; |
|
141 nmethod* volatile _oops_do_mark_link; |
136 |
142 |
137 AbstractCompiler* _compiler; // The compiler which compiled this nmethod |
143 AbstractCompiler* _compiler; // The compiler which compiled this nmethod |
138 |
144 |
139 // Offsets for different nmethod parts |
145 // Offsets for different nmethod parts |
140 int _exception_offset; |
146 int _exception_offset; |
171 zombie = 2, |
177 zombie = 2, |
172 unloaded = 3 }; |
178 unloaded = 3 }; |
173 |
179 |
174 // used by jvmti to track if an unload event has been posted for this nmethod. |
180 // used by jvmti to track if an unload event has been posted for this nmethod. |
175 bool _unload_reported; |
181 bool _unload_reported; |
|
182 |
|
183 jbyte _scavenge_root_state; |
176 |
184 |
177 NOT_PRODUCT(bool _has_debug_info; ) |
185 NOT_PRODUCT(bool _has_debug_info; ) |
178 |
186 |
179 // Nmethod Flushing lock (if non-zero, then the nmethod is not removed) |
187 // Nmethod Flushing lock (if non-zero, then the nmethod is not removed) |
180 jint _lock_count; |
188 jint _lock_count; |
240 AbstractCompiler* compiler, |
248 AbstractCompiler* compiler, |
241 int comp_level); |
249 int comp_level); |
242 |
250 |
243 // helper methods |
251 // helper methods |
244 void* operator new(size_t size, int nmethod_size); |
252 void* operator new(size_t size, int nmethod_size); |
245 void check_store(); |
|
246 |
253 |
247 const char* reloc_string_for(u_char* begin, u_char* end); |
254 const char* reloc_string_for(u_char* begin, u_char* end); |
248 void make_not_entrant_or_zombie(int state); |
255 void make_not_entrant_or_zombie(int state); |
249 void inc_decompile_count(); |
256 void inc_decompile_count(); |
250 |
257 |
405 int comp_level() const { return _comp_level; } |
412 int comp_level() const { return _comp_level; } |
406 |
413 |
407 int version() const { return flags.version; } |
414 int version() const { return flags.version; } |
408 void set_version(int v); |
415 void set_version(int v); |
409 |
416 |
|
417 // Non-perm oop support |
|
418 bool on_scavenge_root_list() const { return (_scavenge_root_state & 1) != 0; } |
|
419 protected: |
|
420 enum { npl_on_list = 0x01, npl_marked = 0x10 }; |
|
421 void set_on_scavenge_root_list() { _scavenge_root_state = npl_on_list; } |
|
422 void clear_on_scavenge_root_list() { _scavenge_root_state = 0; } |
|
423 // assertion-checking and pruning logic uses the bits of _scavenge_root_state |
|
424 #ifndef PRODUCT |
|
425 void set_scavenge_root_marked() { _scavenge_root_state |= npl_marked; } |
|
426 void clear_scavenge_root_marked() { _scavenge_root_state &= ~npl_marked; } |
|
427 bool scavenge_root_not_marked() { return (_scavenge_root_state &~ npl_on_list) == 0; } |
|
428 // N.B. there is no positive marked query, and we only use the not_marked query for asserts. |
|
429 #endif //PRODUCT |
|
430 nmethod* scavenge_root_link() const { return _scavenge_root_link; } |
|
431 void set_scavenge_root_link(nmethod *n) { _scavenge_root_link = n; } |
|
432 |
|
433 public: |
|
434 |
410 // Sweeper support |
435 // Sweeper support |
411 long stack_traversal_mark() { return _stack_traversal_mark; } |
436 long stack_traversal_mark() { return _stack_traversal_mark; } |
412 void set_stack_traversal_mark(long l) { _stack_traversal_mark = l; } |
437 void set_stack_traversal_mark(long l) { _stack_traversal_mark = l; } |
413 |
438 |
414 // Exception cache support |
439 // Exception cache support |
423 |
448 |
424 // On-stack replacement support |
449 // On-stack replacement support |
425 int osr_entry_bci() const { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _entry_bci; } |
450 int osr_entry_bci() const { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _entry_bci; } |
426 address osr_entry() const { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _osr_entry_point; } |
451 address osr_entry() const { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _osr_entry_point; } |
427 void invalidate_osr_method(); |
452 void invalidate_osr_method(); |
428 nmethod* link() const { return _link; } |
453 nmethod* osr_link() const { return _osr_link; } |
429 void set_link(nmethod *n) { _link = n; } |
454 void set_osr_link(nmethod *n) { _osr_link = n; } |
430 |
455 |
431 // tells whether frames described by this nmethod can be deoptimized |
456 // tells whether frames described by this nmethod can be deoptimized |
432 // note: native wrappers cannot be deoptimized. |
457 // note: native wrappers cannot be deoptimized. |
433 bool can_be_deoptimized() const { return is_java_method(); } |
458 bool can_be_deoptimized() const { return is_java_method(); } |
434 |
459 |
465 oop* root, bool unloading_occurred); |
490 oop* root, bool unloading_occurred); |
466 |
491 |
467 void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, |
492 void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, |
468 OopClosure* f); |
493 OopClosure* f); |
469 void oops_do(OopClosure* f); |
494 void oops_do(OopClosure* f); |
|
495 bool detect_scavenge_root_oops(); |
|
496 void verify_scavenge_root_oops() PRODUCT_RETURN; |
|
497 |
|
498 bool test_set_oops_do_mark(); |
|
499 static void oops_do_marking_prologue(); |
|
500 static void oops_do_marking_epilogue(); |
|
501 static bool oops_do_marking_is_active() { return _oops_do_mark_nmethods != NULL; } |
|
502 DEBUG_ONLY(bool test_oops_do_mark() { return _oops_do_mark_link != NULL; }) |
470 |
503 |
471 // ScopeDesc for an instruction |
504 // ScopeDesc for an instruction |
472 ScopeDesc* scope_desc_at(address pc); |
505 ScopeDesc* scope_desc_at(address pc); |
473 |
506 |
474 private: |
507 private: |