<!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>[161230] trunk/Source/JavaScriptCore</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/161230">161230</a></dd>
<dt>Author</dt> <dd>mhahnenberg@apple.com</dd>
<dt>Date</dt> <dd>2014-01-02 14:57:14 -0800 (Thu, 02 Jan 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Storing new CopiedSpace memory into a JSObject should fire a write barrier
https://bugs.webkit.org/show_bug.cgi?id=126025
Reviewed by Filip Pizlo.
Technically this is creating a pointer between a (potentially) old generation object and a young
generation chunk of memory, thus there needs to be a barrier.
* JavaScriptCore.xcodeproj/project.pbxproj:
* dfg/DFGOperations.cpp:
* heap/CopyWriteBarrier.h: Added. This class functions similarly to the WriteBarrier class. It
acts as a proxy for pointers to CopiedSpace. Assignments to the field cause a write barrier to
fire for the object that is the owner of the CopiedSpace memory. This is to ensure during nursery
collections that objects with new backing stores are visited, even if they are old generation objects.
(JSC::CopyWriteBarrier::CopyWriteBarrier):
(JSC::CopyWriteBarrier::operator!):
(JSC::CopyWriteBarrier::operator UnspecifiedBoolType*):
(JSC::CopyWriteBarrier::get):
(JSC::CopyWriteBarrier::operator*):
(JSC::CopyWriteBarrier::operator->):
(JSC::CopyWriteBarrier::set):
(JSC::CopyWriteBarrier::setWithoutWriteBarrier):
(JSC::CopyWriteBarrier::clear):
* heap/Heap.h:
* runtime/JSArray.cpp:
(JSC::JSArray::unshiftCountSlowCase):
(JSC::JSArray::shiftCountWithArrayStorage):
(JSC::JSArray::unshiftCountWithArrayStorage):
* runtime/JSCell.h:
(JSC::JSCell::unvalidatedStructure):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory):
* runtime/JSObject.cpp:
(JSC::JSObject::copyButterfly):
(JSC::JSObject::getOwnPropertySlotByIndex):
(JSC::JSObject::putByIndex):
(JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
(JSC::JSObject::createInitialIndexedStorage):
(JSC::JSObject::createArrayStorage):
(JSC::JSObject::deletePropertyByIndex):
(JSC::JSObject::getOwnPropertyNames):
(JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
(JSC::JSObject::countElements):
(JSC::JSObject::increaseVectorLength):
(JSC::JSObject::ensureLengthSlow):
* runtime/JSObject.h:
(JSC::JSObject::butterfly):
(JSC::JSObject::setStructureAndButterfly):
(JSC::JSObject::setButterflyWithoutChangingStructure):
(JSC::JSObject::JSObject):
(JSC::JSObject::putDirectInternal):
(JSC::JSObject::putDirectWithoutTransition):
* runtime/MapData.cpp:
(JSC::MapData::ensureSpaceForAppend):
* runtime/Structure.cpp:
(JSC::Structure::materializePropertyMap):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreGNUmakefilelistam">trunk/Source/JavaScriptCore/GNUmakefile.list.am</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArraycpp">trunk/Source/JavaScriptCore/runtime/JSArray.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCellh">trunk/Source/JavaScriptCore/runtime/JSCell.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGenericTypedArrayViewInlinesh">trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjectcpp">trunk/Source/JavaScriptCore/runtime/JSObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjecth">trunk/Source/JavaScriptCore/runtime/JSObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeMapDatacpp">trunk/Source/JavaScriptCore/runtime/MapData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructurecpp">trunk/Source/JavaScriptCore/runtime/Structure.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreheapCopyWriteBarrierh">trunk/Source/JavaScriptCore/heap/CopyWriteBarrier.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -1,3 +1,62 @@
</span><ins>+2014-01-02 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Storing new CopiedSpace memory into a JSObject should fire a write barrier
+ https://bugs.webkit.org/show_bug.cgi?id=126025
+
+ Reviewed by Filip Pizlo.
+
+ Technically this is creating a pointer between a (potentially) old generation object and a young
+ generation chunk of memory, thus there needs to be a barrier.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGOperations.cpp:
+ * heap/CopyWriteBarrier.h: Added. This class functions similarly to the WriteBarrier class. It
+ acts as a proxy for pointers to CopiedSpace. Assignments to the field cause a write barrier to
+ fire for the object that is the owner of the CopiedSpace memory. This is to ensure during nursery
+ collections that objects with new backing stores are visited, even if they are old generation objects.
+ (JSC::CopyWriteBarrier::CopyWriteBarrier):
+ (JSC::CopyWriteBarrier::operator!):
+ (JSC::CopyWriteBarrier::operator UnspecifiedBoolType*):
+ (JSC::CopyWriteBarrier::get):
+ (JSC::CopyWriteBarrier::operator*):
+ (JSC::CopyWriteBarrier::operator->):
+ (JSC::CopyWriteBarrier::set):
+ (JSC::CopyWriteBarrier::setWithoutWriteBarrier):
+ (JSC::CopyWriteBarrier::clear):
+ * heap/Heap.h:
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::unshiftCountSlowCase):
+ (JSC::JSArray::shiftCountWithArrayStorage):
+ (JSC::JSArray::unshiftCountWithArrayStorage):
+ * runtime/JSCell.h:
+ (JSC::JSCell::unvalidatedStructure):
+ * runtime/JSGenericTypedArrayViewInlines.h:
+ (JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::copyButterfly):
+ (JSC::JSObject::getOwnPropertySlotByIndex):
+ (JSC::JSObject::putByIndex):
+ (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
+ (JSC::JSObject::createInitialIndexedStorage):
+ (JSC::JSObject::createArrayStorage):
+ (JSC::JSObject::deletePropertyByIndex):
+ (JSC::JSObject::getOwnPropertyNames):
+ (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
+ (JSC::JSObject::countElements):
+ (JSC::JSObject::increaseVectorLength):
+ (JSC::JSObject::ensureLengthSlow):
+ * runtime/JSObject.h:
+ (JSC::JSObject::butterfly):
+ (JSC::JSObject::setStructureAndButterfly):
+ (JSC::JSObject::setButterflyWithoutChangingStructure):
+ (JSC::JSObject::JSObject):
+ (JSC::JSObject::putDirectInternal):
+ (JSC::JSObject::putDirectWithoutTransition):
+ * runtime/MapData.cpp:
+ (JSC::MapData::ensureSpaceForAppend):
+ * runtime/Structure.cpp:
+ (JSC::Structure::materializePropertyMap):
+
</ins><span class="cx"> 2013-12-23 Oliver Hunt <oliver@apple.com>
</span><span class="cx">
</span><span class="cx"> Refactor PutPropertySlot to be aware of custom properties
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/GNUmakefile.list.am (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/GNUmakefile.list.am        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/GNUmakefile.list.am        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -502,6 +502,7 @@
</span><span class="cx">         Source/JavaScriptCore/heap/CopyVisitorInlines.h \
</span><span class="cx">         Source/JavaScriptCore/heap/CopyVisitor.cpp \
</span><span class="cx">         Source/JavaScriptCore/heap/CopyWorkList.h \
</span><ins>+        Source/JavaScriptCore/heap/CopyWriteBarrier.h \
</ins><span class="cx">         Source/JavaScriptCore/heap/ConservativeRoots.cpp \
</span><span class="cx">         Source/JavaScriptCore/heap/ConservativeRoots.h \
</span><span class="cx"> Source/JavaScriptCore/heap/DeferGC.cpp \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -984,6 +984,7 @@
</span><span class="cx"> <ClInclude Include="..\heap\CopyVisitor.h" />
</span><span class="cx"> <ClInclude Include="..\heap\CopyVisitorInlines.h" />
</span><span class="cx"> <ClInclude Include="..\heap\CopyWorkList.h" />
</span><ins>+ <ClInclude Include="..\heap\CopyWriteBarrier.h" />
</ins><span class="cx"> <ClInclude Include="..\heap\DeferGC.h" />
</span><span class="cx"> <ClInclude Include="..\heap\DelayedReleaseScope.h" />
</span><span class="cx"> <ClInclude Include="..\heap\GCAssertions.h" />
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -1628,6 +1628,9 @@
</span><span class="cx"> <ClInclude Include="..\heap\CopyWorkList.h">
</span><span class="cx"> <Filter>heap</Filter>
</span><span class="cx"> </ClInclude>
</span><ins>+ <ClInclude Include="..\heap\CopyWriteBarrier.h">
+ <Filter>heap</Filter>
+ </ClInclude>
</ins><span class="cx"> <ClInclude Include="..\heap\DeferGC.h">
</span><span class="cx"> <Filter>heap</Filter>
</span><span class="cx"> </ClInclude>
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -720,6 +720,7 @@
</span><span class="cx">                 2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = C211B574176A224D000E2A23 /* APICallbackFunction.h */; };
</span><span class="cx">                 2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */; };
</span><span class="cx">                 2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A6F462517E959CE00C45C98 /* HeapOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */; };
</span><span class="cx">                 2AAD964A18569417001F93BE /* RecursiveAllocationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AAD964918569417001F93BE /* RecursiveAllocationScope.h */; };
</span><span class="lines">@@ -2027,6 +2028,7 @@
</span><span class="cx">                 2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DelayedReleaseScope.h; sourceTree = "<group>"; };
</span><span class="cx">                 2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierBuffer.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierBuffer.h; sourceTree = "<group>"; };
</span><ins>+                2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyWriteBarrier.h; sourceTree = "<group>"; };
</ins><span class="cx">                 2A6F462517E959CE00C45C98 /* HeapOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapOperation.h; sourceTree = "<group>"; };
</span><span class="cx">                 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeferGC.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 2AAD964918569417001F93BE /* RecursiveAllocationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecursiveAllocationScope.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -3212,6 +3214,7 @@
</span><span class="cx">                                 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */,
</span><span class="cx">                                 2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */,
</span><span class="cx">                                 2AAD964918569417001F93BE /* RecursiveAllocationScope.h */,
</span><ins>+                                2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = heap;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -4373,6 +4376,7 @@
</span><span class="cx">                                 86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
</span><span class="cx">                                 86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
</span><span class="cx">                                 65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */,
</span><ins>+                                2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */,
</ins><span class="cx">                                 2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */,
</span><span class="cx">                                 A532439218569709002ED692 /* CodeGeneratorInspector.py in Headers */,
</span><span class="cx">                                 A532439318569709002ED692 /* CodeGeneratorInspectorStrings.py in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -851,7 +851,7 @@
</span><span class="cx">
</span><span class="cx"> ASSERT(!object->structure()->outOfLineCapacity());
</span><span class="cx"> Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
</span><del>- object->setButterflyWithoutChangingStructure(result);
</del><ins>+ object->setButterflyWithoutChangingStructure(vm, result);
</ins><span class="cx"> return reinterpret_cast<char*>(result);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -861,7 +861,7 @@
</span><span class="cx"> NativeCallFrameTracer tracer(&vm, exec);
</span><span class="cx">
</span><span class="cx"> Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
</span><del>- object->setButterflyWithoutChangingStructure(result);
</del><ins>+ object->setButterflyWithoutChangingStructure(vm, result);
</ins><span class="cx"> return reinterpret_cast<char*>(result);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCopyWriteBarrierh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/CopyWriteBarrier.h (0 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CopyWriteBarrier.h         (rev 0)
+++ trunk/Source/JavaScriptCore/heap/CopyWriteBarrier.h        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CopyWriteBarrier_h
+#define CopyWriteBarrier_h
+
+#include "Heap.h"
+
+namespace JSC {
+
+template <typename T>
+class CopyWriteBarrier {
+public:
+ CopyWriteBarrier()
+ : m_value(0)
+ {
+ }
+
+ CopyWriteBarrier(VM& vm, const JSCell* owner, T& value)
+ {
+ this->set(vm, owner, &value);
+ }
+
+ CopyWriteBarrier(VM& vm, const JSCell* owner, T* value)
+ {
+ this->set(vm, owner, value);
+ }
+
+ bool operator!() const { return !m_value; }
+
+ typedef T* (CopyWriteBarrier::*UnspecifiedBoolType);
+ operator UnspecifiedBoolType*() const { return m_value ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+
+ T* get() const
+ {
+ return m_value;
+ }
+
+ T* operator*() const
+ {
+ return get();
+ }
+
+ T* operator->() const
+ {
+ return get();
+ }
+
+ void set(VM&, const JSCell* owner, T* value)
+ {
+ this->m_value = value;
+ Heap::writeBarrier(owner);
+ }
+
+ void setWithoutWriteBarrier(T* value)
+ {
+ this->m_value = value;
+ }
+
+ void clear() { m_value = 0; }
+
+private:
+ T* m_value;
+};
+
+} // namespace JSC
+
+#endif // CopyWriteBarrier_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArraycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.cpp (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -321,9 +321,8 @@
</span><span class="cx">
</span><span class="cx"> newButterfly->arrayStorage()->setVectorLength(newVectorLength);
</span><span class="cx"> newButterfly->arrayStorage()->m_indexBias = newIndexBias;
</span><ins>+ setButterflyWithoutChangingStructure(vm, newButterfly);
</ins><span class="cx">
</span><del>- m_butterfly = newButterfly;
-
</del><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -720,7 +719,7 @@
</span><span class="cx"> // Adjust the Butterfly and the index bias. We only need to do this here because we're changing
</span><span class="cx"> // the start of the Butterfly, which needs to point at the first indexed property in the used
</span><span class="cx"> // portion of the vector.
</span><del>- m_butterfly = m_butterfly->shift(structure(), count);
</del><ins>+ m_butterfly.setWithoutWriteBarrier(m_butterfly->shift(structure(), count));
</ins><span class="cx"> storage = m_butterfly->arrayStorage();
</span><span class="cx"> storage->m_indexBias += count;
</span><span class="cx">
</span><span class="lines">@@ -857,10 +856,11 @@
</span><span class="cx"> unsigned vectorLength = storage->vectorLength();
</span><span class="cx">
</span><span class="cx"> if (moveFront && storage->m_indexBias >= count) {
</span><del>- m_butterfly = storage->butterfly()->unshift(structure(), count);
- storage = m_butterfly->arrayStorage();
</del><ins>+ Butterfly* newButterfly = storage->butterfly()->unshift(structure(), count);
+ storage = newButterfly->arrayStorage();
</ins><span class="cx"> storage->m_indexBias -= count;
</span><span class="cx"> storage->setVectorLength(vectorLength + count);
</span><ins>+ setButterflyWithoutChangingStructure(exec->vm(), newButterfly);
</ins><span class="cx"> } else if (!moveFront && vectorLength - length >= count)
</span><span class="cx"> storage = storage->butterfly()->arrayStorage();
</span><span class="cx"> else if (unshiftCountSlowCase(exec->vm(), moveFront, count))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCellh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCell.h (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCell.h        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/runtime/JSCell.h        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -146,7 +146,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(GC_VALIDATION)
</span><del>- Structure* unvalidatedStructure() { return m_structure.unvalidatedGet(); }
</del><ins>+ Structure* unvalidatedStructure() const { return m_structure.unvalidatedGet(); }
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> static const TypedArrayType TypedArrayStorageType = NotTypedArray;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGenericTypedArrayViewInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -506,15 +506,16 @@
</span><span class="cx"> size_t size = thisObject->byteSize();
</span><span class="cx">
</span><span class="cx"> if (thisObject->m_mode == FastTypedArray
</span><del>- && !thisObject->m_butterfly && size >= sizeof(IndexingHeader)) {
</del><ins>+ && !thisObject->butterfly() && size >= sizeof(IndexingHeader)) {
</ins><span class="cx"> ASSERT(thisObject->m_vector);
</span><span class="cx"> // Reuse already allocated memory if at all possible.
</span><del>- thisObject->m_butterfly =
- static_cast<IndexingHeader*>(thisObject->m_vector)->butterfly();
</del><ins>+ thisObject->m_butterfly.setWithoutWriteBarrier(
+ static_cast<IndexingHeader*>(thisObject->m_vector)->butterfly());
</ins><span class="cx"> } else {
</span><del>- thisObject->m_butterfly = Butterfly::createOrGrowArrayRight(
- thisObject->m_butterfly, *heap->vm(), thisObject, thisObject->structure(),
- thisObject->structure()->outOfLineCapacity(), false, 0, 0);
</del><ins>+ VM& vm = *heap->vm();
+ thisObject->m_butterfly.set(vm, thisObject, Butterfly::createOrGrowArrayRight(
+ thisObject->butterfly(), vm, thisObject, thisObject->structure(),
+ thisObject->structure()->outOfLineCapacity(), false, 0, 0));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RefPtr<ArrayBuffer> buffer;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.cpp (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -159,7 +159,7 @@
</span><span class="cx"> memcpy(currentTarget, currentSource, count * sizeof(EncodedJSValue));
</span><span class="cx"> }
</span><span class="cx">
</span><del>- m_butterfly = newButterfly;
</del><ins>+ m_butterfly.setWithoutWriteBarrier(newButterfly);
</ins><span class="cx"> visitor.didCopy(butterfly->base(preCapacity, propertyCapacity), capacityInBytes);
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -283,7 +283,7 @@
</span><span class="cx">
</span><span class="cx"> case ALL_INT32_INDEXING_TYPES:
</span><span class="cx"> case ALL_CONTIGUOUS_INDEXING_TYPES: {
</span><del>- Butterfly* butterfly = thisObject->m_butterfly;
</del><ins>+ Butterfly* butterfly = thisObject->butterfly();
</ins><span class="cx"> if (i >= butterfly->vectorLength())
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="lines">@@ -297,7 +297,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case ALL_DOUBLE_INDEXING_TYPES: {
</span><del>- Butterfly* butterfly = thisObject->m_butterfly;
</del><ins>+ Butterfly* butterfly = thisObject->butterfly();
</ins><span class="cx"> if (i >= butterfly->vectorLength())
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="lines">@@ -437,7 +437,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case ALL_CONTIGUOUS_INDEXING_TYPES: {
</span><del>- Butterfly* butterfly = thisObject->m_butterfly;
</del><ins>+ Butterfly* butterfly = thisObject->butterfly();
</ins><span class="cx"> if (propertyName >= butterfly->vectorLength())
</span><span class="cx"> break;
</span><span class="cx"> butterfly->contiguous()[propertyName].set(exec->vm(), thisObject, value);
</span><span class="lines">@@ -460,7 +460,7 @@
</span><span class="cx"> putByIndex(cell, exec, propertyName, value, shouldThrow);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><del>- Butterfly* butterfly = thisObject->m_butterfly;
</del><ins>+ Butterfly* butterfly = thisObject->butterfly();
</ins><span class="cx"> if (propertyName >= butterfly->vectorLength())
</span><span class="cx"> break;
</span><span class="cx"> butterfly->contiguousDouble()[propertyName] = valueAsDouble;
</span><span class="lines">@@ -549,11 +549,10 @@
</span><span class="cx"> DeferGC deferGC(vm.heap);
</span><span class="cx"> Butterfly* newButterfly = storage->butterfly()->resizeArray(vm, this, structure(), 0, ArrayStorage::sizeFor(0));
</span><span class="cx"> RELEASE_ASSERT(newButterfly);
</span><del>-
- m_butterfly = newButterfly;
</del><span class="cx"> newButterfly->arrayStorage()->m_indexBias = 0;
</span><span class="cx"> newButterfly->arrayStorage()->setVectorLength(0);
</span><span class="cx"> newButterfly->arrayStorage()->m_sparseMap.set(vm, this, map);
</span><ins>+ setButterflyWithoutChangingStructure(vm, newButterfly);
</ins><span class="cx">
</span><span class="cx"> return newButterfly->arrayStorage();
</span><span class="cx"> }
</span><span class="lines">@@ -601,7 +600,7 @@
</span><span class="cx"> ASSERT(!indexingShouldBeSparse());
</span><span class="cx"> unsigned vectorLength = std::max(length, BASE_VECTOR_LEN);
</span><span class="cx"> Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(
</span><del>- m_butterfly, vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
</del><ins>+ m_butterfly.get(), vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
</ins><span class="cx"> elementSize * vectorLength);
</span><span class="cx"> newButterfly->setPublicLength(length);
</span><span class="cx"> newButterfly->setVectorLength(vectorLength);
</span><span class="lines">@@ -652,7 +651,7 @@
</span><span class="cx"> IndexingType oldType = structure()->indexingType();
</span><span class="cx"> ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType));
</span><span class="cx"> Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(
</span><del>- m_butterfly, vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
</del><ins>+ m_butterfly.get(), vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
</ins><span class="cx"> ArrayStorage::sizeFor(vectorLength));
</span><span class="cx"> RELEASE_ASSERT(newButterfly);
</span><span class="cx">
</span><span class="lines">@@ -1296,7 +1295,7 @@
</span><span class="cx">
</span><span class="cx"> case ALL_INT32_INDEXING_TYPES:
</span><span class="cx"> case ALL_CONTIGUOUS_INDEXING_TYPES: {
</span><del>- Butterfly* butterfly = thisObject->m_butterfly;
</del><ins>+ Butterfly* butterfly = thisObject->butterfly();
</ins><span class="cx"> if (i >= butterfly->vectorLength())
</span><span class="cx"> return true;
</span><span class="cx"> butterfly->contiguous()[i].clear();
</span><span class="lines">@@ -1304,7 +1303,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case ALL_DOUBLE_INDEXING_TYPES: {
</span><del>- Butterfly* butterfly = thisObject->m_butterfly;
</del><ins>+ Butterfly* butterfly = thisObject->butterfly();
</ins><span class="cx"> if (i >= butterfly->vectorLength())
</span><span class="cx"> return true;
</span><span class="cx"> butterfly->contiguousDouble()[i] = QNaN;
</span><span class="lines">@@ -1480,7 +1479,7 @@
</span><span class="cx">
</span><span class="cx"> case ALL_INT32_INDEXING_TYPES:
</span><span class="cx"> case ALL_CONTIGUOUS_INDEXING_TYPES: {
</span><del>- Butterfly* butterfly = object->m_butterfly;
</del><ins>+ Butterfly* butterfly = object->butterfly();
</ins><span class="cx"> unsigned usedLength = butterfly->publicLength();
</span><span class="cx"> for (unsigned i = 0; i < usedLength; ++i) {
</span><span class="cx"> if (!butterfly->contiguous()[i])
</span><span class="lines">@@ -1491,7 +1490,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case ALL_DOUBLE_INDEXING_TYPES: {
</span><del>- Butterfly* butterfly = object->m_butterfly;
</del><ins>+ Butterfly* butterfly = object->butterfly();
</ins><span class="cx"> unsigned usedLength = butterfly->publicLength();
</span><span class="cx"> for (unsigned i = 0; i < usedLength; ++i) {
</span><span class="cx"> double value = butterfly->contiguousDouble()[i];
</span><span class="lines">@@ -1875,7 +1874,7 @@
</span><span class="cx">
</span><span class="cx"> if (i >= MAX_ARRAY_INDEX - 1
</span><span class="cx"> || (i >= MIN_SPARSE_ARRAY_INDEX
</span><del>- && !isDenseEnoughForVector(i, countElements<indexingShape>(m_butterfly)))
</del><ins>+ && !isDenseEnoughForVector(i, countElements<indexingShape>(butterfly())))
</ins><span class="cx"> || indexIsSufficientlyBeyondLengthForSparseMap(i, m_butterfly->vectorLength())) {
</span><span class="cx"> ASSERT(i <= MAX_ARRAY_INDEX);
</span><span class="cx"> ensureArrayStorageSlow(vm);
</span><span class="lines">@@ -2312,13 +2311,13 @@
</span><span class="cx"> return 0;
</span><span class="cx">
</span><span class="cx"> case ALL_INT32_INDEXING_TYPES:
</span><del>- return countElements<Int32Shape>(m_butterfly);
</del><ins>+ return countElements<Int32Shape>(butterfly());
</ins><span class="cx">
</span><span class="cx"> case ALL_DOUBLE_INDEXING_TYPES:
</span><del>- return countElements<DoubleShape>(m_butterfly);
</del><ins>+ return countElements<DoubleShape>(butterfly());
</ins><span class="cx">
</span><span class="cx"> case ALL_CONTIGUOUS_INDEXING_TYPES:
</span><del>- return countElements<ContiguousShape>(m_butterfly);
</del><ins>+ return countElements<ContiguousShape>(butterfly());
</ins><span class="cx">
</span><span class="cx"> default:
</span><span class="cx"> CRASH();
</span><span class="lines">@@ -2352,8 +2351,8 @@
</span><span class="cx"> ArrayStorage::sizeFor(vectorLength), ArrayStorage::sizeFor(newVectorLength));
</span><span class="cx"> if (!newButterfly)
</span><span class="cx"> return false;
</span><del>- m_butterfly = newButterfly;
</del><span class="cx"> newButterfly->arrayStorage()->setVectorLength(newVectorLength);
</span><ins>+ setButterflyWithoutChangingStructure(vm, newButterfly);
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2366,10 +2365,9 @@
</span><span class="cx"> newIndexBias, true, ArrayStorage::sizeFor(newVectorLength));
</span><span class="cx"> if (!newButterfly)
</span><span class="cx"> return false;
</span><del>-
- m_butterfly = newButterfly;
</del><span class="cx"> newButterfly->arrayStorage()->setVectorLength(newVectorLength);
</span><span class="cx"> newButterfly->arrayStorage()->m_indexBias = newIndexBias;
</span><ins>+ setButterflyWithoutChangingStructure(vm, newButterfly);
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2384,15 +2382,17 @@
</span><span class="cx"> MAX_STORAGE_VECTOR_LENGTH);
</span><span class="cx"> unsigned oldVectorLength = m_butterfly->vectorLength();
</span><span class="cx"> DeferGC deferGC(vm.heap);
</span><del>- m_butterfly = m_butterfly->growArrayRight(
</del><ins>+ m_butterfly.set(vm, this, m_butterfly->growArrayRight(
</ins><span class="cx"> vm, this, structure(), structure()->outOfLineCapacity(), true,
</span><span class="cx"> oldVectorLength * sizeof(EncodedJSValue),
</span><del>- newVectorLength * sizeof(EncodedJSValue));
</del><ins>+ newVectorLength * sizeof(EncodedJSValue)));
+
+ m_butterfly->setVectorLength(newVectorLength);
+
</ins><span class="cx"> if (hasDouble(structure()->indexingType())) {
</span><span class="cx"> for (unsigned i = oldVectorLength; i < newVectorLength; ++i)
</span><span class="cx"> m_butterfly->contiguousDouble().data()[i] = QNaN;
</span><span class="cx"> }
</span><del>- m_butterfly->setVectorLength(newVectorLength);
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Butterfly* JSObject::growOutOfLineStorage(VM& vm, size_t oldSize, size_t newSize)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.h (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.h        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.h        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -27,10 +27,13 @@
</span><span class="cx"> #include "ArrayConventions.h"
</span><span class="cx"> #include "ArrayStorage.h"
</span><span class="cx"> #include "Butterfly.h"
</span><ins>+#include "CallFrame.h"
</ins><span class="cx"> #include "ClassInfo.h"
</span><span class="cx"> #include "CommonIdentifiers.h"
</span><del>-#include "CallFrame.h"
</del><ins>+#include "CopyWriteBarrier.h"
</ins><span class="cx"> #include "DeferGC.h"
</span><ins>+#include "Heap.h"
+#include "IndexingHeaderInlines.h"
</ins><span class="cx"> #include "JSCell.h"
</span><span class="cx"> #include "PropertySlot.h"
</span><span class="cx"> #include "PropertyStorage.h"
</span><span class="lines">@@ -539,8 +542,8 @@
</span><span class="cx"> return inlineStorageUnsafe();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- const Butterfly* butterfly() const { return m_butterfly; }
- Butterfly* butterfly() { return m_butterfly; }
</del><ins>+ const Butterfly* butterfly() const { return m_butterfly.get(); }
+ Butterfly* butterfly() { return m_butterfly.get(); }
</ins><span class="cx">
</span><span class="cx"> ConstPropertyStorage outOfLineStorage() const { return m_butterfly->propertyStorage(); }
</span><span class="cx"> PropertyStorage outOfLineStorage() { return m_butterfly->propertyStorage(); }
</span><span class="lines">@@ -605,7 +608,7 @@
</span><span class="cx"> void reifyStaticFunctionsForDelete(ExecState* exec);
</span><span class="cx">
</span><span class="cx"> JS_EXPORT_PRIVATE Butterfly* growOutOfLineStorage(VM&, size_t oldSize, size_t newSize);
</span><del>- void setButterflyWithoutChangingStructure(Butterfly*); // You probably don't want to call this.
</del><ins>+ void setButterflyWithoutChangingStructure(VM&, Butterfly*);
</ins><span class="cx">
</span><span class="cx"> void setStructure(VM&, Structure*);
</span><span class="cx"> void setStructureAndButterfly(VM&, Structure*, Butterfly*);
</span><span class="lines">@@ -975,7 +978,7 @@
</span><span class="cx"> ContiguousJSValues ensureContiguousSlow(VM&, DoubleToContiguousMode);
</span><span class="cx">
</span><span class="cx"> protected:
</span><del>- Butterfly* m_butterfly;
</del><ins>+ CopyWriteBarrier<Butterfly> m_butterfly;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> // JSNonFinalObject is a type of JSObject that has some internal storage,
</span><span class="lines">@@ -1135,7 +1138,9 @@
</span><span class="cx">
</span><span class="cx"> inline void JSObject::setStructureAndButterfly(VM& vm, Structure* structure, Butterfly* butterfly)
</span><span class="cx"> {
</span><del>- m_butterfly = butterfly;
</del><ins>+ ASSERT(structure);
+ ASSERT(!butterfly == (!structure->outOfLineCapacity() && !structure->hasIndexingHeader(this)));
+ m_butterfly.set(vm, this, butterfly);
</ins><span class="cx"> setStructure(vm, structure);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1146,9 +1151,9 @@
</span><span class="cx"> JSCell::setStructure(vm, structure);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline void JSObject::setButterflyWithoutChangingStructure(Butterfly* butterfly)
</del><ins>+inline void JSObject::setButterflyWithoutChangingStructure(VM& vm, Butterfly* butterfly)
</ins><span class="cx"> {
</span><del>- m_butterfly = butterfly;
</del><ins>+ m_butterfly.set(vm, this, butterfly);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline CallType getCallData(JSValue value, CallData& callData)
</span><span class="lines">@@ -1178,7 +1183,7 @@
</span><span class="cx">
</span><span class="cx"> inline JSObject::JSObject(VM& vm, Structure* structure, Butterfly* butterfly)
</span><span class="cx"> : JSCell(vm, structure)
</span><del>- , m_butterfly(butterfly)
</del><ins>+ , m_butterfly(vm, this, butterfly)
</ins><span class="cx"> {
</span><span class="cx"> vm.heap.ascribeOwner(this, butterfly);
</span><span class="cx"> }
</span><span class="lines">@@ -1302,7 +1307,7 @@
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="cx"> DeferGC deferGC(vm.heap);
</span><del>- Butterfly* newButterfly = m_butterfly;
</del><ins>+ Butterfly* newButterfly = butterfly();
</ins><span class="cx"> if (structure()->putWillGrowOutOfLineStorage())
</span><span class="cx"> newButterfly = growOutOfLineStorage(vm, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
</span><span class="cx"> offset = structure()->addPropertyWithoutTransition(vm, propertyName, attributes, specificFunction);
</span><span class="lines">@@ -1323,9 +1328,11 @@
</span><span class="cx"> size_t currentCapacity = structure()->outOfLineCapacity();
</span><span class="cx"> if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) {
</span><span class="cx"> DeferGC deferGC(vm.heap);
</span><del>- Butterfly* newButterfly = m_butterfly;
- if (currentCapacity != structure->outOfLineCapacity())
</del><ins>+ Butterfly* newButterfly = butterfly();
+ if (currentCapacity != structure->outOfLineCapacity()) {
+ ASSERT(structure != this->structure());
</ins><span class="cx"> newButterfly = growOutOfLineStorage(vm, currentCapacity, structure->outOfLineCapacity());
</span><ins>+ }
</ins><span class="cx">
</span><span class="cx"> validateOffset(offset);
</span><span class="cx"> ASSERT(structure->isValidOffset(offset));
</span><span class="lines">@@ -1436,7 +1443,7 @@
</span><span class="cx"> {
</span><span class="cx"> DeferGC deferGC(vm.heap);
</span><span class="cx"> ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
</span><del>- Butterfly* newButterfly = m_butterfly;
</del><ins>+ Butterfly* newButterfly = m_butterfly.get();
</ins><span class="cx"> if (structure()->putWillGrowOutOfLineStorage())
</span><span class="cx"> newButterfly = growOutOfLineStorage(vm, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
</span><span class="cx"> PropertyOffset offset = structure()->addPropertyWithoutTransition(vm, propertyName, attributes, getCallableObject(value));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeMapDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/MapData.cpp (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/MapData.cpp        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/runtime/MapData.cpp        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -198,16 +198,17 @@
</span><span class="cx">
</span><span class="cx"> size_t requiredSize = std::max(m_capacity + (m_capacity / 2) + 1, minimumMapSize);
</span><span class="cx"> void* newStorage = 0;
</span><ins>+ DeferGC defer(*callFrame->heap());
</ins><span class="cx"> if (!callFrame->heap()->tryAllocateStorage(this, requiredSize * sizeof(Entry), &newStorage)) {
</span><span class="cx"> throwOutOfMemoryError(callFrame);
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><del>- DeferGC defer(*callFrame->heap());
</del><span class="cx"> Entry* newEntries = static_cast<Entry*>(newStorage);
</span><span class="cx"> if (shouldPack())
</span><span class="cx"> replaceAndPackBackingStore(newEntries, requiredSize);
</span><span class="cx"> else
</span><span class="cx"> replaceBackingStore(newEntries, requiredSize);
</span><ins>+ Heap::writeBarrier(this);
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Structure.cpp (161229 => 161230)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Structure.cpp        2014-01-02 22:43:57 UTC (rev 161229)
+++ trunk/Source/JavaScriptCore/runtime/Structure.cpp        2014-01-02 22:57:14 UTC (rev 161230)
</span><span class="lines">@@ -273,7 +273,7 @@
</span><span class="cx"> findStructuresAndMapForMaterialization(structures, structure, table);
</span><span class="cx">
</span><span class="cx"> if (table) {
</span><del>- table = table->copy(vm, 0, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
</del><ins>+ table = table->copy(vm, structure, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
</ins><span class="cx"> structure->m_lock.unlock();
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>