[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:
committed by
Commit Queue
parent
7be0af20f0
commit
9cea247af4
@@ -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}"),
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -39,7 +39,6 @@ class TranslatorOptions {
|
||||
bool printKernel = false;
|
||||
bool printWasm = false;
|
||||
int? sharedMemoryMaxPages;
|
||||
bool stringDataSegments = false;
|
||||
List<int>? watchPoints = null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user