Separate MarkStackThreadSharedData from MarkStack
authormhahnenberg@apple.com <mhahnenberg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Aug 2012 21:49:16 +0000 (21:49 +0000)
committermhahnenberg@apple.com <mhahnenberg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Aug 2012 21:49:16 +0000 (21:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=94294

Reviewed by Filip Pizlo.

MarkStackThreadSharedData is soon going to have data to allow for a parallel copying
mode too, so to separate our concerns we should split it out into its own set of files
and rename it to GCThreadSharedData. For now this is purely a cosmetic refactoring.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* heap/GCThreadSharedData.cpp: Added.
(JSC):
(JSC::GCThreadSharedData::resetChildren):
(JSC::GCThreadSharedData::childVisitCount):
(JSC::GCThreadSharedData::markingThreadMain):
(JSC::GCThreadSharedData::markingThreadStartFunc):
(JSC::GCThreadSharedData::GCThreadSharedData):
(JSC::GCThreadSharedData::~GCThreadSharedData):
(JSC::GCThreadSharedData::reset):
* heap/GCThreadSharedData.h: Added.
(JSC):
(GCThreadSharedData):
* heap/Heap.h:
(Heap):
* heap/ListableHandler.h:
(ListableHandler):
* heap/MarkStack.cpp:
(JSC::MarkStack::MarkStack):
(JSC::MarkStack::~MarkStack):
* heap/MarkStack.h:
(JSC):
(MarkStack):
(JSC::MarkStack::sharedData):
* heap/MarkStackInlineMethods.h: Added.
(JSC):
(JSC::MarkStack::append):
(JSC::MarkStack::appendUnbarrieredPointer):
(JSC::MarkStack::appendUnbarrieredValue):
(JSC::MarkStack::internalAppend):
(JSC::MarkStack::addWeakReferenceHarvester):
(JSC::MarkStack::addUnconditionalFinalizer):
(JSC::MarkStack::addOpaqueRoot):
(JSC::MarkStack::containsOpaqueRoot):
(JSC::MarkStack::opaqueRootCount):
* heap/SlotVisitor.h:
(JSC):
(SlotVisitor):
(JSC::SlotVisitor::SlotVisitor):

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

14 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/GNUmakefile.list.am
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Target.pri
Source/JavaScriptCore/heap/GCThreadSharedData.cpp [new file with mode: 0644]
Source/JavaScriptCore/heap/GCThreadSharedData.h [new file with mode: 0644]
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/heap/ListableHandler.h
Source/JavaScriptCore/heap/MarkStack.cpp
Source/JavaScriptCore/heap/MarkStack.h
Source/JavaScriptCore/heap/MarkStackInlineMethods.h [new file with mode: 0644]
Source/JavaScriptCore/heap/SlotVisitor.h

index 9c18f5b..15de77a 100644 (file)
@@ -107,6 +107,7 @@ SET(JavaScriptCore_SOURCES
     heap/CopiedSpace.cpp
     heap/ConservativeRoots.cpp
     heap/DFGCodeBlocks.cpp
+    heap/GCThreadSharedData.cpp
     heap/HandleSet.cpp
     heap/HandleStack.cpp
     heap/Heap.cpp
index 4cea0d1..53b07e2 100644 (file)
@@ -1,3 +1,58 @@
+2012-08-22  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Separate MarkStackThreadSharedData from MarkStack
+        https://bugs.webkit.org/show_bug.cgi?id=94294
+
+        Reviewed by Filip Pizlo.
+
+        MarkStackThreadSharedData is soon going to have data to allow for a parallel copying 
+        mode too, so to separate our concerns we should split it out into its own set of files 
+        and rename it to GCThreadSharedData. For now this is purely a cosmetic refactoring.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Target.pri:
+        * heap/GCThreadSharedData.cpp: Added.
+        (JSC):
+        (JSC::GCThreadSharedData::resetChildren):
+        (JSC::GCThreadSharedData::childVisitCount):
+        (JSC::GCThreadSharedData::markingThreadMain):
+        (JSC::GCThreadSharedData::markingThreadStartFunc):
+        (JSC::GCThreadSharedData::GCThreadSharedData):
+        (JSC::GCThreadSharedData::~GCThreadSharedData):
+        (JSC::GCThreadSharedData::reset):
+        * heap/GCThreadSharedData.h: Added.
+        (JSC):
+        (GCThreadSharedData):
+        * heap/Heap.h:
+        (Heap):
+        * heap/ListableHandler.h:
+        (ListableHandler):
+        * heap/MarkStack.cpp:
+        (JSC::MarkStack::MarkStack):
+        (JSC::MarkStack::~MarkStack):
+        * heap/MarkStack.h:
+        (JSC):
+        (MarkStack):
+        (JSC::MarkStack::sharedData):
+        * heap/MarkStackInlineMethods.h: Added.
+        (JSC):
+        (JSC::MarkStack::append):
+        (JSC::MarkStack::appendUnbarrieredPointer):
+        (JSC::MarkStack::appendUnbarrieredValue):
+        (JSC::MarkStack::internalAppend):
+        (JSC::MarkStack::addWeakReferenceHarvester):
+        (JSC::MarkStack::addUnconditionalFinalizer):
+        (JSC::MarkStack::addOpaqueRoot):
+        (JSC::MarkStack::containsOpaqueRoot):
+        (JSC::MarkStack::opaqueRootCount):
+        * heap/SlotVisitor.h:
+        (JSC):
+        (SlotVisitor):
+        (JSC::SlotVisitor::SlotVisitor):
+
 2012-08-22  Gabor Ballabas  <gaborb@inf.u-szeged.hu>
 
         Fix JSC build when DFG-JIT is disabled
index ed79e68..bcfcb68 100644 (file)
@@ -273,6 +273,8 @@ javascriptcore_sources += \
        Source/JavaScriptCore/heap/HandleTypes.h \
        Source/JavaScriptCore/heap/BlockAllocator.cpp \
        Source/JavaScriptCore/heap/BlockAllocator.h \
+    Source/JavaScriptCore/heap/GCThreadSharedData.cpp \
+    Source/JavaScriptCore/heap/GCThreadSharedData.h \
        Source/JavaScriptCore/heap/Heap.cpp \
        Source/JavaScriptCore/heap/Heap.h \
        Source/JavaScriptCore/heap/JITStubRoutineSet.cpp \
@@ -284,6 +286,7 @@ javascriptcore_sources += \
        Source/JavaScriptCore/heap/MachineStackMarker.h \
        Source/JavaScriptCore/heap/MarkStack.cpp \
        Source/JavaScriptCore/heap/MarkStack.h \
+    Source/JavaScriptCore/heap/MarkStackInlineMethods.h \
        Source/JavaScriptCore/heap/HeapRootVisitor.h \
        Source/JavaScriptCore/heap/MarkedAllocator.cpp \
        Source/JavaScriptCore/heap/MarkedAllocator.h \
index 8695a75..78c44fe 100644 (file)
                                >
                        </File>
                        <File
+                               RelativePath="..\..\heap\GCThreadSharedData.cpp"
+                               >
+                       </File>
+                       <File
+                       RelativePath="..\..\heap\GCThreadSharedData.h"
+                       >
+                       </File>
+                       <File
                                RelativePath="..\..\heap\Heap.cpp"
                                >
                        </File>
                                >
                        </File>
                        <File
+                               RelativePath="..\..\heap\MarkStackInlineMethods.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\heap\Strong.h"
                                >
                        </File>
index 7dd87fe..f229d2d 100644 (file)
                BCF605140E203EF800B9A64D /* ArgList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF605120E203EF800B9A64D /* ArgList.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFD8C900EEB2EE700283848 /* JumpTable.cpp */; };
                BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; };
