Title: [163414] trunk/Source/_javascript_Core
Revision
163414
Author
[email protected]
Date
2014-02-04 16:08:40 -0800 (Tue, 04 Feb 2014)

Log Message

Refactor MarkStackArray to allow more than JSCells to be stored
https://bugs.webkit.org/show_bug.cgi?id=128203

Reviewed by Geoffrey Garen.

This patch refactors MarkStackArray into a separate template class named GCSegmentedArray.
This class allows subclassing to add functionality that only MarkStackArray wants.
Since it uses the JSC BlockAllocator instead of FastMalloc, this class can be used during
conservative stack scanning, which disallows using FastMalloc.

* GNUmakefile.list.am:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
* _javascript_Core.xcodeproj/project.pbxproj:
* heap/BlockAllocator.h:
* heap/GCSegmentedArray.h: Added.
(JSC::GCArraySegment::GCArraySegment):
(JSC::GCArraySegment::data):
* heap/GCSegmentedArrayInlines.h: Added.
(JSC::GCSegmentedArray<T>::GCSegmentedArray):
(JSC::GCSegmentedArray<T>::~GCSegmentedArray):
(JSC::GCSegmentedArray<T>::clear):
(JSC::GCSegmentedArray<T>::expand):
(JSC::GCSegmentedArray<T>::refill):
(JSC::GCSegmentedArray<T>::fillVector):
(JSC::GCArraySegment<T>::create):
(JSC::GCSegmentedArray<T>::postIncTop):
(JSC::GCSegmentedArray<T>::preDecTop):
(JSC::GCSegmentedArray<T>::setTopForFullSegment):
(JSC::GCSegmentedArray<T>::setTopForEmptySegment):
(JSC::GCSegmentedArray<T>::top):
(JSC::GCSegmentedArray<T>::validatePrevious):
(JSC::GCSegmentedArray<T>::append):
(JSC::GCSegmentedArray<T>::canRemoveLast):
(JSC::GCSegmentedArray<T>::removeLast):
(JSC::GCSegmentedArray<T>::isEmpty):
(JSC::GCSegmentedArray<T>::size):
* heap/MarkStack.cpp:
(JSC::MarkStackArray::MarkStackArray):
(JSC::MarkStackArray::~MarkStackArray):
(JSC::MarkStackArray::donateSomeCellsTo):
(JSC::MarkStackArray::stealSomeCellsFrom):
* heap/MarkStack.h:
* heap/MarkStackInlines.h:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (163413 => 163414)


--- trunk/Source/_javascript_Core/ChangeLog	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-02-05 00:08:40 UTC (rev 163414)
@@ -1,3 +1,50 @@
+2014-02-04  Mark Hahnenberg  <[email protected]>
+
+        Refactor MarkStackArray to allow more than JSCells to be stored
+        https://bugs.webkit.org/show_bug.cgi?id=128203
+
+        Reviewed by Geoffrey Garen.
+
+        This patch refactors MarkStackArray into a separate template class named GCSegmentedArray.
+        This class allows subclassing to add functionality that only MarkStackArray wants.
+        Since it uses the JSC BlockAllocator instead of FastMalloc, this class can be used during 
+        conservative stack scanning, which disallows using FastMalloc.
+
+        * GNUmakefile.list.am:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * heap/BlockAllocator.h:
+        * heap/GCSegmentedArray.h: Added.
+        (JSC::GCArraySegment::GCArraySegment):
+        (JSC::GCArraySegment::data):
+        * heap/GCSegmentedArrayInlines.h: Added.
+        (JSC::GCSegmentedArray<T>::GCSegmentedArray):
+        (JSC::GCSegmentedArray<T>::~GCSegmentedArray):
+        (JSC::GCSegmentedArray<T>::clear):
+        (JSC::GCSegmentedArray<T>::expand):
+        (JSC::GCSegmentedArray<T>::refill):
+        (JSC::GCSegmentedArray<T>::fillVector):
+        (JSC::GCArraySegment<T>::create):
+        (JSC::GCSegmentedArray<T>::postIncTop):
+        (JSC::GCSegmentedArray<T>::preDecTop):
+        (JSC::GCSegmentedArray<T>::setTopForFullSegment):
+        (JSC::GCSegmentedArray<T>::setTopForEmptySegment):
+        (JSC::GCSegmentedArray<T>::top):
+        (JSC::GCSegmentedArray<T>::validatePrevious):
+        (JSC::GCSegmentedArray<T>::append):
+        (JSC::GCSegmentedArray<T>::canRemoveLast):
+        (JSC::GCSegmentedArray<T>::removeLast):
+        (JSC::GCSegmentedArray<T>::isEmpty):
+        (JSC::GCSegmentedArray<T>::size):
+        * heap/MarkStack.cpp:
+        (JSC::MarkStackArray::MarkStackArray):
+        (JSC::MarkStackArray::~MarkStackArray):
+        (JSC::MarkStackArray::donateSomeCellsTo):
+        (JSC::MarkStackArray::stealSomeCellsFrom):
+        * heap/MarkStack.h:
+        * heap/MarkStackInlines.h:
+
 2014-02-04  Anders Carlsson  <[email protected]>
 
         Rename the substring sharing StringImpl::create variants to better indicate what they do

Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (163413 => 163414)


