Skip to content

Commit 03f73c5

Browse files
committed
[JSC] cache TaggedTemplate arrays by callsite rather than by contents
https://bugs.webkit.org/show_bug.cgi?id=182717 Reviewed by Yusuke Suzuki. tc39/ecma262#890 imposes a change to template literals, to allow template callsite arrays to be collected when the code containing the tagged template call is collected. This spec change has received concensus and been ratified. This change eliminates the eternal map associating template contents with arrays. JSTests: * stress/tagged-template-object-collect.js: Renamed from JSTests/stress/tagged-template-registry-key-collect.js. * stress/tagged-template-object.js: Renamed from JSTests/stress/tagged-template-registry-key.js. * stress/tagged-templates-identity.js: * stress/template-string-tags-eval.js: * test262.yaml: Source/JavaScriptCore: * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::setConstantRegisters): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): * bytecode/UnlinkedCodeBlock.cpp: (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): * bytecode/UnlinkedCodeBlock.h: (JSC::UnlinkedCodeBlock::allowDirectEvalCache const): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::addTemplateObjectConstant): (JSC::BytecodeGenerator::emitGetTemplateObject): (JSC::BytecodeGenerator::addTemplateRegistryKeyConstant): Deleted. * bytecompiler/BytecodeGenerator.h: * parser/Parser.cpp: (JSC::Parser<LexerType>::parseInner): (JSC::Parser<LexerType>::parseMemberExpression): * parser/Parser.h: * parser/ParserModes.h: * runtime/EvalExecutable.h: (JSC::EvalExecutable::allowDirectEvalCache const): * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::JSGlobalObject): * runtime/JSGlobalObject.h: (JSC::JSGlobalObject::templateRegistry): Deleted. * runtime/JSTemplateObjectDescriptor.cpp: Renamed from Source/JavaScriptCore/runtime/TemplateRegistry.cpp. (JSC::JSTemplateObjectDescriptor::JSTemplateObjectDescriptor): (JSC::JSTemplateObjectDescriptor::create): (JSC::JSTemplateObjectDescriptor::destroy): (JSC::JSTemplateObjectDescriptor::createTemplateObject): * runtime/JSTemplateObjectDescriptor.h: Renamed from Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h. (JSC::isTemplateObjectDescriptor): * runtime/JSTemplateRegistryKey.cpp: Removed. * runtime/TemplateObjectDescriptor.cpp: Renamed from Source/JavaScriptCore/runtime/TemplateRegistryKey.cpp. (JSC::TemplateObjectDescriptor::~TemplateObjectDescriptor): * runtime/TemplateObjectDescriptor.h: Renamed from Source/JavaScriptCore/runtime/TemplateRegistryKey.h. (JSC::TemplateObjectDescriptor::operator== const): (JSC::TemplateObjectDescriptor::operator!= const): (JSC::TemplateObjectDescriptor::Hasher::hash): (JSC::TemplateObjectDescriptor::Hasher::equal): (JSC::TemplateObjectDescriptor::create): (JSC::TemplateObjectDescriptor::TemplateObjectDescriptor): (JSC::TemplateObjectDescriptor::calculateHash): * runtime/TemplateRegistry.h: Removed. * runtime/TemplateRegistryKeyTable.cpp: Removed. * runtime/TemplateRegistryKeyTable.h: Removed. * runtime/VM.cpp: (JSC::VM::VM): * runtime/VM.h: (JSC::VM::templateRegistryKeyTable): Deleted. * runtime/VMEntryScope.cpp: * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::setConstantRegisters): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): * bytecode/UnlinkedCodeBlock.h: (JSC::UnlinkedCodeBlock::allowDirectEvalCache const): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::addTemplateObjectConstant): (JSC::BytecodeGenerator::emitGetTemplateObject): (JSC::BytecodeGenerator::addTemplateRegistryKeyConstant): Deleted. * bytecompiler/BytecodeGenerator.h: * parser/Parser.cpp: (JSC::Parser<LexerType>::parseInner): (JSC::Parser<LexerType>::parseMemberExpression): * parser/Parser.h: * parser/ParserModes.h: * runtime/EvalExecutable.h: (JSC::EvalExecutable::allowDirectEvalCache const): * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::JSGlobalObject): * runtime/JSGlobalObject.h: (JSC::JSGlobalObject::templateRegistry): Deleted. * runtime/JSTemplateObjectDescriptor.cpp: Renamed from Source/JavaScriptCore/runtime/TemplateRegistry.cpp. (JSC::JSTemplateObjectDescriptor::JSTemplateObjectDescriptor): (JSC::JSTemplateObjectDescriptor::create): (JSC::JSTemplateObjectDescriptor::destroy): (JSC::JSTemplateObjectDescriptor::createTemplateObject): * runtime/JSTemplateObjectDescriptor.h: Renamed from Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h. (JSC::isTemplateObjectDescriptor): * runtime/JSTemplateRegistryKey.cpp: Removed. * runtime/TemplateObjectDescriptor.cpp: Renamed from Source/JavaScriptCore/runtime/TemplateRegistryKey.cpp. (JSC::TemplateObjectDescriptor::~TemplateObjectDescriptor): * runtime/TemplateObjectDescriptor.h: Renamed from Source/JavaScriptCore/runtime/TemplateRegistryKey.h. (JSC::TemplateObjectDescriptor::operator== const): (JSC::TemplateObjectDescriptor::operator!= const): (JSC::TemplateObjectDescriptor::Hasher::hash): (JSC::TemplateObjectDescriptor::Hasher::equal): (JSC::TemplateObjectDescriptor::create): (JSC::TemplateObjectDescriptor::TemplateObjectDescriptor): (JSC::TemplateObjectDescriptor::calculateHash): * runtime/TemplateRegistry.h: Removed. * runtime/TemplateRegistryKeyTable.cpp: Removed. * runtime/TemplateRegistryKeyTable.h: Removed. * runtime/VM.cpp: (JSC::VM::VM): * runtime/VM.h: (JSC::VM::templateRegistryKeyTable): Deleted. * runtime/VMEntryScope.cpp: * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::setConstantRegisters): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): * bytecode/UnlinkedCodeBlock.h: (JSC::UnlinkedCodeBlock::allowDirectEvalCache const): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::addTemplateObjectConstant): (JSC::BytecodeGenerator::emitGetTemplateObject): (JSC::BytecodeGenerator::addTemplateRegistryKeyConstant): Deleted. * bytecompiler/BytecodeGenerator.h: * parser/Parser.cpp: (JSC::Parser<LexerType>::parseInner): (JSC::Parser<LexerType>::parseMemberExpression): * parser/Parser.h: * parser/ParserModes.h: * runtime/EvalExecutable.h: (JSC::EvalExecutable::allowDirectEvalCache const): * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::JSGlobalObject): * runtime/JSGlobalObject.h: (JSC::JSGlobalObject::templateRegistry): Deleted. * runtime/JSTemplateObjectDescriptor.cpp: Renamed from Source/JavaScriptCore/runtime/TemplateRegistry.cpp. (JSC::JSTemplateObjectDescriptor::JSTemplateObjectDescriptor): (JSC::JSTemplateObjectDescriptor::create): (JSC::JSTemplateObjectDescriptor::destroy): (JSC::JSTemplateObjectDescriptor::createTemplateObject): * runtime/JSTemplateObjectDescriptor.h: Renamed from Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h. (JSC::isTemplateObjectDescriptor): * runtime/JSTemplateRegistryKey.cpp: Removed. * runtime/TemplateObjectDescriptor.cpp: Renamed from Source/JavaScriptCore/runtime/TemplateRegistryKey.cpp. (JSC::TemplateObjectDescriptor::~TemplateObjectDescriptor): * runtime/TemplateObjectDescriptor.h: Renamed from Source/JavaScriptCore/runtime/TemplateRegistryKey.h. (JSC::TemplateObjectDescriptor::operator== const): (JSC::TemplateObjectDescriptor::operator!= const): (JSC::TemplateObjectDescriptor::Hasher::hash): (JSC::TemplateObjectDescriptor::Hasher::equal): (JSC::TemplateObjectDescriptor::create): (JSC::TemplateObjectDescriptor::TemplateObjectDescriptor): (JSC::TemplateObjectDescriptor::calculateHash): * runtime/TemplateRegistry.h: Removed. * runtime/TemplateRegistryKeyTable.cpp: Removed. * runtime/TemplateRegistryKeyTable.h: Removed. * runtime/VM.cpp: (JSC::VM::VM): * runtime/VM.h: (JSC::VM::templateRegistryKeyTable): Deleted. * runtime/VMEntryScope.cpp: Canonical link: https://commits.webkit.org/198521@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@228422 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 4d5efe2 commit 03f73c5

