Skip to content

Commit e2cfee0

Browse files
natebiggsCommit Queue
authored andcommitted
[dart2wasm] Improve module import naming conventions.
- Use the empty string for the string import object since these are the most numerous import objects. - Use ascii index encoding for module names (when minified). This mostly improve the size of submodules, the main module only has 1 copy of this name. - Use same ascii encoding instead of base64 encoding for export names. These all show up in the main bundle once and we save a 1-3 bytes per name. Change-Id: I84bdab3ff5e17c8f2db456cf348e1abf1784e30a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/461280 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Nate Biggs <[email protected]>
1 parent da57016 commit e2cfee0

16 files changed

+76
-38
lines changed

pkg/dart2wasm/lib/compile.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ Future<CompilationResult> _runCodegenPhase(
578578
translator.options.requireJsStringBuiltin,
579579
translator.internalizedStringsForJSRuntime)
580580
: jsRuntimeFinalizer.generate(
581+
moduleOutputData.mainModule.moduleImportName,
581582
translator.functions.translatedProcedures,
582583
translator.internalizedStringsForJSRuntime,
583584
translator.options.requireJsStringBuiltin,

pkg/dart2wasm/lib/exports.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class ExportNamer {
3333
String _getExportName(String name) {
3434
if (!minify) return name;
3535
do {
36-
name = intToBase64(_nameCounter++);
36+
name = intToMinString(_nameCounter++);
3737
} while (_reservedNames.contains(name));
3838
return name;
3939
}

pkg/dart2wasm/lib/js/runtime_blob.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ final moduleLoadingHelperTemplate = Template(r'''
200200
...baseImports,
201201
...additionalImports,
202202
<<JS_POLYFILL_IMPORT>>
203-
"module0": dartInstance.exports,
203+
"<<MAIN_MODULE_NAME>>": dartInstance.exports,
204204
});
205205
}
206206
const promises = [];
@@ -222,7 +222,7 @@ final moduleLoadingHelperTemplate = Template(r'''
222222
...baseImports,
223223
...additionalImports,
224224
<<JS_POLYFILL_IMPORT>>
225-
"module0": dartInstance.exports,
225+
"<<MAIN_MODULE_NAME>>": dartInstance.exports,
226226
});
227227
}
228228
},
@@ -235,7 +235,7 @@ final moduleLoadingHelperTemplate = Template(r'''
235235
? WebAssembly.compileStreaming(source, this.builtins)
236236
: WebAssembly.compile(source, this.builtins));
237237
const loadedModule = await WebAssembly.instantiate(module, {
238-
"module0": dartInstance.exports,
238+
"<<MAIN_MODULE_NAME>>": dartInstance.exports,
239239
...jsModule.imports(finalizeWrapper),
240240
});
241241
return loadedModule.exports.$invokeEntryPoint;

pkg/dart2wasm/lib/js/runtime_generator.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,13 @@ class RuntimeFinalizer {
9999
}
100100
if (!requireJsBuiltin) {
101101
sb.writeln(
102-
'${indent}S: new Proxy({}, { get(_, prop) { return prop; } }),');
102+
'$indent"": new Proxy({}, { get(_, prop) { return prop; } }),');
103103
}
104104
return '$sb';
105105
}
106106

107107
String generate(
108+
String mainModuleName,
108109
Iterable<Procedure> translatedProcedures,
109110
List<String> constantStrings,
110111
bool requireJsBuiltin,
@@ -113,7 +114,7 @@ class RuntimeFinalizer {
113114

114115
final builtins = [
115116
'builtins: [\'js-string\']',
116-
if (requireJsBuiltin) 'importedStringConstants: \'S\'',
117+
if (requireJsBuiltin) 'importedStringConstants: \'\'',
117118
];
118119

119120
String internalizedStrings =
@@ -132,6 +133,7 @@ class RuntimeFinalizer {
132133
final moduleLoadingHelperMethods = supportsAdditionalModuleLoading
133134
? moduleLoadingHelperTemplate.instantiate({
134135
...jsStringBuiltinPolyfillImportVars,
136+
'MAIN_MODULE_NAME': mainModuleName,
135137
})
136138
: '';
137139

pkg/dart2wasm/lib/modules.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,16 @@ class ModuleMetadataBuilder {
3232
ModuleMetadata buildModuleMetadata(
3333
{bool emitAsMain = false, bool skipEmit = false}) {
3434
final id = _counter++;
35+
final moduleImportName =
36+
options.translatorOptions.minify ? intToMinString(id) : 'module$id';
3537
return ModuleMetadata._(
36-
id,
38+
moduleImportName,
3739
emitAsMain || id == _mainModuleId
3840
? path.basename(options.outputFile)
3941
: path.basename(
4042
path.setExtension(options.outputFile, '_module$id.wasm')),
41-
skipEmit: skipEmit);
43+
skipEmit: skipEmit,
44+
isMain: id == _mainModuleId);
4245
}
4346
}
4447

@@ -52,24 +55,22 @@ class ModuleMetadataBuilder {
5255
/// by library, by class or neither. [containsReference] should be used to
5356
/// determine if a module contains a given class/member reference.
5457
class ModuleMetadata {
55-
/// The ID for the module which will be included in the emitted name.
56-
final int _id;
57-
5858
/// The set of libraries contained in this module.
5959
final Set<Library> libraries = {};
6060

61-
bool get isMain => _id == _mainModuleId;
61+
final bool isMain;
6262

6363
/// The name used to import and export this module.
64-
String get moduleImportName => 'module$_id';
64+
final String moduleImportName;
6565

6666
/// The name added to the wasm output file for this module.
6767
final String moduleName;
6868

6969
/// Whether or not a wasm file should be emitted for this module.
7070
final bool skipEmit;
7171

72-
ModuleMetadata._(this._id, this.moduleName, {this.skipEmit = false});
72+
ModuleMetadata._(this.moduleImportName, this.moduleName,
73+
{this.skipEmit = false, this.isMain = false});
7374

7475
/// Whether or not the provided kernel [Reference] is included in this module.
7576
bool containsReference(Reference reference) {

pkg/dart2wasm/lib/translator.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2030,7 +2030,7 @@ class Translator with KernelNodes {
20302030
internalizedStringsForJSRuntime.add(s);
20312031
} else {
20322032
internalizedString = module.globals.import(
2033-
'S',
2033+
'',
20342034
s,
20352035
w.GlobalType(w.RefType.extern(nullable: false), mutable: false),
20362036
);

pkg/dart2wasm/lib/util.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,24 @@ List<int> _intToLittleEndianBytes(int i) {
8484

8585
String intToBase64(int i) => base64.encode(_intToLittleEndianBytes(i));
8686

87+
/// Maps ints to minimal length strings.
88+
///
89+
/// For simplicity, this only uses combinations of 1-byte characters. The 2+
90+
/// byte characters don't significantly impact the average string size.
91+
///
92+
/// Starts at 1 to avoid emitting the empty string.
93+
String intToMinString(int i) {
94+
assert(i >= 0);
95+
i += 1;
96+
final codeUnits = <int>[];
97+
while (i > 0) {
98+
int remainder = i % 128;
99+
i ~/= 128;
100+
codeUnits.add(remainder);
101+
}
102+
return String.fromCharCodes(codeUnits);
103+
}
104+
87105
Component createEmptyComponent() {
88106
return Component()
89107
..addMetadataRepository(ProcedureAttributesMetadataRepository())

pkg/dart2wasm/test/ir_tests/deferred.constant.multi_module_use_module1.wat

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@
1212
(field $field0 i32)
1313
(field $field1 (mut i32))
1414
(field $b (ref $JSStringImpl)))))
15-
(global $S.h1-nonshared-const (import "S" "h1-nonshared-const") (ref extern))
16-
(global $S.shared-const (import "S" "shared-const") (ref extern))
15+
(global $.h1-nonshared-const (import "" "h1-nonshared-const") (ref extern))
16+
(global $.shared-const (import "" "shared-const") (ref extern))
1717
(table $module0.constant-table0 (import "module0" "constant-table0") 1 (ref null $JSStringImpl))
1818
(table $module0.constant-table1 (import "module0" "constant-table1") 1 (ref null $MyConstClass))
1919
(global $"C488 MyConstClass" (ref $MyConstClass)
2020
(i32.const 107)
2121
(i32.const 0)
2222
(i32.const 4)
2323
(i32.const 0)
24-
(global.get $S.h1-nonshared-const)
24+
(global.get $.h1-nonshared-const)
2525
(struct.new $JSStringImpl)
2626
(struct.new $MyConstClass))
2727
(func $"modH1Use <noInline>" (param $var0 i32) (result (ref $MyConstClass))
@@ -45,7 +45,7 @@
4545
i32.const 0
4646
i32.const 4
4747
i32.const 0
48-
global.get $S.shared-const
48+
global.get $.shared-const
4949
struct.new $JSStringImpl
5050
local.tee $var1
5151
table.set $module0.constant-table0

pkg/dart2wasm/test/ir_tests/deferred.constant.multi_module_use_module3.wat

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@
1212
(field $field0 i32)
1313
(field $field1 (mut i32))
1414
(field $b (ref $JSStringImpl)))))
15-
(global $S.shared-const (import "S" "shared-const") (ref extern))
16-
(global $S.h0-nonshared-const (import "S" "h0-nonshared-const") (ref extern))
15+
(global $.shared-const (import "" "shared-const") (ref extern))
16+
(global $.h0-nonshared-const (import "" "h0-nonshared-const") (ref extern))
1717
(table $module0.constant-table0 (import "module0" "constant-table0") 1 (ref null $JSStringImpl))
1818
(table $module0.constant-table1 (import "module0" "constant-table1") 1 (ref null $MyConstClass))
1919
(global $"C492 MyConstClass" (ref $MyConstClass)
2020
(i32.const 107)
2121
(i32.const 0)
2222
(i32.const 4)
2323
(i32.const 0)
24-
(global.get $S.h0-nonshared-const)
24+
(global.get $.h0-nonshared-const)
2525
(struct.new $JSStringImpl)
2626
(struct.new $MyConstClass))
2727
(func $"modH0Use <noInline>" (param $var0 i32) (result (ref $MyConstClass))
@@ -45,7 +45,7 @@
4545
i32.const 0
4646
i32.const 4
4747
i32.const 0
48-
global.get $S.shared-const
48+
global.get $.shared-const
4949
struct.new $JSStringImpl
5050
local.tee $var1
5151
table.set $module0.constant-table0

pkg/dart2wasm/test/ir_tests/deferred.constant_module1.wat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
(global $"C62 WasmArray<_Type>[1]" (import "module0" "global3") (ref $Array<_Type>))
3131
(global $"C306 WasmArray<_NamedParameter>[0]" (import "module0" "global4") (ref $Array<_NamedParameter>))
3232
(global $"C28 _InterfaceType" (import "module0" "global7") (ref $_InterfaceType))
33-
(global $S.globalH1Bar< (import "S" "globalH1Bar<") (ref extern))
33+
(global $.globalH1Bar< (import "" "globalH1Bar<") (ref extern))
3434
(table $module0.constant-table0 (import "module0" "constant-table0") 1 (ref null $_FunctionType))
3535
(global $global7 (ref $#Vtable-1-1) <...>)
3636
(global $global4 (ref $#DummyStruct) <...>)
@@ -44,7 +44,7 @@
4444
(global $"C463 \"globalH1Bar<\"" (ref $JSStringImpl)
4545
(i32.const 4)
4646
(i32.const 0)
47-
(global.get $S.globalH1Bar<)
47+
(global.get $.globalH1Bar<)
4848
(struct.new $JSStringImpl))
4949
(global $"C464 \">(\"" (ref $JSStringImpl) <...>)
5050
(func $"modH1UseH1 <noInline>" (result (ref null $#Top))

0 commit comments

Comments
 (0)