+               C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */; };
+               C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               C21122E315DD9AB300790E3A /* MarkStackInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122E015DD9AB300790E3A /* MarkStackInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C240305314B404C90079EB64 /* CopiedSpace.cpp */; };
                C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */; };
                BCF605120E203EF800B9A64D /* ArgList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgList.h; sourceTree = "<group>"; };
                BCFD8C900EEB2EE700283848 /* JumpTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JumpTable.cpp; sourceTree = "<group>"; };
                BCFD8C910EEB2EE700283848 /* JumpTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpTable.h; sourceTree = "<group>"; };
+               C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThreadSharedData.cpp; sourceTree = "<group>"; };
+               C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThreadSharedData.h; sourceTree = "<group>"; };
+               C21122E015DD9AB300790E3A /* MarkStackInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStackInlineMethods.h; sourceTree = "<group>"; };
                C240305314B404C90079EB64 /* CopiedSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CopiedSpace.cpp; sourceTree = "<group>"; };
                C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IncrementalSweeper.cpp; sourceTree = "<group>"; };
                C25F8BCC157544A900245B71 /* IncrementalSweeper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncrementalSweeper.h; sourceTree = "<group>"; };
                142E312A134FF0A600AFADB5 /* heap */ = {
                        isa = PBXGroup;
                        children = (
+                               C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */,
+                               C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */,
+                               C21122E015DD9AB300790E3A /* MarkStackInlineMethods.h */,
                                C2E526BB1590EF000054E48D /* HeapTimer.cpp */,
                                C2E526BC1590EF000054E48D /* HeapTimer.h */,
                                C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */,
                                86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
                                C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
                                C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
+                               C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */,
                                C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
+                               C21122E315DD9AB300790E3A /* MarkStackInlineMethods.h in Headers */,
                                C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
                                BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
                                BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */,
                                FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */,
                                0F63944015C75F1D006A597C /* DFGStructureCheckHoistingPhase.cpp in Sources */,
                                0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */,
+                               C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index e862236..f565c74 100644 (file)
@@ -79,6 +79,7 @@ SOURCES += \
     heap/HandleSet.cpp \
     heap/HandleStack.cpp \
     heap/BlockAllocator.cpp \
+    heap/GCThreadSharedData.cpp \
     heap/Heap.cpp \
     heap/HeapTimer.cpp \
     heap/IncrementalSweeper.cpp \
diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp
new file mode 100644 (file)
index 0000000..82c52d2
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "GCThreadSharedData.h"
+
+#include "JSGlobalData.h"
+#include "MarkStack.h"
+#include "SlotVisitor.h"
+#include <wtf/MainThread.h>
+
+namespace JSC {
+
+#if ENABLE(PARALLEL_GC)
+void GCThreadSharedData::resetChildren()
+{
+    for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i)
+        m_markingThreadsMarkStack[i]->reset();
+}
+
+size_t GCThreadSharedData::childVisitCount()
+{       
+    unsigned long result = 0;
+    for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i)
+        result += m_markingThreadsMarkStack[i]->visitCount();
+    return result;
+}
+
+void GCThreadSharedData::markingThreadMain(SlotVisitor* slotVisitor)
+{
+    WTF::registerGCThread();
+    {
+        ParallelModeEnabler enabler(*slotVisitor);
+        slotVisitor->drainFromShared(SlotVisitor::SlaveDrain);
+    }
+    delete slotVisitor;
+}
+
+void GCThreadSharedData::markingThreadStartFunc(void* myVisitor)
+{               
+    SlotVisitor* slotVisitor = static_cast<SlotVisitor*>(myVisitor);
+
+    slotVisitor->sharedData().markingThreadMain(slotVisitor);
+}
+#endif
+
+GCThreadSharedData::GCThreadSharedData(JSGlobalData* globalData)
+    : m_globalData(globalData)
+    , m_copiedSpace(&globalData->heap.m_storageSpace)
+    , m_shouldHashConst(false)
+    , m_sharedMarkStack(m_segmentAllocator)
+    , m_numberOfActiveParallelMarkers(0)
+    , m_parallelMarkersShouldExit(false)
+{
+#if ENABLE(PARALLEL_GC)
+    for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) {
+        SlotVisitor* slotVisitor = new SlotVisitor(*this);
+        m_markingThreadsMarkStack.append(slotVisitor);
+        m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking"));
+        ASSERT(m_markingThreads.last());
+    }
+#endif
+}
+
+GCThreadSharedData::~GCThreadSharedData()
+{
+#if ENABLE(PARALLEL_GC)    
+    // Destroy our marking threads.
+    {
+        MutexLocker locker(m_markingLock);
+        m_parallelMarkersShouldExit = true;
+        m_markingCondition.broadcast();
+    }
+    for (unsigned i = 0; i < m_markingThreads.size(); ++i)
+        waitForThreadCompletion(m_markingThreads[i]);
+#endif
+}
+    
+void GCThreadSharedData::reset()
+{
+    ASSERT(!m_numberOfActiveParallelMarkers);
+    ASSERT(!m_parallelMarkersShouldExit);
+    ASSERT(m_sharedMarkStack.isEmpty());
+    
+#if ENABLE(PARALLEL_GC)
+    m_segmentAllocator.shrinkReserve();
+    m_opaqueRoots.clear();
+#else
+    ASSERT(m_opaqueRoots.isEmpty());
+#endif
+    m_weakReferenceHarvesters.removeAll();
+
+    if (m_shouldHashConst) {
+        m_globalData->resetNewStringsSinceLastHashConst();
+        m_shouldHashConst = false;
+    }
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.h b/Source/JavaScriptCore/heap/GCThreadSharedData.h
new file mode 100644 (file)
index 0000000..8868b44
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef GCThreadSharedData_h
+#define GCThreadSharedData_h
+
+#include "MarkStack.h"
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class JSGlobalData;
+class CopiedSpace;
+
+class GCThreadSharedData {
+public:
+    GCThreadSharedData(JSGlobalData*);
+    ~GCThreadSharedData();
+    
+    void reset();
+
+#if ENABLE(PARALLEL_GC)
+    void resetChildren();
+    size_t childVisitCount();
+    size_t childDupStrings();
+#endif
+    
+private:
+    friend class MarkStack;
+    friend class SlotVisitor;
+
+#if ENABLE(PARALLEL_GC)
+    void markingThreadMain(SlotVisitor*);
+    static void markingThreadStartFunc(void* heap);
+#endif
+
+    JSGlobalData* m_globalData;
+    CopiedSpace* m_copiedSpace;
+    
+    MarkStackSegmentAllocator m_segmentAllocator;
+    
+    bool m_shouldHashConst;
+
+    Vector<ThreadIdentifier> m_markingThreads;
+    Vector<MarkStack*> m_markingThreadsMarkStack;
+    
+    Mutex m_markingLock;
+    ThreadCondition m_markingCondition;
+    MarkStackArray m_sharedMarkStack;
+    unsigned m_numberOfActiveParallelMarkers;
+    bool m_parallelMarkersShouldExit;
+
+    Mutex m_opaqueRootsLock;
+    HashSet<void*> m_opaqueRoots;
+
+    ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters;
+    ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers;
+};
+
+} // namespace JSC
+
+#endif
index f3474f2..6f13afb 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "BlockAllocator.h"
 #include "DFGCodeBlocks.h"