32 files changed

Lines changed: 415 additions & 384 deletions

‎JSTests/ChangeLog‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
2018-02-13 Caitlin Potter <caitp@igalia.com>
2+
3+
[JSC] cache TaggedTemplate arrays by callsite rather than by contents
4+
https://bugs.webkit.org/show_bug.cgi?id=182717
5+
6+
Reviewed by Yusuke Suzuki.
7+
8+
https://github.com/tc39/ecma262/pull/890 imposes a change to template
9+
literals, to allow template callsite arrays to be collected when the
10+
code containing the tagged template call is collected. This spec change
11+
has received concensus and been ratified.
12+
13+
This change eliminates the eternal map associating template contents
14+
with arrays.
15+
16+
* stress/tagged-template-object-collect.js: Renamed from JSTests/stress/tagged-template-registry-key-collect.js.
17+
* stress/tagged-template-object.js: Renamed from JSTests/stress/tagged-template-registry-key.js.
18+
* stress/tagged-templates-identity.js:
19+
* stress/template-string-tags-eval.js:
20+
* test262.yaml:
21+
122
2018-02-13 Yusuke Suzuki <utatane.tea@gmail.com>
223

324
Support GetArrayLength on ArrayStorage in the FTL
File renamed without changes.

JSTests/stress/tagged-template-registry-key.js renamed to JSTests/stress/tagged-template-object.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ function tag(site)
1717
return tag`Hello`;
1818
}
1919

