<!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>[208953] trunk</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/208953">208953</a></dd>
<dt>Author</dt> <dd>utatane.tea@gmail.com</dd>
<dt>Date</dt> <dd>2016-11-21 15:54:43 -0800 (Mon, 21 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Crash in com.apple.JavaScriptCore: WTF::ThreadSpecific&lt;WTF::WTFThreadData, + 142
https://bugs.webkit.org/show_bug.cgi?id=164898

Reviewed by Darin Adler.

JSTests:

* stress/tagged-template-registry-key-collect.js: Added.
(shouldBe):
(tag):
(i.eval):
* stress/tagged-template-registry-key.js: Added.
(shouldBe):
(tag):
(a):
(b):

Source/JavaScriptCore:

The callsite object (JSArray) of tagged template literal is managed by WeakGCMap since
same tagged template literal need to return an identical object.
The problem is that we used TemplateRegistryKey as the key of the WeakGCMap. WeakGCMap
can prune its entries in the collector thread. At that time, this TemplateRegistryKey
is deallocated. Since it includes String (and then, StringImpl), we accidentally call
ref(), deref() and StringImpl::destroy() in the different thread from the main thread
while this TemplateRegistryKey is allocated in the main thread.

Instead, we use TemplateRegistryKey* as the key of WeakGCMap. Then, to keep its liveness
while the entry of the WeakGCMap is alive, the callsite object has the reference to
the JSTemplateRegistryKey. And it holds Ref&lt;TemplateRegistryKey&gt;.

And now we need to lookup WeakGCMap with TemplateRegistryKey*. To do so, we create
interning system for TemplateRegistryKey. It is similar to AtomicStringTable and
SymbolRegistry. TemplateRegistryKey is allocated from this table. This table atomize the
TemplateRegistryKey. So we can use the pointer comparison between TemplateRegistryKey.
It allows us to lookup the entry from WeakGCMap by TemplateRegistryKey*.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* builtins/BuiltinNames.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::addTemplateRegistryKeyConstant):
(JSC::BytecodeGenerator::emitGetTemplateObject):
* bytecompiler/BytecodeGenerator.h:
* runtime/JSGlobalObject.cpp:
(JSC::getTemplateObject):
* runtime/JSTemplateRegistryKey.cpp:
(JSC::JSTemplateRegistryKey::JSTemplateRegistryKey):
(JSC::JSTemplateRegistryKey::create):
* runtime/JSTemplateRegistryKey.h:
* runtime/TemplateRegistry.cpp:
(JSC::TemplateRegistry::getTemplateObject):
* runtime/TemplateRegistry.h:
* runtime/TemplateRegistryKey.cpp: Copied from Source/JavaScriptCore/runtime/TemplateRegistry.h.
(JSC::TemplateRegistryKey::~TemplateRegistryKey):
* runtime/TemplateRegistryKey.h:
(JSC::TemplateRegistryKey::calculateHash):
(JSC::TemplateRegistryKey::create):
(JSC::TemplateRegistryKey::TemplateRegistryKey):
* runtime/TemplateRegistryKeyTable.cpp: Added.
(JSC::TemplateRegistryKeyTranslator::hash):
(JSC::TemplateRegistryKeyTranslator::equal):
(JSC::TemplateRegistryKeyTranslator::translate):
(JSC::TemplateRegistryKeyTable::~TemplateRegistryKeyTable):
(JSC::TemplateRegistryKeyTable::createKey):
(JSC::TemplateRegistryKeyTable::unregister):
* runtime/TemplateRegistryKeyTable.h: Copied from Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h.
(JSC::TemplateRegistryKeyTable::KeyHash::hash):
(JSC::TemplateRegistryKeyTable::KeyHash::equal):
* runtime/VM.h:
(JSC::VM::templateRegistryKeyTable):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsBuiltinNamesh">trunk/Source/JavaScriptCore/builtins/BuiltinNames.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTemplateRegistryKeycpp">trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTemplateRegistryKeyh">trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTemplateRegistrycpp">trunk/Source/JavaScriptCore/runtime/TemplateRegistry.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTemplateRegistryh">trunk/Source/JavaScriptCore/runtime/TemplateRegistry.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTemplateRegistryKeyh">trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsstresstaggedtemplateregistrykeycollectjs">trunk/JSTests/stress/tagged-template-registry-key-collect.js</a></li>
<li><a href="#trunkJSTestsstresstaggedtemplateregistrykeyjs">trunk/JSTests/stress/tagged-template-registry-key.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTemplateRegistryKeycpp">trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTemplateRegistryKeyTablecpp">trunk/Source/JavaScriptCore/runtime/TemplateRegistryKeyTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTemplateRegistryKeyTableh">trunk/Source/JavaScriptCore/runtime/TemplateRegistryKeyTable.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/JSTests/ChangeLog        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-11-21  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        Crash in com.apple.JavaScriptCore: WTF::ThreadSpecific&lt;WTF::WTFThreadData, + 142
+        https://bugs.webkit.org/show_bug.cgi?id=164898
+
+        Reviewed by Darin Adler.
+
+        * stress/tagged-template-registry-key-collect.js: Added.
+        (shouldBe):
+        (tag):
+        (i.eval):
+        * stress/tagged-template-registry-key.js: Added.
+        (shouldBe):
+        (tag):
+        (a):
+        (b):
+
</ins><span class="cx"> 2016-11-20  Caitlin Potter  &lt;caitp@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] speed up parsing of async functions
</span></span></pre></div>
<a id="trunkJSTestsstresstaggedtemplateregistrykeycollectjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/tagged-template-registry-key-collect.js (0 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/tagged-template-registry-key-collect.js                                (rev 0)
+++ trunk/JSTests/stress/tagged-template-registry-key-collect.js        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+
+function tag(site)
+{
+    return site;
+}
+
+{
+    for (var i = 0; i &lt; 1e4; ++i)
+        eval(`(function () { return tag\`${i}\`; })()`);
+}
+gc();
</ins></span></pre></div>
<a id="trunkJSTestsstresstaggedtemplateregistrykeyjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/tagged-template-registry-key.js (0 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/tagged-template-registry-key.js                                (rev 0)
+++ trunk/JSTests/stress/tagged-template-registry-key.js        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function tag(site)
+{
+    return site;
+}
+
+{
+    function a() {
+        return tag`Hello`;
+    }
+
+    function b() {
+        return tag`Hello`;
+    }
+
+    shouldBe(a() === b(), true);
+    gc();
+    var tagA = a();
+    gc();
+    shouldBe(tagA === b(), true);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -866,6 +866,8 @@
</span><span class="cx">     runtime/SymbolPrototype.cpp
</span><span class="cx">     runtime/SymbolTable.cpp
</span><span class="cx">     runtime/TemplateRegistry.cpp
</span><ins>+    runtime/TemplateRegistryKey.cpp
+    runtime/TemplateRegistryKeyTable.cpp
</ins><span class="cx">     runtime/TestRunnerUtils.cpp
</span><span class="cx">     runtime/ThrowScope.cpp
</span><span class="cx">     runtime/TypeLocationCache.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -1,3 +1,63 @@
</span><ins>+2016-11-21  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        Crash in com.apple.JavaScriptCore: WTF::ThreadSpecific&lt;WTF::WTFThreadData, + 142
+        https://bugs.webkit.org/show_bug.cgi?id=164898
+
+        Reviewed by Darin Adler.
+
+        The callsite object (JSArray) of tagged template literal is managed by WeakGCMap since
+        same tagged template literal need to return an identical object.
+        The problem is that we used TemplateRegistryKey as the key of the WeakGCMap. WeakGCMap
+        can prune its entries in the collector thread. At that time, this TemplateRegistryKey
+        is deallocated. Since it includes String (and then, StringImpl), we accidentally call
+        ref(), deref() and StringImpl::destroy() in the different thread from the main thread
+        while this TemplateRegistryKey is allocated in the main thread.
+
+        Instead, we use TemplateRegistryKey* as the key of WeakGCMap. Then, to keep its liveness
+        while the entry of the WeakGCMap is alive, the callsite object has the reference to
+        the JSTemplateRegistryKey. And it holds Ref&lt;TemplateRegistryKey&gt;.
+
+        And now we need to lookup WeakGCMap with TemplateRegistryKey*. To do so, we create
+        interning system for TemplateRegistryKey. It is similar to AtomicStringTable and
+        SymbolRegistry. TemplateRegistryKey is allocated from this table. This table atomize the
+        TemplateRegistryKey. So we can use the pointer comparison between TemplateRegistryKey.
+        It allows us to lookup the entry from WeakGCMap by TemplateRegistryKey*.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/BuiltinNames.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::addTemplateRegistryKeyConstant):
+        (JSC::BytecodeGenerator::emitGetTemplateObject):
+        * bytecompiler/BytecodeGenerator.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::getTemplateObject):
+        * runtime/JSTemplateRegistryKey.cpp:
+        (JSC::JSTemplateRegistryKey::JSTemplateRegistryKey):
+        (JSC::JSTemplateRegistryKey::create):
+        * runtime/JSTemplateRegistryKey.h:
+        * runtime/TemplateRegistry.cpp:
+        (JSC::TemplateRegistry::getTemplateObject):
+        * runtime/TemplateRegistry.h:
+        * runtime/TemplateRegistryKey.cpp: Copied from Source/JavaScriptCore/runtime/TemplateRegistry.h.
+        (JSC::TemplateRegistryKey::~TemplateRegistryKey):
+        * runtime/TemplateRegistryKey.h:
+        (JSC::TemplateRegistryKey::calculateHash):
+        (JSC::TemplateRegistryKey::create):
+        (JSC::TemplateRegistryKey::TemplateRegistryKey):
+        * runtime/TemplateRegistryKeyTable.cpp: Added.
+        (JSC::TemplateRegistryKeyTranslator::hash):
+        (JSC::TemplateRegistryKeyTranslator::equal):
+        (JSC::TemplateRegistryKeyTranslator::translate):
+        (JSC::TemplateRegistryKeyTable::~TemplateRegistryKeyTable):
+        (JSC::TemplateRegistryKeyTable::createKey):
+        (JSC::TemplateRegistryKeyTable::unregister):
+        * runtime/TemplateRegistryKeyTable.h: Copied from Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h.
+        (JSC::TemplateRegistryKeyTable::KeyHash::hash):
+        (JSC::TemplateRegistryKeyTable::KeyHash::equal):
+        * runtime/VM.h:
+        (JSC::VM::templateRegistryKeyTable):
+
</ins><span class="cx"> 2016-11-21  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix exception scope verification failures in runtime/Error* files.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -2329,6 +2329,9 @@
</span><span class="cx">                 FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
</span><span class="cx">                 FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                1A8826B1653C4CD1A642983B /* TemplateRegistryKeyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */; };
+                78274D8E4C4D4FCD9A1DC6E6 /* TemplateRegistryKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */; };
+                95D4261AF4C84CE2ACBAC981 /* TemplateRegistryKeyTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 08FC2F37AB76483A9966688F /* TemplateRegistryKeyTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx"> /* End PBXBuildFile section */
</span><span class="cx"> 
</span><span class="cx"> /* Begin PBXContainerItemProxy section */
</span><span class="lines">@@ -4819,6 +4822,9 @@
</span><span class="cx">                 FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TemplateRegistryKeyTable.cpp; path = TemplateRegistryKeyTable.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TemplateRegistryKey.cpp; path = TemplateRegistryKey.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                08FC2F37AB76483A9966688F /* TemplateRegistryKeyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemplateRegistryKeyTable.h; path = TemplateRegistryKeyTable.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx"> /* End PBXFileReference section */
</span><span class="cx"> 
</span><span class="cx"> /* Begin PBXFrameworksBuildPhase section */
</span><span class="lines">@@ -6637,6 +6643,9 @@
</span><span class="cx">                                 147341D91DC0300100AA29BA /* WebAssemblyExecutable.h */,
</span><span class="cx">                                 A7DCB77912E3D90500911940 /* WriteBarrier.h */,
</span><span class="cx">                                 C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */,
</span><ins>+                                8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */,
+                                BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */,
+                                08FC2F37AB76483A9966688F /* TemplateRegistryKeyTable.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = runtime;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -8971,6 +8980,7 @@
</span><span class="cx">                                 A79D3ED9C5064DD0A8466A3A /* ModuleScopeData.h in Headers */,
</span><span class="cx">                                 D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */,
</span><span class="cx">                                 473DA4A4764C45FE871B0485 /* DefinePropertyAttributes.h in Headers */,
</span><ins>+                                95D4261AF4C84CE2ACBAC981 /* TemplateRegistryKeyTable.h in Headers */,
</ins><span class="cx">                         );
</span><span class="cx">                         runOnlyForDeploymentPostprocessing = 0;
</span><span class="cx">                 };
</span><span class="lines">@@ -10363,6 +10373,8 @@
</span><span class="cx">                                 86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
</span><span class="cx">                                 0F2BBD991C5FF3F50023EF23 /* B3VariableValue.cpp in Sources */,
</span><span class="cx">                                 13FECE06D3B445FCB6C93461 /* JSModuleLoader.cpp in Sources */,
</span><ins>+                                1A8826B1653C4CD1A642983B /* TemplateRegistryKeyTable.cpp in Sources */,
+                                78274D8E4C4D4FCD9A1DC6E6 /* TemplateRegistryKey.cpp in Sources */,
</ins><span class="cx">                         );
</span><span class="cx">                         runOnlyForDeploymentPostprocessing = 0;
</span><span class="cx">                 };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsBuiltinNamesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/BuiltinNames.h (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/BuiltinNames.h        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/builtins/BuiltinNames.h        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -81,6 +81,7 @@
</span><span class="cx">     macro(BuiltinLog) \
</span><span class="cx">     macro(homeObject) \
</span><span class="cx">     macro(getTemplateObject) \
</span><ins>+    macro(templateRegistryKey) \
</ins><span class="cx">     macro(enqueueJob) \
</span><span class="cx">     macro(handler) \
</span><span class="cx">     macro(promiseState) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -2995,14 +2995,13 @@
</span><span class="cx">     return stringInMap;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(const TemplateRegistryKey&amp; templateRegistryKey)
</del><ins>+JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(Ref&lt;TemplateRegistryKey&gt;&amp;&amp; templateRegistryKey)
</ins><span class="cx"> {
</span><del>-    JSTemplateRegistryKey*&amp; templateRegistryKeyInMap = m_templateRegistryKeyMap.add(templateRegistryKey, nullptr).iterator-&gt;value;
-    if (!templateRegistryKeyInMap) {
-        templateRegistryKeyInMap = JSTemplateRegistryKey::create(*vm(), templateRegistryKey);
-        addConstantValue(templateRegistryKeyInMap);
-    }
-    return templateRegistryKeyInMap;
</del><ins>+    return m_templateRegistryKeyMap.ensure(templateRegistryKey.copyRef(), [&amp;] {
+        auto* result = JSTemplateRegistryKey::create(*vm(), WTFMove(templateRegistryKey));
+        addConstantValue(result);
+        return result;
+    }).iterator-&gt;value;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
</span><span class="lines">@@ -4398,7 +4397,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     CallArguments arguments(*this, nullptr);
</span><del>-    emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(TemplateRegistryKey(rawStrings, cookedStrings))));
</del><ins>+    emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(m_vm-&gt;templateRegistryKeyTable().createKey(rawStrings, cookedStrings))));
</ins><span class="cx">     return emitCall(dst, getTemplateObject.get(), NoExpectedFunction, arguments, taggedTemplate-&gt;divot(), taggedTemplate-&gt;divotStart(), taggedTemplate-&gt;divotEnd(), DebuggableCall::No);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -801,7 +801,7 @@
</span><span class="cx"> 
</span><span class="cx">         typedef HashMap&lt;double, JSValue&gt; NumberMap;
</span><span class="cx">         typedef HashMap&lt;UniquedStringImpl*, JSString*, IdentifierRepHash&gt; IdentifierStringMap;
</span><del>-        typedef HashMap&lt;TemplateRegistryKey, JSTemplateRegistryKey*&gt; TemplateRegistryKeyMap;
</del><ins>+        typedef HashMap&lt;Ref&lt;TemplateRegistryKey&gt;, JSTemplateRegistryKey*&gt; TemplateRegistryKeyMap;
</ins><span class="cx">         
</span><span class="cx">         // Helper for emitCall() and emitConstruct(). This works because the set of
</span><span class="cx">         // expected functions have identical behavior for both call and construct
</span><span class="lines">@@ -885,7 +885,7 @@
</span><span class="cx"> 
</span><span class="cx">     public:
</span><span class="cx">         JSString* addStringConstant(const Identifier&amp;);
</span><del>-        JSTemplateRegistryKey* addTemplateRegistryKeyConstant(const TemplateRegistryKey&amp;);
</del><ins>+        JSTemplateRegistryKey* addTemplateRegistryKeyConstant(Ref&lt;TemplateRegistryKey&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><span class="cx">         Vector&lt;UnlinkedInstruction, 0, UnsafeVectorOverflow&gt;&amp; instructions() { return m_instructions; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -290,7 +290,7 @@
</span><span class="cx"> {
</span><span class="cx">     JSValue thisValue = exec-&gt;thisValue();
</span><span class="cx">     ASSERT(thisValue.inherits(JSTemplateRegistryKey::info()));
</span><del>-    return JSValue::encode(exec-&gt;lexicalGlobalObject()-&gt;templateRegistry().getTemplateObject(exec, jsCast&lt;JSTemplateRegistryKey*&gt;(thisValue)-&gt;templateRegistryKey()));
</del><ins>+    return JSValue::encode(exec-&gt;lexicalGlobalObject()-&gt;templateRegistry().getTemplateObject(exec, jsCast&lt;JSTemplateRegistryKey*&gt;(thisValue)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTemplateRegistryKeycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -35,15 +35,15 @@
</span><span class="cx"> const ClassInfo JSTemplateRegistryKey::s_info = { &quot;TemplateRegistryKey&quot;, &amp;Base::s_info, nullptr, CREATE_METHOD_TABLE(JSTemplateRegistryKey) };
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-JSTemplateRegistryKey::JSTemplateRegistryKey(VM&amp; vm, const TemplateRegistryKey&amp; templateRegistryKey)
</del><ins>+JSTemplateRegistryKey::JSTemplateRegistryKey(VM&amp; vm, Ref&lt;TemplateRegistryKey&gt;&amp;&amp; templateRegistryKey)
</ins><span class="cx">     : Base(vm, vm.templateRegistryKeyStructure.get())
</span><del>-    , m_templateRegistryKey(templateRegistryKey)
</del><ins>+    , m_templateRegistryKey(WTFMove(templateRegistryKey))
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSTemplateRegistryKey* JSTemplateRegistryKey::create(VM&amp; vm, const TemplateRegistryKey&amp; templateRegistryKey)
</del><ins>+JSTemplateRegistryKey* JSTemplateRegistryKey::create(VM&amp; vm, Ref&lt;TemplateRegistryKey&gt;&amp;&amp; templateRegistryKey)
</ins><span class="cx"> {
</span><del>-    JSTemplateRegistryKey* result = new (NotNull, allocateCell&lt;JSTemplateRegistryKey&gt;(vm.heap)) JSTemplateRegistryKey(vm, templateRegistryKey);
</del><ins>+    JSTemplateRegistryKey* result = new (NotNull, allocateCell&lt;JSTemplateRegistryKey&gt;(vm.heap)) JSTemplateRegistryKey(vm, WTFMove(templateRegistryKey));
</ins><span class="cx">     result-&gt;finishCreation(vm);
</span><span class="cx">     return result;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTemplateRegistryKeyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx"> public:
</span><span class="cx">     typedef JSDestructibleObject Base;
</span><span class="cx"> 
</span><del>-    static JSTemplateRegistryKey* create(VM&amp;, const TemplateRegistryKey&amp;);
</del><ins>+    static JSTemplateRegistryKey* create(VM&amp;, Ref&lt;TemplateRegistryKey&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
</span><span class="cx">     {
</span><span class="lines">@@ -44,15 +44,15 @@
</span><span class="cx"> 
</span><span class="cx">     DECLARE_INFO;
</span><span class="cx"> 
</span><del>-    const TemplateRegistryKey&amp; templateRegistryKey() const { return m_templateRegistryKey; }
</del><ins>+    const TemplateRegistryKey&amp; templateRegistryKey() const { return m_templateRegistryKey.get(); }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     static void destroy(JSCell*);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    JSTemplateRegistryKey(VM&amp;, const TemplateRegistryKey&amp;);
</del><ins>+    JSTemplateRegistryKey(VM&amp;, Ref&lt;TemplateRegistryKey&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><del>-    TemplateRegistryKey m_templateRegistryKey;
</del><ins>+    Ref&lt;TemplateRegistryKey&gt; m_templateRegistryKey;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTemplateRegistrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TemplateRegistry.cpp (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TemplateRegistry.cpp        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/runtime/TemplateRegistry.cpp        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -27,9 +27,12 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;TemplateRegistry.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;BuiltinNames.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><ins>+#include &quot;JSTemplateRegistryKey.h&quot;
</ins><span class="cx"> #include &quot;ObjectConstructor.h&quot;
</span><ins>+#include &quot;TemplateRegistryKey.h&quot;
</ins><span class="cx"> #include &quot;WeakGCMapInlines.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -39,9 +42,10 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSArray* TemplateRegistry::getTemplateObject(ExecState* exec, const TemplateRegistryKey&amp; templateKey)
</del><ins>+JSArray* TemplateRegistry::getTemplateObject(ExecState* exec, JSTemplateRegistryKey* templateKeyObject)
</ins><span class="cx"> {
</span><del>-    JSArray* cached = m_templateMap.get(templateKey);
</del><ins>+    auto&amp; templateKey = templateKeyObject-&gt;templateRegistryKey();
+    JSArray* cached = m_templateMap.get(&amp;templateKey);
</ins><span class="cx">     if (cached)
</span><span class="cx">         return cached;
</span><span class="cx"> 
</span><span class="lines">@@ -63,10 +67,14 @@
</span><span class="cx"> 
</span><span class="cx">     templateObject-&gt;putDirect(vm, exec-&gt;propertyNames().raw, rawObject, ReadOnly | DontEnum | DontDelete);
</span><span class="cx"> 
</span><ins>+    // Template JSArray hold the reference to JSTemplateRegistryKey to make TemplateRegistryKey pointer live until this JSArray is collected.
+    // TemplateRegistryKey pointer is used for TemplateRegistry's key.
+    templateObject-&gt;putDirect(vm, vm.propertyNames-&gt;builtinNames().templateRegistryKeyPrivateName(), templateKeyObject, ReadOnly | DontEnum | DontDelete);
+
</ins><span class="cx">     objectConstructorFreeze(exec, templateObject);
</span><span class="cx">     ASSERT(!scope.exception());
</span><span class="cx"> 
</span><del>-    m_templateMap.set(templateKey, templateObject);
</del><ins>+    m_templateMap.set(&amp;templateKey, templateObject);
</ins><span class="cx"> 
</span><span class="cx">     return templateObject;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTemplateRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TemplateRegistry.h (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TemplateRegistry.h        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/runtime/TemplateRegistry.h        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -26,20 +26,22 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSArray.h&quot;
</span><del>-#include &quot;TemplateRegistryKey.h&quot;
</del><span class="cx"> #include &quot;WeakGCMap.h&quot;
</span><span class="cx"> #include &lt;limits&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class JSTemplateRegistryKey;
+class TemplateRegistryKey;
+
</ins><span class="cx"> class TemplateRegistry {
</span><span class="cx"> public:
</span><span class="cx">     TemplateRegistry(VM&amp;);
</span><span class="cx"> 
</span><del>-    JSArray* getTemplateObject(ExecState*, const TemplateRegistryKey&amp;);
</del><ins>+    JSArray* getTemplateObject(ExecState*, JSTemplateRegistryKey*);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    WeakGCMap&lt;TemplateRegistryKey, JSArray&gt; m_templateMap;
</del><ins>+    WeakGCMap&lt;const TemplateRegistryKey*, JSArray&gt; m_templateMap;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTemplateRegistryKeycppfromrev208952trunkSourceJavaScriptCoreruntimeTemplateRegistryh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.cpp (from rev 208952, trunk/Source/JavaScriptCore/runtime/TemplateRegistry.h) (0 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.cpp        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+/*
+ * Copyright (C) 2016 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;.
+ *
+ * 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;TemplateRegistryKey.h&quot;
+
+#include &quot;TemplateRegistryKeyTable.h&quot;
+
+namespace JSC {
+
+TemplateRegistryKey::~TemplateRegistryKey()
+{
+    if (m_table)
+        m_table-&gt;unregister(*this);
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTemplateRegistryKeyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.h (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.h        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.h        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -32,11 +32,13 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-class TemplateRegistryKey {
</del><ins>+class TemplateRegistryKeyTable;
+
+class TemplateRegistryKey : public RefCounted&lt;TemplateRegistryKey&gt; {
</ins><span class="cx"> public:
</span><ins>+    friend class TemplateRegistryKeyTable;
</ins><span class="cx">     typedef Vector&lt;String, 4&gt; StringVector;
</span><span class="cx"> 
</span><del>-    TemplateRegistryKey(const StringVector&amp; rawStrings, const StringVector&amp; cookedStrings);
</del><span class="cx">     enum DeletedValueTag { DeletedValue };
</span><span class="cx">     TemplateRegistryKey(DeletedValueTag);
</span><span class="cx">     enum EmptyValueTag { EmptyValue };
</span><span class="lines">@@ -60,7 +62,18 @@
</span><span class="cx">         static const bool safeToCompareToEmptyOrDeleted = false;
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    static unsigned calculateHash(const StringVector&amp; rawStrings);
+    ~TemplateRegistryKey();
+
</ins><span class="cx"> private:
</span><ins>+    static Ref&lt;TemplateRegistryKey&gt; create(const StringVector&amp; rawStrings, const StringVector&amp; cookedStrings)
+    {
+        return adoptRef(*new TemplateRegistryKey(rawStrings, cookedStrings));
+    }
+
+    TemplateRegistryKey(const StringVector&amp; rawStrings, const StringVector&amp; cookedStrings);
+
+    TemplateRegistryKeyTable* m_table { nullptr };
</ins><span class="cx">     StringVector m_rawStrings;
</span><span class="cx">     StringVector m_cookedStrings;
</span><span class="cx">     unsigned m_hash { 0 };
</span><span class="lines">@@ -69,10 +82,8 @@
</span><span class="cx"> inline TemplateRegistryKey::TemplateRegistryKey(const StringVector&amp; rawStrings, const StringVector&amp; cookedStrings)
</span><span class="cx">     : m_rawStrings(rawStrings)
</span><span class="cx">     , m_cookedStrings(cookedStrings)
</span><ins>+    , m_hash(calculateHash(rawStrings))
</ins><span class="cx"> {
</span><del>-    m_hash = 0;
-    for (const String&amp; string : rawStrings)
-        m_hash += WTF::StringHash::hash(string);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline TemplateRegistryKey::TemplateRegistryKey(DeletedValueTag)
</span><span class="lines">@@ -85,6 +96,18 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline unsigned TemplateRegistryKey::calculateHash(const StringVector&amp; rawStrings)
+{
+    StringHasher hasher;
+    for (const String&amp; string : rawStrings) {
+        if (string.is8Bit())
+            hasher.addCharacters(string.characters8(), string.length());
+        else
+            hasher.addCharacters(string.characters16(), string.length());
+    }
+    return hasher.hash();
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTemplateRegistryKeyTablecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/TemplateRegistryKeyTable.cpp (0 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TemplateRegistryKeyTable.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/TemplateRegistryKeyTable.cpp        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/*
+ * Copyright (C) 2016 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;.
+ *
+ * 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;TemplateRegistryKeyTable.h&quot;
+
+#include &quot;TemplateRegistryKey.h&quot;
+
+namespace JSC {
+
+struct TemplateRegistryKeyTranslator {
+    static unsigned hash(TemplateRegistryKey* generator) { return generator-&gt;hash(); }
+    static inline bool equal(TemplateRegistryKey* key, TemplateRegistryKey* generator) { return *key == *generator; }
+    static void translate(TemplateRegistryKey*&amp; location, TemplateRegistryKey* generator, unsigned) { location = generator; }
+};
+
+TemplateRegistryKeyTable::~TemplateRegistryKeyTable()
+{
+    for (auto&amp; key : m_atomicTable)
+        key-&gt;m_table = nullptr;
+}
+
+Ref&lt;TemplateRegistryKey&gt; TemplateRegistryKeyTable::createKey(const TemplateRegistryKey::StringVector&amp; rawStrings, const TemplateRegistryKey::StringVector&amp; cookedStrings)
+{
+    auto key = TemplateRegistryKey::create(rawStrings, cookedStrings);
+    auto addResult = m_atomicTable.add&lt;TemplateRegistryKeyTranslator&gt;(key.ptr());
+    if (addResult.isNewEntry)
+        (*addResult.iterator)-&gt;m_table = this;
+
+    return **addResult.iterator;
+}
+
+void TemplateRegistryKeyTable::unregister(TemplateRegistryKey&amp; key)
+{
+    ASSERT(key.m_table == this);
+    auto iterator = m_atomicTable.find(&amp;key);
+    ASSERT_WITH_MESSAGE(iterator != m_atomicTable.end(), &quot;The TemplateRegistryKey being removed is registered in the other TemplateRegistryKeyTable.&quot;);
+    m_atomicTable.remove(iterator);
+
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTemplateRegistryKeyTablehfromrev208952trunkSourceJavaScriptCoreruntimeJSTemplateRegistryKeyh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/runtime/TemplateRegistryKeyTable.h (from rev 208952, trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h) (0 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TemplateRegistryKeyTable.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/TemplateRegistryKeyTable.h        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+/*
+ * Copyright (C) 2016 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;.
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include &quot;TemplateRegistryKey.h&quot;
+#include &lt;wtf/Forward.h&gt;
+#include &lt;wtf/HashSet.h&gt;
+#include &lt;wtf/Noncopyable.h&gt;
+
+namespace JSC {
+
+class TemplateRegistryKeyTable {
+    WTF_MAKE_NONCOPYABLE(TemplateRegistryKeyTable);
+public:
+    using StringVector = Vector&lt;String, 4&gt;;
+
+    TemplateRegistryKeyTable() = default;
+
+    Ref&lt;TemplateRegistryKey&gt; createKey(const StringVector&amp; rawStrings, const StringVector&amp; cookedStrings);
+
+    void unregister(TemplateRegistryKey&amp;);
+
+    ~TemplateRegistryKeyTable();
+
+private:
+    struct KeyHash {
+        static unsigned hash(const TemplateRegistryKey* key) { return key-&gt;hash(); }
+        static bool equal(const TemplateRegistryKey* a, const TemplateRegistryKey* b) { return *a == *b; }
+        static const bool safeToCompareToEmptyOrDeleted = false;
+    };
+
+    HashSet&lt;TemplateRegistryKey*, KeyHash&gt; m_atomicTable;
+};
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (208952 => 208953)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2016-11-21 23:54:43 UTC (rev 208953)
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx"> #include &quot;SmallStrings.h&quot;
</span><span class="cx"> #include &quot;SourceCode.h&quot;
</span><span class="cx"> #include &quot;Strong.h&quot;
</span><ins>+#include &quot;TemplateRegistryKeyTable.h&quot;
</ins><span class="cx"> #include &quot;ThunkGenerators.h&quot;
</span><span class="cx"> #include &quot;VMEntryRecord.h&quot;
</span><span class="cx"> #include &quot;Watchpoint.h&quot;
</span><span class="lines">@@ -349,6 +350,7 @@
</span><span class="cx"> 
</span><span class="cx">     AtomicStringTable* m_atomicStringTable;
</span><span class="cx">     WTF::SymbolRegistry m_symbolRegistry;
</span><ins>+    TemplateRegistryKeyTable m_templateRegistryKeytable;
</ins><span class="cx">     CommonIdentifiers* propertyNames;
</span><span class="cx">     const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
</span><span class="cx">     SmallStrings smallStrings;
</span><span class="lines">@@ -362,6 +364,8 @@
</span><span class="cx">     AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; }
</span><span class="cx">     WTF::SymbolRegistry&amp; symbolRegistry() { return m_symbolRegistry; }
</span><span class="cx"> 
</span><ins>+    TemplateRegistryKeyTable&amp; templateRegistryKeyTable() { return m_templateRegistryKeytable; }
+
</ins><span class="cx">     WeakGCMap&lt;SymbolImpl*, Symbol, PtrHash&lt;SymbolImpl*&gt;&gt; symbolImplToSymbolMap;
</span><span class="cx"> 
</span><span class="cx">     enum class DeletePropertyMode {
</span></span></pre>
</div>
</div>

</body>
</html>