+#include "GCThreadSharedData.h"
 #include "HandleSet.h"
 #include "HandleStack.h"
 #include "JITStubRoutineSet.h"
@@ -74,7 +75,7 @@ namespace JSC {
         WTF_MAKE_NONCOPYABLE(Heap);
     public:
         friend class JIT;
-        friend class MarkStackThreadSharedData;
+        friend class GCThreadSharedData;
         static Heap* heap(const JSValue); // 0 for immediate values
         static Heap* heap(const JSCell*);
 
@@ -231,7 +232,7 @@ namespace JSC {
 
         MachineThreads m_machineThreads;
         
-        MarkStackThreadSharedData m_sharedData;
+        GCThreadSharedData m_sharedData;
         SlotVisitor m_slotVisitor;
 
         HandleSet m_handleSet;
index 2cb0325..16c3414 100644 (file)
@@ -52,7 +52,7 @@ protected:
 private:
     // Allow these classes to use ListableHandler::List.
     friend class MarkStack;
-    friend class MarkStackThreadSharedData;
+    friend class GCThreadSharedData;
     friend class SlotVisitor;
     
     class List {
index 02a1307..9d30621 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 #include "MarkStack.h"
+#include "MarkStackInlineMethods.h"
 
 #include "CopiedSpace.h"
 #include "CopiedSpaceInlineMethods.h"
@@ -223,89 +224,22 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread
         append(other.removeLast());
 }
 
-#if ENABLE(PARALLEL_GC)
-void MarkStackThreadSharedData::resetChildren()
-{
-    for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i)
-        m_markingThreadsMarkStack[i]->reset();
-}
-
-size_t MarkStackThreadSharedData::childVisitCount()
-{       
-    unsigned long result = 0;
-    for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i)
-        result += m_markingThreadsMarkStack[i]->visitCount();
-    return result;
-}
-
-void MarkStackThreadSharedData::markingThreadMain(SlotVisitor* slotVisitor)
-{
-    WTF::registerGCThread();
-    {
-        ParallelModeEnabler enabler(*slotVisitor);
-        slotVisitor->drainFromShared(SlotVisitor::SlaveDrain);
-    }
-    delete slotVisitor;
-}
-
-void MarkStackThreadSharedData::markingThreadStartFunc(void* myVisitor)
-{               
-    SlotVisitor* slotVisitor = static_cast<SlotVisitor*>(myVisitor);
-
-    slotVisitor->sharedData().markingThreadMain(slotVisitor);
-}
+MarkStack::MarkStack(GCThreadSharedData& shared)
+    : m_stack(shared.m_segmentAllocator)
+#if !ASSERT_DISABLED
+    , m_isCheckingForDefaultMarkViolation(false)
+    , m_isDraining(false)
 #endif
