<html>
    <head>
      <base href="https://bugs.webkit.org/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - ScratchRegisterAllocator::preserveReusedRegistersByPushing() should allow room for C helper calls and keep sp properly aligned."
   href="https://bugs.webkit.org/show_bug.cgi?id=148564">148564</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>ScratchRegisterAllocator::preserveReusedRegistersByPushing() should allow room for C helper calls and keep sp properly aligned.
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>WebKit
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>WebKit Local Build
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Unspecified
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Unspecified
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>Normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P2
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>JavaScriptCore
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>webkit-unassigned&#64;lists.webkit.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>mark.lam&#64;apple.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>ScratchRegisterAllocator::preserveReusedRegistersByPushing() pushes registers on the stack in order to preserve them.  But emitPutTransitionStub() which uses preserveReusedRegistersByPushing() may also emit a call to a C helper function to flush the heap write barrier buffer.  The code for emitting C helper calls expects the stack pointer (sp) to already be pointing to a location on the stack where there's adequate space reserved for storing the arguments that the C helper expects, and that space is expected to be at the top of the stack.  Hence, there is a conflict of expectations.  As a result, the arguments for the C helper will overwrite and corrupt the values that are pushed on the stack by preserveReusedRegistersByPushing().

In addition, JIT compiled functions always position the sp such that it will be aligned (according to platform ABI dictates) after a C call is made (i.e. after the frame pointer and return address is pushed on to the stack).  preserveReusedRegistersByPushing()'s arbitrary pushing of a number of saved register values may mess up this alignment.

The fix is to have preserveReusedRegistersByPushing(), after it has pushed the saved register values, adjust the sp to reserve an additional amount of stack space needed for C call helpers plus any padding needed to restore proper sp alignment.  The stack's ReservedZone will ensure that we have enough stack space for this.  ScratchRegisterAllocator::restoreReusedRegistersByPopping() also needs to updated to perform the complement of this behavior.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>