Title: [155317] trunk/Source/_javascript_Core
Revision
155317
Author
[email protected]
Date
2013-09-08 17:11:57 -0700 (Sun, 08 Sep 2013)

Log Message

Calculating the size of the Heap should not require walking over it
https://bugs.webkit.org/show_bug.cgi?id=120910

Reviewed by Geoffrey Garen.

Currently Heap::size() is O(sizeof(Heap)). This is too expensive to 
call during a collection. We should keep a count of visited and copied 
bytes as each collection progresses so as to avoid re-walking the Heap 
at the end of collection.

* heap/GCThreadSharedData.cpp:
(JSC::GCThreadSharedData::childBytesVisited):
(JSC::GCThreadSharedData::childBytesCopied):
* heap/GCThreadSharedData.h:
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::markRoots):
(JSC::Heap::sizeAfterCollect):
(JSC::Heap::collect):
* heap/Heap.h:
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::SlotVisitor):
(JSC::SlotVisitor::reset):
* heap/SlotVisitor.h:
(JSC::SlotVisitor::bytesVisited):
(JSC::SlotVisitor::bytesCopied):
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::internalAppend):
(JSC::SlotVisitor::copyLater):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (155316 => 155317)


--- trunk/Source/_javascript_Core/ChangeLog	2013-09-08 23:36:40 UTC (rev 155316)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-09-09 00:11:57 UTC (rev 155317)
@@ -1,5 +1,37 @@
 2013-09-08  Mark Hahnenberg  <[email protected]>
 
+        Calculating the size of the Heap should not require walking over it
+        https://bugs.webkit.org/show_bug.cgi?id=120910
+
+        Reviewed by Geoffrey Garen.
+
+        Currently Heap::size() is O(sizeof(Heap)). This is too expensive to 
+        call during a collection. We should keep a count of visited and copied 
+        bytes as each collection progresses so as to avoid re-walking the Heap 
+        at the end of collection.
+
+        * heap/GCThreadSharedData.cpp:
+        (JSC::GCThreadSharedData::childBytesVisited):
+        (JSC::GCThreadSharedData::childBytesCopied):
+        * heap/GCThreadSharedData.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::markRoots):
+        (JSC::Heap::sizeAfterCollect):
+        (JSC::Heap::collect):
+        * heap/Heap.h:
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::SlotVisitor):
+        (JSC::SlotVisitor::reset):
+        * heap/SlotVisitor.h:
+        (JSC::SlotVisitor::bytesVisited):
+        (JSC::SlotVisitor::bytesCopied):
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::internalAppend):
+        (JSC::SlotVisitor::copyLater):
+
+2013-09-08  Mark Hahnenberg  <[email protected]>
+
         Clearing MarkedBlock::m_newlyAllocated should be separate from MarkedBlock::clearMarks
         https://bugs.webkit.org/show_bug.cgi?id=121007
 

Modified: trunk/Source/_javascript_Core/heap/GCThreadSharedData.cpp (155316 => 155317)


--- trunk/Source/_javascript_Core/heap/GCThreadSharedData.cpp	2013-09-08 23:36:40 UTC (rev 155316)
+++ trunk/Source/_javascript_Core/heap/GCThreadSharedData.cpp	2013-09-09 00:11:57 UTC (rev 155317)
@@ -50,6 +50,22 @@
         result += m_gcThreads[i]->slotVisitor()->visitCount();
     return result;
 }
+
+size_t GCThreadSharedData::childBytesVisited()
+{       
+    size_t result = 0;
+    for (unsigned i = 0; i < m_gcThreads.size(); ++i)
+        result += m_gcThreads[i]->slotVisitor()->bytesVisited();
+    return result;
+}
+
+size_t GCThreadSharedData::childBytesCopied()
+{       
+    size_t result = 0;
+    for (unsigned i = 0; i < m_gcThreads.size(); ++i)
+        result += m_gcThreads[i]->slotVisitor()->bytesCopied();
+    return result;
+}
 #endif
 
 GCThreadSharedData::GCThreadSharedData(VM* vm)

Modified: trunk/Source/_javascript_Core/heap/GCThreadSharedData.h (155316 => 155317)


--- trunk/Source/_javascript_Core/heap/GCThreadSharedData.h	2013-09-08 23:36:40 UTC (rev 155316)
+++ trunk/Source/_javascript_Core/heap/GCThreadSharedData.h	2013-09-09 00:11:57 UTC (rev 155317)
@@ -65,6 +65,8 @@
 #if ENABLE(PARALLEL_GC)
     void resetChildren();
     size_t childVisitCount();
+    size_t childBytesVisited();
+    size_t childBytesCopied();
     size_t childDupStrings();
 #endif
     

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (155316 => 155317)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2013-09-08 23:36:40 UTC (rev 155316)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2013-09-09 00:11:57 UTC (rev 155317)
@@ -251,6 +251,8 @@
     , m_bytesAllocatedLimit(m_minBytesPerCycle)
     , m_bytesAllocated(0)
     , m_bytesAbandoned(0)
+    , m_totalBytesVisited(0)
+    , m_totalBytesCopied(0)
     , m_operationInProgress(NoOperation)
     , m_blockAllocator()
     , m_objectSpace(this)
