comparison src/share/vm/code/nmethod.cpp @ 2405:3d58a4983660

7022998: JSR 292 recursive method handle calls inline themselves infinitely Reviewed-by: never, kvn
author twisti
date Mon, 28 Mar 2011 03:58:07 -0700
parents c7f3d0b4570f
children 0654ee04b214 2aa9ddbb9e60
comparison
equal deleted inserted replaced
2404:b40d4fa697bf 2405:3d58a4983660
26 #include "code/codeCache.hpp" 26 #include "code/codeCache.hpp"
27 #include "code/compiledIC.hpp" 27 #include "code/compiledIC.hpp"
28 #include "code/nmethod.hpp" 28 #include "code/nmethod.hpp"
29 #include "code/scopeDesc.hpp" 29 #include "code/scopeDesc.hpp"
30 #include "compiler/abstractCompiler.hpp" 30 #include "compiler/abstractCompiler.hpp"
31 #include "compiler/compileBroker.hpp"
31 #include "compiler/compileLog.hpp" 32 #include "compiler/compileLog.hpp"
32 #include "compiler/compilerOracle.hpp" 33 #include "compiler/compilerOracle.hpp"
33 #include "compiler/disassembler.hpp" 34 #include "compiler/disassembler.hpp"
34 #include "interpreter/bytecode.hpp" 35 #include "interpreter/bytecode.hpp"
35 #include "oops/methodDataOop.hpp" 36 #include "oops/methodDataOop.hpp"
467 #endif // def HAVE_DTRACE_H 468 #endif // def HAVE_DTRACE_H
468 } 469 }
469 470
470 471
471 nmethod* nmethod::new_native_nmethod(methodHandle method, 472 nmethod* nmethod::new_native_nmethod(methodHandle method,
473 int compile_id,
472 CodeBuffer *code_buffer, 474 CodeBuffer *code_buffer,
473 int vep_offset, 475 int vep_offset,
474 int frame_complete, 476 int frame_complete,
475 int frame_size, 477 int frame_size,
476 ByteSize basic_lock_owner_sp_offset, 478 ByteSize basic_lock_owner_sp_offset,
483 int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod)); 485 int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
484 CodeOffsets offsets; 486 CodeOffsets offsets;
485 offsets.set_value(CodeOffsets::Verified_Entry, vep_offset); 487 offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
486 offsets.set_value(CodeOffsets::Frame_Complete, frame_complete); 488 offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
487 nm = new (native_nmethod_size) 489 nm = new (native_nmethod_size)
488 nmethod(method(), native_nmethod_size, &offsets, 490 nmethod(method(), native_nmethod_size, compile_id, &offsets,
489 code_buffer, frame_size, 491 code_buffer, frame_size,
490 basic_lock_owner_sp_offset, basic_lock_sp_offset, 492 basic_lock_owner_sp_offset, basic_lock_sp_offset,
491 oop_maps); 493 oop_maps);
492 NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_native_nmethod(nm)); 494 NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_native_nmethod(nm));
493 if (PrintAssembly && nm != NULL) 495 if (PrintAssembly && nm != NULL)
608 610
609 // For native wrappers 611 // For native wrappers
610 nmethod::nmethod( 612 nmethod::nmethod(
611 methodOop method, 613 methodOop method,
612 int nmethod_size, 614 int nmethod_size,
615 int compile_id,
613 CodeOffsets* offsets, 616 CodeOffsets* offsets,
614 CodeBuffer* code_buffer, 617 CodeBuffer* code_buffer,
615 int frame_size, 618 int frame_size,
616 ByteSize basic_lock_owner_sp_offset, 619 ByteSize basic_lock_owner_sp_offset,
617 ByteSize basic_lock_sp_offset, 620 ByteSize basic_lock_sp_offset,
642 _scopes_pcs_offset = _scopes_data_offset; 645 _scopes_pcs_offset = _scopes_data_offset;
643 _dependencies_offset = _scopes_pcs_offset; 646 _dependencies_offset = _scopes_pcs_offset;
644 _handler_table_offset = _dependencies_offset; 647 _handler_table_offset = _dependencies_offset;
645 _nul_chk_table_offset = _handler_table_offset; 648 _nul_chk_table_offset = _handler_table_offset;
646 _nmethod_end_offset = _nul_chk_table_offset; 649 _nmethod_end_offset = _nul_chk_table_offset;
647 _compile_id = 0; // default 650 _compile_id = compile_id;
648 _comp_level = CompLevel_none; 651 _comp_level = CompLevel_none;
649 _entry_point = code_begin() + offsets->value(CodeOffsets::Entry); 652 _entry_point = code_begin() + offsets->value(CodeOffsets::Entry);
650 _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry); 653 _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry);
651 _osr_entry_point = NULL; 654 _osr_entry_point = NULL;
652 _exception_cache = NULL; 655 _exception_cache = NULL;
928 } 931 }
929 932
930 #undef LOG_OFFSET 933 #undef LOG_OFFSET
931 934
932 935
933 void nmethod::print_compilation(outputStream *st, const char *method_name, const char *title,
934 methodOop method, bool is_blocking, int compile_id, int bci, int comp_level) {
935 bool is_synchronized = false, has_xhandler = false, is_native = false;
936 int code_size = -1;
937 if (method != NULL) {
938 is_synchronized = method->is_synchronized();
939 has_xhandler = method->has_exception_handler();
940 is_native = method->is_native();
941 code_size = method->code_size();
942 }
943 // print compilation number
944 st->print("%7d %3d", (int)tty->time_stamp().milliseconds(), compile_id);
945
946 // print method attributes
947 const bool is_osr = bci != InvocationEntryBci;
948 const char blocking_char = is_blocking ? 'b' : ' ';
949 const char compile_type = is_osr ? '%' : ' ';
950 const char sync_char = is_synchronized ? 's' : ' ';
951 const char exception_char = has_xhandler ? '!' : ' ';
952 const char native_char = is_native ? 'n' : ' ';
953 st->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, native_char);
954 if (TieredCompilation) {
955 st->print("%d ", comp_level);
956 }
957
958 // print optional title
959 bool do_nl = false;
960 if (title != NULL) {
961 int tlen = (int) strlen(title);
962 bool do_nl = false;
963 if (tlen > 0 && title[tlen-1] == '\n') { tlen--; do_nl = true; }
964 st->print("%.*s", tlen, title);
965 } else {
966 do_nl = true;
967 }
968
969 // print method name string if given
970 if (method_name != NULL) {
971 st->print(method_name);
972 } else {
973 // otherwise as the method to print itself
974 if (method != NULL && !Universe::heap()->is_gc_active()) {
975 method->print_short_name(st);
976 } else {
977 st->print("(method)");
978 }
979 }
980
981 if (method != NULL) {
982 // print osr_bci if any
983 if (is_osr) st->print(" @ %d", bci);
984 // print method size
985 st->print(" (%d bytes)", code_size);
986 }
987 if (do_nl) st->cr();
988 }
989
990 // Print out more verbose output usually for a newly created nmethod. 936 // Print out more verbose output usually for a newly created nmethod.
991 void nmethod::print_on(outputStream* st, const char* title) const { 937 void nmethod::print_on(outputStream* st, const char* msg) const {
992 if (st != NULL) { 938 if (st != NULL) {
993 ttyLocker ttyl; 939 ttyLocker ttyl;
994 print_compilation(st, /*method_name*/NULL, title, 940 CompileTask::print_compilation(st, this, msg);
995 method(), /*is_blocking*/false,
996 compile_id(),
997 is_osr_method() ? osr_entry_bci() : InvocationEntryBci,
998 comp_level());
999 if (WizardMode) st->print(" (" INTPTR_FORMAT ")", this); 941 if (WizardMode) st->print(" (" INTPTR_FORMAT ")", this);
1000 } 942 }
1001 } 943 }
1002 944
1003 945
1307 xtty->stamp(); 1249 xtty->stamp();
1308 xtty->end_elem(); 1250 xtty->end_elem();
1309 } 1251 }
1310 } 1252 }
1311 if (PrintCompilation && _state != unloaded) { 1253 if (PrintCompilation && _state != unloaded) {
1312 print_on(tty, _state == zombie ? "made zombie " : "made not entrant "); 1254 print_on(tty, _state == zombie ? "made zombie" : "made not entrant");
1313 tty->cr();
1314 } 1255 }
1315 } 1256 }
1316 1257
1317 // Common functionality for both make_not_entrant and make_zombie 1258 // Common functionality for both make_not_entrant and make_zombie
1318 bool nmethod::make_not_entrant_or_zombie(unsigned int state) { 1259 bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
1814 Atomic::cmpxchg_ptr(this, &_oops_do_mark_nmethods, required_mark_nmethods); 1755 Atomic::cmpxchg_ptr(this, &_oops_do_mark_nmethods, required_mark_nmethods);
1815 if (observed_mark_nmethods == required_mark_nmethods) 1756 if (observed_mark_nmethods == required_mark_nmethods)
1816 break; 1757 break;
1817 } 1758 }
1818 // Mark was clear when we first saw this guy. 1759 // Mark was clear when we first saw this guy.
1819 NOT_PRODUCT(if (TraceScavenge) print_on(tty, "oops_do, mark\n")); 1760 NOT_PRODUCT(if (TraceScavenge) print_on(tty, "oops_do, mark"));
1820 return false; 1761 return false;
1821 } 1762 }
1822 } 1763 }
1823 // On fall through, another racing thread marked this nmethod before we did. 1764 // On fall through, another racing thread marked this nmethod before we did.
1824 return true; 1765 return true;
1839 while (cur != NMETHOD_SENTINEL) { 1780 while (cur != NMETHOD_SENTINEL) {
1840 assert(cur != NULL, "not NULL-terminated"); 1781 assert(cur != NULL, "not NULL-terminated");
1841 nmethod* next = cur->_oops_do_mark_link; 1782 nmethod* next = cur->_oops_do_mark_link;
1842 cur->_oops_do_mark_link = NULL; 1783 cur->_oops_do_mark_link = NULL;
1843 cur->fix_oop_relocations(); 1784 cur->fix_oop_relocations();
1844 NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark\n")); 1785 NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark"));
1845 cur = next; 1786 cur = next;
1846 } 1787 }
1847 void* required = _oops_do_mark_nmethods; 1788 void* required = _oops_do_mark_nmethods;
1848 void* observed = Atomic::cmpxchg_ptr(NULL, &_oops_do_mark_nmethods, required); 1789 void* observed = Atomic::cmpxchg_ptr(NULL, &_oops_do_mark_nmethods, required);
1849 guarantee(observed == required, "no races in this sequential code"); 1790 guarantee(observed == required, "no races in this sequential code");
2394 2335
2395 void nmethod::print() const { 2336 void nmethod::print() const {
2396 ResourceMark rm; 2337 ResourceMark rm;
2397 ttyLocker ttyl; // keep the following output all in one block 2338 ttyLocker ttyl; // keep the following output all in one block
2398 2339
2399 tty->print("Compiled "); 2340 tty->print("Compiled method ");
2400 2341
2401 if (is_compiled_by_c1()) { 2342 if (is_compiled_by_c1()) {
2402 tty->print("(c1) "); 2343 tty->print("(c1) ");
2403 } else if (is_compiled_by_c2()) { 2344 } else if (is_compiled_by_c2()) {
2404 tty->print("(c2) "); 2345 tty->print("(c2) ");
2406 tty->print("(shark) "); 2347 tty->print("(shark) ");
2407 } else { 2348 } else {
2408 tty->print("(nm) "); 2349 tty->print("(nm) ");
2409 } 2350 }
2410 2351
2411 print_on(tty, "nmethod"); 2352 print_on(tty, NULL);
2412 tty->cr(); 2353
2413 if (WizardMode) { 2354 if (WizardMode) {
2414 tty->print("((nmethod*) "INTPTR_FORMAT ") ", this); 2355 tty->print("((nmethod*) "INTPTR_FORMAT ") ", this);
2415 tty->print(" for method " INTPTR_FORMAT , (address)method()); 2356 tty->print(" for method " INTPTR_FORMAT , (address)method());
2416 tty->print(" { "); 2357 tty->print(" { ");
2417 if (is_in_use()) tty->print("in_use "); 2358 if (is_in_use()) tty->print("in_use ");
2794 } 2735 }
2795 2736
2796 #ifndef PRODUCT 2737 #ifndef PRODUCT
2797 2738
2798 void nmethod::print_value_on(outputStream* st) const { 2739 void nmethod::print_value_on(outputStream* st) const {
2799 print_on(st, "nmethod"); 2740 st->print("nmethod");
2741 print_on(st, NULL);
2800 } 2742 }
2801 2743
2802 void nmethod::print_calls(outputStream* st) { 2744 void nmethod::print_calls(outputStream* st) {
2803 RelocIterator iter(this); 2745 RelocIterator iter(this);
2804 while (iter.next()) { 2746 while (iter.next()) {