comparison src/share/vm/code/nmethod.cpp @ 1579:e9ff18c4ace7

Merge
author jrose
date Wed, 02 Jun 2010 22:45:42 -0700
parents c18cbe5936b8 852d0157c696
children 136b78722a08
comparison
equal deleted inserted replaced
1562:dfe27f03244a 1579:e9ff18c4ace7
97 total_size += nm->size(); 97 total_size += nm->size();
98 relocation_size += nm->relocation_size(); 98 relocation_size += nm->relocation_size();
99 code_size += nm->code_size(); 99 code_size += nm->code_size();
100 stub_size += nm->stub_size(); 100 stub_size += nm->stub_size();
101 consts_size += nm->consts_size(); 101 consts_size += nm->consts_size();
102 oops_size += nm->oops_size();
102 scopes_data_size += nm->scopes_data_size(); 103 scopes_data_size += nm->scopes_data_size();
103 scopes_pcs_size += nm->scopes_pcs_size(); 104 scopes_pcs_size += nm->scopes_pcs_size();
104 dependencies_size += nm->dependencies_size(); 105 dependencies_size += nm->dependencies_size();
105 handler_table_size += nm->handler_table_size(); 106 handler_table_size += nm->handler_table_size();
106 nul_chk_table_size += nm->nul_chk_table_size(); 107 nul_chk_table_size += nm->nul_chk_table_size();
107 oops_size += nm->oops_size();
108 } 108 }
109 void print_nmethod_stats() { 109 void print_nmethod_stats() {
110 if (nmethod_count == 0) return; 110 if (nmethod_count == 0) return;
111 tty->print_cr("Statistics for %d bytecoded nmethods:", nmethod_count); 111 tty->print_cr("Statistics for %d bytecoded nmethods:", nmethod_count);
112 if (total_size != 0) tty->print_cr(" total in heap = %d", total_size); 112 if (total_size != 0) tty->print_cr(" total in heap = %d", total_size);
113 if (relocation_size != 0) tty->print_cr(" relocation = %d", relocation_size); 113 if (relocation_size != 0) tty->print_cr(" relocation = %d", relocation_size);
114 if (code_size != 0) tty->print_cr(" main code = %d", code_size); 114 if (code_size != 0) tty->print_cr(" main code = %d", code_size);
115 if (stub_size != 0) tty->print_cr(" stub code = %d", stub_size); 115 if (stub_size != 0) tty->print_cr(" stub code = %d", stub_size);
116 if (consts_size != 0) tty->print_cr(" constants = %d", consts_size); 116 if (consts_size != 0) tty->print_cr(" constants = %d", consts_size);
117 if (oops_size != 0) tty->print_cr(" oops = %d", oops_size);
117 if (scopes_data_size != 0) tty->print_cr(" scopes data = %d", scopes_data_size); 118 if (scopes_data_size != 0) tty->print_cr(" scopes data = %d", scopes_data_size);
118 if (scopes_pcs_size != 0) tty->print_cr(" scopes pcs = %d", scopes_pcs_size); 119 if (scopes_pcs_size != 0) tty->print_cr(" scopes pcs = %d", scopes_pcs_size);
119 if (dependencies_size != 0) tty->print_cr(" dependencies = %d", dependencies_size); 120 if (dependencies_size != 0) tty->print_cr(" dependencies = %d", dependencies_size);
120 if (handler_table_size != 0) tty->print_cr(" handler table = %d", handler_table_size); 121 if (handler_table_size != 0) tty->print_cr(" handler table = %d", handler_table_size);
121 if (nul_chk_table_size != 0) tty->print_cr(" nul chk table = %d", nul_chk_table_size); 122 if (nul_chk_table_size != 0) tty->print_cr(" nul chk table = %d", nul_chk_table_size);
122 if (oops_size != 0) tty->print_cr(" oops = %d", oops_size);
123 } 123 }
124 124
125 int native_nmethod_count; 125 int native_nmethod_count;
126 int native_total_size; 126 int native_total_size;
127 int native_relocation_size; 127 int native_relocation_size;
598 #ifdef HAVE_DTRACE_H 598 #ifdef HAVE_DTRACE_H
599 _trap_offset = 0; 599 _trap_offset = 0;
600 #endif // def HAVE_DTRACE_H 600 #endif // def HAVE_DTRACE_H
601 _stub_offset = data_offset(); 601 _stub_offset = data_offset();
602 _consts_offset = data_offset(); 602 _consts_offset = data_offset();
603 _scopes_data_offset = data_offset(); 603 _oops_offset = data_offset();
604 _scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize);
604 _scopes_pcs_offset = _scopes_data_offset; 605 _scopes_pcs_offset = _scopes_data_offset;
605 _dependencies_offset = _scopes_pcs_offset; 606 _dependencies_offset = _scopes_pcs_offset;
606 _handler_table_offset = _dependencies_offset; 607 _handler_table_offset = _dependencies_offset;
607 _nul_chk_table_offset = _handler_table_offset; 608 _nul_chk_table_offset = _handler_table_offset;
608 _nmethod_end_offset = _nul_chk_table_offset; 609 _nmethod_end_offset = _nul_chk_table_offset;
688 _unwind_handler_offset = -1; 689 _unwind_handler_offset = -1;
689 _trap_offset = offsets->value(CodeOffsets::Dtrace_trap); 690 _trap_offset = offsets->value(CodeOffsets::Dtrace_trap);
690 _orig_pc_offset = 0; 691 _orig_pc_offset = 0;
691 _stub_offset = data_offset(); 692 _stub_offset = data_offset();
692 _consts_offset = data_offset(); 693 _consts_offset = data_offset();
693 _scopes_data_offset = data_offset(); 694 _oops_offset = data_offset();
695 _scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize);
694 _scopes_pcs_offset = _scopes_data_offset; 696 _scopes_pcs_offset = _scopes_data_offset;
695 _dependencies_offset = _scopes_pcs_offset; 697 _dependencies_offset = _scopes_pcs_offset;
696 _handler_table_offset = _dependencies_offset; 698 _handler_table_offset = _dependencies_offset;
697 _nul_chk_table_offset = _handler_table_offset; 699 _nul_chk_table_offset = _handler_table_offset;
698 _nmethod_end_offset = _nul_chk_table_offset; 700 _nmethod_end_offset = _nul_chk_table_offset;
803 _unwind_handler_offset = instructions_offset() + offsets->value(CodeOffsets::UnwindHandler); 805 _unwind_handler_offset = instructions_offset() + offsets->value(CodeOffsets::UnwindHandler);
804 } else { 806 } else {
805 _unwind_handler_offset = -1; 807 _unwind_handler_offset = -1;
806 } 808 }
807 _consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start()); 809 _consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start());
808 _scopes_data_offset = data_offset(); 810 _oops_offset = data_offset();
809 _scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize); 811 _scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size (), oopSize);
812 _scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize);
810 _dependencies_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size()); 813 _dependencies_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size());
811 _handler_table_offset = _dependencies_offset + round_to(dependencies->size_in_bytes (), oopSize); 814 _handler_table_offset = _dependencies_offset + round_to(dependencies->size_in_bytes (), oopSize);
812 _nul_chk_table_offset = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize); 815 _nul_chk_table_offset = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize);
813 _nmethod_end_offset = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize); 816 _nmethod_end_offset = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize);
814 817
985 } 988 }
986 989
987 990
988 void nmethod::set_version(int v) { 991 void nmethod::set_version(int v) {
989 flags.version = v; 992 flags.version = v;
993 }
994
995
996 // Promote one word from an assembly-time handle to a live embedded oop.
997 inline void nmethod::initialize_immediate_oop(oop* dest, jobject handle) {
998 if (handle == NULL ||
999 // As a special case, IC oops are initialized to 1 or -1.
1000 handle == (jobject) Universe::non_oop_word()) {
1001 (*dest) = (oop) handle;
1002 } else {
1003 (*dest) = JNIHandles::resolve_non_null(handle);
1004 }
1005 }
1006
1007
1008 void nmethod::copy_oops(GrowableArray<jobject>* array) {
1009 //assert(oops_size() == 0, "do this handshake just once, please");
1010 int length = array->length();
1011 assert((address)(oops_begin() + length) <= data_end(), "oops big enough");
1012 oop* dest = oops_begin();
1013 for (int index = 0 ; index < length; index++) {
1014 initialize_immediate_oop(&dest[index], array->at(index));
1015 }
1016
1017 // Now we can fix up all the oops in the code. We need to do this
1018 // in the code because the assembler uses jobjects as placeholders.
1019 // The code and relocations have already been initialized by the
1020 // CodeBlob constructor, so it is valid even at this early point to
1021 // iterate over relocations and patch the code.
1022 fix_oop_relocations(NULL, NULL, /*initialize_immediates=*/ true);
1023 }
1024
1025
1026 bool nmethod::is_at_poll_return(address pc) {
1027 RelocIterator iter(this, pc, pc+1);
1028 while (iter.next()) {
1029 if (iter.type() == relocInfo::poll_return_type)
1030 return true;
1031 }
1032 return false;
1033 }
1034
1035
1036 bool nmethod::is_at_poll_or_poll_return(address pc) {
1037 RelocIterator iter(this, pc, pc+1);
1038 while (iter.next()) {
1039 relocInfo::relocType t = iter.type();
1040 if (t == relocInfo::poll_return_type || t == relocInfo::poll_type)
1041 return true;
1042 }
1043 return false;
1044 }
1045
1046
1047 void nmethod::fix_oop_relocations(address begin, address end, bool initialize_immediates) {
1048 // re-patch all oop-bearing instructions, just in case some oops moved
1049 RelocIterator iter(this, begin, end);
1050 while (iter.next()) {
1051 if (iter.type() == relocInfo::oop_type) {
1052 oop_Relocation* reloc = iter.oop_reloc();
1053 if (initialize_immediates && reloc->oop_is_immediate()) {
1054 oop* dest = reloc->oop_addr();
1055 initialize_immediate_oop(dest, (jobject) *dest);
1056 }
1057 // Refresh the oop-related bits of this instruction.
1058 reloc->fix_oop_relocation();
1059 }
1060
1061 // There must not be any interfering patches or breakpoints.
1062 assert(!(iter.type() == relocInfo::breakpoint_type
1063 && iter.breakpoint_reloc()->active()),
1064 "no active breakpoint");
1065 }
990 } 1066 }
991 1067
992 1068
993 ScopeDesc* nmethod::scope_desc_at(address pc) { 1069 ScopeDesc* nmethod::scope_desc_at(address pc) {
994 PcDesc* pd = pc_desc_at(pc); 1070 PcDesc* pd = pc_desc_at(pc);
1264 1340
1265 // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event 1341 // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
1266 // and it hasn't already been reported for this nmethod then report it now. 1342 // and it hasn't already been reported for this nmethod then report it now.
1267 // (the event may have been reported earilier if the GC marked it for unloading). 1343 // (the event may have been reported earilier if the GC marked it for unloading).
1268 if (state == zombie) { 1344 if (state == zombie) {
1269 1345 post_compiled_method_unload();
1270 DTRACE_METHOD_UNLOAD_PROBE(method());
1271
1272 if (JvmtiExport::should_post_compiled_method_unload() &&
1273 !unload_reported()) {
1274 assert(method() != NULL, "checking");
1275 {
1276 HandleMark hm;
1277 JvmtiExport::post_compiled_method_unload_at_safepoint(
1278 method()->jmethod_id(), code_begin());
1279 }
1280 set_unload_reported();
1281 }
1282 } 1346 }
1283 1347
1284 1348
1285 // Zombie only stuff 1349 // Zombie only stuff
1286 if (state == zombie) { 1350 if (state == zombie) {
1428 JvmtiExport::post_compiled_method_load(this); 1492 JvmtiExport::post_compiled_method_load(this);
1429 } 1493 }
1430 } 1494 }
1431 1495
1432 void nmethod::post_compiled_method_unload() { 1496 void nmethod::post_compiled_method_unload() {
1497 if (unload_reported()) {
1498 // During unloading we transition to unloaded and then to zombie
1499 // and the unloading is reported during the first transition.
1500 return;
1501 }
1502
1433 assert(_method != NULL && !is_unloaded(), "just checking"); 1503 assert(_method != NULL && !is_unloaded(), "just checking");
1434 DTRACE_METHOD_UNLOAD_PROBE(method()); 1504 DTRACE_METHOD_UNLOAD_PROBE(method());
1435 1505
1436 // If a JVMTI agent has enabled the CompiledMethodUnload event then 1506 // If a JVMTI agent has enabled the CompiledMethodUnload event then
1437 // post the event. Sometime later this nmethod will be made a zombie by 1507 // post the event. Sometime later this nmethod will be made a zombie by
1438 // the sweeper but the methodOop will not be valid at that point. 1508 // the sweeper but the methodOop will not be valid at that point.
1439 if (JvmtiExport::should_post_compiled_method_unload()) { 1509 if (JvmtiExport::should_post_compiled_method_unload()) {
1440 assert(!unload_reported(), "already unloaded"); 1510 assert(!unload_reported(), "already unloaded");
1441 HandleMark hm; 1511 HandleMark hm;
1442 JvmtiExport::post_compiled_method_unload_at_safepoint( 1512 JvmtiExport::post_compiled_method_unload(method()->jmethod_id(), code_begin());
1443 method()->jmethod_id(), code_begin());
1444 } 1513 }
1445 1514
1446 // The JVMTI CompiledMethodUnload event can be enabled or disabled at 1515 // The JVMTI CompiledMethodUnload event can be enabled or disabled at
1447 // any time. As the nmethod is being unloaded now we mark it has 1516 // any time. As the nmethod is being unloaded now we mark it has
1448 // having the unload event reported - this will ensure that we don't 1517 // having the unload event reported - this will ensure that we don't
2280 stub_size()); 2349 stub_size());
2281 if (consts_size () > 0) tty->print_cr(" constants [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", 2350 if (consts_size () > 0) tty->print_cr(" constants [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
2282 consts_begin(), 2351 consts_begin(),
2283 consts_end(), 2352 consts_end(),
2284 consts_size()); 2353 consts_size());
2354 if (oops_size () > 0) tty->print_cr(" oops [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
2355 oops_begin(),
2356 oops_end(),
2357 oops_size());
2285 if (scopes_data_size () > 0) tty->print_cr(" scopes data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", 2358 if (scopes_data_size () > 0) tty->print_cr(" scopes data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
2286 scopes_data_begin(), 2359 scopes_data_begin(),
2287 scopes_data_end(), 2360 scopes_data_end(),
2288 scopes_data_size()); 2361 scopes_data_size());
2289 if (scopes_pcs_size () > 0) tty->print_cr(" scopes pcs [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", 2362 if (scopes_pcs_size () > 0) tty->print_cr(" scopes pcs [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",