Convert template objects to singletons

Create file-scoped template objects that are instantiated once and reused between different tagged template evaluations. This is a closer match to the spec behavior which demands reuse, but does not match the spec exactly with respect to scoping as it’s possible to have similar template objects defined in different file scopes within the same program. For now we are not able to cleanly handle this case as it would require a registry or similar lookup mechanism that is consistent across different combinations of builds and optimizers.

This has a 40x increase in six-speed throughput.

Partial fix for #971
This commit is contained in:
kpdecker 2015-06-30 01:22:06 -05:00
parent faa6ce1a08
commit eed750206c
6 changed files with 42 additions and 5 deletions

View File

@ -407,6 +407,30 @@ export default class File {
return uid;
}
addTemplateObject(helperName: string, strings: Array, raw: Array): Object {
// Generate a unique name based on the string literals so we dedupe
// identical strings used in the program.
var stringIds = raw.elements.map(function(string) {
return string.value;
});
var name = `${helperName}_${raw.elements.length}_${stringIds.join(",")}`;
var declar = this.declarations[name];
if (declar) return declar;
var uid = this.declarations[name] = this.scope.generateUidIdentifier(name);
var helperId = this.addHelper(helperName);
var init = t.callExpression(helperId, [strings, raw]);
init._compact = true;
this.scope.push({
id: uid,
init: init,
_blockHoist: 1.9 // This ensures that we don't fail if not using function expression helpers
});
return uid;
}
/**
* [Please add a description.]
*/

View File

@ -64,7 +64,9 @@ export var visitor = {
var templateName = "tagged-template-literal";
if (file.isLoose("es6.templateLiterals")) templateName += "-loose";
args.push(t.callExpression(file.addHelper(templateName), [strings, raw]));
var templateObject = file.addTemplateObject(templateName, strings, raw);
args.push(templateObject);
args = args.concat(quasi.expressions);

View File

@ -829,14 +829,15 @@ export default class Scope {
var unique = opts.unique;
var kind = opts.kind || "var";
var blockHoist = opts._blockHoist || 2;
var dataKey = `declaration:${kind}`;
var dataKey = `declaration:${kind}:${blockHoist}`;
var declar = !unique && path.getData(dataKey);
if (!declar) {
declar = t.variableDeclaration(kind, []);
declar._generated = true;
declar._blockHoist = 2;
declar._blockHoist = blockHoist;
this.hub.file.attachAuxiliaryComment(declar);

View File

@ -1 +1,3 @@
var foo = bar`wow\na${ 42 }b ${_.foobar()}`;
var bar = bar`wow\nab${ 42 } ${_.foobar()}`;
var bar = bar`wow\naB${ 42 } ${_.foobar()}`;

View File

@ -1,5 +1,7 @@
"use strict";
var _taggedTemplateLiteralLoose_3_wowNaB = _taggedTemplateLiteralLoose(["wow\na", "b ", ""], ["wow\\na", "b ", ""]);
function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
var foo = bar(_taggedTemplateLiteralLoose(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), 42, _.foobar());
var foo = bar(_taggedTemplateLiteralLoose_3_wowNaB, 42, _.foobar());

View File

@ -1,5 +1,11 @@
"use strict";
var _taggedTemplateLiteral_3_wowNaB = _taggedTemplateLiteral(["wow\na", "b ", ""], ["wow\\na", "b ", ""]),
_taggedTemplateLiteral_3_wowNab = _taggedTemplateLiteral(["wow\nab", " ", ""], ["wow\\nab", " ", ""]),
_taggedTemplateLiteral_3_wowNaB2 = _taggedTemplateLiteral(["wow\naB", " ", ""], ["wow\\naB", " ", ""]);
function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
var foo = bar(_taggedTemplateLiteral(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), 42, _.foobar());
var foo = bar(_taggedTemplateLiteral_3_wowNaB, 42, _.foobar());
var bar = bar(_taggedTemplateLiteral_3_wowNab, 42, _.foobar());
var bar = bar(_taggedTemplateLiteral_3_wowNaB2, 42, _.foobar());