Title: [280847] branches/safari-611.3.10.0-branch
Revision
280847
Author
[email protected]
Date
2021-08-10 10:08:11 -0700 (Tue, 10 Aug 2021)

Log Message

Cherry-pick r275472. rdar://problem/81710596

    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/_javascript_Core:

    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):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275472 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-611.3.10.0-branch/JSTests/ChangeLog (280846 => 280847)


--- branches/safari-611.3.10.0-branch/JSTests/ChangeLog	2021-08-10 16:56:35 UTC (rev 280846)
+++ branches/safari-611.3.10.0-branch/JSTests/ChangeLog	2021-08-10 17:08:11 UTC (rev 280847)
@@ -1,3 +1,71 @@
+2021-08-10  Russell Epstein  <[email protected]>
+
+        Cherry-pick r275472. rdar://problem/81710596
+
+    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/_javascript_Core:
+    
+    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):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-04-05  Keith Miller  <[email protected]>
+
+            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.
+
+            * 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):
+
 2021-06-15  Alan Coon  <[email protected]>
 
         Cherry-pick r278819. rdar://problem/79355258

Added: branches/safari-611.3.10.0-branch/JSTests/stress/dfg-arity-fixup-uses-callers-exit-origin.js (0 => 280847)


--- branches/safari-611.3.10.0-branch/JSTests/stress/dfg-arity-fixup-uses-callers-exit-origin.js	                        (rev 0)
+++ branches/safari-611.3.10.0-branch/JSTests/stress/dfg-arity-fixup-uses-callers-exit-origin.js	2021-08-10 17:08:11 UTC (rev 280847)
@@ -0,0 +1,54 @@
+function main() {
+const v12 = [1337,1337];
+const v13 = [1337,v12,v12,0];
+for (let v14 = 0; v14 < 1000; v14++) {
+    function v15(v16,v17) {
+        const v18 = v14 + 127;
+        const v19 = String();
+        const v20 = String.fromCharCode();
+        const v21 = v13.shift();
+        function v22() {
+            const v23 = arguments;
+        }
+        const v24 = Object();
+        const v25 = {};
+        const v26 = v22(v25);
+        const v27 = [-903931.176976766,v20,null,null,-903931.176976766];
+        function v30() {
+        }
+        const v31 = {ownKeys:v30};
+        const v32 = {};
+        const v33 = new Proxy(v32,v31);
+        Function.__proto__ = v33;
+        const v34 = v27.join();
+        try {
+            const v35 = Function();
+            const v36 = v35();
+            for (let v37 = 0; v37 < 127; v37++) {
+                const v38 = isFinite();
+                const v39 = isFinite;
+                function v40(v41,v42,v43) {
+                }
+                const v44 = 1337;
+                const v45 = undefined;
+                const v46 = "function(){}";
+                function* v47(v48,v49,v50,v51,v52) {
+                }
+                const v53 = charAt;
+                function v56(v57,v58,v59,v60,v61) {
+                    const v62 = v36(v35,v37);
+                }
+                for (let v64 = 0; v64 >= 100000; v64++) {
+                }
+                const v65 = 10000;
+                const v66 = v38[4];
+            }
+        } catch(v67) {
+        }
+    }
+    const v68 = v15();
+}
+}
+noDFG(main);
+noFTL(main);
+main();

Modified: branches/safari-611.3.10.0-branch/Source/_javascript_Core/ChangeLog (280846 => 280847)


--- branches/safari-611.3.10.0-branch/Source/_javascript_Core/ChangeLog	2021-08-10 16:56:35 UTC (rev 280846)
+++ branches/safari-611.3.10.0-branch/Source/_javascript_Core/ChangeLog	2021-08-10 17:08:11 UTC (rev 280847)
@@ -1,3 +1,89 @@
+2021-08-10  Russell Epstein  <[email protected]>
+
+        Cherry-pick r275472. rdar://problem/81710596
+
+    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/_javascript_Core:
+    
+    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):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-04-05  Keith Miller  <[email protected]>
+
+            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.
+
+            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):
+
 2021-06-15  Alan Coon  <[email protected]>
 
         Cherry-pick r278819. rdar://problem/79355258

Modified: branches/safari-611.3.10.0-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (280846 => 280847)


--- branches/safari-611.3.10.0-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2021-08-10 16:56:35 UTC (rev 280846)
+++ branches/safari-611.3.10.0-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2021-08-10 17:08:11 UTC (rev 280847)
@@ -746,16 +746,9 @@
 
     NodeOrigin currentNodeOrigin()
     {
-        CodeOrigin semantic;
-        CodeOrigin forExit;
+        CodeOrigin semantic = m_currentSemanticOrigin.isSet() ? m_currentSemanticOrigin : currentCodeOrigin();
+        CodeOrigin forExit = m_currentExitOrigin.isSet() ? m_currentExitOrigin : currentCodeOrigin();
 
-        if (m_currentSemanticOrigin.isSet())
-            semantic = m_currentSemanticOrigin;
-        else
-            semantic = currentCodeOrigin();
-
-        forExit = currentCodeOrigin();
-
         return NodeOrigin(semantic, forExit, m_exitOK);
     }
     
@@ -1144,6 +1137,8 @@
     BytecodeIndex m_currentIndex;
     // The semantic origin of the current node if different from the current Index.
     CodeOrigin m_currentSemanticOrigin;
+    // The exit origin of the current node if different from the current Index.
+    CodeOrigin m_currentExitOrigin;
     // True if it's OK to OSR exit right now.
     bool m_exitOK { false };
 
@@ -1711,6 +1706,31 @@
         calleeVariable->mergeShouldNeverUnbox(true);
     }
 
+    // We want to claim the exit origin for the arity fixup nodes to be in the caller rather than the callee because
+    // otherwise phantom insertion phase will think the virtual registers in the callee's header have been alive from the last
+    // time they were set. 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.
+    // ...
+    // --> 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)
+    //    ...
+
+    // In this example phantom insertion phase will think @3 is always alive because it's in the header of bar. So,
+    // it will think we are about to kill the old value, as loc10 is in the header of bar and therefore always live, and
+    // thus need a Phantom. That Phantom, however, may be inserted  into the caller's NodeOrigin (all the nodes in bar
+    // before @3 are ExitInvalid), which doesn't know about loc10. If we move all of the arity fixup nodes into the
+    // caller's exit origin, forAllKilledOperands, which is how phantom insertion phase decides where phantoms are needed,
+    // will no longer say loc10 is always alive.
+    CodeOrigin oldExitOrigin = m_currentExitOrigin;
+    m_currentExitOrigin = currentCodeOrigin();
+
     InlineStackEntry* callerStackTop = m_inlineStackTop;
     InlineStackEntry inlineStackEntry(this, codeBlock, codeBlock, callee.function(), result,
         inlineCallFrameStart.virtualRegister(), argumentCountIncludingThis, kind, continuationBlock);
@@ -1814,6 +1834,8 @@
         // our callee's frame. We emit an ExitOK below.
     }
 
+    m_currentExitOrigin = oldExitOrigin;
+
     // At this point, it's again OK to OSR exit.
     m_exitOK = true;
     addToGraph(ExitOK);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to