src/cpu/x86/vm/templateInterpreter_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6919934 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/templateInterpreter_x86_32.cpp

Print this page




1533     // value for sender_sp that allows walking the stack but isn't
1534     // truly correct. Correct the value here.
1535 
1536     if (extra_locals != 0 &&
1537         interpreter_frame->sender_sp() == interpreter_frame->interpreter_frame_sender_sp() ) {
1538       interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + extra_locals);
1539     }
1540     *interpreter_frame->interpreter_frame_cache_addr() =
1541       method->constants()->cache();
1542   }
1543   return size;
1544 }
1545 
1546 
1547 //------------------------------------------------------------------------------------------------------------------------
1548 // Exceptions
1549 
1550 void TemplateInterpreterGenerator::generate_throw_exception() {
1551   // Entry point in previous activation (i.e., if the caller was interpreted)
1552   Interpreter::_rethrow_exception_entry = __ pc();

1553 
1554   // Restore sp to interpreter_frame_last_sp even though we are going
1555   // to empty the expression stack for the exception processing.
1556   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1557   // rax,: exception
1558   // rdx: return address/pc that threw exception
1559   __ restore_bcp();                              // rsi points to call/send
1560   __ restore_locals();
1561 
1562   // Entry point for exceptions thrown within interpreter code
1563   Interpreter::_throw_exception_entry = __ pc();
1564   // expression stack is undefined here
1565   // rax,: exception
1566   // rsi: exception bcp
1567   __ verify_oop(rax);
1568 
1569   // expression stack must be empty before entering the VM in case of an exception
1570   __ empty_expression_stack();
1571   __ empty_FPU_stack();
1572   // find exception handler address and preserve exception oop


1581   // the exception is rethrown (i.e. exception continuation is _rethrow_exception).
1582   //
1583   // Note: At this point the bci is still the bxi for the instruction which caused
1584   //       the exception and the expression stack is empty. Thus, for any VM calls
1585   //       at this point, GC will find a legal oop map (with empty expression stack).
1586 
1587   // In current activation
1588   // tos: exception
1589   // rsi: exception bcp
1590 
1591   //
1592   // JVMTI PopFrame support
1593   //
1594 
1595    Interpreter::_remove_activation_preserving_args_entry = __ pc();
1596   __ empty_expression_stack();
1597   __ empty_FPU_stack();
1598   // Set the popframe_processing bit in pending_popframe_condition indicating that we are
1599   // currently handling popframe, so that call_VMs that may happen later do not trigger new
1600   // popframe handling cycles.
1601   __ get_thread(rcx);
1602   __ movl(rdx, Address(rcx, JavaThread::popframe_condition_offset()));
1603   __ orl(rdx, JavaThread::popframe_processing_bit);
1604   __ movl(Address(rcx, JavaThread::popframe_condition_offset()), rdx);
1605 
1606   {
1607     // Check to see whether we are returning to a deoptimized frame.
1608     // (The PopFrame call ensures that the caller of the popped frame is
1609     // either interpreted or compiled and deoptimizes it if compiled.)
1610     // In this case, we can't call dispatch_next() after the frame is
1611     // popped, but instead must save the incoming arguments and restore
1612     // them after deoptimization has occurred.
1613     //
1614     // Note that we don't compare the return PC against the
1615     // deoptimization blob's unpack entry because of the presence of
1616     // adapter frames in C2.
1617     Label caller_not_deoptimized;
1618     __ movptr(rdx, Address(rbp, frame::return_addr_offset * wordSize));
1619     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), rdx);
1620     __ testl(rax, rax);
1621     __ jcc(Assembler::notZero, caller_not_deoptimized);
1622 
1623     // Compute size of arguments for saving when returning to deoptimized caller
1624     __ get_method(rax);
1625     __ verify_oop(rax);
1626     __ load_unsigned_short(rax, Address(rax, in_bytes(methodOopDesc::size_of_parameters_offset())));
1627     __ shlptr(rax, Interpreter::logStackElementSize());
1628     __ restore_locals();
1629     __ subptr(rdi, rax);
1630     __ addptr(rdi, wordSize);
1631     // Save these arguments
1632     __ get_thread(rcx);
1633     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), rcx, rax, rdi);
1634 
1635     __ remove_activation(vtos, rdx,
1636                          /* throw_monitor_exception */ false,
1637                          /* install_monitor_exception */ false,
1638                          /* notify_jvmdi */ false);
1639 
1640     // Inform deoptimization that it is responsible for restoring these arguments
1641     __ get_thread(rcx);
1642     __ movl(Address(rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit);
1643 
1644     // Continue in deoptimization handler
1645     __ jmp(rdx);
1646 
1647     __ bind(caller_not_deoptimized);
1648   }
1649 
1650   __ remove_activation(vtos, rdx,
1651                        /* throw_monitor_exception */ false,
1652                        /* install_monitor_exception */ false,
1653                        /* notify_jvmdi */ false);
1654 
1655   // Finish with popframe handling
1656   // A previous I2C followed by a deoptimization might have moved the
1657   // outgoing arguments further up the stack. PopFrame expects the
1658   // mutations to those outgoing arguments to be preserved and other
1659   // constraints basically require this frame to look exactly as
1660   // though it had previously invoked an interpreted activation with
1661   // no space between the top of the expression stack (current
1662   // last_sp) and the top of stack. Rather than force deopt to
1663   // maintain this kind of invariant all the time we call a small
1664   // fixup routine to move the mutated arguments onto the top of our
1665   // expression stack if necessary.
1666   __ mov(rax, rsp);
1667   __ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
1668   __ get_thread(rcx);
1669   // PC must point into interpreter here
1670   __ set_last_Java_frame(rcx, noreg, rbp, __ pc());
1671   __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), rcx, rax, rbx);
1672   __ get_thread(rcx);
1673   __ reset_last_Java_frame(rcx, true, true);
1674   // Restore the last_sp and null it out
1675   __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
1676   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1677 
1678   __ restore_bcp();
1679   __ restore_locals();
1680   // The method data pointer was incremented already during
1681   // call profiling. We have to restore the mdp for the current bcp.
1682   if (ProfileInterpreter) {
1683     __ set_method_data_pointer_for_bcp();
1684   }
1685 
1686   // Clear the popframe condition flag
1687   __ get_thread(rcx);
1688   __ movl(Address(rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
1689 
1690   __ dispatch_next(vtos);
1691   // end of PopFrame support
1692 
1693   Interpreter::_remove_activation_entry = __ pc();
1694 
1695   // preserve exception over this code sequence
1696   __ pop_ptr(rax);
1697   __ get_thread(rcx);
1698   __ movptr(Address(rcx, JavaThread::vm_result_offset()), rax);
1699   // remove the activation (without doing throws on illegalMonitorExceptions)
1700   __ remove_activation(vtos, rdx, false, true, false);
1701   // restore exception
1702   __ get_thread(rcx);
1703   __ movptr(rax, Address(rcx, JavaThread::vm_result_offset()));
1704   __ movptr(Address(rcx, JavaThread::vm_result_offset()), NULL_WORD);
1705   __ verify_oop(rax);
1706 
1707   // Inbetween activations - previous activation type unknown yet
1708   // compute continuation point - the continuation point expects
1709   // the following registers set up:
1710   //
1711   // rax,: exception
1712   // rdx: return address/pc that threw exception
1713   // rsp: expression stack of caller
1714   // rbp,: rbp, of caller
1715   __ push(rax);                                  // save exception
1716   __ push(rdx);                                  // save return address
1717   __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rdx);
1718   __ mov(rbx, rax);                              // save exception handler
1719   __ pop(rdx);                                   // restore return address
1720   __ pop(rax);                                   // restore exception
1721   // Note that an "issuing PC" is actually the next PC after the call
1722   __ jmp(rbx);                                   // jump to exception handler of caller
1723 }
1724 
1725 
1726 //
1727 // JVMTI ForceEarlyReturn support
1728 //
1729 address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) {
1730   address entry = __ pc();

1731 
1732   __ restore_bcp();
1733   __ restore_locals();
1734   __ empty_expression_stack();
1735   __ empty_FPU_stack();
1736   __ load_earlyret_value(state);
1737 
1738   __ get_thread(rcx);
1739   __ movptr(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset()));
1740   const Address cond_addr(rcx, JvmtiThreadState::earlyret_state_offset());
1741 
1742   // Clear the earlyret state
1743   __ movl(cond_addr, JvmtiThreadState::earlyret_inactive);
1744 
1745   __ remove_activation(state, rsi,
1746                        false, /* throw_monitor_exception */
1747                        false, /* install_monitor_exception */
1748                        true); /* notify_jvmdi */
1749   __ jmp(rsi);
1750   return entry;
1751 } // end of ForceEarlyReturn support
1752 
1753 
1754 //------------------------------------------------------------------------------------------------------------------------
1755 // Helper for vtos entry point generation
1756 
1757 void TemplateInterpreterGenerator::set_vtos_entry_points (Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
1758   assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
1759   Label L;




1533     // value for sender_sp that allows walking the stack but isn't
1534     // truly correct. Correct the value here.
1535 
1536     if (extra_locals != 0 &&
1537         interpreter_frame->sender_sp() == interpreter_frame->interpreter_frame_sender_sp() ) {
1538       interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + extra_locals);
1539     }
1540     *interpreter_frame->interpreter_frame_cache_addr() =
1541       method->constants()->cache();
1542   }
1543   return size;
1544 }
1545 
1546 
1547 //------------------------------------------------------------------------------------------------------------------------
1548 // Exceptions
1549 
1550 void TemplateInterpreterGenerator::generate_throw_exception() {
1551   // Entry point in previous activation (i.e., if the caller was interpreted)
1552   Interpreter::_rethrow_exception_entry = __ pc();
1553   const Register thread = rcx;
1554 
1555   // Restore sp to interpreter_frame_last_sp even though we are going
1556   // to empty the expression stack for the exception processing.
1557   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1558   // rax,: exception
1559   // rdx: return address/pc that threw exception
1560   __ restore_bcp();                              // rsi points to call/send
1561   __ restore_locals();
1562 
1563   // Entry point for exceptions thrown within interpreter code
1564   Interpreter::_throw_exception_entry = __ pc();
1565   // expression stack is undefined here
1566   // rax,: exception
1567   // rsi: exception bcp
1568   __ verify_oop(rax);
1569 
1570   // expression stack must be empty before entering the VM in case of an exception
1571   __ empty_expression_stack();
1572   __ empty_FPU_stack();
1573   // find exception handler address and preserve exception oop


1582   // the exception is rethrown (i.e. exception continuation is _rethrow_exception).
1583   //
1584   // Note: At this point the bci is still the bxi for the instruction which caused
1585   //       the exception and the expression stack is empty. Thus, for any VM calls
1586   //       at this point, GC will find a legal oop map (with empty expression stack).
1587 
1588   // In current activation
1589   // tos: exception
1590   // rsi: exception bcp
1591 
1592   //
1593   // JVMTI PopFrame support
1594   //
1595 
1596    Interpreter::_remove_activation_preserving_args_entry = __ pc();
1597   __ empty_expression_stack();
1598   __ empty_FPU_stack();
1599   // Set the popframe_processing bit in pending_popframe_condition indicating that we are
1600   // currently handling popframe, so that call_VMs that may happen later do not trigger new
1601   // popframe handling cycles.
1602   __ get_thread(thread);
1603   __ movl(rdx, Address(thread, JavaThread::popframe_condition_offset()));
1604   __ orl(rdx, JavaThread::popframe_processing_bit);
1605   __ movl(Address(thread, JavaThread::popframe_condition_offset()), rdx);
1606 
1607   {
1608     // Check to see whether we are returning to a deoptimized frame.
1609     // (The PopFrame call ensures that the caller of the popped frame is
1610     // either interpreted or compiled and deoptimizes it if compiled.)
1611     // In this case, we can't call dispatch_next() after the frame is
1612     // popped, but instead must save the incoming arguments and restore
1613     // them after deoptimization has occurred.
1614     //
1615     // Note that we don't compare the return PC against the
1616     // deoptimization blob's unpack entry because of the presence of
1617     // adapter frames in C2.
1618     Label caller_not_deoptimized;
1619     __ movptr(rdx, Address(rbp, frame::return_addr_offset * wordSize));
1620     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), rdx);
1621     __ testl(rax, rax);
1622     __ jcc(Assembler::notZero, caller_not_deoptimized);
1623 
1624     // Compute size of arguments for saving when returning to deoptimized caller
1625     __ get_method(rax);
1626     __ verify_oop(rax);
1627     __ load_unsigned_short(rax, Address(rax, in_bytes(methodOopDesc::size_of_parameters_offset())));
1628     __ shlptr(rax, Interpreter::logStackElementSize());
1629     __ restore_locals();
1630     __ subptr(rdi, rax);
1631     __ addptr(rdi, wordSize);
1632     // Save these arguments
1633     __ get_thread(thread);
1634     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), thread, rax, rdi);
1635 
1636     __ remove_activation(vtos, rdx,
1637                          /* throw_monitor_exception */ false,
1638                          /* install_monitor_exception */ false,
1639                          /* notify_jvmdi */ false);
1640 
1641     // Inform deoptimization that it is responsible for restoring these arguments
1642     __ get_thread(thread);
1643     __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit);
1644 
1645     // Continue in deoptimization handler
1646     __ jmp(rdx);
1647 
1648     __ bind(caller_not_deoptimized);
1649   }
1650 
1651   __ remove_activation(vtos, rdx,
1652                        /* throw_monitor_exception */ false,
1653                        /* install_monitor_exception */ false,
1654                        /* notify_jvmdi */ false);
1655 
1656   // Finish with popframe handling
1657   // A previous I2C followed by a deoptimization might have moved the
1658   // outgoing arguments further up the stack. PopFrame expects the
1659   // mutations to those outgoing arguments to be preserved and other
1660   // constraints basically require this frame to look exactly as
1661   // though it had previously invoked an interpreted activation with
1662   // no space between the top of the expression stack (current
1663   // last_sp) and the top of stack. Rather than force deopt to
1664   // maintain this kind of invariant all the time we call a small
1665   // fixup routine to move the mutated arguments onto the top of our
1666   // expression stack if necessary.
1667   __ mov(rax, rsp);
1668   __ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
1669   __ get_thread(thread);
1670   // PC must point into interpreter here
1671   __ set_last_Java_frame(thread, noreg, rbp, __ pc());
1672   __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), thread, rax, rbx);
1673   __ get_thread(thread);
1674   __ reset_last_Java_frame(thread, true, true);
1675   // Restore the last_sp and null it out
1676   __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
1677   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
1678 
1679   __ restore_bcp();
1680   __ restore_locals();
1681   // The method data pointer was incremented already during
1682   // call profiling. We have to restore the mdp for the current bcp.
1683   if (ProfileInterpreter) {
1684     __ set_method_data_pointer_for_bcp();
1685   }
1686 
1687   // Clear the popframe condition flag
1688   __ get_thread(thread);
1689   __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
1690 
1691   __ dispatch_next(vtos);
1692   // end of PopFrame support
1693 
1694   Interpreter::_remove_activation_entry = __ pc();
1695 
1696   // preserve exception over this code sequence
1697   __ pop_ptr(rax);
1698   __ get_thread(thread);
1699   __ movptr(Address(thread, JavaThread::vm_result_offset()), rax);
1700   // remove the activation (without doing throws on illegalMonitorExceptions)
1701   __ remove_activation(vtos, rdx, false, true, false);
1702   // restore exception
1703   __ get_thread(thread);
1704   __ movptr(rax, Address(thread, JavaThread::vm_result_offset()));
1705   __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
1706   __ verify_oop(rax);
1707 
1708   // Inbetween activations - previous activation type unknown yet
1709   // compute continuation point - the continuation point expects
1710   // the following registers set up:
1711   //
1712   // rax: exception
1713   // rdx: return address/pc that threw exception
1714   // rsp: expression stack of caller
1715   // rbp: rbp, of caller
1716   __ push(rax);                                  // save exception
1717   __ push(rdx);                                  // save return address
1718   __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, rdx);
1719   __ mov(rbx, rax);                              // save exception handler
1720   __ pop(rdx);                                   // restore return address
1721   __ pop(rax);                                   // restore exception
1722   // Note that an "issuing PC" is actually the next PC after the call
1723   __ jmp(rbx);                                   // jump to exception handler of caller
1724 }
1725 
1726 
1727 //
1728 // JVMTI ForceEarlyReturn support
1729 //
1730 address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) {
1731   address entry = __ pc();
1732   const Register thread = rcx;
1733 
1734   __ restore_bcp();
1735   __ restore_locals();
1736   __ empty_expression_stack();
1737   __ empty_FPU_stack();
1738   __ load_earlyret_value(state);
1739 
1740   __ get_thread(thread);
1741   __ movptr(rcx, Address(thread, JavaThread::jvmti_thread_state_offset()));
1742   const Address cond_addr(rcx, JvmtiThreadState::earlyret_state_offset());
1743 
1744   // Clear the earlyret state
1745   __ movl(cond_addr, JvmtiThreadState::earlyret_inactive);
1746 
1747   __ remove_activation(state, rsi,
1748                        false, /* throw_monitor_exception */
1749                        false, /* install_monitor_exception */
1750                        true); /* notify_jvmdi */
1751   __ jmp(rsi);
1752   return entry;
1753 } // end of ForceEarlyReturn support
1754 
1755 
1756 //------------------------------------------------------------------------------------------------------------------------
1757 // Helper for vtos entry point generation
1758 
1759 void TemplateInterpreterGenerator::set_vtos_entry_points (Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
1760   assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
1761   Label L;


src/cpu/x86/vm/templateInterpreter_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File