20-
shouldBe(a() === b(), true);
20+
shouldBe(a() === b(), false);
2121
gc();
2222
var tagA = a();
2323
gc();
24-
shouldBe(tagA === b(), true);
24+
shouldBe(tagA === b(), false);
2525
}

‎JSTests/stress/tagged-templates-identity.js‎

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ tag`World`;
1313
tag`Hello`;
1414
shouldBe(templates.length, 3);
1515
shouldBe(templates[0] !== templates[1], true);
16-
shouldBe(templates[0] === templates[2], true);
16+
shouldBe(templates[0] !== templates[2], true);
1717

1818
templates = [];
1919
tag`Hello\n`;
@@ -28,7 +28,7 @@ eval("tag`Hello\n`");
2828
eval("tag`Hello\r`");
2929
eval("tag`Hello\u2028`");
3030
shouldBe(templates.length, 3);
31-
shouldBe(templates[0] === templates[1], true);
31+
shouldBe(templates[0] !== templates[1], true);
3232
shouldBe(templates[0] !== templates[2], true);
3333

3434
templates = [];
@@ -38,7 +38,7 @@ eval("tag`Hello\r`");
3838
eval("tag`Hello\\r`");
3939
shouldBe(templates.length, 4);
4040
shouldBe(templates[0] !== templates[1], true);
41-
shouldBe(templates[0] === templates[2], true);
41+
shouldBe(templates[0] !== templates[2], true);
4242
shouldBe(templates[0] !== templates[3], true);
4343
shouldBe(templates[1] !== templates[2], true);
4444
shouldBe(templates[1] !== templates[3], true);
@@ -49,11 +49,93 @@ templates = [];
4949
eval("tag`Hello\n${v}world`");
5050
eval("tag`Hello\n${v}world`");
5151
shouldBe(templates.length, 2);
52-
shouldBe(templates[0] === templates[1], true);
52+
shouldBe(templates[0] !== templates[1], true);
5353

