<!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>[244978] 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/244978">244978</a></dd>
<dt>Author</dt> <dd>ysuzuki@apple.com</dd>
<dt>Date</dt> <dd>2019-05-06 14:33:27 -0700 (Mon, 06 May 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>TemplateObject passed to template literal tags are not always identical for the same source location.
https://bugs.webkit.org/show_bug.cgi?id=190756

Reviewed by Saam Barati.

JSTests:

* complex.yaml:
* complex/tagged-template-regeneration-after.js: Added.
(shouldBe):
* complex/tagged-template-regeneration.js: Added.
(call):
(test):
* modules/tagged-template-inside-module.js: Added.
(from.string_appeared_here.call):
* modules/tagged-template-inside-module/other-tagged-templates.js: Added.
(call):
(export.otherTaggedTemplates):
* stress/call-and-construct-should-return-same-tagged-templates.js: Added.
(shouldBe):
(call):
(poly):
* stress/tagged-templates-in-direct-eval-should-not-produce-same-site-object.js: Added.
(shouldBe):
(call):
* stress/tagged-templates-in-global-function-should-not-produce-same-site-object.js: Added.
(shouldBe):
(call):
* stress/tagged-templates-in-indirect-eval-should-not-produce-same-site-object.js: Added.
(shouldBe):
(call):
* stress/tagged-templates-in-multiple-functions.js: Added.
(shouldBe):
(call):
(a):
(b):
(c):

Source/JavaScriptCore:

Tagged template literal requires that the site object is allocated per source location. Previously, we create the site object
when linking CodeBlock and cache it in CodeBlock. But this is wrong because,

1. CodeBlock can be jettisoned and regenerated. So every time CodeBlock is regenerated, we get the different site object.
2. Call and Construct can have different CodeBlock. Even if the function is called in call-form or construct-form, we should return the same site object.

In this patch, we start caching these site objects in the top-level ScriptExecutable, this matches the spec's per source location since the only one top-level
ScriptExecutable is created for the given script code. Each ScriptExecutable of JSFunction can be created multiple times because CodeBlock creates it.
But the top-level one is not created by CodeBlock. This top-level ScriptExecutable is well-aligned to the Script itself. The top-level ScriptExecutable now has HashMap,
which maps source locations to cached site objects.

1. This patch threads the top-level ScriptExecutable to each FunctionExecutable creation. Each FunctionExecutable has a reference to the top-level ScriptExecutable.
2. We put TemplateObjectMap in ScriptExecutable, which manages cached template objects.
3. We move FunctionExecutable::m_cachedPolyProtoStructure to the FunctionExecutable::RareDate to keep FunctionExecutable 128 bytes.

* Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result:
* Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result:
* Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result:
* Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result:
* Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result:
* Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result:
* Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result:
* Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result:
* Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result:
* Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result:
* Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result:
* Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result:
* Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result:
* Scripts/wkbuiltins/builtins_templates.py:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::setConstantRegisters):
* bytecode/CodeBlock.h:
* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::UnlinkedFunctionExecutable::link):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::addTemplateObjectConstant):
(JSC::BytecodeGenerator::emitGetTemplateObject):
* bytecompiler/BytecodeGenerator.h:
* runtime/CachedTypes.cpp:
(JSC::CachedTemplateObjectDescriptor::encode):
(JSC::CachedTemplateObjectDescriptor::decode const):
(JSC::CachedJSValue::encode):
(JSC::CachedJSValue::decode const):
* runtime/EvalExecutable.cpp:
(JSC::EvalExecutable::ensureTemplateObjectMap):
(JSC::EvalExecutable::visitChildren):
* runtime/EvalExecutable.h:
* runtime/FunctionExecutable.cpp:
(JSC::FunctionExecutable::finishCreation):
(JSC::FunctionExecutable::visitChildren):
(JSC::FunctionExecutable::fromGlobalCode):
(JSC::FunctionExecutable::ensureRareDataSlow):
(JSC::FunctionExecutable::ensureTemplateObjectMap):
* runtime/FunctionExecutable.h:
* runtime/JSModuleRecord.cpp:
(JSC::JSModuleRecord::instantiateDeclarations):
* runtime/JSTemplateObjectDescriptor.cpp:
(JSC::JSTemplateObjectDescriptor::JSTemplateObjectDescriptor):
(JSC::JSTemplateObjectDescriptor::create):
* runtime/JSTemplateObjectDescriptor.h:
* runtime/ModuleProgramExecutable.cpp:
(JSC::ModuleProgramExecutable::ensureTemplateObjectMap):
(JSC::ModuleProgramExecutable::visitChildren):
* runtime/ModuleProgramExecutable.h:
* runtime/ProgramExecutable.cpp:
(JSC::ProgramExecutable::ensureTemplateObjectMap):
(JSC::ProgramExecutable::visitChildren):
* runtime/ProgramExecutable.h:
* runtime/ScriptExecutable.cpp:
(JSC::ScriptExecutable::topLevelExecutable):
(JSC::ScriptExecutable::createTemplateObject):
(JSC::ScriptExecutable::ensureTemplateObjectMap):
* runtime/ScriptExecutable.h:
* tools/JSDollarVM.cpp:
(JSC::functionCreateBuiltin):
(JSC::functionDeleteAllCodeWhenIdle):
(JSC::JSDollarVM::finishCreation):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkJSTestscomplexyaml">trunk/JSTests/complex.yaml</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinPromiseCombinedjsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinPromiseSeparatejsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinprototypeCombinedjsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinprototypeSeparatejsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinConstructorCombinedjsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinConstructorSeparatejsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreInternalClashingNamesCombinedjsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreAnotherGuardedInternalBuiltinSeparatejsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreArbitraryConditionalGuardSeparatejsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreGuardedBuiltinSeparatejsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreGuardedInternalBuiltinSeparatejsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreUnguardedBuiltinSeparatejsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCorexmlCasingTestSeparatejsresult">trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result</a></li>
<li><a href="#trunkSourceJavaScriptCoreScriptswkbuiltinsbuiltins_templatespy">trunk/Source/JavaScriptCore/Scripts/wkbuiltins/builtins_templates.py</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutablecpp">trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutableh">trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.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="#trunkSourceJavaScriptCoreruntimeCachedTypescpp">trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeEvalExecutablecpp">trunk/Source/JavaScriptCore/runtime/EvalExecutable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeEvalExecutableh">trunk/Source/JavaScriptCore/runtime/EvalExecutable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeFunctionExecutablecpp">trunk/Source/JavaScriptCore/runtime/FunctionExecutable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeFunctionExecutableh">trunk/Source/JavaScriptCore/runtime/FunctionExecutable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSModuleRecordcpp">trunk/Source/JavaScriptCore/runtime/JSModuleRecord.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTemplateObjectDescriptorcpp">trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTemplateObjectDescriptorh">trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeModuleProgramExecutablecpp">trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeModuleProgramExecutableh">trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeProgramExecutablecpp">trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeProgramExecutableh">trunk/Source/JavaScriptCore/runtime/ProgramExecutable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeScriptExecutablecpp">trunk/Source/JavaScriptCore/runtime/ScriptExecutable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeScriptExecutableh">trunk/Source/JavaScriptCore/runtime/ScriptExecutable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretoolsJSDollarVMcpp">trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestscomplextaggedtemplateregenerationafterjs">trunk/JSTests/complex/tagged-template-regeneration-after.js</a></li>
<li><a href="#trunkJSTestscomplextaggedtemplateregenerationjs">trunk/JSTests/complex/tagged-template-regeneration.js</a></li>
<li>trunk/JSTests/modules/tagged-template-inside-module/</li>
<li><a href="#trunkJSTestsmodulestaggedtemplateinsidemoduleothertaggedtemplatesjs">trunk/JSTests/modules/tagged-template-inside-module/other-tagged-templates.js</a></li>
<li><a href="#trunkJSTestsmodulestaggedtemplateinsidemodulejs">trunk/JSTests/modules/tagged-template-inside-module.js</a></li>
<li><a href="#trunkJSTestsstresscallandconstructshouldreturnsametaggedtemplatesjs">trunk/JSTests/stress/call-and-construct-should-return-same-tagged-templates.js</a></li>
<li><a href="#trunkJSTestsstresstaggedtemplatesindirectevalshouldnotproducesamesiteobjectjs">trunk/JSTests/stress/tagged-templates-in-direct-eval-should-not-produce-same-site-object.js</a></li>
<li><a href="#trunkJSTestsstresstaggedtemplatesinfunctionindirectevaljs">trunk/JSTests/stress/tagged-templates-in-function-in-direct-eval.js</a></li>
<li><a href="#trunkJSTestsstresstaggedtemplatesinglobalfunctionshouldnotproducesamesiteobjectjs">trunk/JSTests/stress/tagged-templates-in-global-function-should-not-produce-same-site-object.js</a></li>
<li><a href="#trunkJSTestsstresstaggedtemplatesinindirectevalshouldnotproducesamesiteobjectjs">trunk/JSTests/stress/tagged-templates-in-indirect-eval-should-not-produce-same-site-object.js</a></li>
<li><a href="#trunkJSTestsstresstaggedtemplatesinmultiplefunctionsjs">trunk/JSTests/stress/tagged-templates-in-multiple-functions.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog  2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/JSTests/ChangeLog     2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -1,3 +1,41 @@
</span><ins>+2019-05-06  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        TemplateObject passed to template literal tags are not always identical for the same source location.
+        https://bugs.webkit.org/show_bug.cgi?id=190756
+
+        Reviewed by Saam Barati.
+
+        * complex.yaml:
+        * complex/tagged-template-regeneration-after.js: Added.
+        (shouldBe):
+        * complex/tagged-template-regeneration.js: Added.
+        (call):
+        (test):
+        * modules/tagged-template-inside-module.js: Added.
+        (from.string_appeared_here.call):
+        * modules/tagged-template-inside-module/other-tagged-templates.js: Added.
+        (call):
+        (export.otherTaggedTemplates):
+        * stress/call-and-construct-should-return-same-tagged-templates.js: Added.
+        (shouldBe):
+        (call):
+        (poly):
+        * stress/tagged-templates-in-direct-eval-should-not-produce-same-site-object.js: Added.
+        (shouldBe):
+        (call):
+        * stress/tagged-templates-in-global-function-should-not-produce-same-site-object.js: Added.
+        (shouldBe):
+        (call):
+        * stress/tagged-templates-in-indirect-eval-should-not-produce-same-site-object.js: Added.
+        (shouldBe):
+        (call):
+        * stress/tagged-templates-in-multiple-functions.js: Added.
+        (shouldBe):
+        (call):
+        (a):
+        (b):
+        (c):
+
</ins><span class="cx"> 2019-05-06  Stephan Szabo  <stephan.szabo@sony.com>
</span><span class="cx"> 
</span><span class="cx">         [PlayStation] JSC Stress tests failing due to timezone printing
</span></span></pre></div>
<a id="trunkJSTestscomplextaggedtemplateregenerationafterjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/complex/tagged-template-regeneration-after.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/complex/tagged-template-regeneration-after.js                              (rev 0)
+++ trunk/JSTests/complex/tagged-template-regeneration-after.js 2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var second = test();
+shouldBe(first, second);
</ins></span></pre></div>
<a id="trunkJSTestscomplextaggedtemplateregenerationjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/complex/tagged-template-regeneration.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/complex/tagged-template-regeneration.js                            (rev 0)
+++ trunk/JSTests/complex/tagged-template-regeneration.js       2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+function call(site)
+{
+    return site;
+}
+
+function test()
+{
+    return call`Cocoa`;
+}
+
+var first = test();
+$vm.deleteAllCodeWhenIdle();
+fullGC();
</ins></span></pre></div>
<a id="trunkJSTestscomplexyaml"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/complex.yaml (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/complex.yaml       2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/JSTests/complex.yaml  2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -25,3 +25,6 @@
</span><span class="cx"> 
</span><span class="cx"> - path: complex/generator-regeneration.js
</span><span class="cx">   cmd: runComplexTest [], ["generator-regeneration-after.js"], "--useDollarVM=1"
</span><ins>+
+- path: complex/tagged-template-regeneration.js
+  cmd: runComplexTest [], ["tagged-template-regeneration-after.js"], "--useDollarVM=1"
</ins></span></pre></div>
<a id="trunkJSTestsmodulestaggedtemplateinsidemoduleothertaggedtemplatesjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/modules/tagged-template-inside-module/other-tagged-templates.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/modules/tagged-template-inside-module/other-tagged-templates.js                            (rev 0)
+++ trunk/JSTests/modules/tagged-template-inside-module/other-tagged-templates.js       2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+function call(site)
+{
+    return site;
+}
+
+export function otherTaggedTemplates()
+{
+    return call`Cocoa`;
+}
</ins></span></pre></div>
<a id="trunkJSTestsmodulestaggedtemplateinsidemodulejs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/modules/tagged-template-inside-module.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/modules/tagged-template-inside-module.js                           (rev 0)
+++ trunk/JSTests/modules/tagged-template-inside-module.js      2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+import { shouldThrow, shouldBe } from "./resources/assert.js";
+import { otherTaggedTemplates } from "./tagged-template-inside-module/other-tagged-templates.js"
+
+function call(site) {
+    return site;
+}
+
+var template = otherTaggedTemplates();
+shouldBe(call`Cocoa` !== template, true);
+shouldBe(template, otherTaggedTemplates());
+shouldBe(template, new otherTaggedTemplates());
</ins></span></pre></div>
<a id="trunkJSTestsstresscallandconstructshouldreturnsametaggedtemplatesjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/call-and-construct-should-return-same-tagged-templates.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/call-and-construct-should-return-same-tagged-templates.js                           (rev 0)
+++ trunk/JSTests/stress/call-and-construct-should-return-same-tagged-templates.js      2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function call(site)
+{
+    return site;
+}
+
+function poly()
+{
+    return call`Cocoa`;
+}
+
+var first = poly();
+var second = new poly();
+
+shouldBe(first, second);
</ins></span></pre></div>
<a id="trunkJSTestsstresstaggedtemplatesindirectevalshouldnotproducesamesiteobjectjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/tagged-templates-in-direct-eval-should-not-produce-same-site-object.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/tagged-templates-in-direct-eval-should-not-produce-same-site-object.js                              (rev 0)
+++ trunk/JSTests/stress/tagged-templates-in-direct-eval-should-not-produce-same-site-object.js 2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function call(site)
+{
+    return site;
+}
+
+var expr = "call`Cocoa`";
+var first = eval(expr);
+var second = eval(expr);
+shouldBe(first !== second, true);
</ins></span></pre></div>
<a id="trunkJSTestsstresstaggedtemplatesinfunctionindirectevaljs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/tagged-templates-in-function-in-direct-eval.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/tagged-templates-in-function-in-direct-eval.js                              (rev 0)
+++ trunk/JSTests/stress/tagged-templates-in-function-in-direct-eval.js 2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function call(site)
+{
+    return site;
+}
+
+function test()
+{
+    return eval("(function ok() { return call`Cocoa`; })()");
+}
+
+var first = test();
+var second = test();
+shouldBe(first !== second, true);
</ins></span></pre></div>
<a id="trunkJSTestsstresstaggedtemplatesinglobalfunctionshouldnotproducesamesiteobjectjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/tagged-templates-in-global-function-should-not-produce-same-site-object.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/tagged-templates-in-global-function-should-not-produce-same-site-object.js                          (rev 0)
+++ trunk/JSTests/stress/tagged-templates-in-global-function-should-not-produce-same-site-object.js     2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function call(site)
+{
+    return site;
+}
+
+var expr = "return call`Cocoa`";
+var firstFunction = Function(expr);
+var secondFunction = Function(expr);
+var first = firstFunction();
+var second = secondFunction();
+shouldBe(first !== second, true);
+
+shouldBe(first, firstFunction());
+shouldBe(first, new firstFunction());
+shouldBe(second, secondFunction());
+shouldBe(second, new secondFunction());
</ins></span></pre></div>
<a id="trunkJSTestsstresstaggedtemplatesinindirectevalshouldnotproducesamesiteobjectjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/tagged-templates-in-indirect-eval-should-not-produce-same-site-object.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/tagged-templates-in-indirect-eval-should-not-produce-same-site-object.js                            (rev 0)
+++ trunk/JSTests/stress/tagged-templates-in-indirect-eval-should-not-produce-same-site-object.js       2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var indirectEval = eval;
+function call(site)
+{
+    return site;
+}
+
+var expr = "call`Cocoa`";
+var first = indirectEval(expr);
+var second = indirectEval(expr);
+shouldBe(first !== second, true);
</ins></span></pre></div>
<a id="trunkJSTestsstresstaggedtemplatesinmultiplefunctionsjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/tagged-templates-in-multiple-functions.js (0 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/tagged-templates-in-multiple-functions.js                           (rev 0)
+++ trunk/JSTests/stress/tagged-templates-in-multiple-functions.js      2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function call(site)
+{
+    return site;
+}
+
+function a()
+{
+    return call`Cocoa`;
+}
+
+function b()
+{
+    return call`Cocoa`;
+}
+
+function c()
+{
+    return [ call`Cocoa`, call`Cocoa` ];
+}
+
+shouldBe(a() !== b(), true);
+shouldBe(a() === a(), true);
+shouldBe(b() === b(), true);
+var result = c();
+shouldBe(c()[0] === result[0], true);
+shouldBe(c()[1] === result[1], true);
+shouldBe(result[0] !== result[1], true);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/ChangeLog       2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -1,3 +1,90 @@
</span><ins>+2019-05-06  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        TemplateObject passed to template literal tags are not always identical for the same source location.
+        https://bugs.webkit.org/show_bug.cgi?id=190756
+
+        Reviewed by Saam Barati.
+
+        Tagged template literal requires that the site object is allocated per source location. Previously, we create the site object
+        when linking CodeBlock and cache it in CodeBlock. But this is wrong because,
+
+        1. CodeBlock can be jettisoned and regenerated. So every time CodeBlock is regenerated, we get the different site object.
+        2. Call and Construct can have different CodeBlock. Even if the function is called in call-form or construct-form, we should return the same site object.
+
+        In this patch, we start caching these site objects in the top-level ScriptExecutable, this matches the spec's per source location since the only one top-level
+        ScriptExecutable is created for the given script code. Each ScriptExecutable of JSFunction can be created multiple times because CodeBlock creates it.
+        But the top-level one is not created by CodeBlock. This top-level ScriptExecutable is well-aligned to the Script itself. The top-level ScriptExecutable now has HashMap,
+        which maps source locations to cached site objects.
+
+        1. This patch threads the top-level ScriptExecutable to each FunctionExecutable creation. Each FunctionExecutable has a reference to the top-level ScriptExecutable.
+        2. We put TemplateObjectMap in ScriptExecutable, which manages cached template objects.
+        3. We move FunctionExecutable::m_cachedPolyProtoStructure to the FunctionExecutable::RareDate to keep FunctionExecutable 128 bytes.
+
+        * Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result:
+        * Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result:
+        * Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result:
+        * Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result:
+        * Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result:
+        * Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result:
+        * Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result:
+        * Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result:
+        * Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result:
+        * Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result:
+        * Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result:
+        * Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result:
+        * Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result:
+        * Scripts/wkbuiltins/builtins_templates.py:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::finishCreation):
+        (JSC::CodeBlock::setConstantRegisters):
+        * bytecode/CodeBlock.h:
+        * bytecode/UnlinkedFunctionExecutable.cpp:
+        (JSC::UnlinkedFunctionExecutable::link):
+        * bytecode/UnlinkedFunctionExecutable.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::addTemplateObjectConstant):
+        (JSC::BytecodeGenerator::emitGetTemplateObject):
+        * bytecompiler/BytecodeGenerator.h:
+        * runtime/CachedTypes.cpp:
+        (JSC::CachedTemplateObjectDescriptor::encode):
+        (JSC::CachedTemplateObjectDescriptor::decode const):
+        (JSC::CachedJSValue::encode):
+        (JSC::CachedJSValue::decode const):
+        * runtime/EvalExecutable.cpp:
+        (JSC::EvalExecutable::ensureTemplateObjectMap):
+        (JSC::EvalExecutable::visitChildren):
+        * runtime/EvalExecutable.h:
+        * runtime/FunctionExecutable.cpp:
+        (JSC::FunctionExecutable::finishCreation):
+        (JSC::FunctionExecutable::visitChildren):
+        (JSC::FunctionExecutable::fromGlobalCode):
+        (JSC::FunctionExecutable::ensureRareDataSlow):
+        (JSC::FunctionExecutable::ensureTemplateObjectMap):
+        * runtime/FunctionExecutable.h:
+        * runtime/JSModuleRecord.cpp:
+        (JSC::JSModuleRecord::instantiateDeclarations):
+        * runtime/JSTemplateObjectDescriptor.cpp:
+        (JSC::JSTemplateObjectDescriptor::JSTemplateObjectDescriptor):
+        (JSC::JSTemplateObjectDescriptor::create):
+        * runtime/JSTemplateObjectDescriptor.h:
+        * runtime/ModuleProgramExecutable.cpp:
+        (JSC::ModuleProgramExecutable::ensureTemplateObjectMap):
+        (JSC::ModuleProgramExecutable::visitChildren):
+        * runtime/ModuleProgramExecutable.h:
+        * runtime/ProgramExecutable.cpp:
+        (JSC::ProgramExecutable::ensureTemplateObjectMap):
+        (JSC::ProgramExecutable::visitChildren):
+        * runtime/ProgramExecutable.h:
+        * runtime/ScriptExecutable.cpp:
+        (JSC::ScriptExecutable::topLevelExecutable):
+        (JSC::ScriptExecutable::createTemplateObject):
+        (JSC::ScriptExecutable::ensureTemplateObjectMap):
+        * runtime/ScriptExecutable.h:
+        * tools/JSDollarVM.cpp:
+        (JSC::functionCreateBuiltin):
+        (JSC::functionDeleteAllCodeWhenIdle):
+        (JSC::JSDollarVM::finishCreation):
+
</ins><span class="cx"> 2019-05-04  Tadeu Zagallo  <tzagallo@apple.com>
</span><span class="cx"> 
</span><span class="cx">         TypedArrays should not store properties that are canonical numeric indices
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinPromiseCombinedjsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result    2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result       2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -141,7 +141,7 @@
</span><span class="cx"> #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><del>-    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</del><ins>+    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</ins><span class="cx"> JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinPromiseSeparatejsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result    2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result       2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -158,7 +158,7 @@
</span><span class="cx"> #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><del>-    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</del><ins>+    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</ins><span class="cx"> JSC_FOREACH_BUILTIN.PROMISE_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinprototypeCombinedjsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result  2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result     2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -167,7 +167,7 @@
</span><span class="cx"> #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><del>-    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</del><ins>+    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</ins><span class="cx"> JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinprototypeSeparatejsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result  2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result     2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -282,7 +282,7 @@
</span><span class="cx"> #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><del>-    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</del><ins>+    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</ins><span class="cx"> JSC_FOREACH_BUILTIN.PROTOTYPE_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinConstructorCombinedjsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result 2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result    2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -139,7 +139,7 @@
</span><span class="cx"> #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><del>-    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</del><ins>+    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</ins><span class="cx"> JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreBuiltinConstructorSeparatejsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result 2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result    2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -212,7 +212,7 @@
</span><span class="cx"> #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><del>-    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</del><ins>+    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</ins><span class="cx"> JSC_FOREACH_BUILTINCONSTRUCTOR_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedJavaScriptCoreInternalClashingNamesCombinedjsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result      2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result 2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -140,7 +140,7 @@
</span><span class="cx"> #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><del>-    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</del><ins>+    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
</ins><span class="cx"> JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreAnotherGuardedInternalBuiltinSeparatejsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result     2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result        2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -220,7 +220,7 @@
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><span class="cx">     JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
</span><del>-    return clientData->builtinFunctions().anotherGuardedInternalBuiltinBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().anotherGuardedInternalBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</del><ins>+    return clientData->builtinFunctions().anotherGuardedInternalBuiltinBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().anotherGuardedInternalBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</ins><span class="cx"> }
</span><span class="cx"> WEBCORE_FOREACH_ANOTHERGUARDEDINTERNALBUILTIN_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreArbitraryConditionalGuardSeparatejsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result 2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result    2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -190,7 +190,7 @@
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><span class="cx">     JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
</span><del>-    return clientData->builtinFunctions().arbitraryConditionalGuardBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().arbitraryConditionalGuardBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</del><ins>+    return clientData->builtinFunctions().arbitraryConditionalGuardBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().arbitraryConditionalGuardBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</ins><span class="cx"> }
</span><span class="cx"> WEBCORE_FOREACH_ARBITRARYCONDITIONALGUARD_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreGuardedBuiltinSeparatejsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result    2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result       2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -190,7 +190,7 @@
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><span class="cx">     JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
</span><del>-    return clientData->builtinFunctions().guardedBuiltinBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().guardedBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</del><ins>+    return clientData->builtinFunctions().guardedBuiltinBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().guardedBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</ins><span class="cx"> }
</span><span class="cx"> WEBCORE_FOREACH_GUARDEDBUILTIN_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreGuardedInternalBuiltinSeparatejsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result    2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result       2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -222,7 +222,7 @@
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><span class="cx">     JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
</span><del>-    return clientData->builtinFunctions().guardedInternalBuiltinBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().guardedInternalBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</del><ins>+    return clientData->builtinFunctions().guardedInternalBuiltinBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().guardedInternalBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</ins><span class="cx"> }
</span><span class="cx"> WEBCORE_FOREACH_GUARDEDINTERNALBUILTIN_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCoreUnguardedBuiltinSeparatejsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result  2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result     2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -184,7 +184,7 @@
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><span class="cx">     JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
</span><del>-    return clientData->builtinFunctions().unguardedBuiltinBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().unguardedBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</del><ins>+    return clientData->builtinFunctions().unguardedBuiltinBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().unguardedBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</ins><span class="cx"> }
</span><span class="cx"> WEBCORE_FOREACH_UNGUARDEDBUILTIN_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptstestsbuiltinsexpectedWebCorexmlCasingTestSeparatejsresult"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result     2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result        2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -275,7 +275,7 @@
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
</span><span class="cx"> {\
</span><span class="cx">     JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
</span><del>-    return clientData->builtinFunctions().xmlCasingTestBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().xmlCasingTestBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</del><ins>+    return clientData->builtinFunctions().xmlCasingTestBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().xmlCasingTestBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</ins><span class="cx"> }
</span><span class="cx"> WEBCORE_FOREACH_XMLCASINGTEST_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreScriptswkbuiltinsbuiltins_templatespy"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Scripts/wkbuiltins/builtins_templates.py (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Scripts/wkbuiltins/builtins_templates.py     2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/Scripts/wkbuiltins/builtins_templates.py        2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx"> #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \\
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\
</span><span class="cx"> {\\
</span><del>-    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</del><ins>+    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</ins><span class="cx"> }
</span><span class="cx"> ${macroPrefix}_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx"> #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \\
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\
</span><span class="cx"> {\\
</span><del>-    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</del><ins>+    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
</ins><span class="cx"> }
</span><span class="cx"> ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\
</span><span class="cx"> {\\
</span><span class="cx">     JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \\
</span><del>-    return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \\
</del><ins>+    return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \\
</ins><span class="cx"> }
</span><span class="cx"> ${macroPrefix}_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span><span class="lines">@@ -120,7 +120,7 @@
</span><span class="cx"> JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\
</span><span class="cx"> {\\
</span><span class="cx">     JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \\
</span><del>-    return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \\
</del><ins>+    return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \\
</ins><span class="cx"> }
</span><span class="cx"> ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
</span><span class="cx"> #undef DEFINE_BUILTIN_GENERATOR
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp       2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp  2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -395,7 +395,8 @@
</span><span class="cx">     if (m_unlinkedCode->wasCompiledWithTypeProfilerOpcodes() || m_unlinkedCode->wasCompiledWithControlFlowProfilerOpcodes())
</span><span class="cx">         vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(vm), ownerExecutable->typeProfilingEndOffset(vm));
</span><span class="cx"> 
</span><del>-    setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
</del><ins>+    ScriptExecutable* topLevelExecutable = ownerExecutable->topLevelExecutable();
+    setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation(), topLevelExecutable);
</ins><span class="cx">     RETURN_IF_EXCEPTION(throwScope, false);
</span><span class="cx"> 
</span><span class="cx">     for (unsigned i = 0; i < LinkTimeConstantCount; i++) {
</span><span class="lines">@@ -421,7 +422,7 @@
</span><span class="cx">         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
</span><span class="cx">         if (shouldUpdateFunctionHasExecutedCache)
</span><span class="cx">             vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
</span><del>-        m_functionDecls[i].set(vm, this, unlinkedExecutable->link(vm, ownerExecutable->source()));
</del><ins>+        m_functionDecls[i].set(vm, this, unlinkedExecutable->link(vm, topLevelExecutable, ownerExecutable->source()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_functionExprs = RefCountedArray<WriteBarrier<FunctionExecutable>>(unlinkedCodeBlock->numberOfFunctionExprs());
</span><span class="lines">@@ -429,7 +430,7 @@
</span><span class="cx">         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
</span><span class="cx">         if (shouldUpdateFunctionHasExecutedCache)
</span><span class="cx">             vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
</span><del>-        m_functionExprs[i].set(vm, this, unlinkedExecutable->link(vm, ownerExecutable->source()));
</del><ins>+        m_functionExprs[i].set(vm, this, unlinkedExecutable->link(vm, topLevelExecutable, ownerExecutable->source()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (unlinkedCodeBlock->hasRareData()) {
</span><span class="lines">@@ -870,7 +871,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
</del><ins>+void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable)
</ins><span class="cx"> {
</span><span class="cx">     VM& vm = *m_vm;
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="lines">@@ -898,7 +899,7 @@
</span><span class="cx"> 
</span><span class="cx">                     constant = clone;
</span><span class="cx">                 } else if (auto* descriptor = jsDynamicCast<JSTemplateObjectDescriptor*>(vm, cell)) {
</span><del>-                    auto* templateObject = descriptor->createTemplateObject(exec);
</del><ins>+                    auto* templateObject = topLevelExecutable->createTemplateObject(exec, descriptor);
</ins><span class="cx">                     RETURN_IF_EXCEPTION(scope, void());
</span><span class="cx">                     constant = templateObject;
</span><span class="cx">                 }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h 2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h    2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -911,7 +911,7 @@
</span><span class="cx"> 
</span><span class="cx">     void setConstantIdentifierSetRegisters(VM&, const Vector<ConstantIdentifierSetEntry>& constants);
</span><span class="cx"> 
</span><del>-    void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation);
</del><ins>+    void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable);
</ins><span class="cx"> 
</span><span class="cx">     void replaceConstant(int index, JSValue value)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp      2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp 2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -158,7 +158,7 @@
</span><span class="cx">     return SourceCode(parentSource.provider(), startOffset, startOffset + m_sourceLength, firstLine, startColumn);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& passedParentSource, Optional<int> overrideLineNumber, Intrinsic intrinsic)
</del><ins>+FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, ScriptExecutable* topLevelExecutable, const SourceCode& passedParentSource, Optional<int> overrideLineNumber, Intrinsic intrinsic)
</ins><span class="cx"> {
</span><span class="cx">     SourceCode source = linkedSourceCode(passedParentSource);
</span><span class="cx">     FunctionOverrides::OverrideInfo overrideInfo;
</span><span class="lines">@@ -166,7 +166,7 @@
</span><span class="cx">     if (UNLIKELY(Options::functionOverrides()))
</span><span class="cx">         hasFunctionOverride = FunctionOverrides::initializeOverrideFor(source, overrideInfo);
</span><span class="cx"> 
</span><del>-    FunctionExecutable* result = FunctionExecutable::create(vm, source, this, intrinsic);
</del><ins>+    FunctionExecutable* result = FunctionExecutable::create(vm, topLevelExecutable, source, this, intrinsic);
</ins><span class="cx">     if (overrideLineNumber)
</span><span class="cx">         result->setOverrideLineNumber(*overrideLineNumber);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedFunctionExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h        2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h   2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -126,7 +126,7 @@
</span><span class="cx">         int overrideLineNumber, Optional<int> functionConstructorParametersEndPosition);
</span><span class="cx"> 
</span><span class="cx">     SourceCode linkedSourceCode(const SourceCode&) const;
</span><del>-    JS_EXPORT_PRIVATE FunctionExecutable* link(VM&, const SourceCode& parentSource, Optional<int> overrideLineNumber = WTF::nullopt, Intrinsic = NoIntrinsic);
</del><ins>+    JS_EXPORT_PRIVATE FunctionExecutable* link(VM&, ScriptExecutable* topLevelExecutable, const SourceCode& parentSource, Optional<int> overrideLineNumber = WTF::nullopt, Intrinsic = NoIntrinsic);
</ins><span class="cx"> 
</span><span class="cx">     void clearCode(VM& vm)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp   2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp      2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -2948,12 +2948,12 @@
</span><span class="cx">     return stringInMap;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::addTemplateObjectConstant(Ref<TemplateObjectDescriptor>&& descriptor)
</del><ins>+RegisterID* BytecodeGenerator::addTemplateObjectConstant(Ref<TemplateObjectDescriptor>&& descriptor, int startOffset)
</ins><span class="cx"> {
</span><del>-    JSTemplateObjectDescriptor* descriptorValue = m_templateObjectDescriptorMap.ensure(descriptor.copyRef(), [&] {
-        return JSTemplateObjectDescriptor::create(*vm(), WTFMove(descriptor));
</del><ins>+    auto result = m_templateObjectDescriptorSet.add(WTFMove(descriptor));
+    JSTemplateObjectDescriptor* descriptorValue = m_templateDescriptorMap.ensure(startOffset, [&] {
+        return JSTemplateObjectDescriptor::create(*vm(), result.iterator->copyRef(), startOffset);
</ins><span class="cx">     }).iterator->value;
</span><del>-
</del><span class="cx">     int index = addConstantIndex();
</span><span class="cx">     m_codeBlock->addConstant(descriptorValue);
</span><span class="cx">     return &m_constantPoolRegisters[index];
</span><span class="lines">@@ -4141,7 +4141,7 @@
</span><span class="cx">         else
</span><span class="cx">             cookedStrings.append(string->cooked()->impl());
</span><span class="cx">     }
</span><del>-    RefPtr<RegisterID> constant = addTemplateObjectConstant(TemplateObjectDescriptor::create(WTFMove(rawStrings), WTFMove(cookedStrings)));
</del><ins>+    RefPtr<RegisterID> constant = addTemplateObjectConstant(TemplateObjectDescriptor::create(WTFMove(rawStrings), WTFMove(cookedStrings)), taggedTemplate->startOffset());
</ins><span class="cx">     if (!dst)
</span><span class="cx">         return constant.get();
</span><span class="cx">     return move(dst, constant.get());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h     2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -1060,7 +1060,8 @@
</span><span class="cx">         using NumberMap = HashMap<double, JSValue>;
</span><span class="cx">         using IdentifierStringMap = HashMap<UniquedStringImpl*, JSString*, IdentifierRepHash>;
</span><span class="cx">         using IdentifierBigIntMap = HashMap<BigIntMapEntry, JSBigInt*>;
</span><del>-        using TemplateObjectDescriptorMap = HashMap<Ref<TemplateObjectDescriptor>, JSTemplateObjectDescriptor*>;
</del><ins>+        using TemplateObjectDescriptorSet = HashSet<Ref<TemplateObjectDescriptor>>;
+        using TemplateDescriptorMap = HashMap<uint64_t, JSTemplateObjectDescriptor*, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>;
</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">@@ -1152,7 +1153,7 @@
</span><span class="cx">     public:
</span><span class="cx">         JSString* addStringConstant(const Identifier&);
</span><span class="cx">         JSValue addBigIntConstant(const Identifier&, uint8_t radix, bool sign);
</span><del>-        RegisterID* addTemplateObjectConstant(Ref<TemplateObjectDescriptor>&&);
</del><ins>+        RegisterID* addTemplateObjectConstant(Ref<TemplateObjectDescriptor>&&, int);
</ins><span class="cx"> 
</span><span class="cx">         const InstructionStream& instructions() const { return m_writer; }
</span><span class="cx"> 
</span><span class="lines">@@ -1270,7 +1271,8 @@
</span><span class="cx">         JSValueMap m_jsValueMap;
</span><span class="cx">         IdentifierStringMap m_stringMap;
</span><span class="cx">         IdentifierBigIntMap m_bigIntMap;
</span><del>-        TemplateObjectDescriptorMap m_templateObjectDescriptorMap;
</del><ins>+        TemplateObjectDescriptorSet m_templateObjectDescriptorSet;
+        TemplateDescriptorMap m_templateDescriptorMap;
</ins><span class="cx"> 
</span><span class="cx">         StaticPropertyAnalyzer m_staticPropertyAnalyzer;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCachedTypescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp      2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp 2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -1152,24 +1152,26 @@
</span><span class="cx"> 
</span><span class="cx"> class CachedTemplateObjectDescriptor : public CachedObject<TemplateObjectDescriptor> {
</span><span class="cx"> public:
</span><del>-    void encode(Encoder& encoder, const TemplateObjectDescriptor& templateObjectDescriptor)
</del><ins>+    void encode(Encoder& encoder, const JSTemplateObjectDescriptor& descriptor)
</ins><span class="cx">     {
</span><del>-        m_rawStrings.encode(encoder, templateObjectDescriptor.rawStrings());
-        m_cookedStrings.encode(encoder, templateObjectDescriptor.cookedStrings());
</del><ins>+        m_rawStrings.encode(encoder, descriptor.descriptor().rawStrings());
+        m_cookedStrings.encode(encoder, descriptor.descriptor().cookedStrings());
+        m_startOffset = descriptor.startOffset();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Ref<TemplateObjectDescriptor> decode(Decoder& decoder) const
</del><ins>+    JSTemplateObjectDescriptor* decode(Decoder& decoder) const
</ins><span class="cx">     {
</span><span class="cx">         TemplateObjectDescriptor::StringVector decodedRawStrings;
</span><span class="cx">         TemplateObjectDescriptor::OptionalStringVector decodedCookedStrings;
</span><span class="cx">         m_rawStrings.decode(decoder, decodedRawStrings);
</span><span class="cx">         m_cookedStrings.decode(decoder, decodedCookedStrings);
</span><del>-        return TemplateObjectDescriptor::create(WTFMove(decodedRawStrings), WTFMove(decodedCookedStrings));
</del><ins>+        return JSTemplateObjectDescriptor::create(decoder.vm(), TemplateObjectDescriptor::create(WTFMove(decodedRawStrings), WTFMove(decodedCookedStrings)), m_startOffset);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     CachedVector<CachedString, 4> m_rawStrings;
</span><span class="cx">     CachedVector<CachedOptional<CachedString>, 4> m_cookedStrings;
</span><ins>+    int m_startOffset;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class CachedBigInt : public VariableLengthObject<JSBigInt> {
</span><span class="lines">@@ -1243,7 +1245,7 @@
</span><span class="cx"> 
</span><span class="cx">         if (auto* templateObjectDescriptor = jsDynamicCast<JSTemplateObjectDescriptor*>(vm, cell)) {
</span><span class="cx">             m_type = EncodedType::TemplateObjectDescriptor;
</span><del>-            this->allocate<CachedTemplateObjectDescriptor>(encoder)->encode(encoder, templateObjectDescriptor->descriptor());
</del><ins>+            this->allocate<CachedTemplateObjectDescriptor>(encoder)->encode(encoder, *templateObjectDescriptor);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1278,7 +1280,7 @@
</span><span class="cx">             v = this->buffer<CachedRegExp>()->decode(decoder);
</span><span class="cx">             break;
</span><span class="cx">         case EncodedType::TemplateObjectDescriptor:
</span><del>-            v = JSTemplateObjectDescriptor::create(decoder.vm(), this->buffer<CachedTemplateObjectDescriptor>()->decode(decoder));
</del><ins>+            v = this->buffer<CachedTemplateObjectDescriptor>()->decode(decoder);
</ins><span class="cx">             break;
</span><span class="cx">         case EncodedType::BigInt:
</span><span class="cx">             v = this->buffer<CachedBigInt>()->decode(decoder);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeEvalExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/EvalExecutable.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/EvalExecutable.cpp   2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/EvalExecutable.cpp      2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -44,6 +44,11 @@
</span><span class="cx">     static_cast<EvalExecutable*>(cell)->EvalExecutable::~EvalExecutable();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+auto EvalExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
+{
+    return ensureTemplateObjectMapImpl(m_templateObjectMap);
+}
+
</ins><span class="cx"> void EvalExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
</span><span class="cx"> {
</span><span class="cx">     EvalExecutable* thisObject = jsCast<EvalExecutable*>(cell);
</span><span class="lines">@@ -51,6 +56,11 @@
</span><span class="cx">     Base::visitChildren(thisObject, visitor);
</span><span class="cx">     visitor.append(thisObject->m_unlinkedEvalCodeBlock);
</span><span class="cx">     visitor.append(thisObject->m_evalCodeBlock);
</span><ins>+    if (TemplateObjectMap* map = thisObject->m_templateObjectMap.get()) {
+        auto locker = holdLock(thisObject->cellLock());
+        for (auto& entry : *map)
+            visitor.append(entry.value);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeEvalExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/EvalExecutable.h (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/EvalExecutable.h     2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/EvalExecutable.h        2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -69,6 +69,8 @@
</span><span class="cx">     unsigned numTopLevelFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
</span><span class="cx">     bool allowDirectEvalCache() const { return m_unlinkedEvalCodeBlock->allowDirectEvalCache(); }
</span><span class="cx"> 
</span><ins>+    TemplateObjectMap& ensureTemplateObjectMap(VM&);
+
</ins><span class="cx"> protected:
</span><span class="cx">     friend class ExecutableBase;
</span><span class="cx">     friend class ScriptExecutable;
</span><span class="lines">@@ -80,6 +82,7 @@
</span><span class="cx"> 
</span><span class="cx">     WriteBarrier<ExecutableToCodeBlockEdge> m_evalCodeBlock;
</span><span class="cx">     WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
</span><ins>+    std::unique_ptr<TemplateObjectMap> m_templateObjectMap;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeFunctionExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/FunctionExecutable.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/FunctionExecutable.cpp       2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/FunctionExecutable.cpp  2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -54,9 +54,10 @@
</span><span class="cx">         m_singletonFunctionState = ClearWatchpoint;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void FunctionExecutable::finishCreation(VM& vm)
</del><ins>+void FunctionExecutable::finishCreation(VM& vm, ScriptExecutable* topLevelExecutable)
</ins><span class="cx"> {
</span><span class="cx">     Base::finishCreation(vm);
</span><ins>+    m_topLevelExecutable.set(vm, this, topLevelExecutable ? topLevelExecutable : this);
</ins><span class="cx">     if (VM::canUseJIT())
</span><span class="cx">         m_singletonFunction.set(vm, this, InferredValue::create(vm));
</span><span class="cx"> }
</span><span class="lines">@@ -85,12 +86,20 @@
</span><span class="cx">     FunctionExecutable* thisObject = jsCast<FunctionExecutable*>(cell);
</span><span class="cx">     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</span><span class="cx">     Base::visitChildren(thisObject, visitor);
</span><ins>+    visitor.append(thisObject->m_topLevelExecutable);
</ins><span class="cx">     visitor.append(thisObject->m_codeBlockForCall);
</span><span class="cx">     visitor.append(thisObject->m_codeBlockForConstruct);
</span><span class="cx">     visitor.append(thisObject->m_unlinkedExecutable);
</span><span class="cx">     if (VM::canUseJIT())
</span><span class="cx">         visitor.append(thisObject->m_singletonFunction);
</span><del>-    visitor.append(thisObject->m_cachedPolyProtoStructure);
</del><ins>+    if (RareData* rareData = thisObject->m_rareData.get()) {
+        visitor.append(rareData->m_cachedPolyProtoStructure);
+        if (TemplateObjectMap* map = rareData->m_templateObjectMap.get()) {
+            auto locker = holdLock(thisObject->cellLock());
+            for (auto& entry : *map)
+                visitor.append(entry.value);
+        }
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> FunctionExecutable* FunctionExecutable::fromGlobalCode(
</span><span class="lines">@@ -103,7 +112,7 @@
</span><span class="cx">     if (!unlinkedExecutable)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><del>-    return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber);
</del><ins>+    return unlinkedExecutable->link(exec.vm(), nullptr, source, overrideLineNumber);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> FunctionExecutable::RareData& FunctionExecutable::ensureRareDataSlow()
</span><span class="lines">@@ -115,6 +124,7 @@
</span><span class="cx">     rareData->m_parametersStartOffset = parametersStartOffset();
</span><span class="cx">     rareData->m_typeProfilingStartOffset = typeProfilingStartOffset();
</span><span class="cx">     rareData->m_typeProfilingEndOffset = typeProfilingEndOffset();
</span><ins>+    WTF::storeStoreFence();
</ins><span class="cx">     m_rareData = WTFMove(rareData);
</span><span class="cx">     return *m_rareData;
</span><span class="cx"> }
</span><span class="lines">@@ -130,4 +140,10 @@
</span><span class="cx">     rareData.m_typeProfilingEndOffset = overrideInfo.typeProfilingEndOffset;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+auto FunctionExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
+{
+    RareData& rareData = ensureRareData();
+    return ensureTemplateObjectMapImpl(rareData.m_templateObjectMap);
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeFunctionExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/FunctionExecutable.h (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/FunctionExecutable.h 2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/FunctionExecutable.h    2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -48,10 +48,10 @@
</span><span class="cx">         return &vm.functionExecutableSpace.space;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static FunctionExecutable* create(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, Intrinsic intrinsic)
</del><ins>+    static FunctionExecutable* create(VM& vm, ScriptExecutable* topLevelExecutable, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, Intrinsic intrinsic)
</ins><span class="cx">     {
</span><span class="cx">         FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, intrinsic);
</span><del>-        executable->finishCreation(vm);
</del><ins>+        executable->finishCreation(vm, topLevelExecutable);
</ins><span class="cx">         return executable;
</span><span class="cx">     }
</span><span class="cx">     static FunctionExecutable* fromGlobalCode(
</span><span class="lines">@@ -282,8 +282,16 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Cached poly proto structure for the result of constructing this executable.
</span><del>-    Structure* cachedPolyProtoStructure() { return m_cachedPolyProtoStructure.get(); }
-    void setCachedPolyProtoStructure(VM& vm, Structure* structure) { m_cachedPolyProtoStructure.set(vm, this, structure); }
</del><ins>+    Structure* cachedPolyProtoStructure()
+    {
+        if (UNLIKELY(m_rareData))
+            return m_rareData->m_cachedPolyProtoStructure.get();
+        return nullptr;
+    }
+    void setCachedPolyProtoStructure(VM& vm, Structure* structure)
+    {
+        ensureRareData().m_cachedPolyProtoStructure.set(vm, this, structure);
+    }
</ins><span class="cx"> 
</span><span class="cx">     InlineWatchpointSet& ensurePolyProtoWatchpoint()
</span><span class="cx">     {
</span><span class="lines">@@ -294,11 +302,15 @@
</span><span class="cx"> 
</span><span class="cx">     Box<InlineWatchpointSet> sharedPolyProtoWatchpoint() const { return m_polyProtoWatchpoint; }
</span><span class="cx"> 
</span><ins>+    ScriptExecutable* topLevelExecutable() const { return m_topLevelExecutable.get(); }
+
+    TemplateObjectMap& ensureTemplateObjectMap(VM&);
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class ExecutableBase;
</span><span class="cx">     FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, Intrinsic);
</span><span class="cx">     
</span><del>-    void finishCreation(VM&);
</del><ins>+    void finishCreation(VM&, ScriptExecutable* topLevelExecutable);
</ins><span class="cx"> 
</span><span class="cx">     friend class ScriptExecutable;
</span><span class="cx"> 
</span><span class="lines">@@ -311,6 +323,8 @@
</span><span class="cx">         unsigned m_parametersStartOffset { 0 };
</span><span class="cx">         unsigned m_typeProfilingStartOffset { UINT_MAX };
</span><span class="cx">         unsigned m_typeProfilingEndOffset { UINT_MAX };
</span><ins>+        std::unique_ptr<TemplateObjectMap> m_templateObjectMap;
+        WriteBarrier<Structure> m_cachedPolyProtoStructure;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     RareData& ensureRareData()
</span><span class="lines">@@ -321,7 +335,11 @@
</span><span class="cx">     }
</span><span class="cx">     RareData& ensureRareDataSlow();
</span><span class="cx"> 
</span><ins>+    // FIXME: We can merge rareData pointer and top-level executable pointer. First time, setting parent.
+    // If RareData is required, materialize RareData, swap it, and store top-level executable pointer inside RareData.
+    // https://bugs.webkit.org/show_bug.cgi?id=197625
</ins><span class="cx">     std::unique_ptr<RareData> m_rareData;
</span><ins>+    WriteBarrier<ScriptExecutable> m_topLevelExecutable;
</ins><span class="cx">     WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
</span><span class="cx">     WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForCall;
</span><span class="cx">     WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForConstruct;
</span><span class="lines">@@ -329,7 +347,6 @@
</span><span class="cx">         WriteBarrier<InferredValue> m_singletonFunction;
</span><span class="cx">         WatchpointState m_singletonFunctionState;
</span><span class="cx">     };
</span><del>-    WriteBarrier<Structure> m_cachedPolyProtoStructure;
</del><span class="cx">     Box<InlineWatchpointSet> m_polyProtoWatchpoint;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSModuleRecordcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSModuleRecord.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSModuleRecord.cpp   2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/JSModuleRecord.cpp      2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -200,7 +200,7 @@
</span><span class="cx">                     unlinkedFunctionExecutable->typeProfilingStartOffset(),
</span><span class="cx">                     unlinkedFunctionExecutable->typeProfilingEndOffset());
</span><span class="cx">             }
</span><del>-            JSFunction* function = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, moduleProgramExecutable->source()), moduleEnvironment);
</del><ins>+            JSFunction* function = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, moduleProgramExecutable, moduleProgramExecutable->source()), moduleEnvironment);
</ins><span class="cx">             bool putResult = false;
</span><span class="cx">             symbolTablePutTouchWatchpointSet(moduleEnvironment, exec, unlinkedFunctionExecutable->name(), function, /* shouldThrowReadOnlyError */ false, /* ignoreReadOnlyErrors */ true, putResult);
</span><span class="cx">             RETURN_IF_EXCEPTION(scope, void());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTemplateObjectDescriptorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.cpp       2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.cpp  2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -36,15 +36,16 @@
</span><span class="cx"> const ClassInfo JSTemplateObjectDescriptor::s_info = { "TemplateObjectDescriptor", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSTemplateObjectDescriptor) };
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-JSTemplateObjectDescriptor::JSTemplateObjectDescriptor(VM& vm, Ref<TemplateObjectDescriptor>&& descriptor)
</del><ins>+JSTemplateObjectDescriptor::JSTemplateObjectDescriptor(VM& vm, Ref<TemplateObjectDescriptor>&& descriptor, int startOffset)
</ins><span class="cx">     : Base(vm, vm.templateObjectDescriptorStructure.get())
</span><span class="cx">     , m_descriptor(WTFMove(descriptor))
</span><ins>+    , m_startOffset(startOffset)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSTemplateObjectDescriptor* JSTemplateObjectDescriptor::create(VM& vm, Ref<TemplateObjectDescriptor>&& descriptor)
</del><ins>+JSTemplateObjectDescriptor* JSTemplateObjectDescriptor::create(VM& vm, Ref<TemplateObjectDescriptor>&& descriptor, int startOffset)
</ins><span class="cx"> {
</span><del>-    JSTemplateObjectDescriptor* result = new (NotNull, allocateCell<JSTemplateObjectDescriptor>(vm.heap)) JSTemplateObjectDescriptor(vm, WTFMove(descriptor));
</del><ins>+    JSTemplateObjectDescriptor* result = new (NotNull, allocateCell<JSTemplateObjectDescriptor>(vm.heap)) JSTemplateObjectDescriptor(vm, WTFMove(descriptor), startOffset);
</ins><span class="cx">     result->finishCreation(vm);
</span><span class="cx">     return result;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTemplateObjectDescriptorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.h (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.h 2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.h    2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx">     static const bool needsDestruction = true;
</span><span class="cx">     DECLARE_INFO;
</span><span class="cx"> 
</span><del>-    static JSTemplateObjectDescriptor* create(VM&, Ref<TemplateObjectDescriptor>&&);
</del><ins>+    static JSTemplateObjectDescriptor* create(VM&, Ref<TemplateObjectDescriptor>&&, int);
</ins><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
</span><span class="cx">     {
</span><span class="lines">@@ -49,13 +49,16 @@
</span><span class="cx"> 
</span><span class="cx">     JSArray* createTemplateObject(ExecState*);
</span><span class="cx"> 
</span><ins>+    int startOffset() const { return m_startOffset; }
+
</ins><span class="cx"> protected:
</span><span class="cx">     static void destroy(JSCell*);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    JSTemplateObjectDescriptor(VM&, Ref<TemplateObjectDescriptor>&&);
</del><ins>+    JSTemplateObjectDescriptor(VM&, Ref<TemplateObjectDescriptor>&&, int);
</ins><span class="cx"> 
</span><span class="cx">     Ref<TemplateObjectDescriptor> m_descriptor;
</span><ins>+    int m_startOffset { 0 };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeModuleProgramExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp  2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp     2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -85,6 +85,11 @@
</span><span class="cx">     static_cast<ModuleProgramExecutable*>(cell)->ModuleProgramExecutable::~ModuleProgramExecutable();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+auto ModuleProgramExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
+{
+    return ensureTemplateObjectMapImpl(m_templateObjectMap);
+}
+
</ins><span class="cx"> void ModuleProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
</span><span class="cx"> {
</span><span class="cx">     ModuleProgramExecutable* thisObject = jsCast<ModuleProgramExecutable*>(cell);
</span><span class="lines">@@ -93,6 +98,11 @@
</span><span class="cx">     visitor.append(thisObject->m_unlinkedModuleProgramCodeBlock);
</span><span class="cx">     visitor.append(thisObject->m_moduleEnvironmentSymbolTable);
</span><span class="cx">     visitor.append(thisObject->m_moduleProgramCodeBlock);
</span><ins>+    if (TemplateObjectMap* map = thisObject->m_templateObjectMap.get()) {
+        auto locker = holdLock(thisObject->cellLock());
+        for (auto& entry : *map)
+            visitor.append(entry.value);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeModuleProgramExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.h (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.h    2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.h       2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -69,6 +69,8 @@
</span><span class="cx"> 
</span><span class="cx">     SymbolTable* moduleEnvironmentSymbolTable() { return m_moduleEnvironmentSymbolTable.get(); }
</span><span class="cx"> 
</span><ins>+    TemplateObjectMap& ensureTemplateObjectMap(VM&);
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class ExecutableBase;
</span><span class="cx">     friend class ScriptExecutable;
</span><span class="lines">@@ -80,6 +82,7 @@
</span><span class="cx">     WriteBarrier<UnlinkedModuleProgramCodeBlock> m_unlinkedModuleProgramCodeBlock;
</span><span class="cx">     WriteBarrier<SymbolTable> m_moduleEnvironmentSymbolTable;
</span><span class="cx">     WriteBarrier<ExecutableToCodeBlockEdge> m_moduleProgramCodeBlock;
</span><ins>+    std::unique_ptr<TemplateObjectMap> m_templateObjectMap;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeProgramExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp        2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp   2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -216,6 +216,11 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+auto ProgramExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
+{
+    return ensureTemplateObjectMapImpl(m_templateObjectMap);
+}
+
</ins><span class="cx"> void ProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
</span><span class="cx"> {
</span><span class="cx">     ProgramExecutable* thisObject = jsCast<ProgramExecutable*>(cell);
</span><span class="lines">@@ -223,6 +228,11 @@
</span><span class="cx">     Base::visitChildren(thisObject, visitor);
</span><span class="cx">     visitor.append(thisObject->m_unlinkedProgramCodeBlock);
</span><span class="cx">     visitor.append(thisObject->m_programCodeBlock);
</span><ins>+    if (TemplateObjectMap* map = thisObject->m_templateObjectMap.get()) {
+        auto locker = holdLock(thisObject->cellLock());
+        for (auto& entry : *map)
+            visitor.append(entry.value);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeProgramExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ProgramExecutable.h (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ProgramExecutable.h  2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/ProgramExecutable.h     2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -73,6 +73,8 @@
</span><span class="cx"> 
</span><span class="cx">     ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false, EvalContextType::None); }
</span><span class="cx"> 
</span><ins>+    TemplateObjectMap& ensureTemplateObjectMap(VM&);
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class ExecutableBase;
</span><span class="cx">     friend class ScriptExecutable;
</span><span class="lines">@@ -83,6 +85,7 @@
</span><span class="cx"> 
</span><span class="cx">     WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
</span><span class="cx">     WriteBarrier<ExecutableToCodeBlockEdge> m_programCodeBlock;
</span><ins>+    std::unique_ptr<TemplateObjectMap> m_templateObjectMap;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeScriptExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ScriptExecutable.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ScriptExecutable.cpp 2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/ScriptExecutable.cpp    2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include "IsoCellSetInlines.h"
</span><span class="cx"> #include "JIT.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><ins>+#include "JSTemplateObjectDescriptor.h"
</ins><span class="cx"> #include "LLIntEntrypoint.h"
</span><span class="cx"> #include "ModuleProgramCodeBlock.h"
</span><span class="cx"> #include "Parser.h"
</span><span class="lines">@@ -435,6 +436,61 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ScriptExecutable* ScriptExecutable::topLevelExecutable()
+{
+    switch (type()) {
+    case FunctionExecutableType:
+        return jsCast<FunctionExecutable*>(this)->topLevelExecutable();
+    default:
+        return this;
+    }
+}
+
+JSArray* ScriptExecutable::createTemplateObject(ExecState* exec, JSTemplateObjectDescriptor* descriptor)
+{
+    VM& vm = exec->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    TemplateObjectMap& templateObjectMap = ensureTemplateObjectMap(vm);
+    TemplateObjectMap::AddResult result;
+    {
+        auto locker = holdLock(cellLock());
+        result = templateObjectMap.add(descriptor->startOffset(), WriteBarrier<JSArray>());
+    }
+    if (JSArray* array = result.iterator->value.get())
+        return array;
+    JSArray* templateObject = descriptor->createTemplateObject(exec);
+    RETURN_IF_EXCEPTION(scope, nullptr);
+    result.iterator->value.set(vm, this, templateObject);
+    return templateObject;
+}
+
+auto ScriptExecutable::ensureTemplateObjectMapImpl(std::unique_ptr<TemplateObjectMap>& dest) -> TemplateObjectMap&
+{
+    if (dest)
+        return *dest;
+    auto result = std::make_unique<TemplateObjectMap>();
+    WTF::storeStoreFence();
+    dest = WTFMove(result);
+    return *dest;
+}
+
+auto ScriptExecutable::ensureTemplateObjectMap(VM& vm) -> TemplateObjectMap&
+{
+    switch (type()) {
+    case FunctionExecutableType:
+        return static_cast<FunctionExecutable*>(this)->ensureTemplateObjectMap(vm);
+    case EvalExecutableType:
+        return static_cast<EvalExecutable*>(this)->ensureTemplateObjectMap(vm);
+    case ProgramExecutableType:
+        return static_cast<ProgramExecutable*>(this)->ensureTemplateObjectMap(vm);
+    case ModuleProgramExecutableType:
+    default:
+        ASSERT(type() == ModuleProgramExecutableType);
+        return static_cast<ModuleProgramExecutable*>(this)->ensureTemplateObjectMap(vm);
+    }
+}
+
</ins><span class="cx"> CodeBlockHash ScriptExecutable::hashFor(CodeSpecializationKind kind) const
</span><span class="cx"> {
</span><span class="cx">     return CodeBlockHash(source(), kind);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeScriptExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ScriptExecutable.h (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ScriptExecutable.h   2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/runtime/ScriptExecutable.h      2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -29,6 +29,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class JSArray;
+class JSTemplateObjectDescriptor;
</ins><span class="cx"> class IsoCellSet;
</span><span class="cx"> 
</span><span class="cx"> class ScriptExecutable : public ExecutableBase {
</span><span class="lines">@@ -37,6 +39,8 @@
</span><span class="cx">     static const unsigned StructureFlags = Base::StructureFlags;
</span><span class="cx"> 
</span><span class="cx">     static void destroy(JSCell*);
</span><ins>+
+    using TemplateObjectMap = HashMap<uint64_t, WriteBarrier<JSArray>, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>;
</ins><span class="cx">         
</span><span class="cx">     CodeBlockHash hashFor(CodeSpecializationKind) const;
</span><span class="cx"> 
</span><span class="lines">@@ -112,6 +116,9 @@
</span><span class="cx">     template <typename ExecutableType>
</span><span class="cx">     Exception* prepareForExecution(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*& resultCodeBlock);
</span><span class="cx"> 
</span><ins>+    ScriptExecutable* topLevelExecutable();
+    JSArray* createTemplateObject(ExecState*, JSTemplateObjectDescriptor*);
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class ExecutableBase;
</span><span class="cx">     Exception* prepareForExecutionImpl(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*&);
</span><span class="lines">@@ -118,6 +125,8 @@
</span><span class="cx"> 
</span><span class="cx">     bool hasClearableCode(VM&) const;
</span><span class="cx"> 
</span><ins>+    TemplateObjectMap& ensureTemplateObjectMap(VM&);
+
</ins><span class="cx"> protected:
</span><span class="cx">     ScriptExecutable(Structure*, VM&, const SourceCode&, bool isInStrictContext, DerivedContextType, bool isInArrowFunctionContext, EvalContextType, Intrinsic);
</span><span class="cx"> 
</span><span class="lines">@@ -137,6 +146,8 @@
</span><span class="cx">         m_hasCapturedVariables = hasCapturedVariables;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static TemplateObjectMap& ensureTemplateObjectMapImpl(std::unique_ptr<TemplateObjectMap>& dest);
+
</ins><span class="cx">     SourceCode m_source;
</span><span class="cx">     Intrinsic m_intrinsic { NoIntrinsic };
</span><span class="cx">     bool m_didTryToEnterInLoop { false };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretoolsJSDollarVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp (244977 => 244978)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp 2019-05-06 21:14:12 UTC (rev 244977)
+++ trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp    2019-05-06 21:33:27 UTC (rev 244978)
</span><span class="lines">@@ -1846,7 +1846,7 @@
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, encodedJSValue());
</span><span class="cx"> 
</span><span class="cx">     const SourceCode& source = makeSource(functionText, { });
</span><del>-    JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, source), exec->lexicalGlobalObject());
</del><ins>+    JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, nullptr, source), exec->lexicalGlobalObject());
</ins><span class="cx"> 
</span><span class="cx">     return JSValue::encode(func);
</span><span class="cx"> }
</span><span class="lines">@@ -2087,6 +2087,15 @@
</span><span class="cx">     return changeDebuggerModeWhenIdle(exec, { });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static EncodedJSValue JSC_HOST_CALL functionDeleteAllCodeWhenIdle(ExecState* exec)
+{
+    VM* vm = &exec->vm();
+    vm->whenIdle([=] () {
+        vm->deleteAllCode(PreventCollectionAndDeleteAllCode);
+    });
+    return JSValue::encode(jsUndefined());
+}
+
</ins><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionGlobalObjectCount(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     return JSValue::encode(jsNumber(exec->vm().heap.globalObjectCount()));
</span><span class="lines">@@ -2276,6 +2285,8 @@
</span><span class="cx">     addFunction(vm, "enableDebuggerModeWhenIdle", functionEnableDebuggerModeWhenIdle, 0);
</span><span class="cx">     addFunction(vm, "disableDebuggerModeWhenIdle", functionDisableDebuggerModeWhenIdle, 0);
</span><span class="cx"> 
</span><ins>+    addFunction(vm, "deleteAllCodeWhenIdle", functionDeleteAllCodeWhenIdle, 0);
+
</ins><span class="cx">     addFunction(vm, "globalObjectCount", functionGlobalObjectCount, 0);
</span><span class="cx">     addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>