Title: [164371] trunk
Revision
164371
Author
[email protected]
Date
2014-02-19 10:41:27 -0800 (Wed, 19 Feb 2014)

Log Message

Dedicated worker crash caused by global DFG worklists + GC
https://bugs.webkit.org/show_bug.cgi?id=128537

Reviewed by Filip Pizlo.

Source/_javascript_Core:

The process-global DFG worklists were causing objects to participate in the garbage collections of VMs
other than the one they were allocated in. This started manifesting in the worker tests because they're
one of the few WebKit tests that do multithreaded JS.

The fix is to filter out Plans from other VMs during collection.

* dfg/DFGSafepoint.cpp:
(JSC::DFG::Safepoint::vm):
* dfg/DFGSafepoint.h:
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::isActiveForVM):
(JSC::DFG::Worklist::suspendAllThreads):
(JSC::DFG::Worklist::resumeAllThreads):
(JSC::DFG::Worklist::visitChildren):
* dfg/DFGWorklist.h:
* heap/Heap.cpp:
(JSC::Heap::deleteAllCompiledCode):
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::copyLater):

LayoutTests:

Reenable a previously skipped test.

* TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (164370 => 164371)


--- trunk/LayoutTests/ChangeLog	2014-02-19 18:11:28 UTC (rev 164370)
+++ trunk/LayoutTests/ChangeLog	2014-02-19 18:41:27 UTC (rev 164371)
@@ -1,3 +1,14 @@
+2014-02-19  Mark Hahnenberg  <[email protected]>
+
+        Dedicated worker crash caused by global DFG worklists + GC
+        https://bugs.webkit.org/show_bug.cgi?id=128537
+
+        Reviewed by Filip Pizlo.
+
+        Reenable a previously skipped test.
+
+        * TestExpectations:
+
 2014-02-19  Brent Fulgham  <[email protected]>
 
         Windows gardening. Mark more flakes.

Modified: trunk/LayoutTests/TestExpectations (164370 => 164371)


--- trunk/LayoutTests/TestExpectations	2014-02-19 18:11:28 UTC (rev 164370)
+++ trunk/LayoutTests/TestExpectations	2014-02-19 18:41:27 UTC (rev 164371)
@@ -99,7 +99,6 @@
 
 webkit.org/b/127697 fast/writing-mode/ruby-text-logical-left.html [ Skip ]
 
-webkit.org/b/128537 fast/workers/dedicated-worker-lifecycle.html [ Skip ]
 webkit.org/b/128745 [ Debug ] fast/workers/use-machine-stack.html [ Pass Crash ]
 
 webkit.org/b/83618 fast/dom/inline-event-attributes-release.html [ Failure ]

Modified: trunk/Source/_javascript_Core/ChangeLog (164370 => 164371)


--- trunk/Source/_javascript_Core/ChangeLog	2014-02-19 18:11:28 UTC (rev 164370)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-02-19 18:41:27 UTC (rev 164371)
@@ -1,3 +1,30 @@
+2014-02-19  Mark Hahnenberg  <[email protected]>
+
+        Dedicated worker crash caused by global DFG worklists + GC
+        https://bugs.webkit.org/show_bug.cgi?id=128537
+
+        Reviewed by Filip Pizlo.
+
+        The process-global DFG worklists were causing objects to participate in the garbage collections of VMs 
+        other than the one they were allocated in. This started manifesting in the worker tests because they're 
+        one of the few WebKit tests that do multithreaded JS.
+
+        The fix is to filter out Plans from other VMs during collection.
+
+        * dfg/DFGSafepoint.cpp:
+        (JSC::DFG::Safepoint::vm):
+        * dfg/DFGSafepoint.h:
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::isActiveForVM):
+        (JSC::DFG::Worklist::suspendAllThreads):
+        (JSC::DFG::Worklist::resumeAllThreads):
+        (JSC::DFG::Worklist::visitChildren):
+        * dfg/DFGWorklist.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::deleteAllCompiledCode):
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::copyLater):
+
 2014-02-19  Brady Eidson  <[email protected]>
 
         Add FeatureDefines for image controls

Modified: trunk/Source/_javascript_Core/dfg/DFGSafepoint.cpp (164370 => 164371)


--- trunk/Source/_javascript_Core/dfg/DFGSafepoint.cpp	2014-02-19 18:11:28 UTC (rev 164370)
+++ trunk/Source/_javascript_Core/dfg/DFGSafepoint.cpp	2014-02-19 18:41:27 UTC (rev 164371)
@@ -75,6 +75,11 @@
         m_scannables[i]->visitChildren(visitor);
 }
 
