Changeset 275472 in webkit


Ignore:
Timestamp:
Apr 5, 2021 6:52:05 PM (3 years ago)
Author:
keith_miller@apple.com
Message:

DFG arity fixup nodes should exit to the caller's call opcode
https://bugs.webkit.org/show_bug.cgi?id=223278

Reviewed by Saam Barati.

JSTests:

  • stress/dfg-arity-fixup-uses-callers-exit-origin.js: Added.

(main.v22):
(main.v30):
(main.try.v40):
(main.try.v47):
(main.try.v56):
(main.):
(main):

Source/JavaScriptCore:

Right now when we do arity fixup in the DFG we model it in the
same way that it executes, which means all the nodes are part of
the callee. Unfortunately, this causes PhantomInsertionPhase to
think those nodes could be replacing previously defined
VirtualRegisters as they are part of the callee's header (always
alive). When PhantomInsertionPhase then inserts a Phantom it will
put that node in the caller's frame as that's the first ExitOK
node. The caller however may have no knowledge of that
VirtualRegister though. For example:

--> foo: loc10 is a local in foo.

...
1: MovHint(loc10)
2: SetLocal(loc10)

<-- foo loc10 ten is now out of scope for the InlineCallFrame of the caller.
...
Phantom will be inserted here refering to loc10, which doesn't make sense.
--> bar loc10 is an argument to bar and needs arity fixup.

... All of these nodes are ExitInvalid
3: MovHint(loc10, ExitInvalid)
4: SetLocal(loc10, ExitInvalid)
...

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::currentNodeOrigin):
(JSC::DFG::ByteCodeParser::inlineCall):

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r275439 r275472  
     12021-04-05  Keith Miller  <keith_miller@apple.com>
     2
     3        DFG arity fixup nodes should exit to the caller's call opcode
     4        https://bugs.webkit.org/show_bug.cgi?id=223278
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/dfg-arity-fixup-uses-callers-exit-origin.js: Added.
     9        (main.v22):
     10        (main.v30):
     11        (main.try.v40):
     12        (main.try.v47):
     13        (main.try.v56):
     14        (main.):
     15        (main):
     16
    1172021-04-02  Alexey Shvayka  <shvaikalesh@gmail.com>
    218
  • trunk/Source/JavaScriptCore/ChangeLog

    r275439 r275472  
     12021-04-05  Keith Miller  <keith_miller@apple.com>
     2
     3        DFG arity fixup nodes should exit to the caller's call opcode
     4        https://bugs.webkit.org/show_bug.cgi?id=223278
     5
     6        Reviewed by Saam Barati.
     7
     8        Right now when we do arity fixup in the DFG we model it in the
     9        same way that it executes, which means all the nodes are part of
     10        the callee. Unfortunately, this causes PhantomInsertionPhase to
     11        think those nodes could be replacing previously defined
     12        VirtualRegisters as they are part of the callee's header (always
     13        alive). When PhantomInsertionPhase then inserts a Phantom it will
     14        put that node in the caller's frame as that's the first ExitOK
     15        node. The caller however may have no knowledge of that
     16        VirtualRegister though. For example:
     17
     18        --> foo: loc10 is a local in foo.
     19            ...
     20            1: MovHint(loc10)
     21            2: SetLocal(loc10)
     22        <-- foo // loc10 ten is now out of scope for the InlineCallFrame of the caller.
     23        ...
     24        // Phantom will be inserted here refering to loc10, which doesn't make sense.
     25        --> bar // loc10 is an argument to bar and needs arity fixup.
     26            ... // All of these nodes are ExitInvalid
     27            3: MovHint(loc10, ExitInvalid)
     28            4: SetLocal(loc10, ExitInvalid)
     29            ...
     30
     31        * dfg/DFGByteCodeParser.cpp:
     32        (JSC::DFG::ByteCodeParser::currentNodeOrigin):
     33        (JSC::DFG::ByteCodeParser::inlineCall):
     34
    1352021-04-02  Alexey Shvayka  <shvaikalesh@gmail.com>
    236
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r274308 r275472  
    750750    NodeOrigin currentNodeOrigin()
    751751    {
    752         CodeOrigin semantic;
    753         CodeOrigin forExit;
    754 
    755         if (m_currentSemanticOrigin.isSet())
    756             semantic = m_currentSemanticOrigin;
    757         else
    758             semantic = currentCodeOrigin();
    759 
    760         forExit = currentCodeOrigin();
     752        CodeOrigin semantic = m_currentSemanticOrigin.isSet() ? m_currentSemanticOrigin : currentCodeOrigin();
     753        CodeOrigin forExit = m_currentExitOrigin.isSet() ? m_currentExitOrigin : currentCodeOrigin();
    761754
    762755        return NodeOrigin(semantic, forExit, m_exitOK);
     
    11481141    // The semantic origin of the current node if different from the current Index.
    11491142    CodeOrigin m_currentSemanticOrigin;
     1143    // The exit origin of the current node if different from the current Index.
     1144    CodeOrigin m_currentExitOrigin;
    11501145    // True if it's OK to OSR exit right now.
    11511146    bool m_exitOK { false };
     
    17141709        calleeVariable->mergeShouldNeverUnbox(true);
    17151710    }
     1711
     1712    // We want to claim the exit origin for the arity fixup nodes to be in the caller rather than the callee because
     1713    // otherwise phantom insertion phase will think the virtual registers in the callee's header have been alive from the last
     1714    // time they were set. For example:
     1715
     1716    // --> foo: loc10 is a local in foo.
     1717    //    ...
     1718    //    1: MovHint(loc10)
     1719    //    2: SetLocal(loc10)
     1720    // <-- foo: loc10 ten is now out of scope for the InlineCallFrame of the caller.
     1721    // ...
     1722    // --> bar: loc10 is an argument to bar and needs arity fixup.
     1723    //    ... // All of these nodes are ExitInvalid
     1724    //    3: MovHint(loc10, ExitInvalid)
     1725    //    4: SetLocal(loc10, ExitInvalid)
     1726    //    ...
     1727
     1728    // In this example phantom insertion phase will think @3 is always alive because it's in the header of bar. So,
     1729    // it will think we are about to kill the old value, as loc10 is in the header of bar and therefore always live, and
     1730    // thus need a Phantom. That Phantom, however, may be inserted  into the caller's NodeOrigin (all the nodes in bar
     1731    // before @3 are ExitInvalid), which doesn't know about loc10. If we move all of the arity fixup nodes into the
     1732    // caller's exit origin, forAllKilledOperands, which is how phantom insertion phase decides where phantoms are needed,
     1733    // will no longer say loc10 is always alive.
     1734    CodeOrigin oldExitOrigin = m_currentExitOrigin;
     1735    m_currentExitOrigin = currentCodeOrigin();
    17161736
    17171737    InlineStackEntry* callerStackTop = m_inlineStackTop;
     
    18171837        // our callee's frame. We emit an ExitOK below.
    18181838    }
     1839
     1840    m_currentExitOrigin = oldExitOrigin;
    18191841
    18201842    // At this point, it's again OK to OSR exit.
Note: See TracChangeset for help on using the changeset viewer.