Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8068655

frame::safe_for_sender() computes incorrect sender_sp value for interpreted frames

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 9
    • 9
    • hotspot
    • b51
    • x86

        When safe_for_sender() tries to create its sender frame, and the current frame is an interpreted frame, the current code incorrectly uses frame::sender_sp_offset, which is only valid for compiled frame.

         128 if (is_interpreted_frame()) {
         129 // fp must be safe
         130 if (!fp_safe) {
         131 return false;
         132 }
         133
         134 sender_pc = (address) this->fp()[return_addr_offset];
         135 sender_sp = (intptr_t*) addr_at(sender_sp_offset);

        Interpreted frames don't handle local variables the same way as compiled frames. When an interpreted is invoked, arguments are pushed on the stack, but before the frame fixed header is generated, an additional space on the stack is allocated to store extra local variables (local variables that are not arguments) of the callee method. This extra space is not part of the caller method execution stack, but using frame::sender_sp_offset to compute the sender_sp generates a sender_sp value that include this extra space in the caller frame.

        If the caller frame is interpreted, safe_for_sender() calls is_interpreted_frame_valid() on its sender frame, with the sender_sp value it computed. Method is_interpreted_frame_valid() checks the size with the following code:

         571 // stack frames shouldn't be much larger than max_stack elements
         572
         573 if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
         574 return false;
         575 }

        Because of the incorrect sender_sp value, the interval fp() - sp() includes the frame header and the execution stack of the caller frame, but also the extra local variables of the callee frame. In most case the bug has no effect because of the big tolerance introduce by the 1024 margin. However, if the callee method has a huge number of local variables, the test fails (false negative).

        The fix is to get the correct sender_sp from the interpreted frame header:

         129 if (is_interpreted_frame()) {
         130 // fp must be safe
         131 if (!fp_safe) {
         132 return false;
         133 }
         134
         135 sender_pc = (address) this->fp()[return_addr_offset];
         136 sender_sp = (intptr_t*) this->fp()[interpreter_frame_sender_sp_offset];
         137 saved_fp = (intptr_t*) this->fp()[link_offset];

              fparain Frederic Parain
              fparain Frederic Parain
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved:

                  Estimated:
                  Original Estimate - 2 weeks
                  2w
                  Remaining:
                  Remaining Estimate - 1 week
                  1w
                  Logged:
                  Time Spent - Not Specified Time Not Required
                  Not Specified