--- trunk/Source/_javascript_Core/GNUmakefile.list.am	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am	2014-02-05 00:08:40 UTC (rev 163414)
@@ -514,6 +514,8 @@
     Source/_javascript_Core/heap/DeferGC.cpp \
 	Source/_javascript_Core/heap/DeferGC.h \
     Source/_javascript_Core/heap/DelayedReleaseScope.h \
+	Source/_javascript_Core/heap/GCSegmentedArray.h \
+	Source/_javascript_Core/heap/GCSegmentedArrayInlines.h \
 	Source/_javascript_Core/heap/GCAssertions.h \
 	Source/_javascript_Core/heap/GCIncomingRefCounted.h \
 	Source/_javascript_Core/heap/GCIncomingRefCountedInlines.h \
@@ -556,7 +558,6 @@
 	Source/_javascript_Core/heap/MachineStackMarker.h \
 	Source/_javascript_Core/heap/MarkStack.cpp \
 	Source/_javascript_Core/heap/MarkStack.h \
-	Source/_javascript_Core/heap/MarkStackInlines.h \
 	Source/_javascript_Core/heap/HeapRootVisitor.h \
 	Source/_javascript_Core/heap/MarkedAllocator.cpp \
 	Source/_javascript_Core/heap/MarkedAllocator.h \

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (163413 => 163414)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2014-02-05 00:08:40 UTC (rev 163414)
@@ -1008,6 +1008,8 @@
     <ClInclude Include="..\heap\CopyWriteBarrier.h" />
     <ClInclude Include="..\heap\DeferGC.h" />
     <ClInclude Include="..\heap\DelayedReleaseScope.h" />
+    <ClInclude Include="..\heap\GCSegmentedArray.h" />
+    <ClInclude Include="..\heap\GCSegmentedArrayInlines.h" />
     <ClInclude Include="..\heap\GCAssertions.h" />
     <ClInclude Include="..\heap\GCThread.h" />
     <ClInclude Include="..\heap\GCThreadSharedData.h" />
@@ -1034,7 +1036,6 @@
     <ClInclude Include="..\heap\MarkedBlockSet.h" />
     <ClInclude Include="..\heap\MarkedSpace.h" />
     <ClInclude Include="..\heap\MarkStack.h" />
-    <ClInclude Include="..\heap\MarkStackInlines.h" />
     <ClInclude Include="..\heap\RecursiveAllocationScope.h" />
     <ClInclude Include="..\heap\Region.h" />
     <ClInclude Include="..\heap\SlotVisitor.h" />

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters (163413 => 163414)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters	2014-02-05 00:08:40 UTC (rev 163414)
@@ -1655,6 +1655,12 @@
     <ClInclude Include="..\heap\DeferGC.h">
       <Filter>heap</Filter>
     </ClInclude>
+    <ClInclude Include="..\heap\GCSegmentedArray.h">
+      <Filter>heap</Filter>
+    </ClInclude>
+    <ClInclude Include="..\heap\GCSegmentedArrayInlines.h">
+      <Filter>heap</Filter>
+    </ClInclude>
     <ClInclude Include="..\heap\GCAssertions.h">
       <Filter>heap</Filter>
     </ClInclude>
@@ -1733,9 +1739,6 @@
     <ClInclude Include="..\heap\MarkStack.h">
       <Filter>heap</Filter>
     </ClInclude>