5454
var v = 0;
5555
templates = [];
5656
eval("tag`Hello${v}\nworld`");
5757
eval("tag`Hello\n${v}world`");
5858
shouldBe(templates.length, 2);
5959
shouldBe(templates[0] !== templates[1], true);
60+
61+
var v = 0;
62+
templates = [];
63+
for (v = 0; v < 3; ++v) {
64+
tag`Hello${v}world`;
65+
if (!v) continue;
66+
shouldBe(templates[v] === templates[v - 1], true);
67+
}
68+
69+
templates = [];
70+
tag`Hello${1}world`;
71+
tag`Hello${2}world`;
72+
shouldBe(templates[0] !== templates[1], true);
73+
74+
// Disable eval caching if a tagged template occurs in eval code
75+
var v = 0;
76+
templates = [];
77+
for (v = 0; v < 3; ++v) {
78+
eval("tag`Hello${v}world`");
79+
if (!v) continue;
80+
shouldBe(templates[v] !== templates[v - 1], true);
81+
}
82+
83+
templates = [];
84+
eval("tag`Hello${1}world`");
85+
eval("tag`Hello${2}world`");
86+
eval("tag`Hello${3}world`");
87+
shouldBe(templates[0] !== templates[1], true);
88+
shouldBe(templates[1] !== templates[2], true);
89+
90+
91+
// Disable eval caching if a tagged template occurs in a nested function
92+
var v = 0;
93+
templates = [];
94+
for (v = 0; v < 6; v += 2) {
95+
eval("(function() { for (var i = 0; i < 2; ++i) tag`Hello${v}world` })()");
96+
shouldBe(templates[v] === templates[v + 1], true);
97+
}
98+
99+
shouldBe(templates[0] !== templates[2], true);
100+
shouldBe(templates[0] !== templates[4], true);
101+
shouldBe(templates[1] !== templates[3], true);
102+
shouldBe(templates[1] !== templates[5], true);
103+
shouldBe(templates[2] !== templates[4], true);
104+
shouldBe(templates[3] !== templates[5], true);
105+
106+
templates = [];
107+
eval("(function() { for (var i = 0; i < 2; ++i) tag`Hello${1}world` })()");
108+
eval("(function() { for (var i = 0; i < 2; ++i) tag`Hello${2}world` })()");
109+
eval("(function() { for (var i = 0; i < 2; ++i) tag`Hello${2}world` })()");
110+
shouldBe(templates[0] === templates[1], true);
111+
shouldBe(templates[0] !== templates[2], true);
112+
shouldBe(templates[0] !== templates[4], true);
113+
shouldBe(templates[1] !== templates[3], true);
114+
shouldBe(templates[1] !== templates[5], true);
115+
shouldBe(templates[2] === templates[3], true);
116+
shouldBe(templates[2] !== templates[4], true);
117+
shouldBe(templates[3] !== templates[5], true);
118+
shouldBe(templates[4] === templates[5], true);
119+
120+
// Disable eval caching if a tagged template occurs in an even deeper nested function
121+
var v = 0;
122+
templates = [];
123+
for (v = 0; v < 3; ++v) {
124+
eval("(function() { (function() { tag`Hello${v}world` })() })()");
125+
if (!v) continue;
126+
shouldBe(templates[v] !== templates[v - 1], true);
127+
}
128+
129+
templates = [];
130+
eval("(function() { (function() { for (var i = 0; i < 2; ++i) tag`Hello${1}world` })() })()");
131+
eval("(function() { (function() { for (var i = 0; i < 2; ++i) tag`Hello${2}world` })() })()");
132+
eval("(function() { (function() { for (var i = 0; i < 2; ++i) tag`Hello${2}world` })() })()");
133+
shouldBe(templates[0] === templates[1], true);
134+
shouldBe(templates[0] !== templates[2], true);
135+
shouldBe(templates[0] !== templates[4], true);
136+
shouldBe(templates[1] !== templates[3], true);
137+
shouldBe(templates[1] !== templates[5], true);
138+
shouldBe(templates[2] === templates[3], true);
139+
shouldBe(templates[2] !== templates[4], true);
140+
shouldBe(templates[3] !== templates[5], true);
141+
shouldBe(templates[4] === templates[5], true);