+VM& Safepoint::vm() const
+{
+    return m_plan.vm;
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/dfg/DFGSafepoint.h (164370 => 164371)


--- trunk/Source/_javascript_Core/dfg/DFGSafepoint.h	2014-02-19 18:11:28 UTC (rev 164370)
+++ trunk/Source/_javascript_Core/dfg/DFGSafepoint.h	2014-02-19 18:41:27 UTC (rev 164371)
@@ -33,6 +33,7 @@
 namespace JSC {
 
 class SlotVisitor;
+class VM;
 
 namespace DFG {
 
@@ -50,6 +51,8 @@
     
     void visitChildren(SlotVisitor&);
     
+    VM& vm() const;
+
 private:
     Plan& m_plan;
     Vector<Scannable*> m_scannables;

Modified: trunk/Source/_javascript_Core/dfg/DFGWorklist.cpp (164370 => 164371)


--- trunk/Source/_javascript_Core/dfg/DFGWorklist.cpp	2014-02-19 18:11:28 UTC (rev 164370)
+++ trunk/Source/_javascript_Core/dfg/DFGWorklist.cpp	2014-02-19 18:41:27 UTC (rev 164371)
@@ -72,6 +72,16 @@
     return result;
 }
 
+bool Worklist::isActiveForVM(VM& vm) const
+{
+    PlanMap::const_iterator end = m_plans.end();
+    for (PlanMap::const_iterator iter = m_plans.begin(); iter != end; ++iter) {
+        if (&iter->value->vm == &vm)
+            return true;
+    }
+    return false;
+}
+
 void Worklist::enqueue(PassRefPtr<Plan> passedPlan)
 {
     RefPtr<Plan> plan = passedPlan;
@@ -195,6 +205,7 @@
 
 void Worklist::suspendAllThreads()
 {
+    m_suspensionLock.lock();
     for (unsigned i = m_threads.size(); i--;)
         m_threads[i]->m_rightToRun.lock();
 }
@@ -203,18 +214,24 @@
 {
     for (unsigned i = m_threads.size(); i--;)
         m_threads[i]->m_rightToRun.unlock();
+    m_suspensionLock.unlock();
 }
 
 void Worklist::visitChildren(SlotVisitor& visitor, CodeBlockSet& codeBlocks)
 {
+    VM* vm = visitor.heap()->vm();
     for (PlanMap::iterator iter = m_plans.begin(); iter != m_plans.end(); ++iter) {
+        Plan* plan = iter->value.get();
+        if (&plan->vm != vm)
+            continue;
         iter->key.visitChildren(codeBlocks);
         iter->value->visitChildren(visitor, codeBlocks);
     }
     
     for (unsigned i = m_threads.size(); i--;) {
         ThreadData* data = ""
-        if (Safepoint* safepoint = data->m_safepoint)
+        Safepoint* safepoint = data->m_safepoint;
+        if (safepoint && &safepoint->vm() == vm)
             safepoint->visitChildren(visitor);
     }
 }

Modified: trunk/Source/_javascript_Core/dfg/DFGWorklist.h (164370 => 164371)


--- trunk/Source/_javascript_Core/dfg/DFGWorklist.h	2014-02-19 18:11:28 UTC (rev 164370)
+++ trunk/Source/_javascript_Core/dfg/DFGWorklist.h	2014-02-19 18:41:27 UTC (rev 164371)
@@ -71,7 +71,7 @@
     void suspendAllThreads();
     void resumeAllThreads();
     
-    bool isActive() const { return !!m_plans.size(); }
+    bool isActiveForVM(VM&) const;
     
     void visitChildren(SlotVisitor&, CodeBlockSet&); // Only called on the main thread after suspending all threads.
     
@@ -101,6 +101,8 @@
     // Used to quickly find which plans have been compiled and are ready to
     // be completed.
     Vector<RefPtr<Plan>, 16> m_readyPlans;
+
+    Mutex m_suspensionLock;
     
     mutable Mutex m_lock;
     ThreadCondition m_planEnqueued;

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (164370 => 164371)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2014-02-19 18:11:28 UTC (rev 164370)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2014-02-19 18:41:27 UTC (rev 164371)
@@ -743,7 +743,7 @@
 #if ENABLE(DFG_JIT)
     for (unsigned i = DFG::numberOfWorklists(); i--;) {
         if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) {
-            if (worklist->isActive())
+            if (worklist->isActiveForVM(*vm()))
                 return;
         }
     }

Modified: trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h (164370 => 164371)


--- trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h	2014-02-19 18:11:28 UTC (rev 164370)
+++ trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h	2014-02-19 18:41:27 UTC (rev 164371)
@@ -242,6 +242,8 @@
         return;
     }
 
+    ASSERT(heap()->m_storageSpace.contains(block));
+
     SpinLockHolder locker(&block->workListLock());
     if (heap()->operationInProgress() == FullCollection || block->shouldReportLiveBytes(locker, owner)) {
         m_bytesCopied += bytes;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to