-    <ClInclude Include="..\heap\MarkStackInlines.h">
-      <Filter>heap</Filter>
-    </ClInclude>
     <ClInclude Include="..\heap\RecursiveAllocationScope.h">
       <Filter>heap</Filter>
     </ClInclude>

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (163413 => 163414)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2014-02-05 00:08:40 UTC (rev 163414)
@@ -740,6 +740,8 @@
 		2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */; };
 		2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */ = {isa = PBXBuildFile; fileRef = 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */; };
 		2A2825D018341F2D0087FBA9 /* DelayedReleaseScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */; };
+		2A343F7618A1748B0039B085 /* GCSegmentedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A343F7418A1748B0039B085 /* GCSegmentedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		2A343F7818A1749D0039B085 /* GCSegmentedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = C211B574176A224D000E2A23 /* APICallbackFunction.h */; };
 		2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */; };
 		2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1307,7 +1309,6 @@
 		C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		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 /* MarkStackInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122E015DD9AB300790E3A /* MarkStackInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C218D1401655CFD50062BB81 /* CopyWorkList.h in Headers */ = {isa = PBXBuildFile; fileRef = C218D13F1655CFD50062BB81 /* CopyWorkList.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */; };
@@ -2127,6 +2128,8 @@
 		2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringJoiner.cpp; sourceTree = "<group>"; };
 		2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringJoiner.h; sourceTree = "<group>"; };
 		2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DelayedReleaseScope.h; sourceTree = "<group>"; };
+		2A343F7418A1748B0039B085 /* GCSegmentedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCSegmentedArray.h; sourceTree = "<group>"; };
+		2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCSegmentedArrayInlines.h; sourceTree = "<group>"; };
 		2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierBuffer.cpp; sourceTree = "<group>"; };
 		2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierBuffer.h; sourceTree = "<group>"; };
 		2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyWriteBarrier.h; sourceTree = "<group>"; };
@@ -2738,7 +2741,6 @@
 		C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareDataInlines.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 /* MarkStackInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStackInlines.h; sourceTree = "<group>"; };
 		C211B574176A224D000E2A23 /* APICallbackFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APICallbackFunction.h; sourceTree = "<group>"; };
 		C218D13F1655CFD50062BB81 /* CopyWorkList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyWorkList.h; sourceTree = "<group>"; };
 		C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CopyVisitor.cpp; sourceTree = "<group>"; };
@@ -3366,7 +3368,6 @@
 				14D2F3D9139F4BE200491031 /* MarkedSpace.h */,
 				142D6F0E13539A4100B02E86 /* MarkStack.cpp */,
 				142D6F0F13539A4100B02E86 /* MarkStack.h */,
-				C21122E015DD9AB300790E3A /* MarkStackInlines.h */,
 				C20B25981706536200C21F4E /* Region.h */,
 				C225494215F7DBAA0065E898 /* SlotVisitor.cpp */,
 				14BA78F013AAB88F005B7C2C /* SlotVisitor.h */,
@@ -3394,6 +3395,8 @@
 				2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */,
 				2AAD964918569417001F93BE /* RecursiveAllocationScope.h */,
 				2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */,
+				2A343F7418A1748B0039B085 /* GCSegmentedArray.h */,
+				2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */,
 			);
 			path = heap;
 			sourceTree = "<group>";
@@ -4633,6 +4636,8 @@
 				86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
 				86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
 				A5CEEE15187F3BAD00E55C99 /* InspectorAgent.h in Headers */,
+				2A343F7618A1748B0039B085 /* GCSegmentedArray.h in Headers */,
+				2A343F7818A1749D0039B085 /* GCSegmentedArrayInlines.h in Headers */,
 				65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */,
 				2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */,
 				2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */,
@@ -5177,7 +5182,6 @@
 				141448CB13A176EC00F5BA1A /* MarkedBlockSet.h in Headers */,
 				14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */,
 				142D6F1213539A4100B02E86 /* MarkStack.h in Headers */,
-				C21122E315DD9AB300790E3A /* MarkStackInlines.h in Headers */,
 				A5945595182479EB00CC3843 /* InspectorFrontendChannel.h in Headers */,
 				8612E4CD152389EC00C836BE /* MatchResult.h in Headers */,
 				A5840E21187B7B8600843B10 /* InjectedScriptModule.h in Headers */,

Modified: trunk/Source/_javascript_Core/heap/BlockAllocator.h (163413 => 163414)