-
-MarkStackThreadSharedData::MarkStackThreadSharedData(JSGlobalData* globalData)
-    : m_globalData(globalData)
-    , m_copiedSpace(&globalData->heap.m_storageSpace)
+    , m_visitCount(0)
+    , m_isInParallelMode(false)
+    , m_shared(shared)
     , m_shouldHashConst(false)
-    , m_sharedMarkStack(m_segmentAllocator)
-    , m_numberOfActiveParallelMarkers(0)
-    , m_parallelMarkersShouldExit(false)
 {
-#if ENABLE(PARALLEL_GC)
-    for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) {
-        SlotVisitor* slotVisitor = new SlotVisitor(*this);
-        m_markingThreadsMarkStack.append(slotVisitor);
-        m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking"));
-        ASSERT(m_markingThreads.last());
-    }
-#endif
 }
 
-MarkStackThreadSharedData::~MarkStackThreadSharedData()
+MarkStack::~MarkStack()
 {
-#if ENABLE(PARALLEL_GC)    
-    // Destroy our marking threads.
-    {
-        MutexLocker locker(m_markingLock);
-        m_parallelMarkersShouldExit = true;
-        m_markingCondition.broadcast();
-    }
-    for (unsigned i = 0; i < m_markingThreads.size(); ++i)
-        waitForThreadCompletion(m_markingThreads[i]);
-#endif
-}
-    
-void MarkStackThreadSharedData::reset()
-{
-    ASSERT(!m_numberOfActiveParallelMarkers);
-    ASSERT(!m_parallelMarkersShouldExit);
-    ASSERT(m_sharedMarkStack.isEmpty());
-    
-#if ENABLE(PARALLEL_GC)
-    m_segmentAllocator.shrinkReserve();
-    m_opaqueRoots.clear();
-#else
-    ASSERT(m_opaqueRoots.isEmpty());
-#endif
-    m_weakReferenceHarvesters.removeAll();
-
-    if (m_shouldHashConst) {
-        m_globalData->resetNewStringsSinceLastHashConst();
-        m_shouldHashConst = false;
-    }
+    ASSERT(m_stack.isEmpty());
 }
 
 void MarkStack::setup()
