Title: [226362] trunk
Revision
226362
Author
[email protected]
Date
2018-01-03 09:35:35 -0800 (Wed, 03 Jan 2018)

Log Message

Inlining of a function that ends in op_unreachable crashes
https://bugs.webkit.org/show_bug.cgi?id=181027

Reviewed by Filip Pizlo.

JSTests:

* stress/inlining-unreachable.js: Added.
(bar):
(baz):
(i.catch):

Source/_javascript_Core:

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::allocateTargetableBlock):
(JSC::DFG::ByteCodeParser::inlineCall):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (226361 => 226362)


--- trunk/JSTests/ChangeLog	2018-01-03 17:32:31 UTC (rev 226361)
+++ trunk/JSTests/ChangeLog	2018-01-03 17:35:35 UTC (rev 226362)
@@ -1,3 +1,15 @@
+2018-01-03  Robin Morisset  <[email protected]>
+
+        Inlining of a function that ends in op_unreachable crashes
+        https://bugs.webkit.org/show_bug.cgi?id=181027
+
+        Reviewed by Filip Pizlo.
+
+        * stress/inlining-unreachable.js: Added.
+        (bar):
+        (baz):
+        (i.catch):
+
 2018-01-02  Saam Barati  <[email protected]>
 
         Incorrect assertion inside AccessCase

Added: trunk/JSTests/stress/inlining-unreachable.js (0 => 226362)


--- trunk/JSTests/stress/inlining-unreachable.js	                        (rev 0)
+++ trunk/JSTests/stress/inlining-unreachable.js	2018-01-03 17:35:35 UTC (rev 226362)
@@ -0,0 +1,9 @@
+var bar = class Bar { };
+var baz = class Baz {
+    constructor() { bar(); }
+};
+for (var i = 0; i < 10000; i++) {
+    try {
+        new baz();
+    } catch (e) {}
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (226361 => 226362)


--- trunk/Source/_javascript_Core/ChangeLog	2018-01-03 17:32:31 UTC (rev 226361)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-01-03 17:35:35 UTC (rev 226362)
@@ -1,3 +1,14 @@
+2018-01-03  Robin Morisset  <[email protected]>
+
+        Inlining of a function that ends in op_unreachable crashes
+        https://bugs.webkit.org/show_bug.cgi?id=181027
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::allocateTargetableBlock):
+        (JSC::DFG::ByteCodeParser::inlineCall):
+
 2018-01-02  Saam Barati  <[email protected]>
 
         Incorrect assertion inside AccessCase

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (226361 => 226362)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2018-01-03 17:32:31 UTC (rev 226361)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2018-01-03 17:35:35 UTC (rev 226362)
@@ -139,6 +139,7 @@
     // It is also used when doing an early return from an inlined callee: it is easier to fix the bytecode index later on if needed
     // than to move the right index all the way to the treatment of op_ret.
     BasicBlock* allocateTargetableBlock(unsigned bytecodeIndex);
+    BasicBlock* allocateTargetableBlock(InlineStackEntry*, unsigned bytecodeIndex);
     BasicBlock* allocateUntargetableBlock();
     // An untargetable block can be given a bytecodeIndex to be later managed by linkBlock, but only once, and it can never go in the other direction
     void makeBlockTargetable(BasicBlock*, unsigned bytecodeIndex);
@@ -1144,13 +1145,18 @@
 
 BasicBlock* ByteCodeParser::allocateTargetableBlock(unsigned bytecodeIndex)
 {
+    return allocateTargetableBlock(m_inlineStackTop, bytecodeIndex);
+}
+
+BasicBlock* ByteCodeParser::allocateTargetableBlock(InlineStackEntry* stackEntry, unsigned bytecodeIndex)
+{
     ASSERT(bytecodeIndex != UINT_MAX);
     Ref<BasicBlock> block = adoptRef(*new BasicBlock(bytecodeIndex, m_numArguments, m_numLocals, 1));
     BasicBlock* blockPtr = block.ptr();
     // m_blockLinkingTargets must always be sorted in increasing order of bytecodeBegin
-    if (m_inlineStackTop->m_blockLinkingTargets.size())
-        ASSERT(m_inlineStackTop->m_blockLinkingTargets.last()->bytecodeBegin < bytecodeIndex);
-    m_inlineStackTop->m_blockLinkingTargets.append(blockPtr);
+    if (stackEntry->m_blockLinkingTargets.size())
+        ASSERT(stackEntry->m_blockLinkingTargets.last()->bytecodeBegin < bytecodeIndex);
+    stackEntry->m_blockLinkingTargets.append(blockPtr);
     m_graph.appendBlock(WTFMove(block));
     return blockPtr;
 }
@@ -1652,11 +1658,13 @@
 
     linkBlocks(inlineStackEntry.m_unlinkedBlocks, inlineStackEntry.m_blockLinkingTargets);
     
-    // There is an invariant that we use here: every function has at least one op_ret somewhere.
-    // And when parseBlock encounters an op_ret, it setups a continuation block if there was none.
-    // If this invariant was to be changed, we would need to allocate a new block here in the case where there was no continuation block ready.
-    RELEASE_ASSERT(inlineStackEntry.m_continuationBlock);
-    m_currentBlock = inlineStackEntry.m_continuationBlock;
+    // Most functions have at least one op_ret and thus set up the continuation block.
+    // In some rare cases, a function ends in op_unreachable, forcing us to allocate a new continuationBlock here.
+    // We must be careful to allocate it in the caller and not the top of the inline stack, since the callee is still on the stack at this point.
+    if (inlineStackEntry.m_continuationBlock)
+        m_currentBlock = inlineStackEntry.m_continuationBlock;
+    else
+        m_currentBlock = allocateTargetableBlock(inlineStackEntry.m_caller, m_currentIndex);
     ASSERT(!m_currentBlock->terminal());
 
     prepareToParseBlock();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to