Mercurial > hg > truffle
comparison src/cpu/x86/vm/templateInterpreter_x86_32.cpp @ 17980:0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
Summary: make compiled code bang the stack by the worst case size of the interpreter frame at deoptimization points.
Reviewed-by: twisti, kvn
author | roland |
---|---|
date | Tue, 01 Apr 2014 09:36:49 +0200 |
parents | 2100bf712e2a |
children | 5214669b01f2 |
comparison
equal
deleted
inserted
replaced
17978:ad51f24671c2 | 17980:0bf37f737702 |
---|---|
1684 const int method_stack = (method->max_locals() + method->max_stack()) * | 1684 const int method_stack = (method->max_locals() + method->max_stack()) * |
1685 Interpreter::stackElementWords; | 1685 Interpreter::stackElementWords; |
1686 return overhead_size + method_stack + stub_code; | 1686 return overhead_size + method_stack + stub_code; |
1687 } | 1687 } |
1688 | 1688 |
1689 // asm based interpreter deoptimization helpers | |
1690 | |
1691 int AbstractInterpreter::layout_activation(Method* method, | |
1692 int tempcount, | |
1693 int popframe_extra_args, | |
1694 int moncount, | |
1695 int caller_actual_parameters, | |
1696 int callee_param_count, | |
1697 int callee_locals, | |
1698 frame* caller, | |
1699 frame* interpreter_frame, | |
1700 bool is_top_frame, | |
1701 bool is_bottom_frame) { | |
1702 // Note: This calculation must exactly parallel the frame setup | |
1703 // in AbstractInterpreterGenerator::generate_method_entry. | |
1704 // If interpreter_frame!=NULL, set up the method, locals, and monitors. | |
1705 // The frame interpreter_frame, if not NULL, is guaranteed to be the right size, | |
1706 // as determined by a previous call to this method. | |
1707 // It is also guaranteed to be walkable even though it is in a skeletal state | |
1708 // NOTE: return size is in words not bytes | |
1709 | |
1710 // fixed size of an interpreter frame: | |
1711 int max_locals = method->max_locals() * Interpreter::stackElementWords; | |
1712 int extra_locals = (method->max_locals() - method->size_of_parameters()) * | |
1713 Interpreter::stackElementWords; | |
1714 | |
1715 int overhead = frame::sender_sp_offset - frame::interpreter_frame_initial_sp_offset; | |
1716 | |
1717 // Our locals were accounted for by the caller (or last_frame_adjust on the transistion) | |
1718 // Since the callee parameters already account for the callee's params we only need to account for | |
1719 // the extra locals. | |
1720 | |
1721 | |
1722 int size = overhead + | |
1723 ((callee_locals - callee_param_count)*Interpreter::stackElementWords) + | |
1724 (moncount*frame::interpreter_frame_monitor_size()) + | |
1725 tempcount*Interpreter::stackElementWords + popframe_extra_args; | |
1726 | |
1727 if (interpreter_frame != NULL) { | |
1728 #ifdef ASSERT | |
1729 if (!EnableInvokeDynamic) | |
1730 // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences? | |
1731 // Probably, since deoptimization doesn't work yet. | |
1732 assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); | |
1733 assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)"); | |
1734 #endif | |
1735 | |
1736 interpreter_frame->interpreter_frame_set_method(method); | |
1737 // NOTE the difference in using sender_sp and interpreter_frame_sender_sp | |
1738 // interpreter_frame_sender_sp is the original sp of the caller (the unextended_sp) | |
1739 // and sender_sp is fp+8 | |
1740 intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1; | |
1741 | |
1742 #ifdef ASSERT | |
1743 if (caller->is_interpreted_frame()) { | |
1744 assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement"); | |
1745 } | |
1746 #endif | |
1747 | |
1748 interpreter_frame->interpreter_frame_set_locals(locals); | |
1749 BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); | |
1750 BasicObjectLock* monbot = montop - moncount; | |
1751 interpreter_frame->interpreter_frame_set_monitor_end(monbot); | |
1752 | |
1753 // Set last_sp | |
1754 intptr_t* rsp = (intptr_t*) monbot - | |
1755 tempcount*Interpreter::stackElementWords - | |
1756 popframe_extra_args; | |
1757 interpreter_frame->interpreter_frame_set_last_sp(rsp); | |
1758 | |
1759 // All frames but the initial (oldest) interpreter frame we fill in have a | |
1760 // value for sender_sp that allows walking the stack but isn't | |
1761 // truly correct. Correct the value here. | |
1762 | |
1763 if (extra_locals != 0 && | |
1764 interpreter_frame->sender_sp() == interpreter_frame->interpreter_frame_sender_sp() ) { | |
1765 interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + extra_locals); | |
1766 } | |
1767 *interpreter_frame->interpreter_frame_cache_addr() = | |
1768 method->constants()->cache(); | |
1769 } | |
1770 return size; | |
1771 } | |
1772 | |
1773 | |
1774 //------------------------------------------------------------------------------------------------------------------------ | 1689 //------------------------------------------------------------------------------------------------------------------------ |
1775 // Exceptions | 1690 // Exceptions |
1776 | 1691 |
1777 void TemplateInterpreterGenerator::generate_throw_exception() { | 1692 void TemplateInterpreterGenerator::generate_throw_exception() { |
1778 // Entry point in previous activation (i.e., if the caller was interpreted) | 1693 // Entry point in previous activation (i.e., if the caller was interpreted) |