index 467a5bf..54ae1cb 100644 (file)
@@ -74,6 +74,7 @@ namespace JSC {
     class ConservativeRoots;
     class JSGlobalData;
     class MarkStack;
+    class GCThreadSharedData;
     class ParallelModeEnabler;
     class Register;
     class SlotVisitor;
@@ -192,57 +193,12 @@ namespace JSC {
 #endif
     };
 
-    class MarkStackThreadSharedData {
-    public:
-        MarkStackThreadSharedData(JSGlobalData*);
-        ~MarkStackThreadSharedData();
-        
-        void reset();
-
-#if ENABLE(PARALLEL_GC)
-        void resetChildren();
-        size_t childVisitCount();
-        size_t childDupStrings();
-#endif
-    
-    private:
-        friend class MarkStack;
-        friend class SlotVisitor;
-
-#if ENABLE(PARALLEL_GC)
-        void markingThreadMain(SlotVisitor*);
-        static void markingThreadStartFunc(void* heap);
-#endif
-
-        JSGlobalData* m_globalData;
-        CopiedSpace* m_copiedSpace;
-        
-        MarkStackSegmentAllocator m_segmentAllocator;
-        
-        bool m_shouldHashConst;
-
-        Vector<ThreadIdentifier> m_markingThreads;
-        Vector<MarkStack*> m_markingThreadsMarkStack;
-        
-        Mutex m_markingLock;
-        ThreadCondition m_markingCondition;
-        MarkStackArray m_sharedMarkStack;
-        unsigned m_numberOfActiveParallelMarkers;
-        bool m_parallelMarkersShouldExit;
-
-        Mutex m_opaqueRootsLock;
-        HashSet<void*> m_opaqueRoots;
-
-        ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters;
-        ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers;
-    };
-
     class MarkStack {
         WTF_MAKE_NONCOPYABLE(MarkStack);
         friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly.
 
     public:
-        MarkStack(MarkStackThreadSharedData&);
+        MarkStack(GCThreadSharedData&);
         ~MarkStack();
 
         void append(ConservativeRoots&);
@@ -259,7 +215,7 @@ namespace JSC {
         bool containsOpaqueRoot(void*);
         int opaqueRootCount();
 
-        MarkStackThreadSharedData& sharedData() { return m_shared; }
+        GCThreadSharedData& sharedData() { return m_shared; }
         bool isEmpty() { return m_stack.isEmpty(); }
 
         void setup();
@@ -271,15 +227,8 @@ namespace JSC {
         VTableSpectrum m_visitedTypeCounts;
 #endif
 
-        void addWeakReferenceHarvester(WeakReferenceHarvester* weakReferenceHarvester)
-        {
-            m_shared.m_weakReferenceHarvesters.addThreadSafe(weakReferenceHarvester);
-        }
-        
-        void addUnconditionalFinalizer(UnconditionalFinalizer* unconditionalFinalizer)
-        {
-            m_shared.m_unconditionalFinalizers.addThreadSafe(unconditionalFinalizer);
-        }
+        void addWeakReferenceHarvester(WeakReferenceHarvester*);
+        void addUnconditionalFinalizer(UnconditionalFinalizer*);
 
 #if ENABLE(OBJECT_MARK_LOGGING)
         inline void resetChildCount() { m_logChildCount = 0; }
@@ -328,7 +277,7 @@ namespace JSC {
         size_t m_visitCount;
         bool m_isInParallelMode;
         
-        MarkStackThreadSharedData& m_shared;
+        GCThreadSharedData& m_shared;
 
         bool m_shouldHashConst; // Local per-thread copy of shared flag for performance reasons
         typedef HashMap<StringImpl*, JSValue> UniqueStringMap;
@@ -339,63 +288,6 @@ namespace JSC {
 #endif
     };
 
-    inline MarkStack::MarkStack(MarkStackThreadSharedData& shared)
-        : m_stack(shared.m_segmentAllocator)
-#if !ASSERT_DISABLED
-        , m_isCheckingForDefaultMarkViolation(false)
-        , m_isDraining(false)
-#endif
-        , m_visitCount(0)
-        , m_isInParallelMode(false)
-        , m_shared(shared)
-        , m_shouldHashConst(false)
-    {
-    }
-
-    inline MarkStack::~MarkStack()
-    {
-        ASSERT(m_stack.isEmpty());
-    }
-
-    inline void MarkStack::addOpaqueRoot(void* root)
-    {
-#if ENABLE(PARALLEL_GC)
-        if (Options::numberOfGCMarkers() == 1) {
-            // Put directly into the shared HashSet.
-            m_shared.m_opaqueRoots.add(root);
-            return;
-        }
-        // Put into the local set, but merge with the shared one every once in
-        // a while to make sure that the local sets don't grow too large.
-        mergeOpaqueRootsIfProfitable();
-        m_opaqueRoots.add(root);
-#else
-        m_opaqueRoots.add(root);
-#endif
-    }
-
-    inline bool MarkStack::containsOpaqueRoot(void* root)
-    {
-        ASSERT(!m_isInParallelMode);
-#if ENABLE(PARALLEL_GC)
-        ASSERT(m_opaqueRoots.isEmpty());
-        return m_shared.m_opaqueRoots.contains(root);
-#else
-        return m_opaqueRoots.contains(root);
-#endif
-    }
-
-    inline int MarkStack::opaqueRootCount()
-    {
-        ASSERT(!m_isInParallelMode);
-#if ENABLE(PARALLEL_GC)
-        ASSERT(m_opaqueRoots.isEmpty());
-        return m_shared.m_opaqueRoots.size();
-#else
-        return m_opaqueRoots.size();
-#endif
-    }
-
     inline void MarkStackArray::append(const JSCell* cell)
     {
         if (m_top == m_segmentCapacity)
@@ -429,51 +321,6 @@ namespace JSC {
         return m_top + m_segmentCapacity * m_numberOfPreviousSegments;
     }
 
-    ALWAYS_INLINE void MarkStack::append(JSValue* slot, size_t count)
-    {
-        for (size_t i = 0; i < count; ++i) {
-            JSValue& value = slot[i];
-            if (!value)
-                continue;
-            internalAppend(value);
-        }
-    }
-
-    template<typename T>
-    inline void MarkStack::appendUnbarrieredPointer(T** slot)
-    {
-        ASSERT(slot);
-        JSCell* cell = *slot;
-        if (cell)
-            internalAppend(cell);
-    }
-    
-    ALWAYS_INLINE void MarkStack::append(JSValue* slot)
-    {
-        ASSERT(slot);
-        internalAppend(*slot);
-    }
-
-    ALWAYS_INLINE void MarkStack::appendUnbarrieredValue(JSValue* slot)
-    {
-        ASSERT(slot);
-        internalAppend(*slot);
-    }
-
-    ALWAYS_INLINE void MarkStack::append(JSCell** slot)
-    {
-        ASSERT(slot);
-        internalAppend(*slot);
-    }
-
-    ALWAYS_INLINE void MarkStack::internalAppend(JSValue value)
-    {
-        ASSERT(value);
-        if (!value.isCell())
-            return;
-        internalAppend(value.asCell());
-    }
-
     class ParallelModeEnabler {
     public:
         ParallelModeEnabler(MarkStack& stack)
diff --git a/Source/JavaScriptCore/heap/MarkStackInlineMethods.h b/Source/JavaScriptCore/heap/MarkStackInlineMethods.h
new file mode 100644 (file)
index 0000000..8b420d6
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef MarkStackInlineMethods_h
+#define MarkStackInlineMethods_h
+
+#include "GCThreadSharedData.h"
+#include "MarkStack.h"
+
+namespace JSC {
+
+ALWAYS_INLINE void MarkStack::append(JSValue* slot, size_t count)
+{
+    for (size_t i = 0; i < count; ++i) {
+        JSValue& value = slot[i];
+        if (!value)
+            continue;
+        internalAppend(value);
+    }
+}
+
+template<typename T>
+inline void MarkStack::appendUnbarrieredPointer(T** slot)
+{
+    ASSERT(slot);
+    JSCell* cell = *slot;
+    if (cell)
+        internalAppend(cell);
+}
+
+ALWAYS_INLINE void MarkStack::append(JSValue* slot)
+{
+    ASSERT(slot);
+    internalAppend(*slot);
+}
+
+ALWAYS_INLINE void MarkStack::appendUnbarrieredValue(JSValue* slot)
+{
+    ASSERT(slot);
+    internalAppend(*slot);
+}
+
+ALWAYS_INLINE void MarkStack::append(JSCell** slot)
+{
+    ASSERT(slot);
+    internalAppend(*slot);
+}
+
+ALWAYS_INLINE void MarkStack::internalAppend(JSValue value)
+{
+    ASSERT(value);
+    if (!value.isCell())
+        return;
+    internalAppend(value.asCell());
+}
+
+inline void MarkStack::addWeakReferenceHarvester(WeakReferenceHarvester* weakReferenceHarvester)
+{
+    m_shared.m_weakReferenceHarvesters.addThreadSafe(weakReferenceHarvester);
+}
+
+inline void MarkStack::addUnconditionalFinalizer(UnconditionalFinalizer* unconditionalFinalizer)
+{
+    m_shared.m_unconditionalFinalizers.addThreadSafe(unconditionalFinalizer);
+}
+
+inline void MarkStack::addOpaqueRoot(void* root)
+{
+#if ENABLE(PARALLEL_GC)
+    if (Options::numberOfGCMarkers() == 1) {
+        // Put directly into the shared HashSet.
+        m_shared.m_opaqueRoots.add(root);
+        return;
+    }
+    // Put into the local set, but merge with the shared one every once in
+    // a while to make sure that the local sets don't grow too large.
+    mergeOpaqueRootsIfProfitable();
+    m_opaqueRoots.add(root);
+#else
+    m_opaqueRoots.add(root);
+#endif
+}
+
+inline bool MarkStack::containsOpaqueRoot(void* root)
+{
+    ASSERT(!m_isInParallelMode);
+#if ENABLE(PARALLEL_GC)
+    ASSERT(m_opaqueRoots.isEmpty());
+    return m_shared.m_opaqueRoots.contains(root);
+#else
+    return m_opaqueRoots.contains(root);
+#endif
+}
+
+inline int MarkStack::opaqueRootCount()
+{
+    ASSERT(!m_isInParallelMode);
+#if ENABLE(PARALLEL_GC)
+    ASSERT(m_opaqueRoots.isEmpty());
+    return m_shared.m_opaqueRoots.size();
+#else
+    return m_opaqueRoots.size();
+#endif
+}
+
+} // namespace JSC
+
+#endif
index a31e88c..6364b23 100644 (file)
 
 #include "CopiedSpace.h"
 #include "MarkStack.h"
+#include "MarkStackInlineMethods.h"
 
 namespace JSC {
 
 class Heap;
+class GCThreadSharedData;
 
 class SlotVisitor : public MarkStack {
     friend class HeapRootVisitor;
 public:
-    SlotVisitor(MarkStackThreadSharedData&);
+    SlotVisitor(GCThreadSharedData&);
 
     void donate()
     {
@@ -85,7 +87,7 @@ private:
     CopiedAllocator m_copiedAllocator;
 };
 
-inline SlotVisitor::SlotVisitor(MarkStackThreadSharedData& shared)
+inline SlotVisitor::SlotVisitor(GCThreadSharedData& shared)
     : MarkStack(shared)
 {
 }