Title: [208614] trunk
Revision
208614
Author
[email protected]
Date
2016-11-11 15:03:41 -0800 (Fri, 11 Nov 2016)

Log Message

We recursively grab a lock in the DFGBytecodeParser causing us to deadlock
https://bugs.webkit.org/show_bug.cgi?id=164650

Reviewed by Geoffrey Garen.

JSTests:

* stress/dont-dead-lock-put-by-val-as-put-by-id.js: Added.
(ident):
(let.o.set foo):
(foo):

Source/_javascript_Core:

Some code was incorrectly holding a lock when recursively calling
back into the bytecode parser's via inlining a put_by_val as a put_by_id.
This can cause a deadlock if the inlinee CodeBlock is something we're
already holding a lock for. I've changed the range of the lock holder
to be as narrow as possible.

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

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (208613 => 208614)


--- trunk/JSTests/ChangeLog	2016-11-11 22:53:24 UTC (rev 208613)
+++ trunk/JSTests/ChangeLog	2016-11-11 23:03:41 UTC (rev 208614)
@@ -1,3 +1,15 @@
+2016-11-11  Saam Barati  <[email protected]>
+
+        We recursively grab a lock in the DFGBytecodeParser causing us to deadlock
+        https://bugs.webkit.org/show_bug.cgi?id=164650
+
+        Reviewed by Geoffrey Garen.
+
+        * stress/dont-dead-lock-put-by-val-as-put-by-id.js: Added.
+        (ident):
+        (let.o.set foo):
+        (foo):
+
 2016-11-11  Chris Dumez  <[email protected]>
 
         Unreviewed, rolling out r208584.

Added: trunk/JSTests/stress/dont-dead-lock-put-by-val-as-put-by-id.js (0 => 208614)


--- trunk/JSTests/stress/dont-dead-lock-put-by-val-as-put-by-id.js	                        (rev 0)
+++ trunk/JSTests/stress/dont-dead-lock-put-by-val-as-put-by-id.js	2016-11-11 23:03:41 UTC (rev 208614)
@@ -0,0 +1,17 @@
+function ident() { return "foo"; }
+noInline(ident);
+
+let o = {
+    set foo(x) {
+        foo(false);
+    }
+};
+
+function foo(cond) {
+    if (cond)
+        o[ident()] = 20;
+}
+
+for (let i = 0; i < 10000; i++) {
+    foo(true);
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (208613 => 208614)


--- trunk/Source/_javascript_Core/ChangeLog	2016-11-11 22:53:24 UTC (rev 208613)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-11-11 23:03:41 UTC (rev 208614)
@@ -1,3 +1,19 @@
+2016-11-11  Saam Barati  <[email protected]>
+
+        We recursively grab a lock in the DFGBytecodeParser causing us to deadlock
+        https://bugs.webkit.org/show_bug.cgi?id=164650
+
+        Reviewed by Geoffrey Garen.
+
+        Some code was incorrectly holding a lock when recursively calling
+        back into the bytecode parser's via inlining a put_by_val as a put_by_id.
+        This can cause a deadlock if the inlinee CodeBlock is something we're
+        already holding a lock for. I've changed the range of the lock holder
+        to be as narrow as possible.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+
 2016-11-11  Chris Dumez  <[email protected]>
 
         Unreviewed, rolling out r208584.

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (208613 => 208614)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2016-11-11 22:53:24 UTC (rev 208613)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2016-11-11 23:03:41 UTC (rev 208614)
@@ -4295,34 +4295,40 @@
             bool isDirect = opcodeID == op_put_by_val_direct;
             bool compiledAsPutById = false;
             {
-                ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
-                ByValInfo* byValInfo = m_inlineStackTop->m_byValInfos.get(CodeOrigin(currentCodeOrigin().bytecodeIndex));
-                // FIXME: When the bytecode is not compiled in the baseline JIT, byValInfo becomes null.
-                // At that time, there is no information.
-                if (byValInfo 
-                    && byValInfo->stubInfo
-                    && !byValInfo->tookSlowPath
-                    && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent)
-                    && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)
-                    && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell)) {
-                    compiledAsPutById = true;
-                    unsigned identifierNumber = m_graph.identifiers().ensure(byValInfo->cachedId.impl());
-                    UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
+                unsigned identifierNumber;
+                PutByIdStatus putByIdStatus;
+                {
+                    ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
+                    ByValInfo* byValInfo = m_inlineStackTop->m_byValInfos.get(CodeOrigin(currentCodeOrigin().bytecodeIndex));
+                    // FIXME: When the bytecode is not compiled in the baseline JIT, byValInfo becomes null.
+                    // At that time, there is no information.
+                    if (byValInfo 
+                        && byValInfo->stubInfo
+                        && !byValInfo->tookSlowPath
+                        && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent)
+                        && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)
+                        && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell)) {
+                        compiledAsPutById = true;
+                        identifierNumber = m_graph.identifiers().ensure(byValInfo->cachedId.impl());
+                        UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
 
-                    if (Symbol* symbol = byValInfo->cachedSymbol.get()) {
-                        FrozenValue* frozen = m_graph.freezeStrong(symbol);
-                        addToGraph(CheckCell, OpInfo(frozen), property);
-                    } else {
-                        ASSERT(!uid->isSymbol());
-                        addToGraph(CheckStringIdent, OpInfo(uid), property);
+                        if (Symbol* symbol = byValInfo->cachedSymbol.get()) {
+                            FrozenValue* frozen = m_graph.freezeStrong(symbol);
+                            addToGraph(CheckCell, OpInfo(frozen), property);
+                        } else {
+                            ASSERT(!uid->isSymbol());
+                            addToGraph(CheckStringIdent, OpInfo(uid), property);
+                        }
+
+                        putByIdStatus = PutByIdStatus::computeForStubInfo(
+                            locker, m_inlineStackTop->m_profiledBlock,
+                            byValInfo->stubInfo, currentCodeOrigin(), uid);
+
                     }
+                }
 
-                    PutByIdStatus putByIdStatus = PutByIdStatus::computeForStubInfo(
-                        locker, m_inlineStackTop->m_profiledBlock,
-                        byValInfo->stubInfo, currentCodeOrigin(), uid);
-
+                if (compiledAsPutById)
                     handlePutById(base, identifierNumber, value, putByIdStatus, isDirect);
-                }
             }
 
             if (!compiledAsPutById) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to