460 // Fill in default values for various flag fields |
460 // Fill in default values for various flag fields |
461 void nmethod::init_defaults() { |
461 void nmethod::init_defaults() { |
462 _state = alive; |
462 _state = alive; |
463 _marked_for_reclamation = 0; |
463 _marked_for_reclamation = 0; |
464 _has_flushed_dependencies = 0; |
464 _has_flushed_dependencies = 0; |
465 _speculatively_disconnected = 0; |
|
466 _has_unsafe_access = 0; |
465 _has_unsafe_access = 0; |
467 _has_method_handle_invokes = 0; |
466 _has_method_handle_invokes = 0; |
468 _lazy_critical_native = 0; |
467 _lazy_critical_native = 0; |
469 _has_wide_vectors = 0; |
468 _has_wide_vectors = 0; |
470 _marked_for_deoptimization = 0; |
469 _marked_for_deoptimization = 0; |
684 _entry_point = code_begin() + offsets->value(CodeOffsets::Entry); |
682 _entry_point = code_begin() + offsets->value(CodeOffsets::Entry); |
685 _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry); |
683 _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry); |
686 _osr_entry_point = NULL; |
684 _osr_entry_point = NULL; |
687 _exception_cache = NULL; |
685 _exception_cache = NULL; |
688 _pc_desc_cache.reset_to(NULL); |
686 _pc_desc_cache.reset_to(NULL); |
|
687 _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); |
689 |
688 |
690 code_buffer->copy_values_to(this); |
689 code_buffer->copy_values_to(this); |
691 if (ScavengeRootsInCode && detect_scavenge_root_oops()) { |
690 if (ScavengeRootsInCode && detect_scavenge_root_oops()) { |
692 CodeCache::add_scavenge_root_nmethod(this); |
691 CodeCache::add_scavenge_root_nmethod(this); |
693 Universe::heap()->register_nmethod(this); |
692 Universe::heap()->register_nmethod(this); |
768 _entry_point = code_begin() + offsets->value(CodeOffsets::Entry); |
767 _entry_point = code_begin() + offsets->value(CodeOffsets::Entry); |
769 _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry); |
768 _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry); |
770 _osr_entry_point = NULL; |
769 _osr_entry_point = NULL; |
771 _exception_cache = NULL; |
770 _exception_cache = NULL; |
772 _pc_desc_cache.reset_to(NULL); |
771 _pc_desc_cache.reset_to(NULL); |
|
772 _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); |
773 |
773 |
774 code_buffer->copy_values_to(this); |
774 code_buffer->copy_values_to(this); |
775 debug_only(verify_scavenge_root_oops()); |
775 debug_only(verify_scavenge_root_oops()); |
776 CodeCache::commit(this); |
776 CodeCache::commit(this); |
777 } |
777 } |
840 _entry_bci = entry_bci; |
840 _entry_bci = entry_bci; |
841 _compile_id = compile_id; |
841 _compile_id = compile_id; |
842 _comp_level = comp_level; |
842 _comp_level = comp_level; |
843 _compiler = compiler; |
843 _compiler = compiler; |
844 _orig_pc_offset = orig_pc_offset; |
844 _orig_pc_offset = orig_pc_offset; |
|
845 _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); |
845 |
846 |
846 // Section offsets |
847 // Section offsets |
847 _consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts()); |
848 _consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts()); |
848 _stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs()); |
849 _stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs()); |
849 |
850 |
1174 } |
1175 } |
1175 } |
1176 } |
1176 |
1177 |
1177 // This is a private interface with the sweeper. |
1178 // This is a private interface with the sweeper. |
1178 void nmethod::mark_as_seen_on_stack() { |
1179 void nmethod::mark_as_seen_on_stack() { |
1179 assert(is_not_entrant(), "must be a non-entrant method"); |
1180 assert(is_alive(), "Must be an alive method"); |
1180 // Set the traversal mark to ensure that the sweeper does 2 |
1181 // Set the traversal mark to ensure that the sweeper does 2 |
1181 // cleaning passes before moving to zombie. |
1182 // cleaning passes before moving to zombie. |
1182 set_stack_traversal_mark(NMethodSweeper::traversal_count()); |
1183 set_stack_traversal_mark(NMethodSweeper::traversal_count()); |
1183 } |
1184 } |
1184 |
1185 |
1259 // The Method* is gone at this point |
1260 // The Method* is gone at this point |
1260 assert(_method == NULL, "Tautology"); |
1261 assert(_method == NULL, "Tautology"); |
1261 |
1262 |
1262 set_osr_link(NULL); |
1263 set_osr_link(NULL); |
1263 //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods |
1264 //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods |
1264 NMethodSweeper::notify(this); |
1265 NMethodSweeper::notify(); |
1265 } |
1266 } |
1266 |
1267 |
1267 void nmethod::invalidate_osr_method() { |
1268 void nmethod::invalidate_osr_method() { |
1268 assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); |
1269 assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); |
1269 // Remove from list of active nmethods |
1270 // Remove from list of active nmethods |
1349 // This nmethod may have already been unloaded during a full GC. |
1350 // This nmethod may have already been unloaded during a full GC. |
1350 if ((state == zombie) && !is_unloaded()) { |
1351 if ((state == zombie) && !is_unloaded()) { |
1351 nmethod_needs_unregister = true; |
1352 nmethod_needs_unregister = true; |
1352 } |
1353 } |
1353 |
1354 |
|
1355 // Must happen before state change. Otherwise we have a race condition in |
|
1356 // nmethod::can_not_entrant_be_converted(). I.e., a method can immediately |
|
1357 // transition its state from 'not_entrant' to 'zombie' without having to wait |
|
1358 // for stack scanning. |
|
1359 if (state == not_entrant) { |
|
1360 mark_as_seen_on_stack(); |
|
1361 OrderAccess::storestore(); |
|
1362 } |
|
1363 |
1354 // Change state |
1364 // Change state |
1355 _state = state; |
1365 _state = state; |
1356 |
1366 |
1357 // Log the transition once |
1367 // Log the transition once |
1358 log_state_change(); |
1368 log_state_change(); |
1367 if (method() != NULL && (method()->code() == this || |
1377 if (method() != NULL && (method()->code() == this || |
1368 method()->from_compiled_entry() == verified_entry_point())) { |
1378 method()->from_compiled_entry() == verified_entry_point())) { |
1369 HandleMark hm; |
1379 HandleMark hm; |
1370 method()->clear_code(); |
1380 method()->clear_code(); |
1371 } |
1381 } |
1372 |
|
1373 if (state == not_entrant) { |
|
1374 mark_as_seen_on_stack(); |
|
1375 } |
|
1376 |
|
1377 } // leave critical region under Patching_lock |
1382 } // leave critical region under Patching_lock |
1378 |
1383 |
1379 // When the nmethod becomes zombie it is no longer alive so the |
1384 // When the nmethod becomes zombie it is no longer alive so the |
1380 // dependencies must be flushed. nmethods in the not_entrant |
1385 // dependencies must be flushed. nmethods in the not_entrant |
1381 // state will be flushed later when the transition to zombie |
1386 // state will be flushed later when the transition to zombie |
1414 if (TraceCreateZombies) { |
1419 if (TraceCreateZombies) { |
1415 tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (state == not_entrant) ? "not entrant" : "zombie"); |
1420 tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (state == not_entrant) ? "not entrant" : "zombie"); |
1416 } |
1421 } |
1417 |
1422 |
1418 // Make sweeper aware that there is a zombie method that needs to be removed |
1423 // Make sweeper aware that there is a zombie method that needs to be removed |
1419 NMethodSweeper::notify(this); |
1424 NMethodSweeper::notify(); |
1420 |
1425 |
1421 return true; |
1426 return true; |
1422 } |
1427 } |
1423 |
1428 |
1424 void nmethod::flush() { |
1429 void nmethod::flush() { |