Mercurial > hg > truffle
comparison src/share/vm/code/nmethod.cpp @ 1200:ba263cfb7611
6917766: JSR 292 needs its own deopt handler
Summary: We need to introduce a new MH deopt handler so we can easily determine if the deopt happened at a MH call site or not.
Reviewed-by: never, jrose
author | twisti |
---|---|
date | Fri, 29 Jan 2010 12:13:05 +0100 |
parents | 4e6abf09f540 |
children | 24128c2ffa87 |
comparison
equal
deleted
inserted
replaced
1199:0e14bd797dad | 1200:ba263cfb7611 |
---|---|
1 /* | 1 /* |
2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. | 2 * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
590 _compiler = NULL; | 590 _compiler = NULL; |
591 // We have no exception handler or deopt handler make the | 591 // We have no exception handler or deopt handler make the |
592 // values something that will never match a pc like the nmethod vtable entry | 592 // values something that will never match a pc like the nmethod vtable entry |
593 _exception_offset = 0; | 593 _exception_offset = 0; |
594 _deoptimize_offset = 0; | 594 _deoptimize_offset = 0; |
595 _deoptimize_mh_offset = 0; | |
595 _orig_pc_offset = 0; | 596 _orig_pc_offset = 0; |
596 #ifdef HAVE_DTRACE_H | 597 #ifdef HAVE_DTRACE_H |
597 _trap_offset = 0; | 598 _trap_offset = 0; |
598 #endif // def HAVE_DTRACE_H | 599 #endif // def HAVE_DTRACE_H |
599 _stub_offset = data_offset(); | 600 _stub_offset = data_offset(); |
680 _compiler = NULL; | 681 _compiler = NULL; |
681 // We have no exception handler or deopt handler make the | 682 // We have no exception handler or deopt handler make the |
682 // values something that will never match a pc like the nmethod vtable entry | 683 // values something that will never match a pc like the nmethod vtable entry |
683 _exception_offset = 0; | 684 _exception_offset = 0; |
684 _deoptimize_offset = 0; | 685 _deoptimize_offset = 0; |
686 _deoptimize_mh_offset = 0; | |
685 _trap_offset = offsets->value(CodeOffsets::Dtrace_trap); | 687 _trap_offset = offsets->value(CodeOffsets::Dtrace_trap); |
686 _orig_pc_offset = 0; | 688 _orig_pc_offset = 0; |
687 _stub_offset = data_offset(); | 689 _stub_offset = data_offset(); |
688 _consts_offset = data_offset(); | 690 _consts_offset = data_offset(); |
689 _scopes_data_offset = data_offset(); | 691 _scopes_data_offset = data_offset(); |
792 _stub_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->stubs()->start()); | 794 _stub_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->stubs()->start()); |
793 | 795 |
794 // Exception handler and deopt handler are in the stub section | 796 // Exception handler and deopt handler are in the stub section |
795 _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); | 797 _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); |
796 _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt); | 798 _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt); |
799 _deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH); | |
797 _consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start()); | 800 _consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start()); |
798 _scopes_data_offset = data_offset(); | 801 _scopes_data_offset = data_offset(); |
799 _scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize); | 802 _scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize); |
800 _dependencies_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size()); | 803 _dependencies_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size()); |
801 _handler_table_offset = _dependencies_offset + round_to(dependencies->size_in_bytes (), oopSize); | 804 _handler_table_offset = _dependencies_offset + round_to(dependencies->size_in_bytes (), oopSize); |
2029 if (nm == NULL) return; | 2032 if (nm == NULL) return; |
2030 Atomic::dec(&nm->_lock_count); | 2033 Atomic::dec(&nm->_lock_count); |
2031 guarantee(nm->_lock_count >= 0, "unmatched nmethod lock/unlock"); | 2034 guarantee(nm->_lock_count >= 0, "unmatched nmethod lock/unlock"); |
2032 } | 2035 } |
2033 | 2036 |
2034 bool nmethod::is_deopt_pc(address pc) { | 2037 |
2035 bool ret = pc == deopt_handler_begin(); | 2038 // ----------------------------------------------------------------------------- |
2036 return ret; | 2039 // nmethod::get_deopt_original_pc |
2040 // | |
2041 // Return the original PC for the given PC if: | |
2042 // (a) the given PC belongs to a nmethod and | |
2043 // (b) it is a deopt PC | |
2044 address nmethod::get_deopt_original_pc(const frame* fr) { | |
2045 if (fr->cb() == NULL) return NULL; | |
2046 | |
2047 nmethod* nm = fr->cb()->as_nmethod_or_null(); | |
2048 if (nm != NULL && nm->is_deopt_pc(fr->pc())) | |
2049 return nm->get_original_pc(fr); | |
2050 | |
2051 return NULL; | |
2037 } | 2052 } |
2038 | 2053 |
2039 | 2054 |
2040 // ----------------------------------------------------------------------------- | 2055 // ----------------------------------------------------------------------------- |
2041 // MethodHandle | 2056 // MethodHandle |
2402 void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) { | 2417 void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) { |
2403 if (block_begin == entry_point()) stream->print_cr("[Entry Point]"); | 2418 if (block_begin == entry_point()) stream->print_cr("[Entry Point]"); |
2404 if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); | 2419 if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); |
2405 if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); | 2420 if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); |
2406 if (block_begin == stub_begin()) stream->print_cr("[Stub Code]"); | 2421 if (block_begin == stub_begin()) stream->print_cr("[Stub Code]"); |
2422 if (block_begin == deopt_handler_begin()) stream->print_cr("[Deopt Handler Code]"); | |
2423 if (block_begin == deopt_mh_handler_begin()) stream->print_cr("[Deopt MH Handler Code]"); | |
2407 if (block_begin == consts_begin()) stream->print_cr("[Constants]"); | 2424 if (block_begin == consts_begin()) stream->print_cr("[Constants]"); |
2408 if (block_begin == entry_point()) { | 2425 if (block_begin == entry_point()) { |
2409 methodHandle m = method(); | 2426 methodHandle m = method(); |
2410 if (m.not_null()) { | 2427 if (m.not_null()) { |
2411 stream->print(" # "); | 2428 stream->print(" # "); |