Title: [201520] trunk/Source/_javascript_Core
Revision
201520
Author
sbar...@apple.com
Date
2016-05-31 12:45:10 -0700 (Tue, 31 May 2016)

Log Message

Web Inspector: capturing with Allocations timeline causes GC to take 100x longer and cause frame drops
https://bugs.webkit.org/show_bug.cgi?id=158054
<rdar://problem/25280762>

Reviewed by Joseph Pecoraro.

HeapSnapshot::sweepCell was taking a long time on 
http://bl.ocks.org/syntagmatic/6c149c08fc9cde682635
because it has to do a binary search to find if
an item is or is not in the list. 90% of the binary searches
would not find anything. This resulted in a lot of wasted time.

This patch adds a TinyBloomFilter member variable to HeapSnapshot.
We use this filter to try to bypass doing a binary search when the
filter tells us that a particular JSCell is definitely not in our
list. This is a 2x speedup on the steady state GC of the above
website.

* heap/HeapSnapshot.cpp:
(JSC::HeapSnapshot::appendNode):
(JSC::HeapSnapshot::sweepCell):
(JSC::HeapSnapshot::shrinkToFit):
(JSC::HeapSnapshot::nodeForCell):
* heap/HeapSnapshot.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (201519 => 201520)


--- trunk/Source/_javascript_Core/ChangeLog	2016-05-31 19:35:06 UTC (rev 201519)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-05-31 19:45:10 UTC (rev 201520)
@@ -1,3 +1,30 @@
+2016-05-31  Saam Barati  <sbar...@apple.com>
+
+        Web Inspector: capturing with Allocations timeline causes GC to take 100x longer and cause frame drops
+        https://bugs.webkit.org/show_bug.cgi?id=158054
+        <rdar://problem/25280762>
+
+        Reviewed by Joseph Pecoraro.
+
+        HeapSnapshot::sweepCell was taking a long time on 
+        http://bl.ocks.org/syntagmatic/6c149c08fc9cde682635
+        because it has to do a binary search to find if
+        an item is or is not in the list. 90% of the binary searches
+        would not find anything. This resulted in a lot of wasted time.
+
+        This patch adds a TinyBloomFilter member variable to HeapSnapshot.
+        We use this filter to try to bypass doing a binary search when the
+        filter tells us that a particular JSCell is definitely not in our
+        list. This is a 2x speedup on the steady state GC of the above
+        website.
+
+        * heap/HeapSnapshot.cpp:
+        (JSC::HeapSnapshot::appendNode):
+        (JSC::HeapSnapshot::sweepCell):
+        (JSC::HeapSnapshot::shrinkToFit):
+        (JSC::HeapSnapshot::nodeForCell):
+        * heap/HeapSnapshot.h:
+
 2016-05-29  Saam barati  <sbar...@apple.com>
 
         Stack overflow crashes with deep or cyclic proxy prototype chains

Modified: trunk/Source/_javascript_Core/heap/HeapSnapshot.cpp (201519 => 201520)


--- trunk/Source/_javascript_Core/heap/HeapSnapshot.cpp	2016-05-31 19:35:06 UTC (rev 201519)
+++ trunk/Source/_javascript_Core/heap/HeapSnapshot.cpp	2016-05-31 19:45:10 UTC (rev 201520)
@@ -45,13 +45,15 @@
     ASSERT(!m_previous || !m_previous->nodeForCell(node.cell));
 
     m_nodes.append(node);
+    m_filter.add(bitwise_cast<uintptr_t>(node.cell));
 }
 
 void HeapSnapshot::sweepCell(JSCell* cell)
 {
     ASSERT(cell);
 
-    if (m_finalized && !isEmpty()) {
+    if (m_finalized && !m_filter.ruleOut(bitwise_cast<uintptr_t>(cell))) {
+        ASSERT_WITH_MESSAGE(!isEmpty(), "Our filter should have ruled us out if we are empty.");
         unsigned start = 0;
         unsigned end = m_nodes.size();
         while (start != end) {
@@ -79,9 +81,13 @@
 void HeapSnapshot::shrinkToFit()
 {
     if (m_finalized && m_hasCellsToSweep) {
+        m_filter.reset();
         m_nodes.removeAllMatching(
             [&] (const HeapSnapshotNode& node) -> bool {
-                return reinterpret_cast<intptr_t>(node.cell) & CellToSweepTag;
+                bool willRemoveCell = bitwise_cast<intptr_t>(node.cell) & CellToSweepTag;
+                if (!willRemoveCell)
+                    m_filter.add(bitwise_cast<uintptr_t>(node.cell));
+                return willRemoveCell;
             });
         m_nodes.shrinkToFit();
         m_hasCellsToSweep = false;
@@ -126,7 +132,8 @@
 {
     ASSERT(m_finalized);
 
-    if (!isEmpty()) {
+    if (!m_filter.ruleOut(bitwise_cast<uintptr_t>(cell))) {
+        ASSERT_WITH_MESSAGE(!isEmpty(), "Our filter should have ruled us out if we are empty.");
         unsigned start = 0;
         unsigned end = m_nodes.size();
         while (start != end) {

Modified: trunk/Source/_javascript_Core/heap/HeapSnapshot.h (201519 => 201520)


--- trunk/Source/_javascript_Core/heap/HeapSnapshot.h	2016-05-31 19:35:06 UTC (rev 201519)
+++ trunk/Source/_javascript_Core/heap/HeapSnapshot.h	2016-05-31 19:45:10 UTC (rev 201520)
@@ -27,6 +27,7 @@
 #define HeapSnapshot_h
 
 #include "HeapSnapshotBuilder.h"
+#include "TinyBloomFilter.h"
 #include <wtf/Optional.h>
 
 namespace JSC {
@@ -53,6 +54,7 @@
     static const intptr_t CellToSweepTag = 1;
 
     Vector<HeapSnapshotNode> m_nodes;
+    TinyBloomFilter m_filter;
     HeapSnapshot* m_previous { nullptr };
     unsigned m_firstObjectIdentifier { 0 };
     unsigned m_lastObjectIdentifier { 0 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to