<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[161615] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/161615">161615</a></dd>
<dt>Author</dt> <dd>mhahnenberg@apple.com</dd>
<dt>Date</dt> <dd>2014-01-09 18:28:27 -0800 (Thu, 09 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Marking should be generational
https://bugs.webkit.org/show_bug.cgi?id=126552

Reviewed by Geoffrey Garen.

Source/JavaScriptCore: 

Re-marking the same objects over and over is a waste of effort. This patch implements 
the sticky mark bit algorithm (along with our already-present write barriers) to reduce 
overhead during garbage collection caused by rescanning objects.

There are now two collection modes, EdenCollection and FullCollection. EdenCollections
only visit new objects or objects that were added to the remembered set by a write barrier.
FullCollections are normal collections that visit all objects regardless of their 
generation.

In this patch EdenCollections do not do anything in CopiedSpace. This will be fixed in 
https://bugs.webkit.org/show_bug.cgi?id=126555.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::visitAggregate):
* bytecode/CodeBlock.h:
(JSC::CodeBlockSet::mark):
* dfg/DFGOperations.cpp:
* heap/CodeBlockSet.cpp:
(JSC::CodeBlockSet::add):
(JSC::CodeBlockSet::traceMarked):
(JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks):
* heap/CodeBlockSet.h:
* heap/CopiedBlockInlines.h:
(JSC::CopiedBlock::reportLiveBytes):
* heap/CopiedSpace.cpp:
(JSC::CopiedSpace::didStartFullCollection):
* heap/CopiedSpace.h:
(JSC::CopiedSpace::heap):
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::didAbandon):
(JSC::Heap::markRoots):
(JSC::Heap::copyBackingStores):
(JSC::Heap::addToRememberedSet):
(JSC::Heap::collectAllGarbage):
(JSC::Heap::collect):
(JSC::Heap::didAllocate):
(JSC::Heap::writeBarrier):
* heap/Heap.h:
(JSC::Heap::isInRememberedSet):
(JSC::Heap::operationInProgress):
(JSC::Heap::shouldCollect):
(JSC::Heap::isCollecting):
(JSC::Heap::isWriteBarrierEnabled):
(JSC::Heap::writeBarrier):
* heap/HeapOperation.h:
* heap/MarkStack.cpp:
(JSC::MarkStackArray::~MarkStackArray):
(JSC::MarkStackArray::clear):
(JSC::MarkStackArray::fillVector):
* heap/MarkStack.h:
* heap/MarkedAllocator.cpp:
(JSC::isListPagedOut):
(JSC::MarkedAllocator::isPagedOut):
(JSC::MarkedAllocator::tryAllocateHelper):
(JSC::MarkedAllocator::addBlock):
(JSC::MarkedAllocator::removeBlock):
(JSC::MarkedAllocator::reset):
* heap/MarkedAllocator.h:
(JSC::MarkedAllocator::MarkedAllocator):
* heap/MarkedBlock.cpp:
(JSC::MarkedBlock::clearMarks):
(JSC::MarkedBlock::clearRememberedSet):
(JSC::MarkedBlock::clearMarksWithCollectionType):
(JSC::MarkedBlock::lastChanceToFinalize):
* heap/MarkedBlock.h: Changed atomSize to 16 bytes because we have no objects smaller
than 16 bytes. This is also to pay for the additional Bitmap for the remembered set.
(JSC::MarkedBlock::didConsumeEmptyFreeList):
(JSC::MarkedBlock::setRemembered):
(JSC::MarkedBlock::clearRemembered):
(JSC::MarkedBlock::atomicClearRemembered):
(JSC::MarkedBlock::isRemembered):
* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::~MarkedSpace):
(JSC::MarkedSpace::resetAllocators):
(JSC::MarkedSpace::visitWeakSets):
(JSC::MarkedSpace::reapWeakSets):
(JSC::VerifyMarked::operator()):
(JSC::MarkedSpace::clearMarks):
* heap/MarkedSpace.h:
(JSC::ClearMarks::operator()):
(JSC::ClearRememberedSet::operator()):
(JSC::MarkedSpace::didAllocateInBlock):
(JSC::MarkedSpace::clearRememberedSet):
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::~SlotVisitor):
(JSC::SlotVisitor::clearMarkStack):
* heap/SlotVisitor.h:
(JSC::SlotVisitor::markStack):
(JSC::SlotVisitor::sharedData):
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::internalAppend):
(JSC::SlotVisitor::unconditionallyAppend):
(JSC::SlotVisitor::copyLater):
(JSC::SlotVisitor::reportExtraMemoryUsage):
(JSC::SlotVisitor::heap):
* jit/Repatch.cpp:
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::visitChildren):
* runtime/JSPropertyNameIterator.h:
(JSC::StructureRareData::setEnumerationCache):
* runtime/JSString.cpp:
(JSC::JSString::visitChildren):
* runtime/StructureRareDataInlines.h:
(JSC::StructureRareData::setPreviousID):
(JSC::StructureRareData::setObjectToStringValue):
* runtime/WeakMapData.cpp:
(JSC::WeakMapData::visitChildren):

Source/WTF: 