--- trunk/Source/_javascript_Core/heap/BlockAllocator.h	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/heap/BlockAllocator.h	2014-02-05 00:08:40 UTC (rev 163414)
@@ -41,9 +41,10 @@
 class BlockAllocator;
 class CopiedBlock;
 class CopyWorkListSegment;
+template <typename T> class GCArraySegment;
 class HandleBlock;
+class JSCell;
 class VM;
-class MarkStackSegment;
 class MarkedBlock;
 class WeakBlock;
 
@@ -95,7 +96,7 @@
     SuperRegion m_superRegion;
     RegionSet m_copiedRegionSet;
     RegionSet m_markedRegionSet;
-    // WeakBlocks and MarkStackSegments use the same RegionSet since they're the same size.
+    // WeakBlocks and GCArraySegments use the same RegionSet since they're the same size.
     RegionSet m_fourKBBlockRegionSet;
     RegionSet m_workListRegionSet;
 
@@ -235,7 +236,7 @@
 }
 
 template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<MarkStackSegment>()
+inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<GCArraySegment<const JSCell*>>()
 {
     return m_fourKBBlockRegionSet;
 }
@@ -271,7 +272,7 @@
 }
 
 template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<MarkStackSegment>>()
+inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<GCArraySegment<const JSCell*>>>()
 {
     return m_fourKBBlockRegionSet;
 }

Added: trunk/Source/_javascript_Core/heap/GCSegmentedArray.h (0 => 163414)


--- trunk/Source/_javascript_Core/heap/GCSegmentedArray.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/heap/GCSegmentedArray.h	2014-02-05 00:08:40 UTC (rev 163414)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 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. AND ITS CONTRIBUTORS ``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 ITS 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 GCSegmentedArray_h
+#define GCSegmentedArray_h
+
+#include "HeapBlock.h"
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class BlockAllocator;
+class DeadBlock;
+
+template <typename T>
+class GCArraySegment : public HeapBlock<GCArraySegment<T>> {
+public:
+    GCArraySegment(Region* region)
+        : HeapBlock<GCArraySegment>(region)
+#if !ASSERT_DISABLED
+        , m_top(0)
+#endif
+    {
+    }
+
+    static GCArraySegment* create(DeadBlock*);
+
+    T* data()
+    {
+        return bitwise_cast<T*>(this + 1);
+    }
+
+    static const size_t blockSize = 4 * KB;
+
+#if !ASSERT_DISABLED
+    size_t m_top;
+#endif
+};
+
+template <typename T>
+class GCSegmentedArray {
+public:
+    GCSegmentedArray(BlockAllocator&);
+    ~GCSegmentedArray();
+
+    void append(T);
+
+    bool canRemoveLast();
+    const T removeLast();
+    bool refill();
+    
+    size_t size();
+    bool isEmpty();
+
+    void fillVector(Vector<T>&);
+    void clear();
+
+protected:
+    template <size_t size> struct CapacityFromSize {
+        static const size_t value = (size - sizeof(GCArraySegment<T>)) / sizeof(T);
+    };
+
+    void expand();
+    
+    size_t postIncTop();
+    size_t preDecTop();
+    void setTopForFullSegment();
+    void setTopForEmptySegment();
+    size_t top();
+    
+    void validatePrevious();
+
+    DoublyLinkedList<GCArraySegment<T>> m_segments;
+    BlockAllocator& m_blockAllocator;
+
+    JS_EXPORT_PRIVATE static const size_t s_segmentCapacity = CapacityFromSize<GCArraySegment<T>::blockSize>::value;
+    size_t m_top;
+    size_t m_numberOfSegments;
+};
+
+} // namespace JSC
+
+#endif // GCSegmentedArray_h

Added: trunk/Source/_javascript_Core/heap/GCSegmentedArrayInlines.h (0 => 163414)


