Mercurial > hg > graal-jvmci-8
comparison src/share/vm/code/nmethod.cpp @ 8506:c3657d00e343
-Merge with tip
author | Christos Kotselidis <christos.kotselidis@oracle.com> |
---|---|
date | Thu, 21 Mar 2013 14:11:13 +0100 |
parents | 86b4965f0c9a 985a97ba083c |
children | b9a918201d47 |
comparison
equal
deleted
inserted
replaced
8505:dee7c8b578c7 | 8506:c3657d00e343 |
---|---|
40 #include "runtime/sharedRuntime.hpp" | 40 #include "runtime/sharedRuntime.hpp" |
41 #include "runtime/sweeper.hpp" | 41 #include "runtime/sweeper.hpp" |
42 #include "utilities/dtrace.hpp" | 42 #include "utilities/dtrace.hpp" |
43 #include "utilities/events.hpp" | 43 #include "utilities/events.hpp" |
44 #include "utilities/xmlstream.hpp" | 44 #include "utilities/xmlstream.hpp" |
45 #include "utilities/debug.hpp" | |
46 #include "utilities/machineCodePrinter.hpp" | |
47 #ifdef SHARK | 45 #ifdef SHARK |
48 #include "shark/sharkCompiler.hpp" | 46 #include "shark/sharkCompiler.hpp" |
49 #endif | 47 #endif |
50 #ifdef GRAAL | 48 #ifdef GRAAL |
51 #include "graal/graalJavaAccess.hpp" | 49 #include "graal/graalJavaAccess.hpp" |
124 // NMethod statistics | 122 // NMethod statistics |
125 // They are printed under various flags, including: | 123 // They are printed under various flags, including: |
126 // PrintC1Statistics, PrintOptoStatistics, LogVMOutput, and LogCompilation. | 124 // PrintC1Statistics, PrintOptoStatistics, LogVMOutput, and LogCompilation. |
127 // (In the latter two cases, they like other stats are printed to the log only.) | 125 // (In the latter two cases, they like other stats are printed to the log only.) |
128 | 126 |
127 #ifndef PRODUCT | |
129 // These variables are put into one block to reduce relocations | 128 // These variables are put into one block to reduce relocations |
130 // and make it simpler to print from the debugger. | 129 // and make it simpler to print from the debugger. |
131 static | 130 static |
132 struct nmethod_stats_struct { | 131 struct nmethod_stats_struct { |
133 int nmethod_count; | 132 int nmethod_count; |
213 pc_desc_queries, pc_desc_approx, | 212 pc_desc_queries, pc_desc_approx, |
214 pc_desc_repeats, pc_desc_hits, | 213 pc_desc_repeats, pc_desc_hits, |
215 pc_desc_tests, pc_desc_searches, pc_desc_adds); | 214 pc_desc_tests, pc_desc_searches, pc_desc_adds); |
216 } | 215 } |
217 } nmethod_stats; | 216 } nmethod_stats; |
217 #endif //PRODUCT | |
218 | 218 |
219 | 219 |
220 //--------------------------------------------------------------------------------- | 220 //--------------------------------------------------------------------------------- |
221 | 221 |
222 | 222 |
488 _scavenge_root_state = 0; | 488 _scavenge_root_state = 0; |
489 _saved_nmethod_link = NULL; | 489 _saved_nmethod_link = NULL; |
490 _compiler = NULL; | 490 _compiler = NULL; |
491 #ifdef GRAAL | 491 #ifdef GRAAL |
492 _graal_installed_code = NULL; | 492 _graal_installed_code = NULL; |
493 _triggered_deoptimizations = NULL; | |
493 #endif | 494 #endif |
494 #ifdef HAVE_DTRACE_H | 495 #ifdef HAVE_DTRACE_H |
495 _trap_offset = 0; | 496 _trap_offset = 0; |
496 #endif // def HAVE_DTRACE_H | 497 #endif // def HAVE_DTRACE_H |
497 } | 498 } |
518 nm = new (native_nmethod_size) | 519 nm = new (native_nmethod_size) |
519 nmethod(method(), native_nmethod_size, compile_id, &offsets, | 520 nmethod(method(), native_nmethod_size, compile_id, &offsets, |
520 code_buffer, frame_size, | 521 code_buffer, frame_size, |
521 basic_lock_owner_sp_offset, basic_lock_sp_offset, | 522 basic_lock_owner_sp_offset, basic_lock_sp_offset, |
522 oop_maps); | 523 oop_maps); |
523 if (nm != NULL) nmethod_stats.note_native_nmethod(nm); | 524 NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_native_nmethod(nm)); |
524 if (PrintAssembly && nm != NULL) | 525 if (PrintAssembly && nm != NULL) |
525 Disassembler::decode(nm); | 526 Disassembler::decode(nm); |
526 | |
527 if (PrintMachineCodeToFile) { | |
528 MachineCodePrinter::print(nm); | |
529 } | |
530 } | 527 } |
531 // verify nmethod | 528 // verify nmethod |
532 debug_only(if (nm) nm->verify();) // might block | 529 debug_only(if (nm) nm->verify();) // might block |
533 | 530 |
534 if (nm != NULL) { | 531 if (nm != NULL) { |
556 offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset); | 553 offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset); |
557 offsets.set_value(CodeOffsets::Frame_Complete, frame_complete); | 554 offsets.set_value(CodeOffsets::Frame_Complete, frame_complete); |
558 | 555 |
559 nm = new (nmethod_size) nmethod(method(), nmethod_size, &offsets, code_buffer, frame_size); | 556 nm = new (nmethod_size) nmethod(method(), nmethod_size, &offsets, code_buffer, frame_size); |
560 | 557 |
561 if (nm != NULL) nmethod_stats.note_nmethod(nm); | 558 NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm)); |
562 if (PrintAssembly && nm != NULL) | 559 if (PrintAssembly && nm != NULL) |
563 Disassembler::decode(nm); | 560 Disassembler::decode(nm); |
564 } | 561 } |
565 // verify nmethod | 562 // verify nmethod |
566 debug_only(if (nm) nm->verify();) // might block | 563 debug_only(if (nm) nm->verify();) // might block |
587 ImplicitExceptionTable* nul_chk_table, | 584 ImplicitExceptionTable* nul_chk_table, |
588 AbstractCompiler* compiler, | 585 AbstractCompiler* compiler, |
589 int comp_level, | 586 int comp_level, |
590 GrowableArray<jlong>* leaf_graph_ids | 587 GrowableArray<jlong>* leaf_graph_ids |
591 #ifdef GRAAL | 588 #ifdef GRAAL |
592 , Handle installed_code | 589 , Handle installed_code, |
590 Handle triggered_deoptimizations | |
593 #endif | 591 #endif |
594 ) | 592 ) |
595 { | 593 { |
596 assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR"); | 594 assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR"); |
597 code_buffer->finalize_oop_references(method); | 595 code_buffer->finalize_oop_references(method); |
615 nul_chk_table, | 613 nul_chk_table, |
616 compiler, | 614 compiler, |
617 comp_level, | 615 comp_level, |
618 leaf_graph_ids | 616 leaf_graph_ids |
619 #ifdef GRAAL | 617 #ifdef GRAAL |
620 , installed_code | 618 , installed_code, |
619 triggered_deoptimizations | |
621 #endif | 620 #endif |
622 ); | 621 ); |
623 if (nm != NULL) { | 622 if (nm != NULL) { |
624 // To make dependency checking during class loading fast, record | 623 // To make dependency checking during class loading fast, record |
625 // the nmethod dependencies in the classes it is dependent on. | 624 // the nmethod dependencies in the classes it is dependent on. |
635 | 634 |
636 // record this nmethod as dependent on this klass | 635 // record this nmethod as dependent on this klass |
637 InstanceKlass::cast(klass)->add_dependent_nmethod(nm); | 636 InstanceKlass::cast(klass)->add_dependent_nmethod(nm); |
638 } | 637 } |
639 } | 638 } |
640 if (nm != NULL) nmethod_stats.note_nmethod(nm); | 639 NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm)); |
641 if (PrintAssembly && nm != NULL) | 640 if (PrintAssembly && nm != NULL) |
642 Disassembler::decode(nm); | 641 Disassembler::decode(nm); |
643 | |
644 if (nm != NULL && PrintMachineCodeToFile) { | |
645 MachineCodePrinter::print(nm); | |
646 } | |
647 } | 642 } |
648 | 643 |
649 // verify nmethod | 644 // verify nmethod |
650 debug_only(if (nm) nm->verify();) // might block | 645 debug_only(if (nm) nm->verify();) // might block |
651 | 646 |
845 ImplicitExceptionTable* nul_chk_table, | 840 ImplicitExceptionTable* nul_chk_table, |
846 AbstractCompiler* compiler, | 841 AbstractCompiler* compiler, |
847 int comp_level, | 842 int comp_level, |
848 GrowableArray<jlong>* leaf_graph_ids | 843 GrowableArray<jlong>* leaf_graph_ids |
849 #ifdef GRAAL | 844 #ifdef GRAAL |
850 , Handle installed_code | 845 , Handle installed_code, |
846 Handle triggered_deoptimizations | |
851 #endif | 847 #endif |
852 ) | 848 ) |
853 : CodeBlob("nmethod", code_buffer, sizeof(nmethod), | 849 : CodeBlob("nmethod", code_buffer, sizeof(nmethod), |
854 nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps), | 850 nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps), |
855 _native_receiver_sp_offset(in_ByteSize(-1)), | 851 _native_receiver_sp_offset(in_ByteSize(-1)), |
872 _consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts()); | 868 _consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts()); |
873 _stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs()); | 869 _stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs()); |
874 | 870 |
875 #ifdef GRAAL | 871 #ifdef GRAAL |
876 _graal_installed_code = installed_code(); | 872 _graal_installed_code = installed_code(); |
873 _triggered_deoptimizations = (typeArrayOop)triggered_deoptimizations(); | |
877 #endif | 874 #endif |
878 if (compiler->is_graal()) { | 875 if (compiler->is_graal()) { |
879 // Graal might not produce any stub sections | 876 // Graal might not produce any stub sections |
880 if (offsets->value(CodeOffsets::Exceptions) != -1) { | 877 if (offsets->value(CodeOffsets::Exceptions) != -1) { |
881 _exception_offset = code_offset() + offsets->value(CodeOffsets::Exceptions); | 878 _exception_offset = code_offset() + offsets->value(CodeOffsets::Exceptions); |
1691 unloading_occurred = true; | 1688 unloading_occurred = true; |
1692 } | 1689 } |
1693 | 1690 |
1694 #ifdef GRAAL | 1691 #ifdef GRAAL |
1695 // Follow Graal method | 1692 // Follow Graal method |
1696 if (_graal_installed_code != NULL && can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) { | 1693 if (_graal_installed_code != NULL) { |
1697 return; | 1694 if (HotSpotInstalledCode::isDefault(_graal_installed_code)) { |
1695 if (!is_alive->do_object_b(_graal_installed_code)) { | |
1696 _graal_installed_code = NULL; | |
1697 } | |
1698 } else { | |
1699 if (can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) { | |
1700 return; | |
1701 } | |
1702 } | |
1698 } | 1703 } |
1699 #endif | 1704 #endif |
1700 | 1705 |
1701 // Exception cache | 1706 // Exception cache |
1702 ExceptionCache* ec = exception_cache(); | 1707 ExceptionCache* ec = exception_cache(); |
1817 // all strong references alive. Any weak references should have been | 1822 // all strong references alive. Any weak references should have been |
1818 // cleared as well. Visit all the metadata and ensure that it's | 1823 // cleared as well. Visit all the metadata and ensure that it's |
1819 // really alive. | 1824 // really alive. |
1820 void nmethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) { | 1825 void nmethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) { |
1821 #ifdef ASSERT | 1826 #ifdef ASSERT |
1822 RelocIterator iter(this, low_boundary); | 1827 RelocIterator iter(this, low_boundary); |
1823 while (iter.next()) { | 1828 while (iter.next()) { |
1824 // static_stub_Relocations may have dangling references to | 1829 // static_stub_Relocations may have dangling references to |
1825 // Method*s so trim them out here. Otherwise it looks like | 1830 // Method*s so trim them out here. Otherwise it looks like |
1826 // compiled code is maintaining a link to dead metadata. | 1831 // compiled code is maintaining a link to dead metadata. |
1827 address static_call_addr = NULL; | 1832 address static_call_addr = NULL; |
1828 if (iter.type() == relocInfo::opt_virtual_call_type) { | 1833 if (iter.type() == relocInfo::opt_virtual_call_type) { |
1829 CompiledIC* cic = CompiledIC_at(iter.reloc()); | 1834 CompiledIC* cic = CompiledIC_at(iter.reloc()); |
1830 if (!cic->is_call_to_interpreted()) { | 1835 if (!cic->is_call_to_interpreted()) { |
1831 static_call_addr = iter.addr(); | 1836 static_call_addr = iter.addr(); |
1832 cic->set_to_clean(); | |
1833 } | 1837 } |
1834 } else if (iter.type() == relocInfo::static_call_type) { | 1838 } else if (iter.type() == relocInfo::static_call_type) { |
1835 CompiledStaticCall* csc = compiledStaticCall_at(iter.reloc()); | 1839 CompiledStaticCall* csc = compiledStaticCall_at(iter.reloc()); |
1836 if (!csc->is_call_to_interpreted()) { | 1840 if (!csc->is_call_to_interpreted()) { |
1837 static_call_addr = iter.addr(); | 1841 static_call_addr = iter.addr(); |
1838 csc->set_to_clean(); | |
1839 } | 1842 } |
1840 } | 1843 } |
1841 if (static_call_addr != NULL) { | 1844 if (static_call_addr != NULL) { |
1842 RelocIterator sciter(this, low_boundary); | 1845 RelocIterator sciter(this, low_boundary); |
1843 while (sciter.next()) { | 1846 while (sciter.next()) { |
1920 } | 1923 } |
1921 | 1924 |
1922 #ifdef GRAAL | 1925 #ifdef GRAAL |
1923 if (_graal_installed_code != NULL) { | 1926 if (_graal_installed_code != NULL) { |
1924 f->do_oop((oop*) &_graal_installed_code); | 1927 f->do_oop((oop*) &_graal_installed_code); |
1928 } | |
1929 if (_triggered_deoptimizations != NULL) { | |
1930 f->do_oop((oop*) &_triggered_deoptimizations); | |
1925 } | 1931 } |
1926 #endif | 1932 #endif |
1927 | 1933 |
1928 RelocIterator iter(this, low_boundary); | 1934 RelocIterator iter(this, low_boundary); |
1929 | 1935 |
2511 // Right now there is no way to find out which entries support | 2517 // Right now there is no way to find out which entries support |
2512 // an interrupt point. It would be nice if we had this | 2518 // an interrupt point. It would be nice if we had this |
2513 // information in a table. | 2519 // information in a table. |
2514 break; | 2520 break; |
2515 } | 2521 } |
2516 #ifndef GRAAL | |
2517 assert(stub == NULL || stub_contains(stub), "static call stub outside stub section"); | 2522 assert(stub == NULL || stub_contains(stub), "static call stub outside stub section"); |
2518 #endif | |
2519 } | 2523 } |
2520 } | 2524 } |
2521 | 2525 |
2522 | 2526 |
2523 // ----------------------------------------------------------------------------- | 2527 // ----------------------------------------------------------------------------- |
3005 | 3009 |
3006 void nmethod::print_nul_chk_table() { | 3010 void nmethod::print_nul_chk_table() { |
3007 ImplicitExceptionTable(this).print(code_begin()); | 3011 ImplicitExceptionTable(this).print(code_begin()); |
3008 } | 3012 } |
3009 | 3013 |
3010 #endif // PRODUCT | |
3011 | |
3012 void nmethod::print_statistics() { | 3014 void nmethod::print_statistics() { |
3013 ttyLocker ttyl; | 3015 ttyLocker ttyl; |
3014 if (xtty != NULL) xtty->head("statistics type='nmethod'"); | 3016 if (xtty != NULL) xtty->head("statistics type='nmethod'"); |
3015 nmethod_stats.print_native_nmethod_stats(); | 3017 nmethod_stats.print_native_nmethod_stats(); |
3016 nmethod_stats.print_nmethod_stats(); | 3018 nmethod_stats.print_nmethod_stats(); |
3018 nmethod_stats.print_pc_stats(); | 3020 nmethod_stats.print_pc_stats(); |
3019 Dependencies::print_statistics(); | 3021 Dependencies::print_statistics(); |
3020 if (xtty != NULL) xtty->tail("statistics"); | 3022 if (xtty != NULL) xtty->tail("statistics"); |
3021 } | 3023 } |
3022 | 3024 |
3023 #ifdef GRAAL | 3025 #endif // PRODUCT |
3024 void DebugScopedNMethod::print_on(outputStream* st) { | |
3025 if (_nm != NULL) { | |
3026 st->print("nmethod@%p", _nm); | |
3027 Method* method = _nm->method(); | |
3028 if (method != NULL) { | |
3029 char holder[O_BUFLEN]; | |
3030 char nameAndSig[O_BUFLEN]; | |
3031 method->method_holder()->name()->as_C_string(holder, O_BUFLEN); | |
3032 method->name_and_sig_as_C_string(nameAndSig, O_BUFLEN); | |
3033 st->print(" - %s::%s", holder, nameAndSig); | |
3034 } | |
3035 } | |
3036 } | |
3037 #endif |