Bug 1430800: Optimize String.raw by avoiding rest-parameter array allocation. r=evilpie

This commit is contained in:
André Bargull 2018-01-18 04:20:55 -08:00
Родитель ca93312f36
Коммит 30901afb92
2 изменённых файлов: 34 добавлений и 38 удалений

Просмотреть файл

@ -688,57 +688,53 @@ function String_toLocaleUpperCase() {
return intl_toLocaleUpperCase(string, requestedLocale);
}
/* ES6 Draft May 22, 2014 21.1.2.4 */
function String_static_raw(callSite, ...substitutions) {
// Step 1 (implicit).
// Step 2.
var numberOfSubstitutions = substitutions.length;
// ES2018 draft rev 8fadde42cf6a9879b4ab0cb6142b31c4ee501667
// 21.1.2.4 String.raw ( template, ...substitutions )
function String_static_raw(callSite/*, ...substitutions*/) {
// Steps 1-2 (not applicable).
// Steps 3-4.
// Step 3.
var cooked = ToObject(callSite);
// Steps 5-7.
// Step 4.
var raw = ToObject(cooked.raw);
// Steps 8-10.
// Step 5.
var literalSegments = ToLength(raw.length);
// Step 11.
if (literalSegments <= 0)
// Step 6.
if (literalSegments === 0)
return "";
// Step 12.
var resultString = "";
// Special case for |String.raw `<literal>`| callers to avoid falling into
// the loop code below.
if (literalSegments === 1)
return ToString(raw[0]);
// Step 13.
var nextIndex = 0;
// Steps 7-9 were reordered to use the arguments object instead of a rest
// parameter, because the former is currently more optimized.
//
// String.raw intersperses the substitution elements between the literal
// segments, i.e. a substitution is added iff there are still pending
// literal segments. Furthermore by moving the access to |raw[0]| outside
// of the loop, we can use |nextIndex| to index into both, the |raw| array
// and the arguments object.
// Step 14.
while (true) {
// Steps a-d.
var nextSeg = ToString(raw[nextIndex]);
// Steps 7 (implicit) and 9.a-c.
var resultString = ToString(raw[0]);
// Step e.
resultString = resultString + nextSeg;
// Steps 8-9, 9.d, and 9.i.
for (var nextIndex = 1; nextIndex < literalSegments; nextIndex++) {
// Steps 9.e-h.
if (nextIndex < arguments.length)
resultString += ToString(arguments[nextIndex]);
// Step f.
if (nextIndex + 1 === literalSegments)
// Step f.i.
return resultString;
// Steps g-j.
var nextSub;
if (nextIndex < numberOfSubstitutions)
nextSub = ToString(substitutions[nextIndex]);
else
nextSub = "";
// Step k.
resultString = resultString + nextSub;
// Step l.
nextIndex++;
// Steps 9.a-c.
resultString += ToString(raw[nextIndex]);
}
// Step 9.d.i.
return resultString;
}
/**

Просмотреть файл

@ -3610,7 +3610,7 @@ static const JSFunctionSpec string_static_methods[] = {
JS_INLINABLE_FN("fromCharCode", js::str_fromCharCode, 1, 0, StringFromCharCode),
JS_INLINABLE_FN("fromCodePoint", js::str_fromCodePoint, 1, 0, StringFromCodePoint),
JS_SELF_HOSTED_FN("raw", "String_static_raw", 2,0),
JS_SELF_HOSTED_FN("raw", "String_static_raw", 1,0),
JS_SELF_HOSTED_FN("substring", "String_static_substring", 3,0),
JS_SELF_HOSTED_FN("substr", "String_static_substr", 3,0),
JS_SELF_HOSTED_FN("slice", "String_static_slice", 3,0),