* wtf/Bitmap.h:
(WTF::WordType&gt;::count): Added a cast that became necessary when Bitmap
is used with smaller types than int32_t.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCodeBlockSetcpp">trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCodeBlockSeth">trunk/Source/JavaScriptCore/heap/CodeBlockSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCopiedBlockInlinesh">trunk/Source/JavaScriptCore/heap/CopiedBlockInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCopiedSpacecpp">trunk/Source/JavaScriptCore/heap/CopiedSpace.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCopiedSpaceh">trunk/Source/JavaScriptCore/heap/CopiedSpace.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeaph">trunk/Source/JavaScriptCore/heap/Heap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapOperationh">trunk/Source/JavaScriptCore/heap/HeapOperation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkStackcpp">trunk/Source/JavaScriptCore/heap/MarkStack.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkStackh">trunk/Source/JavaScriptCore/heap/MarkStack.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedAllocatorcpp">trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedAllocatorh">trunk/Source/JavaScriptCore/heap/MarkedAllocator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedBlockcpp">trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedBlockh">trunk/Source/JavaScriptCore/heap/MarkedBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedSpacecpp">trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedSpaceh">trunk/Source/JavaScriptCore/heap/MarkedSpace.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapSlotVisitorcpp">trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapSlotVisitorh">trunk/Source/JavaScriptCore/heap/SlotVisitor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapSlotVisitorInlinesh">trunk/Source/JavaScriptCore/heap/SlotVisitorInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGenericTypedArrayViewInlinesh">trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSPropertyNameIteratorh">trunk/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSStringcpp">trunk/Source/JavaScriptCore/runtime/JSString.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureRareDataInlinesh">trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeWeakMapDatacpp">trunk/Source/JavaScriptCore/runtime/WeakMapData.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfBitmaph">trunk/Source/WTF/wtf/Bitmap.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -1,3 +1,119 @@
</span><ins>+2014-01-07  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
+
+        Marking should be generational
+        https://bugs.webkit.org/show_bug.cgi?id=126552
+
+        Reviewed by Geoffrey Garen.
+
+        Re-marking the same objects over and over is a waste of effort. This patch implements 
+        the sticky mark bit algorithm (along with our already-present write barriers) to reduce 
+        overhead during garbage collection caused by rescanning objects.
+
+        There are now two collection modes, EdenCollection and FullCollection. EdenCollections
+        only visit new objects or objects that were added to the remembered set by a write barrier.
+        FullCollections are normal collections that visit all objects regardless of their 
+        generation.
+
+        In this patch EdenCollections do not do anything in CopiedSpace. This will be fixed in 
+        https://bugs.webkit.org/show_bug.cgi?id=126555.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::visitAggregate):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlockSet::mark):
+        * dfg/DFGOperations.cpp:
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::add):
+        (JSC::CodeBlockSet::traceMarked):
+        (JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks):
+        * heap/CodeBlockSet.h:
+        * heap/CopiedBlockInlines.h:
+        (JSC::CopiedBlock::reportLiveBytes):
+        * heap/CopiedSpace.cpp:
+        (JSC::CopiedSpace::didStartFullCollection):
+        * heap/CopiedSpace.h:
+        (JSC::CopiedSpace::heap):
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::didAbandon):
+        (JSC::Heap::markRoots):
+        (JSC::Heap::copyBackingStores):
+        (JSC::Heap::addToRememberedSet):
+        (JSC::Heap::collectAllGarbage):
+        (JSC::Heap::collect):
+        (JSC::Heap::didAllocate):
+        (JSC::Heap::writeBarrier):
+        * heap/Heap.h:
+        (JSC::Heap::isInRememberedSet):
+        (JSC::Heap::operationInProgress):
+        (JSC::Heap::shouldCollect):
+        (JSC::Heap::isCollecting):
+        (JSC::Heap::isWriteBarrierEnabled):
+        (JSC::Heap::writeBarrier):
+        * heap/HeapOperation.h:
+        * heap/MarkStack.cpp:
+        (JSC::MarkStackArray::~MarkStackArray):
+        (JSC::MarkStackArray::clear):
+        (JSC::MarkStackArray::fillVector):
+        * heap/MarkStack.h:
+        * heap/MarkedAllocator.cpp:
+        (JSC::isListPagedOut):
+        (JSC::MarkedAllocator::isPagedOut):
+        (JSC::MarkedAllocator::tryAllocateHelper):
+        (JSC::MarkedAllocator::addBlock):
+        (JSC::MarkedAllocator::removeBlock):
+        (JSC::MarkedAllocator::reset):
+        * heap/MarkedAllocator.h:
+        (JSC::MarkedAllocator::MarkedAllocator):
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::clearMarks):
+        (JSC::MarkedBlock::clearRememberedSet):
+        (JSC::MarkedBlock::clearMarksWithCollectionType):
+        (JSC::MarkedBlock::lastChanceToFinalize):
+        * heap/MarkedBlock.h: Changed atomSize to 16 bytes because we have no objects smaller
+        than 16 bytes. This is also to pay for the additional Bitmap for the remembered set.
+        (JSC::MarkedBlock::didConsumeEmptyFreeList):
+        (JSC::MarkedBlock::setRemembered):
+        (JSC::MarkedBlock::clearRemembered):
+        (JSC::MarkedBlock::atomicClearRemembered):
+        (JSC::MarkedBlock::isRemembered):
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::~MarkedSpace):
+        (JSC::MarkedSpace::resetAllocators):
+        (JSC::MarkedSpace::visitWeakSets):
+        (JSC::MarkedSpace::reapWeakSets):
+        (JSC::VerifyMarked::operator()):
+        (JSC::MarkedSpace::clearMarks):
+        * heap/MarkedSpace.h:
+        (JSC::ClearMarks::operator()):
+        (JSC::ClearRememberedSet::operator()):
+        (JSC::MarkedSpace::didAllocateInBlock):
+        (JSC::MarkedSpace::clearRememberedSet):
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::~SlotVisitor):
+        (JSC::SlotVisitor::clearMarkStack):
+        * heap/SlotVisitor.h:
+        (JSC::SlotVisitor::markStack):
+        (JSC::SlotVisitor::sharedData):
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::internalAppend):
+        (JSC::SlotVisitor::unconditionallyAppend):
+        (JSC::SlotVisitor::copyLater):
+        (JSC::SlotVisitor::reportExtraMemoryUsage):
+        (JSC::SlotVisitor::heap):
+        * jit/Repatch.cpp:
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::visitChildren):
+        * runtime/JSPropertyNameIterator.h:
+        (JSC::StructureRareData::setEnumerationCache):
+        * runtime/JSString.cpp:
+        (JSC::JSString::visitChildren):
+        * runtime/StructureRareDataInlines.h:
+        (JSC::StructureRareData::setPreviousID):
+        (JSC::StructureRareData::setObjectToStringValue):
+        * runtime/WeakMapData.cpp:
+        (JSC::WeakMapData::visitChildren):
+
</ins><span class="cx"> 2014-01-09  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed Windows build fix for r161563.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -1954,15 +1954,15 @@
</span><span class="cx">     if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
</span><span class="cx">         otherBlock-&gt;visitAggregate(visitor);
</span><span class="cx"> 
</span><del>-    visitor.reportExtraMemoryUsage(sizeof(CodeBlock));
</del><ins>+    visitor.reportExtraMemoryUsage(ownerExecutable(), sizeof(CodeBlock));
</ins><span class="cx">     if (m_jitCode)
</span><del>-        visitor.reportExtraMemoryUsage(m_jitCode-&gt;size());
</del><ins>+        visitor.reportExtraMemoryUsage(ownerExecutable(), m_jitCode-&gt;size());
</ins><span class="cx">     if (m_instructions.size()) {
</span><span class="cx">         // Divide by refCount() because m_instructions points to something that is shared
</span><span class="cx">         // by multiple CodeBlocks, and we only want to count it towards the heap size once.
</span><span class="cx">         // Having each CodeBlock report only its proportional share of the size is one way
</span><span class="cx">         // of accomplishing this.
</span><del>-        visitor.reportExtraMemoryUsage(m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
</del><ins>+        visitor.reportExtraMemoryUsage(ownerExecutable(), m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     visitor.append(&amp;m_unlinkedCode);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -1269,6 +1269,9 @@
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     (*iter)-&gt;m_mayBeExecuting = true;
</span><ins>+#if ENABLE(GGC)
+    m_currentlyExecuting.append(static_cast&lt;CodeBlock*&gt;(candidateCodeBlock));
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -850,6 +850,7 @@
</span><span class="cx">     NativeCallFrameTracer tracer(&amp;vm, exec);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(!object-&gt;structure()-&gt;outOfLineCapacity());
</span><ins>+    DeferGC deferGC(vm.heap);
</ins><span class="cx">     Butterfly* result = object-&gt;growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
</span><span class="cx">     object-&gt;setButterflyWithoutChangingStructure(vm, result);
</span><span class="cx">     return reinterpret_cast&lt;char*&gt;(result);
</span><span class="lines">@@ -860,6 +861,7 @@
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(&amp;vm, exec);
</span><span class="cx"> 
</span><ins>+    DeferGC deferGC(vm.heap);
</ins><span class="cx">     Butterfly* result = object-&gt;growOutOfLineStorage(vm, object-&gt;structure()-&gt;outOfLineCapacity(), newSize);
</span><span class="cx">     object-&gt;setButterflyWithoutChangingStructure(vm, result);
</span><span class="cx">     return reinterpret_cast&lt;char*&gt;(result);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCodeBlockSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -45,7 +45,8 @@
</span><span class="cx"> 
</span><span class="cx"> void CodeBlockSet::add(PassRefPtr&lt;CodeBlock&gt; codeBlock)
</span><span class="cx"> {
</span><del>-    bool isNewEntry = m_set.add(codeBlock.leakRef()).isNewEntry;
</del><ins>+    CodeBlock* block = codeBlock.leakRef();
+    bool isNewEntry = m_set.add(block).isNewEntry;
</ins><span class="cx">     ASSERT_UNUSED(isNewEntry, isNewEntry);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -101,9 +102,20 @@
</span><span class="cx">         CodeBlock* codeBlock = *iter;
</span><span class="cx">         if (!codeBlock-&gt;m_mayBeExecuting)
</span><span class="cx">             continue;
</span><del>-        codeBlock-&gt;visitAggregate(visitor);
</del><ins>+        codeBlock-&gt;ownerExecutable()-&gt;methodTable()-&gt;visitChildren(codeBlock-&gt;ownerExecutable(), visitor);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CodeBlockSet::rememberCurrentlyExecutingCodeBlocks(Heap* heap)
+{
+#if ENABLE(GGC)
+    for (size_t i = 0; i &lt; m_currentlyExecuting.size(); ++i)
+        heap-&gt;addToRememberedSet(m_currentlyExecuting[i]-&gt;ownerExecutable());
+    m_currentlyExecuting.clear();
+#else
+    UNUSED_PARAM(heap);
+#endif // ENABLE(GGC)
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCodeBlockSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CodeBlockSet.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CodeBlockSet.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/CodeBlockSet.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -30,10 +30,12 @@
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><ins>+#include &lt;wtf/Vector.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class CodeBlock;
</span><ins>+class Heap;
</ins><span class="cx"> class SlotVisitor;
</span><span class="cx"> 
</span><span class="cx"> // CodeBlockSet tracks all CodeBlocks. Every CodeBlock starts out with one
</span><span class="lines">@@ -65,11 +67,16 @@
</span><span class="cx">     // mayBeExecuting.
</span><span class="cx">     void traceMarked(SlotVisitor&amp;);
</span><span class="cx"> 
</span><ins>+    // Add all currently executing CodeBlocks to the remembered set to be 
+    // re-scanned during the next collection.
+    void rememberCurrentlyExecutingCodeBlocks(Heap*);
+
</ins><span class="cx"> private:
</span><span class="cx">     // This is not a set of RefPtr&lt;CodeBlock&gt; because we need to be able to find
</span><span class="cx">     // arbitrary bogus pointers. I could have written a thingy that had peek types
</span><span class="cx">     // and all, but that seemed like overkill.
</span><span class="cx">     HashSet&lt;CodeBlock* &gt; m_set;
</span><ins>+    Vector&lt;CodeBlock*&gt; m_currentlyExecuting;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCopiedBlockInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CopiedBlockInlines.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CopiedBlockInlines.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/CopiedBlockInlines.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -42,6 +42,9 @@
</span><span class="cx"> #endif
</span><span class="cx">     m_liveBytes += bytes;
</span><span class="cx"> 
</span><ins>+    if (isPinned())
+        return;
+
</ins><span class="cx">     if (!shouldEvacuate()) {
</span><span class="cx">         pin();
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCopiedSpacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CopiedSpace.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CopiedSpace.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/CopiedSpace.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -316,4 +316,17 @@
</span><span class="cx">         || isBlockListPagedOut(deadline, &amp;m_oversizeBlocks);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CopiedSpace::didStartFullCollection()
+{
+    ASSERT(heap()-&gt;operationInProgress() == FullCollection);
+
+    ASSERT(m_fromSpace-&gt;isEmpty());
+
+    for (CopiedBlock* block = m_toSpace-&gt;head(); block; block = block-&gt;next())
+        block-&gt;didSurviveGC();
+
+    for (CopiedBlock* block = m_oversizeBlocks.head(); block; block = block-&gt;next())
+        block-&gt;didSurviveGC();
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCopiedSpaceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CopiedSpace.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CopiedSpace.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/CopiedSpace.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -60,6 +60,8 @@
</span><span class="cx">     
</span><span class="cx">     CopiedAllocator&amp; allocator() { return m_allocator; }
</span><span class="cx"> 
</span><ins>+    void didStartFullCollection();
+
</ins><span class="cx">     void startedCopying();
</span><span class="cx">     void doneCopying();
</span><span class="cx">     bool isInCopyPhase() { return m_inCopyingPhase; }
</span><span class="lines">@@ -80,6 +82,8 @@
</span><span class="cx"> 
</span><span class="cx">     static CopiedBlock* blockFor(void*);
</span><span class="cx"> 
</span><ins>+    Heap* heap() const { return m_heap; }
+
</ins><span class="cx"> private:
</span><span class="cx">     static bool isOversize(size_t);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -253,9 +253,11 @@
</span><span class="cx">     , m_ramSize(ramSize())
</span><span class="cx">     , m_minBytesPerCycle(minHeapSize(m_heapType, m_ramSize))
</span><span class="cx">     , m_sizeAfterLastCollect(0)
</span><del>-    , m_bytesAllocatedLimit(m_minBytesPerCycle)
-    , m_bytesAllocated(0)
-    , m_bytesAbandoned(0)
</del><ins>+    , m_bytesAllocatedThisCycle(0)
+    , m_bytesAbandonedThisCycle(0)
+    , m_maxEdenSize(m_minBytesPerCycle)
+    , m_maxHeapSize(m_minBytesPerCycle)
+    , m_shouldDoFullCollection(false)
</ins><span class="cx">     , m_totalBytesVisited(0)
</span><span class="cx">     , m_totalBytesCopied(0)
</span><span class="cx">     , m_operationInProgress(NoOperation)
</span><span class="lines">@@ -269,7 +271,7 @@
</span><span class="cx">     , m_copyVisitor(m_sharedData)
</span><span class="cx">     , m_handleSet(vm)
</span><span class="cx">     , m_isSafeToCollect(false)
</span><del>-    , m_writeBarrierBuffer(128)
</del><ins>+    , m_writeBarrierBuffer(256)
</ins><span class="cx">     , m_vm(vm)
</span><span class="cx">     , m_lastGCLength(0)
</span><span class="cx">     , m_lastCodeDiscardTime(WTF::monotonicallyIncreasingTime())
</span><span class="lines">@@ -332,8 +334,8 @@
</span><span class="cx"> void Heap::didAbandon(size_t bytes)
</span><span class="cx"> {
</span><span class="cx">     if (m_activityCallback)
</span><del>-        m_activityCallback-&gt;didAllocate(m_bytesAllocated + m_bytesAbandoned);
-    m_bytesAbandoned += bytes;
</del><ins>+        m_activityCallback-&gt;didAllocate(m_bytesAllocatedThisCycle + m_bytesAbandonedThisCycle);
+    m_bytesAbandonedThisCycle += bytes;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Heap::protect(JSValue k)
</span><span class="lines">@@ -487,6 +489,9 @@
</span><span class="cx">     visitor.setup();
</span><span class="cx">     HeapRootVisitor heapRootVisitor(visitor);
</span><span class="cx"> 
</span><ins>+    Vector&lt;const JSCell*&gt; rememberedSet(m_slotVisitor.markStack().size());
+    m_slotVisitor.markStack().fillVector(rememberedSet);
+
</ins><span class="cx">     {
</span><span class="cx">         ParallelModeEnabler enabler(visitor);
</span><span class="cx"> 
</span><span class="lines">@@ -590,6 +595,14 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    {
+        GCPHASE(ClearRememberedSet);
+        for (unsigned i = 0; i &lt; rememberedSet.size(); ++i) {
+            const JSCell* cell = rememberedSet[i];
+            MarkedBlock::blockFor(cell)-&gt;clearRemembered(cell);
+        }
+    }
+
</ins><span class="cx">     GCCOUNTER(VisitedValueCount, visitor.visitCount());
</span><span class="cx"> 
</span><span class="cx">     m_sharedData.didFinishMarking();
</span><span class="lines">@@ -601,8 +614,14 @@
</span><span class="cx">     MARK_LOG_MESSAGE2(&quot;\nNumber of live Objects after full GC %lu, took %.6f secs\n&quot;, visitCount, WTF::monotonicallyIncreasingTime() - gcStartTime);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    m_totalBytesVisited = visitor.bytesVisited();
-    m_totalBytesCopied = visitor.bytesCopied();
</del><ins>+    if (m_operationInProgress == EdenCollection) {
+        m_totalBytesVisited += visitor.bytesVisited();
+        m_totalBytesCopied += visitor.bytesCopied();
+    } else {
+        ASSERT(m_operationInProgress == FullCollection);
+        m_totalBytesVisited = visitor.bytesVisited();
+        m_totalBytesCopied = visitor.bytesCopied();
+    }
</ins><span class="cx"> #if ENABLE(PARALLEL_GC)
</span><span class="cx">     m_totalBytesVisited += m_sharedData.childBytesVisited();
</span><span class="cx">     m_totalBytesCopied += m_sharedData.childBytesCopied();
</span><span class="lines">@@ -615,8 +634,12 @@
</span><span class="cx">     m_sharedData.reset();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template &lt;HeapOperation collectionType&gt;
</ins><span class="cx"> void Heap::copyBackingStores()
</span><span class="cx"> {
</span><ins>+    if (collectionType == EdenCollection)
+        return;
+
</ins><span class="cx">     m_storageSpace.startedCopying();
</span><span class="cx">     if (m_storageSpace.shouldDoCopyPhase()) {
</span><span class="cx">         m_sharedData.didStartCopying();
</span><span class="lines">@@ -627,7 +650,7 @@
</span><span class="cx">         // before signaling that the phase is complete.
</span><span class="cx">         m_storageSpace.doneCopying();
</span><span class="cx">         m_sharedData.didFinishCopying();
</span><del>-    } else 
</del><ins>+    } else
</ins><span class="cx">         m_storageSpace.doneCopying();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -723,11 +746,22 @@
</span><span class="cx">     m_jitStubRoutines.deleteUnmarkedJettisonedStubRoutines();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Heap::addToRememberedSet(const JSCell* cell)
+{
+    ASSERT(cell);
+    ASSERT(!Options::enableConcurrentJIT() || !isCompilationThread());
+    if (isInRememberedSet(cell))
+        return;
+    MarkedBlock::blockFor(cell)-&gt;setRemembered(cell);
+    m_slotVisitor.unconditionallyAppend(const_cast&lt;JSCell*&gt;(cell));
+}
+
</ins><span class="cx"> void Heap::collectAllGarbage()
</span><span class="cx"> {
</span><span class="cx">     if (!m_isSafeToCollect)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    m_shouldDoFullCollection = true;
</ins><span class="cx">     collect();
</span><span class="cx"> 
</span><span class="cx">     SamplingRegion samplingRegion(&quot;Garbage Collection: Sweeping&quot;);
</span><span class="lines">@@ -764,10 +798,29 @@
</span><span class="cx">         RecursiveAllocationScope scope(*this);
</span><span class="cx">         m_vm-&gt;prepareToDiscardCode();
</span><span class="cx">     }
</span><del>-    
-    m_operationInProgress = Collection;
-    m_extraMemoryUsage = 0;
</del><span class="cx"> 
</span><ins>+    bool isFullCollection = m_shouldDoFullCollection;
+    if (isFullCollection) {
+        m_operationInProgress = FullCollection;
+        m_slotVisitor.clearMarkStack();
+        m_shouldDoFullCollection = false;
+        if (Options::logGC())
+            dataLog(&quot;FullCollection, &quot;);
+    } else {
+#if ENABLE(GGC)
+        m_operationInProgress = EdenCollection;
+        if (Options::logGC())
+            dataLog(&quot;EdenCollection, &quot;);
+#else
+        m_operationInProgress = FullCollection;
+        m_slotVisitor.clearMarkStack();
+        if (Options::logGC())
+            dataLog(&quot;FullCollection, &quot;);
+#endif
+    }
+    if (m_operationInProgress == FullCollection)
+        m_extraMemoryUsage = 0;
+
</ins><span class="cx">     if (m_activityCallback)
</span><span class="cx">         m_activityCallback-&gt;willCollect();
</span><span class="cx"> 
</span><span class="lines">@@ -780,8 +833,18 @@
</span><span class="cx">     {
</span><span class="cx">         GCPHASE(StopAllocation);
</span><span class="cx">         m_objectSpace.stopAllocating();
</span><ins>+        if (m_operationInProgress == FullCollection)
+            m_storageSpace.didStartFullCollection();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    {
+        GCPHASE(FlushWriteBarrierBuffer);
+        if (m_operationInProgress == EdenCollection)
+            m_writeBarrierBuffer.flush(*this);
+        else
+            m_writeBarrierBuffer.reset();
+    }
+
</ins><span class="cx">     markRoots();
</span><span class="cx">     
</span><span class="cx">     {
</span><span class="lines">@@ -796,13 +859,16 @@
</span><span class="cx">         m_arrayBuffers.sweep();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    {
</del><ins>+    if (m_operationInProgress == FullCollection) {
</ins><span class="cx">         m_blockSnapshot.resize(m_objectSpace.blocks().set().size());
</span><span class="cx">         MarkedBlockSnapshotFunctor functor(m_blockSnapshot);
</span><span class="cx">         m_objectSpace.forEachBlock(functor);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    copyBackingStores();
</del><ins>+    if (m_operationInProgress == FullCollection)
+        copyBackingStores&lt;FullCollection&gt;();
+    else
+        copyBackingStores&lt;EdenCollection&gt;();
</ins><span class="cx"> 
</span><span class="cx">     {
</span><span class="cx">         GCPHASE(FinalizeUnconditionalFinalizers);
</span><span class="lines">@@ -819,10 +885,17 @@
</span><span class="cx">         m_vm-&gt;clearSourceProviderCaches();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_sweeper-&gt;startSweeping(m_blockSnapshot);
-    m_bytesAbandoned = 0;
</del><ins>+    if (m_operationInProgress == FullCollection)
+        m_sweeper-&gt;startSweeping(m_blockSnapshot);
</ins><span class="cx"> 
</span><span class="cx">     {
</span><ins>+        GCPHASE(AddCurrentlyExecutingCodeBlocksToRememberedSet);
+        m_codeBlocks.rememberCurrentlyExecutingCodeBlocks(this);
+    }
+
+    m_bytesAbandonedThisCycle = 0;
+
+    {
</ins><span class="cx">         GCPHASE(ResetAllocators);
</span><span class="cx">         m_objectSpace.resetAllocators();
</span><span class="cx">     }
</span><span class="lines">@@ -831,21 +904,32 @@
</span><span class="cx">     if (Options::gcMaxHeapSize() &amp;&amp; currentHeapSize &gt; Options::gcMaxHeapSize())
</span><span class="cx">         HeapStatistics::exitWithFailure();
</span><span class="cx"> 
</span><ins>+    if (m_operationInProgress == FullCollection) {
+        // To avoid pathological GC churn in very small and very large heaps, we set
+        // the new allocation limit based on the current size of the heap, with a
+        // fixed minimum.
+        m_maxHeapSize = max(minHeapSize(m_heapType, m_ramSize), proportionalHeapSize(currentHeapSize, m_ramSize));
+        m_maxEdenSize = m_maxHeapSize - currentHeapSize;
+    } else {
+        ASSERT(currentHeapSize &gt;= m_sizeAfterLastCollect);
+        m_maxEdenSize = m_maxHeapSize - currentHeapSize;
+        double edenToOldGenerationRatio = (double)m_maxEdenSize / (double)m_maxHeapSize;
+        double minEdenToOldGenerationRatio = 1.0 / 3.0;
+        if (edenToOldGenerationRatio &lt; minEdenToOldGenerationRatio)
+            m_shouldDoFullCollection = true;
+        m_maxHeapSize += currentHeapSize - m_sizeAfterLastCollect;
+        m_maxEdenSize = m_maxHeapSize - currentHeapSize;
+    }
+
</ins><span class="cx">     m_sizeAfterLastCollect = currentHeapSize;
</span><span class="cx"> 
</span><del>-    // To avoid pathological GC churn in very small and very large heaps, we set
-    // the new allocation limit based on the current size of the heap, with a
-    // fixed minimum.
-    size_t maxHeapSize = max(minHeapSize(m_heapType, m_ramSize), proportionalHeapSize(currentHeapSize, m_ramSize));
-    m_bytesAllocatedLimit = maxHeapSize - currentHeapSize;
-
-    m_bytesAllocated = 0;
</del><ins>+    m_bytesAllocatedThisCycle = 0;
</ins><span class="cx">     double lastGCEndTime = WTF::monotonicallyIncreasingTime();
</span><span class="cx">     m_lastGCLength = lastGCEndTime - lastGCStartTime;
</span><span class="cx"> 
</span><span class="cx">     if (Options::recordGCPauseTimes())
</span><span class="cx">         HeapStatistics::recordGCPauseTime(lastGCStartTime, lastGCEndTime);
</span><del>-    RELEASE_ASSERT(m_operationInProgress == Collection);
</del><ins>+    RELEASE_ASSERT(m_operationInProgress == EdenCollection || m_operationInProgress == FullCollection);
</ins><span class="cx"> 
</span><span class="cx">     m_operationInProgress = NoOperation;
</span><span class="cx">     JAVASCRIPTCORE_GC_END();
</span><span class="lines">@@ -863,10 +947,6 @@
</span><span class="cx">         double after = currentTimeMS();
</span><span class="cx">         dataLog(after - before, &quot; ms, &quot;, currentHeapSize / 1024, &quot; kb]\n&quot;);
</span><span class="cx">     }
</span><del>-
-#if ENABLE(ALLOCATION_LOGGING)
-    dataLogF(&quot;JSC GC finishing collection.\n&quot;);
-#endif
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool Heap::collectIfNecessaryOrDefer()
</span><span class="lines">@@ -916,8 +996,8 @@
</span><span class="cx"> void Heap::didAllocate(size_t bytes)
</span><span class="cx"> {
</span><span class="cx">     if (m_activityCallback)
</span><del>-        m_activityCallback-&gt;didAllocate(m_bytesAllocated + m_bytesAbandoned);
-    m_bytesAllocated += bytes;
</del><ins>+        m_activityCallback-&gt;didAllocate(m_bytesAllocatedThisCycle + m_bytesAbandonedThisCycle);
+    m_bytesAllocatedThisCycle += bytes;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool Heap::isValidAllocation(size_t)
</span><span class="lines">@@ -994,6 +1074,15 @@
</span><span class="cx">     collectIfNecessaryOrDefer();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Heap::writeBarrier(const JSCell* from)
+{
+    ASSERT_GC_OBJECT_LOOKS_VALID(const_cast&lt;JSCell*&gt;(from));
+    if (!from || !isMarked(from))
+        return;
+    Heap* heap = Heap::heap(from);
+    heap-&gt;addToRememberedSet(from);
+}
+
</ins><span class="cx"> void Heap::flushWriteBarrierBuffer(JSCell* cell)
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(GGC)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/Heap.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -94,11 +94,17 @@
</span><span class="cx">         static bool testAndSetMarked(const void*);
</span><span class="cx">         static void setMarked(const void*);
</span><span class="cx"> 
</span><ins>+        JS_EXPORT_PRIVATE void addToRememberedSet(const JSCell*);
+        bool isInRememberedSet(const JSCell* cell) const
+        {
+            ASSERT(cell);
+            ASSERT(!Options::enableConcurrentJIT() || !isCompilationThread());
+            return MarkedBlock::blockFor(cell)-&gt;isRemembered(cell);
+        }
</ins><span class="cx">         static bool isWriteBarrierEnabled();
</span><del>-        static void writeBarrier(const JSCell*);
</del><ins>+        JS_EXPORT_PRIVATE static void writeBarrier(const JSCell*);
</ins><span class="cx">         static void writeBarrier(const JSCell*, JSValue);
</span><span class="cx">         static void writeBarrier(const JSCell*, JSCell*);
</span><del>-        static uint8_t* addressOfCardFor(JSCell*);
</del><span class="cx"> 
</span><span class="cx">         WriteBarrierBuffer&amp; writeBarrierBuffer() { return m_writeBarrierBuffer; }
</span><span class="cx">         void flushWriteBarrierBuffer(JSCell*);
</span><span class="lines">@@ -120,6 +126,7 @@
</span><span class="cx"> 
</span><span class="cx">         // true if collection is in progress
</span><span class="cx">         inline bool isCollecting();
</span><ins>+        inline HeapOperation operationInProgress() { return m_operationInProgress; }
</ins><span class="cx">         // true if an allocation or collection is in progress
</span><span class="cx">         inline bool isBusy();
</span><span class="cx">         
</span><span class="lines">@@ -236,6 +243,7 @@
</span><span class="cx">         void markRoots();
</span><span class="cx">         void markProtectedObjects(HeapRootVisitor&amp;);
</span><span class="cx">         void markTempSortVectors(HeapRootVisitor&amp;);
</span><ins>+        template &lt;HeapOperation collectionType&gt;
</ins><span class="cx">         void copyBackingStores();
</span><span class="cx">         void harvestWeakReferences();
</span><span class="cx">         void finalizeUnconditionalFinalizers();
</span><span class="lines">@@ -257,10 +265,11 @@
</span><span class="cx">         const size_t m_minBytesPerCycle;
</span><span class="cx">         size_t m_sizeAfterLastCollect;
</span><span class="cx"> 
</span><del>-        size_t m_bytesAllocatedLimit;
-        size_t m_bytesAllocated;
-        size_t m_bytesAbandoned;
-
</del><ins>+        size_t m_bytesAllocatedThisCycle;
+        size_t m_bytesAbandonedThisCycle;
+        size_t m_maxEdenSize;
+        size_t m_maxHeapSize;
+        bool m_shouldDoFullCollection;
</ins><span class="cx">         size_t m_totalBytesVisited;
</span><span class="cx">         size_t m_totalBytesCopied;
</span><span class="cx">         
</span><span class="lines">@@ -271,6 +280,8 @@
</span><span class="cx">         GCIncomingRefCountedSet&lt;ArrayBuffer&gt; m_arrayBuffers;
</span><span class="cx">         size_t m_extraMemoryUsage;
</span><span class="cx"> 
</span><ins>+        HashSet&lt;const JSCell*&gt; m_copyingRememberedSet;
+
</ins><span class="cx">         ProtectCountSet m_protectedValues;
</span><span class="cx">         Vector&lt;Vector&lt;ValueStringPair, 0, UnsafeVectorOverflow&gt;* &gt; m_tempSortingVectors;
</span><span class="cx">         OwnPtr&lt;HashSet&lt;MarkedArgumentBuffer*&gt;&gt; m_markListSet;
</span><span class="lines">@@ -322,8 +333,8 @@
</span><span class="cx">         if (isDeferred())
</span><span class="cx">             return false;
</span><span class="cx">         if (Options::gcMaxHeapSize())
</span><del>-            return m_bytesAllocated &gt; Options::gcMaxHeapSize() &amp;&amp; m_isSafeToCollect &amp;&amp; m_operationInProgress == NoOperation;
-        return m_bytesAllocated &gt; m_bytesAllocatedLimit &amp;&amp; m_isSafeToCollect &amp;&amp; m_operationInProgress == NoOperation;
</del><ins>+            return m_bytesAllocatedThisCycle &gt; Options::gcMaxHeapSize() &amp;&amp; m_isSafeToCollect &amp;&amp; m_operationInProgress == NoOperation;
+        return m_bytesAllocatedThisCycle &gt; m_maxEdenSize &amp;&amp; m_isSafeToCollect &amp;&amp; m_operationInProgress == NoOperation;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool Heap::isBusy()
</span><span class="lines">@@ -333,7 +344,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool Heap::isCollecting()
</span><span class="cx">     {
</span><del>-        return m_operationInProgress == Collection;
</del><ins>+        return m_operationInProgress == FullCollection || m_operationInProgress == EdenCollection;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     inline Heap* Heap::heap(const JSCell* cell)
</span><span class="lines">@@ -370,28 +381,35 @@
</span><span class="cx"> 
</span><span class="cx">     inline bool Heap::isWriteBarrierEnabled()
</span><span class="cx">     {
</span><del>-#if ENABLE(WRITE_BARRIER_PROFILING)
</del><ins>+#if ENABLE(WRITE_BARRIER_PROFILING) || ENABLE(GGC)
</ins><span class="cx">         return true;
</span><span class="cx"> #else
</span><span class="cx">         return false;
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    inline void Heap::writeBarrier(const JSCell*)
</del><ins>+    inline void Heap::writeBarrier(const JSCell* from, JSCell* to)
</ins><span class="cx">     {
</span><ins>+#if ENABLE(WRITE_BARRIER_PROFILING)
</ins><span class="cx">         WriteBarrierCounters::countWriteBarrier();
</span><ins>+#endif
+        if (!from || !isMarked(from))
+            return;
+        if (!to || isMarked(to))
+            return;
+        Heap::heap(from)-&gt;addToRememberedSet(from);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    inline void Heap::writeBarrier(const JSCell*, JSCell*)
</del><ins>+    inline void Heap::writeBarrier(const JSCell* from, JSValue to)
</ins><span class="cx">     {
</span><ins>+#if ENABLE(WRITE_BARRIER_PROFILING)
</ins><span class="cx">         WriteBarrierCounters::countWriteBarrier();
</span><ins>+#endif
+        if (!to.isCell())
+            return;
+        writeBarrier(from, to.asCell());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    inline void Heap::writeBarrier(const JSCell*, JSValue)
-    {
-        WriteBarrierCounters::countWriteBarrier();
-    }
-
</del><span class="cx">     inline void Heap::reportExtraMemoryCost(size_t cost)
</span><span class="cx">     {
</span><span class="cx">         if (cost &gt; minExtraCost) 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapOperationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/HeapOperation.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapOperation.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/HeapOperation.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-enum HeapOperation { NoOperation, Allocation, Collection };
</del><ins>+enum HeapOperation { NoOperation, Allocation, FullCollection, EdenCollection };
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkStackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkStack.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkStack.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/MarkStack.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -57,10 +57,31 @@
</span><span class="cx"> 
</span><span class="cx"> MarkStackArray::~MarkStackArray()
</span><span class="cx"> {
</span><del>-    ASSERT(m_numberOfSegments == 1 &amp;&amp; m_segments.size() == 1);
</del><ins>+    ASSERT(m_numberOfSegments == 1);
+    ASSERT(m_segments.size() == 1);
</ins><span class="cx">     m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead()));
</span><ins>+    m_numberOfSegments--;
+    ASSERT(!m_numberOfSegments);
+    ASSERT(!m_segments.size());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MarkStackArray::clear()
+{
+    if (!m_segments.head())
+        return;
+    MarkStackSegment* next;
+    for (MarkStackSegment* current = m_segments.head(); current-&gt;next(); current = next) {
+        next = current-&gt;next();
+        m_segments.remove(current);
+        m_blockAllocator.deallocate(MarkStackSegment::destroy(current));
+    }
+    m_top = 0;
+    m_numberOfSegments = 1;
+#if !ASSERT_DISABLED
+    m_segments.head()-&gt;m_top = 0;
+#endif
+}
+
</ins><span class="cx"> void MarkStackArray::expand()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_segments.head()-&gt;m_top == s_segmentCapacity);
</span><span class="lines">@@ -167,4 +188,28 @@
</span><span class="cx">         append(other.removeLast());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MarkStackArray::fillVector(Vector&lt;const JSCell*&gt;&amp; vector)
+{
+    ASSERT(vector.size() == size());
+
+    MarkStackSegment* currentSegment = m_segments.head();
+    if (!currentSegment)
+        return;
+
+    unsigned count = 0;
+    for (unsigned i = 0; i &lt; m_top; ++i) {
+        ASSERT(currentSegment-&gt;data()[i]);
+        vector[count++] = currentSegment-&gt;data()[i];
+    }
+
+    currentSegment = currentSegment-&gt;next();
+    while (currentSegment) {
+        for (unsigned i = 0; i &lt; s_segmentCapacity; ++i) {
+            ASSERT(currentSegment-&gt;data()[i]);
+            vector[count++] = currentSegment-&gt;data()[i];
+        }
+        currentSegment = currentSegment-&gt;next();
+    }
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkStackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkStack.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkStack.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/MarkStack.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -52,6 +52,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;HeapBlock.h&quot;
</span><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><ins>+#include &lt;wtf/Vector.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -100,6 +101,9 @@
</span><span class="cx">     size_t size();
</span><span class="cx">     bool isEmpty();
</span><span class="cx"> 
</span><ins>+    void fillVector(Vector&lt;const JSCell*&gt;&amp;);
+    void clear();
+
</ins><span class="cx"> private:
</span><span class="cx">     template &lt;size_t size&gt; struct CapacityFromSize {
</span><span class="cx">         static const size_t value = (size - sizeof(MarkStackSegment)) / sizeof(const JSCell*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedAllocatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -10,10 +10,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-bool MarkedAllocator::isPagedOut(double deadline)
</del><ins>+static bool isListPagedOut(double deadline, DoublyLinkedList&lt;MarkedBlock&gt;&amp; list)
</ins><span class="cx"> {
</span><span class="cx">     unsigned itersSinceLastTimeCheck = 0;
</span><del>-    MarkedBlock* block = m_blockList.head();
</del><ins>+    MarkedBlock* block = list.head();
</ins><span class="cx">     while (block) {
</span><span class="cx">         block = block-&gt;next();
</span><span class="cx">         ++itersSinceLastTimeCheck;
</span><span class="lines">@@ -24,7 +24,13 @@
</span><span class="cx">             itersSinceLastTimeCheck = 0;
</span><span class="cx">         }
</span><span class="cx">     }
</span><ins>+    return false;
+}
</ins><span class="cx"> 
</span><ins>+bool MarkedAllocator::isPagedOut(double deadline)
+{
+    if (isListPagedOut(deadline, m_blockList))
+        return true;
</ins><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -36,15 +42,23 @@
</span><span class="cx">     while (!m_freeList.head) {
</span><span class="cx">         DelayedReleaseScope delayedReleaseScope(*m_markedSpace);
</span><span class="cx">         if (m_currentBlock) {
</span><del>-            ASSERT(m_currentBlock == m_blocksToSweep);
</del><ins>+            ASSERT(m_currentBlock == m_nextBlockToSweep);
</ins><span class="cx">             m_currentBlock-&gt;didConsumeFreeList();
</span><del>-            m_blocksToSweep = m_currentBlock-&gt;next();
</del><ins>+            m_nextBlockToSweep = m_currentBlock-&gt;next();
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (MarkedBlock*&amp; block = m_blocksToSweep; block; block = block-&gt;next()) {
</del><ins>+        MarkedBlock* next;
+        for (MarkedBlock*&amp; block = m_nextBlockToSweep; block; block = next) {
+            next = block-&gt;next();
+
</ins><span class="cx">             MarkedBlock::FreeList freeList = block-&gt;sweep(MarkedBlock::SweepToFreeList);
</span><ins>+            
</ins><span class="cx">             if (!freeList.head) {
</span><span class="cx">                 block-&gt;didConsumeEmptyFreeList();
</span><ins>+                m_blockList.remove(block);
+                m_blockList.push(block);
+                if (!m_lastFullBlock)
+                    m_lastFullBlock = block;
</ins><span class="cx">                 continue;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -68,6 +82,7 @@
</span><span class="cx">     MarkedBlock::FreeCell* head = m_freeList.head;
</span><span class="cx">     m_freeList.head = head-&gt;next;
</span><span class="cx">     ASSERT(head);
</span><ins>+    m_markedSpace-&gt;didAllocateInBlock(m_currentBlock);
</ins><span class="cx">     return head;
</span><span class="cx"> }
</span><span class="cx">     
</span><span class="lines">@@ -136,7 +151,7 @@
</span><span class="cx">     ASSERT(!m_freeList.head);
</span><span class="cx">     
</span><span class="cx">     m_blockList.append(block);
</span><del>-    m_blocksToSweep = m_currentBlock = block;
</del><ins>+    m_nextBlockToSweep = m_currentBlock = block;
</ins><span class="cx">     m_freeList = block-&gt;sweep(MarkedBlock::SweepToFreeList);
</span><span class="cx">     m_markedSpace-&gt;didAddBlock(block);
</span><span class="cx"> }
</span><span class="lines">@@ -147,9 +162,27 @@
</span><span class="cx">         m_currentBlock = m_currentBlock-&gt;next();
</span><span class="cx">         m_freeList = MarkedBlock::FreeList();
</span><span class="cx">     }
</span><del>-    if (m_blocksToSweep == block)
-        m_blocksToSweep = m_blocksToSweep-&gt;next();
</del><ins>+    if (m_nextBlockToSweep == block)
+        m_nextBlockToSweep = m_nextBlockToSweep-&gt;next();
+
+    if (block == m_lastFullBlock)
+        m_lastFullBlock = m_lastFullBlock-&gt;prev();
+    
</ins><span class="cx">     m_blockList.remove(block);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MarkedAllocator::reset()
+{
+    m_lastActiveBlock = 0;
+    m_currentBlock = 0;
+    m_freeList = MarkedBlock::FreeList();
+    if (m_heap-&gt;operationInProgress() == FullCollection)
+        m_lastFullBlock = 0;
+
+    if (m_lastFullBlock)
+        m_nextBlockToSweep = m_lastFullBlock-&gt;next() ? m_lastFullBlock-&gt;next() : m_lastFullBlock;
+    else
+        m_nextBlockToSweep = m_blockList.head();
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedAllocatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedAllocator.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedAllocator.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/MarkedAllocator.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -52,7 +52,8 @@
</span><span class="cx">     MarkedBlock::FreeList m_freeList;
</span><span class="cx">     MarkedBlock* m_currentBlock;
</span><span class="cx">     MarkedBlock* m_lastActiveBlock;
</span><del>-    MarkedBlock* m_blocksToSweep;
</del><ins>+    MarkedBlock* m_nextBlockToSweep;
+    MarkedBlock* m_lastFullBlock;
</ins><span class="cx">     DoublyLinkedList&lt;MarkedBlock&gt; m_blockList;
</span><span class="cx">     size_t m_cellSize;
</span><span class="cx">     MarkedBlock::DestructorType m_destructorType;
</span><span class="lines">@@ -68,7 +69,8 @@
</span><span class="cx"> inline MarkedAllocator::MarkedAllocator()
</span><span class="cx">     : m_currentBlock(0)
</span><span class="cx">     , m_lastActiveBlock(0)
</span><del>-    , m_blocksToSweep(0)
</del><ins>+    , m_nextBlockToSweep(0)
+    , m_lastFullBlock(0)
</ins><span class="cx">     , m_cellSize(0)
</span><span class="cx">     , m_destructorType(MarkedBlock::None)
</span><span class="cx">     , m_heap(0)
</span><span class="lines">@@ -102,14 +104,6 @@
</span><span class="cx">     return head;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void MarkedAllocator::reset()
-{
-    m_lastActiveBlock = 0;
-    m_currentBlock = 0;
-    m_freeList = MarkedBlock::FreeList();
-    m_blocksToSweep = m_blockList.head();
-}
-
</del><span class="cx"> inline void MarkedAllocator::stopAllocating()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_lastActiveBlock);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -197,6 +197,45 @@
</span><span class="cx">     m_state = Marked;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MarkedBlock::clearMarks()
+{
+    if (heap()-&gt;operationInProgress() == JSC::EdenCollection)
+        this-&gt;clearMarksWithCollectionType&lt;EdenCollection&gt;();
+    else
+        this-&gt;clearMarksWithCollectionType&lt;FullCollection&gt;();
+}
+
+void MarkedBlock::clearRememberedSet()
+{
+    m_rememberedSet.clearAll();
+}
+
+template &lt;HeapOperation collectionType&gt;
+void MarkedBlock::clearMarksWithCollectionType()
+{
+    ASSERT(collectionType == FullCollection || collectionType == EdenCollection);
+    HEAP_LOG_BLOCK_STATE_TRANSITION(this);
+
+    ASSERT(m_state != New &amp;&amp; m_state != FreeListed);
+    if (collectionType == FullCollection) {
+        m_marks.clearAll();
+        m_rememberedSet.clearAll();
+    }
+
+    // This will become true at the end of the mark phase. We set it now to
+    // avoid an extra pass to do so later.
+    m_state = Marked;
+}
+
+void MarkedBlock::lastChanceToFinalize()
+{
+    m_weakSet.lastChanceToFinalize();
+
+    clearNewlyAllocated();
+    clearMarksWithCollectionType&lt;FullCollection&gt;();
+    sweep();
+}
+
</ins><span class="cx"> MarkedBlock::FreeList MarkedBlock::resumeAllocating()
</span><span class="cx"> {
</span><span class="cx">     HEAP_LOG_BLOCK_STATE_TRANSITION(this);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedBlock.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedBlock.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/MarkedBlock.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx"> #include &quot;BlockAllocator.h&quot;
</span><span class="cx"> #include &quot;HeapBlock.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;HeapOperation.h&quot;
</ins><span class="cx"> #include &quot;WeakSet.h&quot;
</span><span class="cx"> #include &lt;wtf/Bitmap.h&gt;
</span><span class="cx"> #include &lt;wtf/DataLog.h&gt;
</span><span class="lines">@@ -72,7 +73,7 @@
</span><span class="cx">         friend class LLIntOffsetsExtractor;
</span><span class="cx"> 
</span><span class="cx">     public:
</span><del>-        static const size_t atomSize = 8; // bytes
</del><ins>+        static const size_t atomSize = 16; // bytes
</ins><span class="cx">         static const size_t atomShiftAmount = 4; // log_2(atomSize) FIXME: Change atomSize to 16.
</span><span class="cx">         static const size_t blockSize = 64 * KB;
</span><span class="cx">         static const size_t blockMask = ~(blockSize - 1); // blockSize must be a power of two.
</span><span class="lines">@@ -140,11 +141,16 @@
</span><span class="cx">         void stopAllocating(const FreeList&amp;);
</span><span class="cx">         FreeList resumeAllocating(); // Call this if you canonicalized a block for some non-collection related purpose.
</span><span class="cx">         void didConsumeEmptyFreeList(); // Call this if you sweep a block, but the returned FreeList is empty.
</span><ins>+        void didSweepToNoAvail(); // Call this if you sweep a block and get an empty free list back.
</ins><span class="cx"> 
</span><span class="cx">         // Returns true if the &quot;newly allocated&quot; bitmap was non-null 
</span><span class="cx">         // and was successfully cleared and false otherwise.
</span><span class="cx">         bool clearNewlyAllocated();
</span><span class="cx">         void clearMarks();
</span><ins>+        void clearRememberedSet();
+        template &lt;HeapOperation collectionType&gt;
+        void clearMarksWithCollectionType();
+
</ins><span class="cx">         size_t markCount();
</span><span class="cx">         bool isEmpty();
</span><span class="cx"> 
</span><span class="lines">@@ -161,6 +167,11 @@
</span><span class="cx">         void setMarked(const void*);
</span><span class="cx">         void clearMarked(const void*);
</span><span class="cx"> 
</span><ins>+        void setRemembered(const void*);
+        void clearRemembered(const void*);
+        void atomicClearRemembered(const void*);
+        bool isRemembered(const void*);
+
</ins><span class="cx">         bool isNewlyAllocated(const void*);
</span><span class="cx">         void setNewlyAllocated(const void*);
</span><span class="cx">         void clearNewlyAllocated(const void*);
</span><span class="lines">@@ -190,9 +201,11 @@
</span><span class="cx">         size_t m_atomsPerCell;
</span><span class="cx">         size_t m_endAtom; // This is a fuzzy end. Always test for &lt; m_endAtom.
</span><span class="cx"> #if ENABLE(PARALLEL_GC)
</span><del>-        WTF::Bitmap&lt;atomsPerBlock, WTF::BitmapAtomic&gt; m_marks;
</del><ins>+        WTF::Bitmap&lt;atomsPerBlock, WTF::BitmapAtomic, uint8_t&gt; m_marks;
+        WTF::Bitmap&lt;atomsPerBlock, WTF::BitmapAtomic, uint8_t&gt; m_rememberedSet;
</ins><span class="cx"> #else
</span><del>-        WTF::Bitmap&lt;atomsPerBlock, WTF::BitmapNotAtomic&gt; m_marks;
</del><ins>+        WTF::Bitmap&lt;atomsPerBlock, WTF::BitmapNotAtomic, uint8_t&gt; m_marks;
+        WTF::Bitmap&lt;atomsPerBlock, WTF::BitmapNotAtomic, uint8_t&gt; m_rememberedSet;
</ins><span class="cx"> #endif
</span><span class="cx">         OwnPtr&lt;WTF::Bitmap&lt;atomsPerBlock&gt;&gt; m_newlyAllocated;
</span><span class="cx"> 
</span><span class="lines">@@ -234,15 +247,6 @@
</span><span class="cx">         return reinterpret_cast&lt;MarkedBlock*&gt;(reinterpret_cast&lt;Bits&gt;(p) &amp; blockMask);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    inline void MarkedBlock::lastChanceToFinalize()
-    {
-        m_weakSet.lastChanceToFinalize();
-
-        clearNewlyAllocated();
-        clearMarks();
-        sweep();
-    }
-
</del><span class="cx">     inline MarkedAllocator* MarkedBlock::allocator() const
</span><span class="cx">     {
</span><span class="cx">         return m_allocator;
</span><span class="lines">@@ -291,26 +295,10 @@
</span><span class="cx">         HEAP_LOG_BLOCK_STATE_TRANSITION(this);
</span><span class="cx"> 
</span><span class="cx">         ASSERT(!m_newlyAllocated);
</span><del>-#ifndef NDEBUG
-        for (size_t i = firstAtom(); i &lt; m_endAtom; i += m_atomsPerCell)
-            ASSERT(m_marks.get(i));
-#endif
</del><span class="cx">         ASSERT(m_state == FreeListed);
</span><span class="cx">         m_state = Marked;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    inline void MarkedBlock::clearMarks()
-    {
-        HEAP_LOG_BLOCK_STATE_TRANSITION(this);
-
-        ASSERT(m_state != New &amp;&amp; m_state != FreeListed);
-        m_marks.clearAll();
-
-        // This will become true at the end of the mark phase. We set it now to
-        // avoid an extra pass to do so later.
-        m_state = Marked;
-    }
-
</del><span class="cx">     inline size_t MarkedBlock::markCount()
</span><span class="cx">     {
</span><span class="cx">         return m_marks.count();
</span><span class="lines">@@ -346,6 +334,26 @@
</span><span class="cx">         return (reinterpret_cast&lt;Bits&gt;(p) - reinterpret_cast&lt;Bits&gt;(this)) / atomSize;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    inline void MarkedBlock::setRemembered(const void* p)
+    {
+        m_rememberedSet.set(atomNumber(p));
+    }
+
+    inline void MarkedBlock::clearRemembered(const void* p)
+    {
+        m_rememberedSet.clear(atomNumber(p));
+    }
+
+    inline void MarkedBlock::atomicClearRemembered(const void* p)
+    {
+        m_rememberedSet.concurrentTestAndClear(atomNumber(p));
+    }
+
+    inline bool MarkedBlock::isRemembered(const void* p)
+    {
+        return m_rememberedSet.get(atomNumber(p));
+    }
+
</ins><span class="cx">     inline bool MarkedBlock::isMarked(const void* p)
</span><span class="cx">     {
</span><span class="cx">         return m_marks.get(atomNumber(p));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedSpacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -105,6 +105,7 @@
</span><span class="cx"> {
</span><span class="cx">     Free free(Free::FreeAll, this);
</span><span class="cx">     forEachBlock(free);
</span><ins>+    ASSERT(!m_blocks.set().size());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> struct LastChanceToFinalize : MarkedBlock::VoidFunctor {
</span><span class="lines">@@ -143,17 +144,27 @@
</span><span class="cx">     m_normalSpace.largeAllocator.reset();
</span><span class="cx">     m_normalDestructorSpace.largeAllocator.reset();
</span><span class="cx">     m_immortalStructureDestructorSpace.largeAllocator.reset();
</span><ins>+
+    m_blocksWithNewObjects.clear();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MarkedSpace::visitWeakSets(HeapRootVisitor&amp; heapRootVisitor)
</span><span class="cx"> {
</span><span class="cx">     VisitWeakSet visitWeakSet(heapRootVisitor);
</span><del>-    forEachBlock(visitWeakSet);
</del><ins>+    if (m_heap-&gt;operationInProgress() == EdenCollection) {
+        for (unsigned i = 0; i &lt; m_blocksWithNewObjects.size(); ++i)
+            visitWeakSet(m_blocksWithNewObjects[i]);
+    } else
+        forEachBlock(visitWeakSet);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MarkedSpace::reapWeakSets()
</span><span class="cx"> {
</span><del>-    forEachBlock&lt;ReapWeakSet&gt;();
</del><ins>+    if (m_heap-&gt;operationInProgress() == EdenCollection) {
+        for (unsigned i = 0; i &lt; m_blocksWithNewObjects.size(); ++i)
+            m_blocksWithNewObjects[i]-&gt;reapWeakSet();
+    } else
+        forEachBlock&lt;ReapWeakSet&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename Functor&gt;
</span><span class="lines">@@ -305,6 +316,24 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#ifndef NDEBUG
+struct VerifyMarked : MarkedBlock::VoidFunctor {
+    void operator()(MarkedBlock* block) { ASSERT(block-&gt;needsSweeping()); }
+};
+#endif
+
+void MarkedSpace::clearMarks()
+{
+    if (m_heap-&gt;operationInProgress() == EdenCollection) {
+        for (unsigned i = 0; i &lt; m_blocksWithNewObjects.size(); ++i)
+            m_blocksWithNewObjects[i]-&gt;clearMarks();
+    } else
+        forEachBlock&lt;ClearMarks&gt;();
+#ifndef NDEBUG
+    forEachBlock&lt;VerifyMarked&gt;();
+#endif
+}
+
</ins><span class="cx"> void MarkedSpace::willStartIterating()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!isIterating());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedSpaceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedSpace.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedSpace.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/MarkedSpace.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -46,9 +46,19 @@
</span><span class="cx"> class SlotVisitor;
</span><span class="cx"> 
</span><span class="cx"> struct ClearMarks : MarkedBlock::VoidFunctor {
</span><del>-    void operator()(MarkedBlock* block) { block-&gt;clearMarks(); }
</del><ins>+    void operator()(MarkedBlock* block)
+    {
+        block-&gt;clearMarks();
+    }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct ClearRememberedSet : MarkedBlock::VoidFunctor {
+    void operator()(MarkedBlock* block)
+    {
+        block-&gt;clearRememberedSet();
+    }
+};
+
</ins><span class="cx"> struct Sweep : MarkedBlock::VoidFunctor {
</span><span class="cx">     void operator()(MarkedBlock* block) { block-&gt;sweep(); }
</span><span class="cx"> };
</span><span class="lines">@@ -105,8 +115,10 @@
</span><span class="cx"> 
</span><span class="cx">     void didAddBlock(MarkedBlock*);
</span><span class="cx">     void didConsumeFreeList(MarkedBlock*);
</span><ins>+    void didAllocateInBlock(MarkedBlock*);
</ins><span class="cx"> 
</span><span class="cx">     void clearMarks();
</span><ins>+    void clearRememberedSet();
</ins><span class="cx">     void clearNewlyAllocated();
</span><span class="cx">     void sweep();
</span><span class="cx">     size_t objectCount();
</span><span class="lines">@@ -150,6 +162,7 @@
</span><span class="cx">     size_t m_capacity;
</span><span class="cx">     bool m_isIterating;
</span><span class="cx">     MarkedBlockSet m_blocks;
</span><ins>+    Vector&lt;MarkedBlock*&gt; m_blocksWithNewObjects;
</ins><span class="cx"> 
</span><span class="cx">     DelayedReleaseScope* m_currentDelayedReleaseScope;
</span><span class="cx"> };
</span><span class="lines">@@ -262,11 +275,16 @@
</span><span class="cx">     m_blocks.add(block);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void MarkedSpace::clearMarks()
</del><ins>+inline void MarkedSpace::didAllocateInBlock(MarkedBlock* block)
</ins><span class="cx"> {
</span><del>-    forEachBlock&lt;ClearMarks&gt;();
</del><ins>+    m_blocksWithNewObjects.append(block);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void MarkedSpace::clearRememberedSet()
+{
+    forEachBlock&lt;ClearRememberedSet&gt;();
+}
+
</ins><span class="cx"> inline size_t MarkedSpace::objectCount()
</span><span class="cx"> {
</span><span class="cx">     return forEachBlock&lt;MarkCount&gt;();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapSlotVisitorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> SlotVisitor::~SlotVisitor()
</span><span class="cx"> {
</span><del>-    ASSERT(m_stack.isEmpty());
</del><ins>+    clearMarkStack();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SlotVisitor::setup()
</span><span class="lines">@@ -63,6 +63,11 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SlotVisitor::clearMarkStack()
+{
+    m_stack.clear();
+}
+
</ins><span class="cx"> void SlotVisitor::append(ConservativeRoots&amp; conservativeRoots)
</span><span class="cx"> {
</span><span class="cx">     StackStats::probe();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapSlotVisitorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/SlotVisitor.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/SlotVisitor.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/SlotVisitor.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -49,6 +49,10 @@
</span><span class="cx">     SlotVisitor(GCThreadSharedData&amp;);
</span><span class="cx">     ~SlotVisitor();
</span><span class="cx"> 
</span><ins>+    MarkStackArray&amp; markStack() { return m_stack; }
+
+    Heap* heap() const;
+
</ins><span class="cx">     void append(ConservativeRoots&amp;);
</span><span class="cx">     
</span><span class="cx">     template&lt;typename T&gt; void append(JITWriteBarrier&lt;T&gt;*);
</span><span class="lines">@@ -61,17 +65,19 @@
</span><span class="cx">     void appendUnbarrieredValue(JSValue*);
</span><span class="cx">     template&lt;typename T&gt;
</span><span class="cx">     void appendUnbarrieredWeak(Weak&lt;T&gt;*);
</span><ins>+    void unconditionallyAppend(JSCell*);
</ins><span class="cx">     
</span><span class="cx">     void addOpaqueRoot(void*);
</span><span class="cx">     bool containsOpaqueRoot(void*);
</span><span class="cx">     TriState containsOpaqueRootTriState(void*);
</span><span class="cx">     int opaqueRootCount();
</span><span class="cx"> 
</span><del>-    GCThreadSharedData&amp; sharedData() { return m_shared; }
</del><ins>+    GCThreadSharedData&amp; sharedData() const { return m_shared; }
</ins><span class="cx">     bool isEmpty() { return m_stack.isEmpty(); }
</span><span class="cx"> 
</span><span class="cx">     void setup();
</span><span class="cx">     void reset();
</span><ins>+    void clearMarkStack();
</ins><span class="cx"> 
</span><span class="cx">     size_t bytesVisited() const { return m_bytesVisited; }
</span><span class="cx">     size_t bytesCopied() const { return m_bytesCopied; }
</span><span class="lines">@@ -89,7 +95,7 @@
</span><span class="cx"> 
</span><span class="cx">     void copyLater(JSCell*, CopyToken, void*, size_t);
</span><span class="cx">     
</span><del>-    void reportExtraMemoryUsage(size_t size);
</del><ins>+    void reportExtraMemoryUsage(JSCell* owner, size_t);
</ins><span class="cx">     
</span><span class="cx">     void addWeakReferenceHarvester(WeakReferenceHarvester*);
</span><span class="cx">     void addUnconditionalFinalizer(UnconditionalFinalizer*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapSlotVisitorInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/SlotVisitorInlines.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/SlotVisitorInlines.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/heap/SlotVisitorInlines.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -105,6 +105,14 @@
</span><span class="cx">         
</span><span class="cx">     MARK_LOG_CHILD(*this, cell);
</span><span class="cx"> 
</span><ins>+    unconditionallyAppend(cell);
+}
+
+ALWAYS_INLINE void SlotVisitor::unconditionallyAppend(JSCell* cell)
+{
+    ASSERT(Heap::isMarked(cell));
+    m_visitCount++;
+        
</ins><span class="cx">     // Should never attempt to mark something that is zapped.
</span><span class="cx">     ASSERT(!cell-&gt;isZapped());
</span><span class="cx">         
</span><span class="lines">@@ -218,6 +226,9 @@
</span><span class="cx"> inline void SlotVisitor::copyLater(JSCell* owner, CopyToken token, void* ptr, size_t bytes)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(bytes);
</span><ins>+    // We don't do any copying during EdenCollections.
+    ASSERT(heap()-&gt;operationInProgress() != EdenCollection);
+
</ins><span class="cx">     m_bytesCopied += bytes;
</span><span class="cx"> 
</span><span class="cx">     CopiedBlock* block = CopiedSpace::blockFor(ptr);
</span><span class="lines">@@ -226,14 +237,15 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (block-&gt;isPinned())
-        return;
-
</del><span class="cx">     block-&gt;reportLiveBytes(owner, token, bytes);
</span><span class="cx"> }
</span><span class="cx">     
</span><del>-inline void SlotVisitor::reportExtraMemoryUsage(size_t size)
</del><ins>+inline void SlotVisitor::reportExtraMemoryUsage(JSCell* owner, size_t size)
</ins><span class="cx"> {
</span><ins>+    // We don't want to double-count the extra memory that was reported in previous collections.
+    if (heap()-&gt;operationInProgress() == EdenCollection &amp;&amp; MarkedBlock::blockFor(owner)-&gt;isRemembered(owner))
+        return;
+
</ins><span class="cx">     size_t* counter = &amp;m_shared.m_vm-&gt;heap.m_extraMemoryUsage;
</span><span class="cx">     
</span><span class="cx"> #if ENABLE(COMPARE_AND_SWAP)
</span><span class="lines">@@ -247,6 +259,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline Heap* SlotVisitor::heap() const
+{
+    return &amp;sharedData().m_vm-&gt;heap;
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // SlotVisitorInlines_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include &quot;PolymorphicPutByIdList.h&quot;
</span><span class="cx"> #include &quot;RepatchBuffer.h&quot;
</span><span class="cx"> #include &quot;ScratchRegisterAllocator.h&quot;
</span><ins>+#include &quot;StackAlignment.h&quot;
</ins><span class="cx"> #include &quot;StructureRareDataInlines.h&quot;
</span><span class="cx"> #include &quot;StructureStubClearingWatchpoint.h&quot;
</span><span class="cx"> #include &quot;ThunkGenerators.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGenericTypedArrayViewInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -447,7 +447,7 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case OversizeTypedArray: {
</span><del>-        visitor.reportExtraMemoryUsage(thisObject-&gt;byteSize());
</del><ins>+        visitor.reportExtraMemoryUsage(thisObject, thisObject-&gt;byteSize());
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSPropertyNameIteratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -109,9 +109,9 @@
</span><span class="cx">         return m_enumerationCache.get();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    inline void StructureRareData::setEnumerationCache(VM&amp; vm, const Structure* owner, JSPropertyNameIterator* value)
</del><ins>+    inline void StructureRareData::setEnumerationCache(VM&amp; vm, const Structure*, JSPropertyNameIterator* value)
</ins><span class="cx">     {
</span><del>-        m_enumerationCache.set(vm, owner, value);
</del><ins>+        m_enumerationCache.set(vm, this, value);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSStringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSString.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSString.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/runtime/JSString.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx">     else {
</span><span class="cx">         StringImpl* impl = thisObject-&gt;m_value.impl();
</span><span class="cx">         ASSERT(impl);
</span><del>-        visitor.reportExtraMemoryUsage(impl-&gt;costDuringGC());
</del><ins>+        visitor.reportExtraMemoryUsage(thisObject, impl-&gt;costDuringGC());
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureRareDataInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -35,9 +35,9 @@
</span><span class="cx">     return m_previous.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void StructureRareData::setPreviousID(VM&amp; vm, Structure* transition, Structure* structure)
</del><ins>+inline void StructureRareData::setPreviousID(VM&amp; vm, Structure*, Structure* structure)
</ins><span class="cx"> {
</span><del>-    m_previous.set(vm, transition, structure);
</del><ins>+    m_previous.set(vm, this, structure);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void StructureRareData::clearPreviousID()
</span><span class="lines">@@ -50,9 +50,9 @@
</span><span class="cx">     return m_objectToStringValue.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void StructureRareData::setObjectToStringValue(VM&amp; vm, const JSCell* owner, JSString* value)
</del><ins>+inline void StructureRareData::setObjectToStringValue(VM&amp; vm, const JSCell*, JSString* value)
</ins><span class="cx"> {
</span><del>-    m_objectToStringValue.set(vm, owner, value);
</del><ins>+    m_objectToStringValue.set(vm, this, value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeWeakMapDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/WeakMapData.cpp (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/WeakMapData.cpp        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/JavaScriptCore/runtime/WeakMapData.cpp        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -64,7 +64,7 @@
</span><span class="cx">     // Rough approximation of the external storage needed for the hashtable.
</span><span class="cx">     // This isn't exact, but it is close enough, and proportional to the actual
</span><span class="cx">     // external mermory usage.
</span><del>-    visitor.reportExtraMemoryUsage(thisObj-&gt;m_map.capacity() * (sizeof(JSObject*) + sizeof(WriteBarrier&lt;Unknown&gt;)));
</del><ins>+    visitor.reportExtraMemoryUsage(thisObj, thisObj-&gt;m_map.capacity() * (sizeof(JSObject*) + sizeof(WriteBarrier&lt;Unknown&gt;)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WeakMapData::set(VM&amp; vm, JSObject* key, JSValue value)
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/WTF/ChangeLog        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2014-01-07  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
+
+        Marking should be generational
+        https://bugs.webkit.org/show_bug.cgi?id=126552
+
+        Reviewed by Geoffrey Garen.
+
+        * wtf/Bitmap.h:
+        (WTF::WordType&gt;::count): Added a cast that became necessary when Bitmap
+        is used with smaller types than int32_t.
+
</ins><span class="cx"> 2014-01-09  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Enable async scrolling for iOS
</span></span></pre></div>
<a id="trunkSourceWTFwtfBitmaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Bitmap.h (161614 => 161615)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Bitmap.h        2014-01-10 02:02:45 UTC (rev 161614)
+++ trunk/Source/WTF/wtf/Bitmap.h        2014-01-10 02:28:27 UTC (rev 161615)
</span><span class="lines">@@ -196,7 +196,7 @@
</span><span class="cx">             ++result;
</span><span class="cx">     }
</span><span class="cx">     for (size_t i = start / wordSize; i &lt; words; ++i)
</span><del>-        result += WTF::bitCount(bits[i]);
</del><ins>+        result += WTF::bitCount(static_cast&lt;unsigned&gt;(bits[i]));
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>