--- trunk/Source/_javascript_Core/heap/GCSegmentedArrayInlines.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/heap/GCSegmentedArrayInlines.h	2014-02-05 00:08:40 UTC (rev 163414)
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2014 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. AND ITS CONTRIBUTORS ``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 ITS 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 GCSegmentedArrayInlines_h
+#define GCSegmentedArrayInlines_h
+
+#include "BlockAllocator.h"
+#include "GCSegmentedArray.h"
+
+namespace JSC {
+
+template <typename T>
+GCSegmentedArray<T>::GCSegmentedArray(BlockAllocator& blockAllocator)
+    : m_blockAllocator(blockAllocator)
+    , m_top(0)
+    , m_numberOfSegments(0)
+{
+    m_segments.push(GCArraySegment<T>::create(m_blockAllocator.allocate<GCArraySegment<T>>()));
+    m_numberOfSegments++;
+}
+
+template <typename T>
+GCSegmentedArray<T>::~GCSegmentedArray()
+{
+    ASSERT(m_numberOfSegments == 1);
+    ASSERT(m_segments.size() == 1);
+    m_blockAllocator.deallocate(GCArraySegment<T>::destroy(m_segments.removeHead()));
+    m_numberOfSegments--;
+    ASSERT(!m_numberOfSegments);
+    ASSERT(!m_segments.size());
+}
+
+template <typename T>
+void GCSegmentedArray<T>::clear()
+{
+    if (!m_segments.head())
+        return;
+    GCArraySegment<T>* next;
+    for (GCArraySegment<T>* current = m_segments.head(); current->next(); current = next) {
+        next = current->next();
+        m_segments.remove(current);
+        m_blockAllocator.deallocate(GCArraySegment<T>::destroy(current));
+    }
+    m_top = 0;
+    m_numberOfSegments = 1;
+#if !ASSERT_DISABLED
+    m_segments.head()->m_top = 0;
+#endif
+}
+
+template <typename T>
+void GCSegmentedArray<T>::expand()
+{
+    ASSERT(m_segments.head()->m_top == s_segmentCapacity);
+    
+    GCArraySegment<T>* nextSegment = GCArraySegment<T>::create(m_blockAllocator.allocate<GCArraySegment<T>>());
+    m_numberOfSegments++;
+    
+#if !ASSERT_DISABLED
+    nextSegment->m_top = 0;
+#endif
+
+    m_segments.push(nextSegment);
+    setTopForEmptySegment();
+    validatePrevious();
+}
+
+template <typename T>
+bool GCSegmentedArray<T>::refill()
+{
+    validatePrevious();
+    if (top())
+        return true;
+    m_blockAllocator.deallocate(GCArraySegment<T>::destroy(m_segments.removeHead()));
+    ASSERT(m_numberOfSegments > 1);
+    m_numberOfSegments--;
+    setTopForFullSegment();
+    validatePrevious();
+    return true;
+}
+
+template <typename T>
+void GCSegmentedArray<T>::fillVector(Vector<T>& vector)
+{
+    ASSERT(vector.size() == size());
+
+    GCArraySegment<T>* currentSegment = m_segments.head();
+    if (!currentSegment)
+        return;
+
+    unsigned count = 0;
+    for (unsigned i = 0; i < m_top; ++i) {
+        ASSERT(currentSegment->data()[i]);
+        vector[count++] = currentSegment->data()[i];
+    }
+
+    currentSegment = currentSegment->next();
+    while (currentSegment) {
+        for (unsigned i = 0; i < s_segmentCapacity; ++i) {
+            ASSERT(currentSegment->data()[i]);
+            vector[count++] = currentSegment->data()[i];
+        }
+        currentSegment = currentSegment->next();
+    }
+}
+
+template <typename T>
+inline GCArraySegment<T>* GCArraySegment<T>::create(DeadBlock* block)
+{
+    return new (NotNull, block) GCArraySegment<T>(block->region());
+}
+
+template <typename T>
+inline size_t GCSegmentedArray<T>::postIncTop()
+{
+    size_t result = m_top++;
+    ASSERT(result == m_segments.head()->m_top++);
+    return result;
+}
+
+template <typename T>
+inline size_t GCSegmentedArray<T>::preDecTop()
+{
+    size_t result = --m_top;
+    ASSERT(result == --m_segments.head()->m_top);
+    return result;
+}
+
+template <typename T>
+inline void GCSegmentedArray<T>::setTopForFullSegment()
+{
+    ASSERT(m_segments.head()->m_top == s_segmentCapacity);
+    m_top = s_segmentCapacity;
+}
+
+template <typename T>
+inline void GCSegmentedArray<T>::setTopForEmptySegment()
+{
+    ASSERT(!m_segments.head()->m_top);
+    m_top = 0;
+}
+
+template <typename T>
+inline size_t GCSegmentedArray<T>::top()
+{
+    ASSERT(m_top == m_segments.head()->m_top);
+    return m_top;
+}
+
+template <typename T>
+#if ASSERT_DISABLED
+inline void GCSegmentedArray<T>::validatePrevious() { }
+#else
+inline void GCSegmentedArray<T>::validatePrevious()
+{
+    unsigned count = 0;
+    for (GCArraySegment<T>* current = m_segments.head(); current; current = current->next())
+        count++;
+    ASSERT(m_segments.size() == m_numberOfSegments);
+}
+#endif
+
+template <typename T>
+inline void GCSegmentedArray<T>::append(T value)
+{
+    if (m_top == s_segmentCapacity)
+        expand();
+    m_segments.head()->data()[postIncTop()] = value;
+}
+
+template <typename T>
+inline bool GCSegmentedArray<T>::canRemoveLast()
+{
+    return !!m_top;
+}
+
+template <typename T>
+inline const T GCSegmentedArray<T>::removeLast()
+{
+    return m_segments.head()->data()[preDecTop()];
+}
+
+template <typename T>
+inline bool GCSegmentedArray<T>::isEmpty()
+{
+    if (m_top)
+        return false;
+    if (m_segments.head()->next()) {
+        ASSERT(m_segments.head()->next()->m_top == s_segmentCapacity);
+        return false;
+    }
+    return true;
+}
+
+template <typename T>
+inline size_t GCSegmentedArray<T>::size()
+{
+    return m_top + s_segmentCapacity * (m_numberOfSegments - 1);
+}
+
+} // namespace JSC
+
+#endif // GCSegmentedArrayInlines_h

