r134080 causes heap problem on linux systems where PAGESIZE != 4096
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 Jan 2013 20:49:58 +0000 (20:49 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 Jan 2013 20:49:58 +0000 (20:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=102828

Patch by Balazs Kilvady <kilvadyb@homejinni.com> on 2013-01-18
Reviewed by Mark Hahnenberg.

Make MarkStackSegment::blockSize as the capacity of segments of a MarkStackArray.

* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
* heap/MarkStack.cpp:
(JSC):
(JSC::MarkStackArray::MarkStackArray):
(JSC::MarkStackArray::expand):
(JSC::MarkStackArray::donateSomeCellsTo):
(JSC::MarkStackArray::stealSomeCellsFrom):
* heap/MarkStack.h:
(JSC::MarkStackSegment::data):
(CapacityFromSize):
(MarkStackArray):
* heap/MarkStackInlines.h:
(JSC::MarkStackArray::setTopForFullSegment):
(JSC::MarkStackArray::append):
(JSC::MarkStackArray::isEmpty):
(JSC::MarkStackArray::size):
* runtime/Options.h:
(JSC):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def
Source/JavaScriptCore/heap/MarkStack.cpp
Source/JavaScriptCore/heap/MarkStack.h
Source/JavaScriptCore/heap/MarkStackInlines.h
Source/JavaScriptCore/runtime/Options.h

index 05039f0..f167e35 100644 (file)
@@ -1,3 +1,31 @@
+2013-01-18  Balazs Kilvady  <kilvadyb@homejinni.com>
+
+        r134080 causes heap problem on linux systems where PAGESIZE != 4096
+        https://bugs.webkit.org/show_bug.cgi?id=102828
+
+        Reviewed by Mark Hahnenberg.
+
+        Make MarkStackSegment::blockSize as the capacity of segments of a MarkStackArray.
+
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+        * heap/MarkStack.cpp:
+        (JSC):
+        (JSC::MarkStackArray::MarkStackArray):
+        (JSC::MarkStackArray::expand):
+        (JSC::MarkStackArray::donateSomeCellsTo):
+        (JSC::MarkStackArray::stealSomeCellsFrom):
+        * heap/MarkStack.h:
+        (JSC::MarkStackSegment::data):
+        (CapacityFromSize):
+        (MarkStackArray):
+        * heap/MarkStackInlines.h:
+        (JSC::MarkStackArray::setTopForFullSegment):
+        (JSC::MarkStackArray::append):
+        (JSC::MarkStackArray::isEmpty):
+        (JSC::MarkStackArray::size):
+        * runtime/Options.h:
+        (JSC):
+
 2013-01-18  Geoffrey Garen  <ggaren@apple.com>
 
         Weak GC maps should be easier to use
index 6ea879b..bf68eb6 100644 (file)
@@ -345,6 +345,7 @@ EXPORTS
     ?restoreAll@Profile@JSC@@QAEXXZ
     ?retrieveCallerFromVMCode@Interpreter@JSC@@QBE?AVJSValue@2@PAVExecState@2@PAVJSFunction@2@@Z
     ?retrieveLastCaller@Interpreter@JSC@@QBEXPAVExecState@2@AAH1AAVString@WTF@@AAVJSValue@2@@Z
+    ?s_segmentCapacity@MarkStackArray@JSC@@0IB
     ?save@Database@Profiler@JSC@@QBE_NPBD@Z
     ?setConfigurable@PropertyDescriptor@JSC@@QAEX_N@Z
     ?setCustomAllocation@MemoryClassInfo@WTF@@QAEX_N@Z
index 755a0ad..39907c7 100644 (file)
@@ -31,7 +31,6 @@
 #include "CopiedSpace.h"
 #include "CopiedSpaceInlines.h"
 #include "Heap.h"
-#include "Options.h"
 #include "JSArray.h"
 #include "JSCell.h"
 #include "JSObject.h"
 
 namespace JSC {
 
+COMPILE_ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize, blockSizeMatch);
+
 MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator)
     : m_blockAllocator(blockAllocator)
-    , m_segmentCapacity(MarkStackSegment::capacityFromSize(Options::gcMarkStackSegmentSize()))
     , m_top(0)
     , m_numberOfSegments(0)
 {
-    ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize);
     m_segments.push(MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>()));
     m_numberOfSegments++;
 }
