<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 - Graph::methodOfGettingAValueProfileFor() should be returning the profile for operand node."
   href="https://bugs.webkit.org/show_bug.cgi?id=164600">164600</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Graph::methodOfGettingAValueProfileFor() should be returning the profile for operand node.
          </td>
        </tr>

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

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

        <tr>
          <th>Version</th>
          <td>WebKit Nightly 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>Currently, Graph::methodOfGettingAValueProfileFor() assumes that the operand DFG node that it is provided with always has a different origin than the node that is using that operand.  For example, in a DFG graph that looks like this:
    a: ...
    b: ArithAdd(&#64;a, ...)

... when emitting speculation checks on &#64;a for the ArithAdd node at &#64;b, Graph::methodOfGettingAValueProfileFor() is passed &#64;a, and expects &#64;a's to originate from a different bytecode than &#64;b.

However, op_negate can be compiled into the following series of nodes:

    a: BooleanToNumber(...)
    b: DoubleRep(&#64;a)
    c: ArithNegate(&#64;b)

All 3 nodes maps to the same op_negate bytecode i.e. they have the same origin.  When the speculativeJIT does a speculationCheck in DoubleRep, it calls Graph::methodOfGettingAValueProfileFor() to get the ArithProfile for the BooleanToNumber node.  But because all 3 nodes have the same origin, Graph::methodOfGettingAValueProfileFor() erroneously returns the ArithProfile for the op_negate.  Subsequently, the OSR exit ramp will modify the ArithProfile of the op_negate and corrupt its profile.  Instead, what the OSR exit ramp should be doing is update the ArithProfile of op_negate's operand i.e. BooleanToNumber's operand in this case.

The fix is to always pass the current node we're generating code for (in addition to the operand node) to Graph::methodOfGettingAValueProfileFor().  This way, we can determine if the profile is valid if and only if the current node and its operand node does not have the same origin.</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>