Modified: trunk/Source/_javascript_Core/heap/MarkStack.cpp (163413 => 163414)


--- trunk/Source/_javascript_Core/heap/MarkStack.cpp	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/heap/MarkStack.cpp	2014-02-05 00:08:40 UTC (rev 163414)
@@ -25,92 +25,14 @@
 
 #include "config.h"
 #include "MarkStack.h"
-#include "MarkStackInlines.h"
 
-#include "ConservativeRoots.h"
-#include "CopiedSpace.h"
-#include "CopiedSpaceInlines.h"
-#include "Heap.h"
-#include "JSArray.h"
-#include "JSCell.h"
-#include "JSObject.h"
-
-#include "SlotVisitorInlines.h"
-#include "Structure.h"
-#include "WriteBarrier.h"
-#include <wtf/Atomics.h>
-#include <wtf/DataLog.h>
-#include <wtf/MainThread.h>
-
 namespace JSC {
 
-COMPILE_ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize, blockSizeMatch);
-
 MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator)
-    : m_blockAllocator(blockAllocator)
-    , m_top(0)
-    , m_numberOfSegments(0)
+    : GCSegmentedArray<const JSCell*>(blockAllocator)
 {
-    m_segments.push(MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>()));
-    m_numberOfSegments++;
 }
 