‎JSTests/stress/template-string-tags-eval.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ var site1 = eval("0, tag`Cocoa`");
1313
var site2 = eval("1, tag`Cappuccino`");
1414
var site3 = eval("2, tag`Cocoa`");
1515

16-
shouldBe(site1 === site3, true);
16+
shouldBe(site1 !== site3, true);
1717
shouldBe(site1 !== site2, true);

‎JSTests/test262.yaml‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83846,17 +83846,17 @@
8384683846
- path: test262/test/language/expressions/tagged-template/cache-different-functions-same-site.js
8384783847
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
8384883848
- path: test262/test/language/expressions/tagged-template/cache-differing-expressions-eval.js
83849-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
83849+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
8385083850
- path: test262/test/language/expressions/tagged-template/cache-differing-expressions-eval.js
83851-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
83851+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
8385283852
- path: test262/test/language/expressions/tagged-template/cache-differing-expressions-new-function.js
83853-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
83853+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
8385483854
- path: test262/test/language/expressions/tagged-template/cache-differing-expressions-new-function.js
83855-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
83855+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
8385683856
- path: test262/test/language/expressions/tagged-template/cache-differing-expressions.js
83857-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
83857+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
8385883858
- path: test262/test/language/expressions/tagged-template/cache-differing-expressions.js
83859-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
83859+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
8386083860
- path: test262/test/language/expressions/tagged-template/cache-differing-raw-strings.js
8386183861
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
8386283862
- path: test262/test/language/expressions/tagged-template/cache-differing-raw-strings.js
@@ -83866,17 +83866,17 @@
8386683866
- path: test262/test/language/expressions/tagged-template/cache-differing-string-count.js
8386783867
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
8386883868
- path: test262/test/language/expressions/tagged-template/cache-identical-source-eval.js
83869-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
83869+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
8387083870
- path: test262/test/language/expressions/tagged-template/cache-identical-source-eval.js
83871-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
83871+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
8387283872
- path: test262/test/language/expressions/tagged-template/cache-identical-source-new-function.js
83873-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
83873+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
8387483874
- path: test262/test/language/expressions/tagged-template/cache-identical-source-new-function.js
83875-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
83875+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
8387683876
- path: test262/test/language/expressions/tagged-template/cache-identical-source.js
83877-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
83877+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
8387883878
- path: test262/test/language/expressions/tagged-template/cache-identical-source.js
83879-
cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
83879+
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
8388083880
- path: test262/test/language/expressions/tagged-template/cache-realm.js
8388183881
cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
8388283882
- path: test262/test/language/expressions/tagged-template/cache-realm.js

‎Source/JavaScriptCore/CMakeLists.txt‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -858,9 +858,7 @@ set(JavaScriptCore_FORWARDING_HEADERS
858858
runtime/Symbol.h
859859
runtime/SymbolPrototype.h
860860
runtime/SymbolTable.h
861-
runtime/TemplateRegistry.h
862-
runtime/TemplateRegistryKey.h
863-
runtime/TemplateRegistryKeyTable.h
861+
runtime/TemplateObjectDescriptor.h
864862
runtime/TestRunnerUtils.h
865863
runtime/ThrowScope.h
866864
runtime/ToNativeFromValue.h

0 commit comments

Comments
 (0)