mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 20:09:41 +00:00
[dart2wasm] Specialize string interpolation expressions for 1/2/3/4 arguments
This affects very common string interpolation expressions where we now avoid creating arrays and looping over arrays and casting references when getting things out of arrays. e.g. `StringBuffer.write()` uses "$obj" in it's implementation which will benefit from this. Change-Id: Ie6615e5f76a4a8ccb4ff9aa85c05c7e39eab6f00 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371660 Reviewed-by: Ömer Ağacan <omersa@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
4b704b8f0b
commit
7078310249
|
@ -2876,11 +2876,35 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
|
|||
return visitStringLiteral(expr, expectedType);
|
||||
}
|
||||
|
||||
makeArrayFromExpressions(node.expressions,
|
||||
translator.coreTypes.objectRawType(Nullability.nullable));
|
||||
return translator.outputOrVoid(call(translator.options.jsCompatibility
|
||||
? translator.jsStringInterpolate.reference
|
||||
: translator.stringInterpolate.reference));
|
||||
late final Procedure target;
|
||||
|
||||
final expressions = node.expressions;
|
||||
// We have special cases for 1/2/3/4 arguments in non-JSCM mode.
|
||||
if (!translator.options.jsCompatibility && expressions.length <= 4) {
|
||||
final nullableObjectType =
|
||||
translator.translateType(translator.coreTypes.objectNullableRawType);
|
||||
for (final expression in expressions) {
|
||||
wrap(expression, nullableObjectType);
|
||||
}
|
||||
if (expressions.length == 1) {
|
||||
target = translator.stringInterpolate1;
|
||||
} else if (expressions.length == 2) {
|
||||
target = translator.stringInterpolate2;
|
||||
} else if (expressions.length == 3) {
|
||||
target = translator.stringInterpolate3;
|
||||
} else {
|
||||
assert(expressions.length == 4);
|
||||
target = translator.stringInterpolate4;
|
||||
}
|
||||
} else {
|
||||
final nullableObjectType = translator.coreTypes.objectNullableRawType;
|
||||
makeArrayFromExpressions(node.expressions, nullableObjectType);
|
||||
target = translator.options.jsCompatibility
|
||||
? translator.jsStringInterpolate
|
||||
: translator.stringInterpolate;
|
||||
}
|
||||
|
||||
return translator.outputOrVoid(call(target.reference));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -240,6 +240,14 @@ mixin KernelNodes {
|
|||
index.getProcedure("dart:_string", "StringBase", "_equals");
|
||||
late final Procedure stringInterpolate =
|
||||
index.getProcedure("dart:_string", "StringBase", "_interpolate");
|
||||
late final Procedure stringInterpolate1 =
|
||||
index.getProcedure("dart:_string", "StringBase", "_interpolate1");
|
||||
late final Procedure stringInterpolate2 =
|
||||
index.getProcedure("dart:_string", "StringBase", "_interpolate2");
|
||||
late final Procedure stringInterpolate3 =
|
||||
index.getProcedure("dart:_string", "StringBase", "_interpolate3");
|
||||
late final Procedure stringInterpolate4 =
|
||||
index.getProcedure("dart:_string", "StringBase", "_interpolate4");
|
||||
late final Procedure truncDiv =
|
||||
index.getProcedure("dart:core", "_BoxedInt", "_truncDiv");
|
||||
late final Procedure runtimeTypeEquals =
|
||||
|
|
|
@ -918,6 +918,53 @@ abstract final class StringBase extends WasmStringBase {
|
|||
return StringBase._concatAllFallback(values, totalLength);
|
||||
}
|
||||
|
||||
@pragma("wasm:entry-point", "call")
|
||||
static String _interpolate1(Object? value) {
|
||||
return value is String ? value : value.toString();
|
||||
}
|
||||
|
||||
@pragma("wasm:entry-point", "call")
|
||||
static String _interpolate2(Object? value1, Object? value2) {
|
||||
final String string1 = value1 is String ? value1 : value1.toString();
|
||||
final String string2 = value2 is String ? value2 : value2.toString();
|
||||
if (string1 is OneByteString && string2 is OneByteString) {
|
||||
return OneByteString._concat2(string1, string2);
|
||||
}
|
||||
return StringBase._interpolate(
|
||||
WasmArray<Object?>.literal([string1, string2]));
|
||||
}
|
||||
|
||||
@pragma("wasm:entry-point", "call")
|
||||
static String _interpolate3(Object? value1, Object? value2, Object? value3) {
|
||||
final String string1 = value1 is String ? value1 : value1.toString();
|
||||
final String string2 = value2 is String ? value2 : value2.toString();
|
||||
final String string3 = value3 is String ? value3 : value3.toString();
|
||||
if (string1 is OneByteString &&
|
||||
string2 is OneByteString &&
|
||||
string3 is OneByteString) {
|
||||
return OneByteString._concat3(string1, string2, string3);
|
||||
}
|
||||
return StringBase._interpolate(
|
||||
WasmArray<Object?>.literal([string1, string2, string3]));
|
||||
}
|
||||
|
||||
@pragma("wasm:entry-point", "call")
|
||||
static String _interpolate4(
|
||||
Object? value1, Object? value2, Object? value3, Object? value4) {
|
||||
final String string1 = value1 is String ? value1 : value1.toString();
|
||||
final String string2 = value2 is String ? value2 : value2.toString();
|
||||
final String string3 = value3 is String ? value3 : value3.toString();
|
||||
final String string4 = value4 is String ? value4 : value4.toString();
|
||||
if (string1 is OneByteString &&
|
||||
string2 is OneByteString &&
|
||||
string3 is OneByteString &&
|
||||
string4 is OneByteString) {
|
||||
return OneByteString._concat4(string1, string2, string3, string4);
|
||||
}
|
||||
return StringBase._interpolate(
|
||||
WasmArray<Object?>.literal([string1, string2, string3, string4]));
|
||||
}
|
||||
|
||||
@pragma('wasm:entry-point')
|
||||
static bool _equals(String left, String? right) {
|
||||
return left == right;
|
||||
|
@ -1154,6 +1201,64 @@ final class OneByteString extends StringBase {
|
|||
return result;
|
||||
}
|
||||
|
||||
static OneByteString _concat2(OneByteString string1, OneByteString string2) {
|
||||
final bytes1 = string1._array;
|
||||
final bytes2 = string2._array;
|
||||
|
||||
final result = OneByteString.withLength(bytes1.length + bytes2.length);
|
||||
final resultBytes = result._array;
|
||||
|
||||
int resultOffset = 0;
|
||||
resultBytes.copy(resultOffset, bytes1, 0, bytes1.length);
|
||||
resultOffset += bytes1.length;
|
||||
resultBytes.copy(resultOffset, bytes2, 0, bytes2.length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static OneByteString _concat3(
|
||||
OneByteString string1, OneByteString string2, OneByteString string3) {
|
||||
final bytes1 = string1._array;
|
||||
final bytes2 = string2._array;
|
||||
final bytes3 = string3._array;
|
||||
|
||||
final result =
|
||||
OneByteString.withLength(bytes1.length + bytes2.length + bytes3.length);
|
||||
final resultBytes = result._array;
|
||||
|
||||
int resultOffset = 0;
|
||||
resultBytes.copy(resultOffset, bytes1, 0, bytes1.length);
|
||||
resultOffset += bytes1.length;
|
||||
resultBytes.copy(resultOffset, bytes2, 0, bytes2.length);
|
||||
resultOffset += bytes2.length;
|
||||
resultBytes.copy(resultOffset, bytes3, 0, bytes3.length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static OneByteString _concat4(OneByteString string1, OneByteString string2,
|
||||
OneByteString string3, OneByteString string4) {
|
||||
final bytes1 = string1._array;
|
||||
final bytes2 = string2._array;
|
||||
final bytes3 = string3._array;
|
||||
final bytes4 = string4._array;
|
||||
|
||||
final result = OneByteString.withLength(
|
||||
bytes1.length + bytes2.length + bytes3.length + bytes4.length);
|
||||
final resultBytes = result._array;
|
||||
|
||||
int resultOffset = 0;
|
||||
resultBytes.copy(resultOffset, bytes1, 0, bytes1.length);
|
||||
resultOffset += bytes1.length;
|
||||
resultBytes.copy(resultOffset, bytes2, 0, bytes2.length);
|
||||
resultOffset += bytes2.length;
|
||||
resultBytes.copy(resultOffset, bytes3, 0, bytes3.length);
|
||||
resultOffset += bytes3.length;
|
||||
resultBytes.copy(resultOffset, bytes4, 0, bytes4.length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// All element of 'strings' must be OneByteStrings.
|
||||
static OneByteString _concatRange(
|
||||
WasmArray<String> strings, int start, int end, int totalLength) {
|
||||
|
|
Loading…
Reference in a new issue