-MarkStackArray::~MarkStackArray()
-{
-    ASSERT(m_numberOfSegments == 1);
-    ASSERT(m_segments.size() == 1);
-    m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead()));
-    m_numberOfSegments--;
-    ASSERT(!m_numberOfSegments);
-    ASSERT(!m_segments.size());
-}
-
-void MarkStackArray::clear()
-{
-    if (!m_segments.head())
-        return;
-    MarkStackSegment* next;
-    for (MarkStackSegment* current = m_segments.head(); current->next(); current = next) {
-        next = current->next();
-        m_segments.remove(current);
-        m_blockAllocator.deallocate(MarkStackSegment::destroy(current));
-    }
-    m_top = 0;
-    m_numberOfSegments = 1;
-#if !ASSERT_DISABLED
-    m_segments.head()->m_top = 0;
-#endif
-}
-
-void MarkStackArray::expand()
-{
-    ASSERT(m_segments.head()->m_top == s_segmentCapacity);
-    
-    MarkStackSegment* nextSegment = MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>());
-    m_numberOfSegments++;
-    
-#if !ASSERT_DISABLED
-    nextSegment->m_top = 0;
-#endif
-
-    m_segments.push(nextSegment);
-    setTopForEmptySegment();
-    validatePrevious();
-}
-
-bool MarkStackArray::refill()
-{
-    validatePrevious();
-    if (top())
-        return true;
-    m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead()));
-    ASSERT(m_numberOfSegments > 1);
-    m_numberOfSegments--;
-    setTopForFullSegment();
-    validatePrevious();
-    return true;
-}
-
 void MarkStackArray::donateSomeCellsTo(MarkStackArray& other)
 {
     // Try to donate about 1 / 2 of our cells. To reduce copying costs,
@@ -133,11 +55,11 @@
 
     // Remove our head and the head of the other list before we start moving segments around.
     // We'll add them back on once we're done donating.
-    MarkStackSegment* myHead = m_segments.removeHead();
-    MarkStackSegment* otherHead = other.m_segments.removeHead();
+    GCArraySegment<const JSCell*>* myHead = m_segments.removeHead();
+    GCArraySegment<const JSCell*>* otherHead = other.m_segments.removeHead();
 
     while (segmentsToDonate--) {
-        MarkStackSegment* current = m_segments.removeHead();
+        GCArraySegment<const JSCell*>* current = m_segments.removeHead();
         ASSERT(current);
         ASSERT(m_numberOfSegments > 1);
         other.m_segments.push(current);
@@ -165,8 +87,8 @@
     // If other has an entire segment, steal it and return.
     if (other.m_numberOfSegments > 1) {
         // Move the heads of the lists aside. We'll push them back on after.
-        MarkStackSegment* otherHead = other.m_segments.removeHead();
-        MarkStackSegment* myHead = m_segments.removeHead();
+        GCArraySegment<const JSCell*>* otherHead = other.m_segments.removeHead();
+        GCArraySegment<const JSCell*>* myHead = m_segments.removeHead();
 
         ASSERT(other.m_segments.head()->m_top == s_segmentCapacity);
 
@@ -188,28 +110,4 @@
         append(other.removeLast());
 }
 
-void MarkStackArray::fillVector(Vector<const JSCell*>& vector)
-{
-    ASSERT(vector.size() == size());
-
-    MarkStackSegment* currentSegment = m_segments.head();
-    if (!currentSegment)
-        return;
-
-    unsigned count = 0;
-    for (unsigned i = 0; i < m_top; ++i) {
-        ASSERT(currentSegment->data()[i]);
-        vector[count++] = currentSegment->data()[i];
-    }
-
-    currentSegment = currentSegment->next();
-    while (currentSegment) {
-        for (unsigned i = 0; i < s_segmentCapacity; ++i) {
-            ASSERT(currentSegment->data()[i]);
-            vector[count++] = currentSegment->data()[i];
-        }
-        currentSegment = currentSegment->next();
-    }
-}
-
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/heap/MarkStack.h (163413 => 163414)


--- trunk/Source/_javascript_Core/heap/MarkStack.h	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/heap/MarkStack.h	2014-02-05 00:08:40 UTC (rev 163414)
@@ -50,82 +50,18 @@
 #define MARK_LOG_CHILD(visitor, child) do { } while (false)
 #endif
 
-#include "HeapBlock.h"
-#include <wtf/StdLibExtras.h>
-#include <wtf/Vector.h>
+#include "GCSegmentedArrayInlines.h"
 
 namespace JSC {
 
-class BlockAllocator;
-class DeadBlock;
 class JSCell;
 
-class MarkStackSegment : public HeapBlock<MarkStackSegment> {
+class MarkStackArray : public GCSegmentedArray<const JSCell*> {
 public:
-    MarkStackSegment(Region* region)
-        : HeapBlock<MarkStackSegment>(region)
-#if !ASSERT_DISABLED
-        , m_top(0)
-#endif
-    {
-    }
-
-    static MarkStackSegment* create(DeadBlock*);
-
-    const JSCell** data()
-    {
-        return bitwise_cast<const JSCell**>(this + 1);
-    }
-
-    static const size_t blockSize = 4 * KB;
-
-#if !ASSERT_DISABLED
-    size_t m_top;
-#endif
-};
-
-class MarkStackArray {
-public:
     MarkStackArray(BlockAllocator&);
-    ~MarkStackArray();
 
-    void append(const JSCell*);
-
-    bool canRemoveLast();
-    const JSCell* removeLast();
-    bool refill();
-    
     void donateSomeCellsTo(MarkStackArray& other);
     void stealSomeCellsFrom(MarkStackArray& other, size_t idleThreadCount);
-
-    size_t size();
-    bool isEmpty();
-
-    void fillVector(Vector<const JSCell*>&);
-    void clear();
-
-private:
-    template <size_t size> struct CapacityFromSize {
-        static const size_t value = (size - sizeof(MarkStackSegment)) / sizeof(const JSCell*);
-    };
-
-    JS_EXPORT_PRIVATE void expand();
-    
-    size_t postIncTop();
-    size_t preDecTop();
-    void setTopForFullSegment();
-    void setTopForEmptySegment();
-    size_t top();
-    
-    void validatePrevious();
-
-    DoublyLinkedList<MarkStackSegment> m_segments;
-    BlockAllocator& m_blockAllocator;
-
-    JS_EXPORT_PRIVATE static const size_t s_segmentCapacity = CapacityFromSize<MarkStackSegment::blockSize>::value;
-    size_t m_top;
-    size_t m_numberOfSegments;
-   
 };
 
 } // namespace JSC

Deleted: trunk/Source/_javascript_Core/heap/MarkStackInlines.h (163413 => 163414)


--- trunk/Source/_javascript_Core/heap/MarkStackInlines.h	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/heap/MarkStackInlines.h	2014-02-05 00:08:40 UTC (rev 163414)
@@ -1,119 +0,0 @@
-/*
- * 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 MarkStackInlines_h
-#define MarkStackInlines_h
-
-#include "GCThreadSharedData.h"
-#include "MarkStack.h"
-
-namespace JSC {
-
-inline MarkStackSegment* MarkStackSegment::create(DeadBlock* block)
-{
-    return new (NotNull, block) MarkStackSegment(block->region());
-}
-
-inline size_t MarkStackArray::postIncTop()
-{
-    size_t result = m_top++;
-    ASSERT(result == m_segments.head()->m_top++);
-    return result;
-}
-
-inline size_t MarkStackArray::preDecTop()
-{
-    size_t result = --m_top;
-    ASSERT(result == --m_segments.head()->m_top);
-    return result;
-}
-
-inline void MarkStackArray::setTopForFullSegment()
-{
-    ASSERT(m_segments.head()->m_top == s_segmentCapacity);
-    m_top = s_segmentCapacity;
-}
-
-inline void MarkStackArray::setTopForEmptySegment()
-{
-    ASSERT(!m_segments.head()->m_top);
-    m_top = 0;
-}
-
-inline size_t MarkStackArray::top()
-{
-    ASSERT(m_top == m_segments.head()->m_top);
-    return m_top;
-}
-
-#if ASSERT_DISABLED
-inline void MarkStackArray::validatePrevious() { }
-#else
-inline void MarkStackArray::validatePrevious()
-{
-    unsigned count = 0;
-    for (MarkStackSegment* current = m_segments.head(); current; current = current->next())
-        count++;
-    ASSERT(m_segments.size() == m_numberOfSegments);
-}
-#endif
-
-inline void MarkStackArray::append(const JSCell* cell)
-{
-    if (m_top == s_segmentCapacity)
-        expand();
-    m_segments.head()->data()[postIncTop()] = cell;
-}
-
-inline bool MarkStackArray::canRemoveLast()
-{
-    return !!m_top;
-}
-
-inline const JSCell* MarkStackArray::removeLast()
-{
-    return m_segments.head()->data()[preDecTop()];
-}
-
-inline bool MarkStackArray::isEmpty()
-{
-    if (m_top)
-        return false;
-    if (m_segments.head()->next()) {
-        ASSERT(m_segments.head()->next()->m_top == s_segmentCapacity);
-        return false;
-    }
-    return true;
-}
-
-inline size_t MarkStackArray::size()
-{
-    return m_top + s_segmentCapacity * (m_numberOfSegments - 1);
-}
-
-} // namespace JSC
-
-#endif // MarkStackInlines_h
-

Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.h (163413 => 163414)


--- trunk/Source/_javascript_Core/heap/SlotVisitor.h	2014-02-04 23:57:22 UTC (rev 163413)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.h	2014-02-05 00:08:40 UTC (rev 163414)
@@ -28,8 +28,9 @@
 
 #include "CopyToken.h"
 #include "HandleTypes.h"
-#include "MarkStackInlines.h"
+#include "MarkStack.h"
 
+#include <wtf/HashSet.h>
 #include <wtf/text/StringHash.h>
 
 namespace JSC {
@@ -37,9 +38,11 @@
 class ConservativeRoots;
 class GCThreadSharedData;
 class Heap;
+template<typename T> class JITWriteBarrier;
+class UnconditionalFinalizer;
 template<typename T> class Weak;
+class WeakReferenceHarvester;
 template<typename T> class WriteBarrierBase;
-template<typename T> class JITWriteBarrier;
 
 class SlotVisitor {
     WTF_MAKE_NONCOPYABLE(SlotVisitor);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to