@@ -591,6 +593,13 @@
     MARK_LOG_MESSAGE2("\nNumber of live Objects after full GC %lu, took %.6f secs\n", visitCount, WTF::monotonicallyIncreasingTime() - gcStartTime);
 #endif
 
+    m_totalBytesVisited = visitor.bytesVisited();
+    m_totalBytesCopied = visitor.bytesCopied();
+#if ENABLE(PARALLEL_GC)
+    m_totalBytesVisited += m_sharedData.childBytesVisited();
+    m_totalBytesCopied += m_sharedData.childBytesCopied();
+#endif
+
     visitor.reset();
 #if ENABLE(PARALLEL_GC)
     m_sharedData.resetChildren();
@@ -634,6 +643,16 @@
     return m_objectSpace.capacity() + m_storageSpace.capacity() + extraSize();
 }
 
+size_t Heap::sizeAfterCollect()
+{
+    // The result here may not agree with the normal Heap::size(). 
+    // This is due to the fact that we only count live copied bytes
+    // rather than all used (including dead) copied bytes, thus it's 
+    // always the case that m_totalBytesCopied <= m_storageSpace.size(). 
+    ASSERT(m_totalBytesCopied <= m_storageSpace.size());
+    return m_totalBytesVisited + m_totalBytesCopied + extraSize();
+}
+
 size_t Heap::protectedGlobalObjectCount()
 {
     return forEachProtectedCell<CountIfGlobalObject>();
@@ -798,7 +817,7 @@
         m_objectSpace.resetAllocators();
     }
     
-    size_t currentHeapSize = size();
+    size_t currentHeapSize = sizeAfterCollect();
     if (Options::gcMaxHeapSize() && currentHeapSize > Options::gcMaxHeapSize())
         HeapStatistics::exitWithFailure();
 

Modified: trunk/Source/_javascript_Core/heap/Heap.h (155316 => 155317)


--- trunk/Source/_javascript_Core/heap/Heap.h	2013-09-08 23:36:40 UTC (rev 155316)
+++ trunk/Source/_javascript_Core/heap/Heap.h	2013-09-09 00:11:57 UTC (rev 155317)
@@ -232,6 +232,8 @@
         void zombifyDeadObjects();
         void markDeadObjects();
 
+        size_t sizeAfterCollect();
+
         JSStack& stack();
         BlockAllocator& blockAllocator();
         
@@ -247,6 +249,9 @@
         size_t m_bytesAllocatedLimit;
         size_t m_bytesAllocated;
         size_t m_bytesAbandoned;
+
+        size_t m_totalBytesVisited;
+        size_t m_totalBytesCopied;
         
         OperationInProgress m_operationInProgress;
         BlockAllocator m_blockAllocator;

Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.cpp (155316 => 155317)


--- trunk/Source/_javascript_Core/heap/SlotVisitor.cpp	2013-09-08 23:36:40 UTC (rev 155316)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.cpp	2013-09-09 00:11:57 UTC (rev 155317)
@@ -18,6 +18,8 @@
 
 SlotVisitor::SlotVisitor(GCThreadSharedData& shared)
     : m_stack(shared.m_vm->heap.blockAllocator())
+    , m_bytesVisited(0)
+    , m_bytesCopied(0)
     , m_visitCount(0)
     , m_isInParallelMode(false)
     , m_shared(shared)
@@ -46,6 +48,8 @@
 
 void SlotVisitor::reset()
 {
+    m_bytesVisited = 0;
+    m_bytesCopied = 0;
     m_visitCount = 0;
     ASSERT(m_stack.isEmpty());
 #if ENABLE(PARALLEL_GC)

Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.h (155316 => 155317)


--- trunk/Source/_javascript_Core/heap/SlotVisitor.h	2013-09-08 23:36:40 UTC (rev 155316)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.h	2013-09-09 00:11:57 UTC (rev 155317)
@@ -72,6 +72,8 @@
     void setup();
     void reset();
 
+    size_t bytesVisited() const { return m_bytesVisited; }
+    size_t bytesCopied() const { return m_bytesCopied; }
     size_t visitCount() const { return m_visitCount; }
 
     void donate();
@@ -123,6 +125,8 @@
     MarkStackArray m_stack;
     HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
     
+    size_t m_bytesVisited;
+    size_t m_bytesCopied;
     size_t m_visitCount;
     bool m_isInParallelMode;
     

Modified: trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h (155316 => 155317)


--- trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h	2013-09-08 23:36:40 UTC (rev 155316)
+++ trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h	2013-09-09 00:11:57 UTC (rev 155317)
@@ -100,6 +100,7 @@
     if (Heap::testAndSetMarked(cell) || !cell->structure())
         return;
 
+    m_bytesVisited += MarkedBlock::blockFor(cell)->cellSize();
     m_visitCount++;
         
     MARK_LOG_CHILD(*this, cell);
@@ -211,6 +212,8 @@
 inline void SlotVisitor::copyLater(JSCell* owner, CopyToken token, void* ptr, size_t bytes)
 {
     ASSERT(bytes);
+    m_bytesCopied += bytes;
+
     CopiedBlock* block = CopiedSpace::blockFor(ptr);
     if (block->isOversize()) {
         m_shared.m_copiedSpace->pin(block);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to