[dart2wasm] Remove the --string-data-segments option

In WasmGC MVP, the `array.new_data` instruction will not be a constant
instruction. This means we can't implement the option that places
eager string constants in data segments and reads them using
`array.new_data`. We can still do this for lazy strings.

Also clean out the string function generator (which is dead since we
started using `array.new_data` for lazy strings) and the special case
for the empty string (which is obsolete since we started using
`array.new_fixed` for eager strings).

Change-Id: If28bdf6913ae0cd0f4faf7d87d64cb9412e56bb5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/271120
Reviewed-by: Ömer Ağacan <omersa@google.com>
This commit is contained in:
Aske Simon Christensen
2022-11-22 15:11:35 +00:00
committed by Commit Queue
parent 7be0af20f0
commit 9cea247af4
4 changed files with 1 additions and 86 deletions
-3
View File
@@ -35,9 +35,6 @@ final List<Option> options = [
defaultsTo: _d.translatorOptions.printKernel),
Flag("print-wasm", (o, value) => o.translatorOptions.printWasm = value,
defaultsTo: _d.translatorOptions.printWasm),
Flag("string-data-segments",
(o, value) => o.translatorOptions.stringDataSegments = value,
defaultsTo: _d.translatorOptions.stringDataSegments),
IntOption(
"inlining-limit", (o, value) => o.translatorOptions.inliningLimit = value,
defaultsTo: "${_d.translatorOptions.inliningLimit}"),
-1
View File
@@ -20,7 +20,6 @@ where *options* include:
| `--`[`no-`]`print-kernel` | no | Print IR for each function before compiling it.
| `--`[`no-`]`print-wasm` | no | Print Wasm instructions of each compiled function.
| `--shared-memory-max-pages` *pagecount* | | Max size of the imported memory buffer. If `--shared-import-memory` is specified, this must also be specified.
| `--`[`no-`]`string-data-segments` | no | Use experimental array init from data segment for string constants.
| `--watch` *offset* | | Print stack trace leading to the byte at offset *offset* in the `.wasm` output file. Can be specified multiple times.
The resulting `.wasm` file can be run with:
+1 -81
View File
@@ -49,39 +49,16 @@ class Constants {
final Map<Constant, ConstantInfo> constantInfo = {};
w.DataSegment? oneByteStringSegment;
w.DataSegment? twoByteStringSegment;
late final w.DefinedGlobal emptyString;
late final w.DefinedGlobal emptyTypeList;
late final ClassInfo typeInfo = translator.classInfo[translator.typeClass]!;
bool currentlyCreating = false;
Constants(this.translator) {
_initEmptyString();
_initEmptyTypeList();
}
w.Module get m => translator.m;
bool get stringDataSegments => translator.options.stringDataSegments;
void _initEmptyString() {
ClassInfo info = translator.classInfo[translator.oneByteStringClass]!;
translator.functions.allocateClass(info.classId);
w.ArrayType arrayType =
(info.struct.fields.last.type as w.RefType).heapType as w.ArrayType;
w.RefType emptyStringType = info.nonNullableType;
emptyString = m.addGlobal(w.GlobalType(emptyStringType, mutable: false));
w.Instructions ib = emptyString.initializer;
ib.i32_const(info.classId);
ib.i32_const(initialIdentityHash);
ib.array_new_fixed(arrayType, 0);
ib.struct_new(info.struct);
ib.end(); // end of global initializer expression
Constant emptyStringConstant = StringConstant("");
constantInfo[emptyStringConstant] =
ConstantInfo(emptyStringConstant, emptyString, null);
}
void _initEmptyTypeList() {
ClassInfo info = translator.classInfo[translator.immutableListClass]!;
@@ -120,63 +97,6 @@ class Constants {
translator.typeParameterIndex[info.cls!.typeParameters.single]!);
}
/// Create one of the two Wasm functions (one for each string type) called
/// from every lazily initialized string constant (of that type) to create and
/// initialize the string.
///
/// The function signature is (i32 offset, i32 length) -> (ref stringClass)
/// where offset and length are measured in characters and indicate the place
/// in the corresponding string data segment from which to copy this string.
w.DefinedFunction makeStringFunction(Class cls) {
ClassInfo info = translator.classInfo[cls]!;
w.FunctionType ftype = m.addFunctionType(
const [w.NumType.i32, w.NumType.i32], [info.nonNullableType]);
return m.addFunction(ftype, "makeString ${cls.name}");
}
void makeStringFunctionBody(Class cls, w.DefinedFunction function,
void Function(w.Instructions) emitLoad) {
ClassInfo info = translator.classInfo[cls]!;
w.ArrayType arrayType =
(info.struct.fields.last.type as w.RefType).heapType as w.ArrayType;
w.Local offset = function.locals[0];
w.Local length = function.locals[1];
w.Local array =
function.addLocal(w.RefType.def(arrayType, nullable: false));
w.Local index = function.addLocal(w.NumType.i32);
w.Instructions b = function.body;
b.local_get(length);
b.array_new_default(arrayType);
b.local_set(array);
b.i32_const(0);
b.local_set(index);
w.Label loop = b.loop();
b.local_get(array);
b.local_get(index);
b.local_get(offset);
b.local_get(index);
b.i32_add();
emitLoad(b);
b.array_set(arrayType);
b.local_get(index);
b.i32_const(1);
b.i32_add();
b.local_tee(index);
b.local_get(length);
b.i32_lt_u();
b.br_if(loop);
b.end();
b.i32_const(info.classId);
b.i32_const(initialIdentityHash);
b.local_get(array);
b.struct_new(info.struct);
b.end();
}
/// Makes a type list [ListConstant].
ListConstant makeTypeList(List<DartType> types) => ListConstant(
InterfaceType(translator.typeClass, Nullability.nonNullable),
@@ -417,7 +337,7 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?> {
b.i32_const(info.classId);
b.i32_const(initialIdentityHash);
if (lazy || constants.stringDataSegments) {
if (lazy) {
// Initialize string contents from passive data segment.
w.DataSegment segment;
Uint8List bytes;
-1
View File
@@ -39,7 +39,6 @@ class TranslatorOptions {
bool printKernel = false;
bool printWasm = false;
int? sharedMemoryMaxPages;
bool stringDataSegments = false;
List<int>? watchPoints = null;
}