@@ -64,7 +63,7 @@ MarkStackArray::~MarkStackArray()
 
 void MarkStackArray::expand()
 {
-    ASSERT(m_segments.head()->m_top == m_segmentCapacity);
+    ASSERT(m_segments.head()->m_top == s_segmentCapacity);
     
     MarkStackSegment* nextSegment = MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>());
     m_numberOfSegments++;
@@ -97,8 +96,6 @@ void MarkStackArray::donateSomeCellsTo(MarkStackArray& other)
     // we prefer donating whole segments over donating individual cells,
     // even if this skews away from our 1 / 2 target.
 
-    ASSERT(m_segmentCapacity == other.m_segmentCapacity);
-
     size_t segmentsToDonate = m_numberOfSegments / 2; // If we only have one segment (our head) we don't donate any segments.
 
     if (!segmentsToDonate) {
@@ -141,7 +138,6 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread
     // To reduce copying costs, we prefer stealing a whole segment over stealing
     // individual cells, even if this skews away from our 1 / N target.
 
-    ASSERT(m_segmentCapacity == other.m_segmentCapacity);
     validatePrevious();
     other.validatePrevious();
         
@@ -151,7 +147,7 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread
         MarkStackSegment* otherHead = other.m_segments.removeHead();
         MarkStackSegment* myHead = m_segments.removeHead();
 
-        ASSERT(other.m_segments.head()->m_top == m_segmentCapacity);
+        ASSERT(other.m_segments.head()->m_top == s_segmentCapacity);
 
         m_segments.push(other.m_segments.removeHead());
 
index 2a7f044..c97b6a7 100644 (file)
@@ -75,16 +75,6 @@ public:
     {
         return bitwise_cast<const JSCell**>(this + 1);
     }
-    
-    static size_t capacityFromSize(size_t size)
-    {
-        return (size - sizeof(MarkStackSegment)) / sizeof(const JSCell*);
-    }
-    
-    static size_t sizeFromCapacity(size_t capacity)
-    {
-        return sizeof(MarkStackSegment) + capacity * sizeof(const JSCell*);
-    }
 
     static const size_t blockSize = 4 * KB;
 
@@ -111,6 +101,10 @@ public:
     bool isEmpty();
 
 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();
@@ -124,7 +118,7 @@ private:
     DoublyLinkedList<MarkStackSegment> m_segments;
     BlockAllocator& m_blockAllocator;
 
-    size_t m_segmentCapacity;
+    JS_EXPORT_PRIVATE static const size_t s_segmentCapacity = CapacityFromSize<MarkStackSegment::blockSize>::value;
     size_t m_top;
     size_t m_numberOfSegments;
    
index 1595e84..c577de6 100644 (file)
@@ -52,8 +52,8 @@ inline size_t MarkStackArray::preDecTop()
 
 inline void MarkStackArray::setTopForFullSegment()
 {
-    ASSERT(m_segments.head()->m_top == m_segmentCapacity);
-    m_top = m_segmentCapacity;
+    ASSERT(m_segments.head()->m_top == s_segmentCapacity);
+    m_top = s_segmentCapacity;
 }
 
 inline void MarkStackArray::setTopForEmptySegment()
@@ -82,7 +82,7 @@ inline void MarkStackArray::validatePrevious()
 
 inline void MarkStackArray::append(const JSCell* cell)
 {
-    if (m_top == m_segmentCapacity)
+    if (m_top == s_segmentCapacity)
         expand();
     m_segments.head()->data()[postIncTop()] = cell;
 }
@@ -102,7 +102,7 @@ inline bool MarkStackArray::isEmpty()
     if (m_top)
         return false;
     if (m_segments.head()->next()) {
-        ASSERT(m_segments.head()->next()->m_top == m_segmentCapacity);
+        ASSERT(m_segments.head()->next()->m_top == s_segmentCapacity);
         return false;
     }
     return true;
@@ -110,7 +110,7 @@ inline bool MarkStackArray::isEmpty()
 
 inline size_t MarkStackArray::size()
 {
-    return m_top + m_segmentCapacity * (m_numberOfSegments - 1);
+    return m_top + s_segmentCapacity * (m_numberOfSegments - 1);
 }
 
 } // namespace JSC
index e4b0001..c358fae 100644 (file)
@@ -122,7 +122,6 @@ namespace JSC {
     v(double, structureCheckVoteRatioForHoisting, 1) \
     \
     v(unsigned, minimumNumberOfScansBetweenRebalance, 100) \
-    v(unsigned, gcMarkStackSegmentSize, pageSize()) \
     v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7)) \
     v(unsigned, opaqueRootMergeThreshold, 1000) \
     v(double, minHeapUtilization, 0.8) \