mirror of
https://github.com/flutter/flutter
synced 2024-08-25 02:46:31 +00:00
Use dart compile wasm
for wasm compilations (#143298)
* Flags to `dart compile wasm` Some options are not relevant to a standalone user of `dart compile wasm` (e.g. specyfing dart-sdk, platform file etc). => Those aren't offered by the `dart compile wasm` tool directly. => We use the `--extra-compiler-option=` instead which passes through arbitrary options to the dart2wasm compiler. => We don't maintain compatibility of those options, if we update them we'll ensure to also update flutter tools * Binaryen optimization passes This change will mean we use the binaryen flags from Dart SDK which are slightly different from the ones in flutter. * Optimization configuration This change will also start using the more standardized `-O` flag for determining optimization levels. The meaning of those flags have been mostly aligned with dart2js (with some differences remaining). * Minimization Using the new optimization flags, namely `-O4` for `--wasm-opt=full`, will automatically enable the new `--minify` support. Minification is Dart semantics preserving but changes the `<obj>.runtimeType.toString()` to use minified names (just as in dart2js). * Code size changes Overall this change will reduce wonderous code size by around 10%. Issue https://github.com/dart-lang/sdk/issues/54675
This commit is contained in:
parent
295eeaf100
commit
abadf9ff8c
|
@ -249,9 +249,8 @@ class Dart2WasmTarget extends Dart2WebTarget {
|
|||
}
|
||||
final BuildMode buildMode = BuildMode.fromCliName(buildModeEnvironment);
|
||||
final Artifacts artifacts = environment.artifacts;
|
||||
final File outputWasmFile = environment.buildDir.childFile(
|
||||
compilerConfig.runWasmOpt ? 'main.dart.unopt.wasm' : 'main.dart.wasm'
|
||||
);
|
||||
final File outputWasmFile =
|
||||
environment.buildDir.childFile('main.dart.wasm');
|
||||
final File depFile = environment.buildDir.childFile('dart2wasm.d');
|
||||
final String dartSdkPath = artifacts.getArtifactPath(Artifact.engineDartSdkPath, platform: TargetPlatform.web_javascript);
|
||||
final String platformBinariesPath = artifacts.getHostArtifact(HostArtifact.webPlatformKernelFolder).path;
|
||||
|
@ -261,12 +260,16 @@ class Dart2WasmTarget extends Dart2WebTarget {
|
|||
);
|
||||
|
||||
final List<String> compilationArgs = <String>[
|
||||
artifacts.getArtifactPath(Artifact.engineDartAotRuntime, platform: TargetPlatform.web_javascript),
|
||||
'--disable-dart-dev',
|
||||
artifacts.getArtifactPath(Artifact.dart2wasmSnapshot, platform: TargetPlatform.web_javascript),
|
||||
artifacts.getArtifactPath(Artifact.engineDartBinary, platform: TargetPlatform.web_javascript),
|
||||
'compile',
|
||||
'wasm',
|
||||
'--packages=.dart_tool/package_config.json',
|
||||
'--dart-sdk=$dartSdkPath',
|
||||
'--platform=$platformFilePath',
|
||||
'--extra-compiler-option=--dart-sdk=$dartSdkPath',
|
||||
'--extra-compiler-option=--platform=$platformFilePath',
|
||||
if (compilerConfig.renderer == WebRendererMode.skwasm) ...<String>[
|
||||
'--extra-compiler-option=--import-shared-memory',
|
||||
'--extra-compiler-option=--shared-memory-max-pages=32768',
|
||||
],
|
||||
if (buildMode == BuildMode.profile)
|
||||
'-Ddart.vm.profile=true'
|
||||
else
|
||||
|
@ -274,16 +277,12 @@ class Dart2WasmTarget extends Dart2WebTarget {
|
|||
...decodeCommaSeparated(environment.defines, kExtraFrontEndOptions),
|
||||
for (final String dartDefine in dartDefines)
|
||||
'-D$dartDefine',
|
||||
...compilerConfig.toCommandOptions(),
|
||||
if (compilerConfig.renderer == WebRendererMode.skwasm)
|
||||
...<String>[
|
||||
'--import-shared-memory',
|
||||
'--shared-memory-max-pages=32768',
|
||||
],
|
||||
'--depfile=${depFile.path}',
|
||||
'--extra-compiler-option=--depfile=${depFile.path}',
|
||||
|
||||
environment.buildDir.childFile('main.dart').path, // dartfile
|
||||
...compilerConfig.toCommandOptions(),
|
||||
'-o',
|
||||
outputWasmFile.path,
|
||||
environment.buildDir.childFile('main.dart').path, // dartfile
|
||||
];
|
||||
|
||||
final ProcessUtils processUtils = ProcessUtils(
|
||||
|
@ -295,37 +294,6 @@ class Dart2WasmTarget extends Dart2WebTarget {
|
|||
throwOnError: true,
|
||||
compilationArgs,
|
||||
);
|
||||
if (compilerConfig.runWasmOpt) {
|
||||
final String wasmOptBinary = artifacts.getArtifactPath(
|
||||
Artifact.wasmOptBinary,
|
||||
platform: TargetPlatform.web_javascript
|
||||
);
|
||||
final File optimizedOutput = environment.buildDir.childFile('main.dart.wasm');
|
||||
final List<String> optimizeArgs = <String>[
|
||||
wasmOptBinary,
|
||||
'--all-features',
|
||||
'--closed-world',
|
||||
'--traps-never-happen',
|
||||
'-O3',
|
||||
'--type-ssa',
|
||||
'--gufa',
|
||||
'-O3',
|
||||
'--type-merging',
|
||||
if (compilerConfig.wasmOpt == WasmOptLevel.debug)
|
||||
'--debuginfo',
|
||||
outputWasmFile.path,
|
||||
'-o',
|
||||
optimizedOutput.path,
|
||||
];
|
||||
await processUtils.run(
|
||||
throwOnError: true,
|
||||
optimizeArgs,
|
||||
);
|
||||
|
||||
// Rename the .mjs file not to have the `.unopt` bit
|
||||
final File jsRuntimeFile = environment.buildDir.childFile('main.dart.unopt.mjs');
|
||||
await jsRuntimeFile.rename(environment.buildDir.childFile('main.dart.mjs').path);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -148,12 +148,23 @@ class WasmCompilerConfig extends WebCompilerConfig {
|
|||
@override
|
||||
CompileTarget get compileTarget => CompileTarget.wasm;
|
||||
|
||||
bool get runWasmOpt =>
|
||||
wasmOpt == WasmOptLevel.full || wasmOpt == WasmOptLevel.debug;
|
||||
List<String> toCommandOptions() {
|
||||
// -O1: Optimizes
|
||||
// -O2: Same as -O1 but also minifies (still semantics preserving)
|
||||
// -O3: Same as -O2 but also omits implicit type checks.
|
||||
// -O4: Same as -O3 but also omits explicit type checks.
|
||||
// (NOTE: This differs from dart2js -O4 semantics atm.)
|
||||
|
||||
List<String> toCommandOptions() => <String>[
|
||||
if (omitTypeChecks) '--omit-type-checks',
|
||||
];
|
||||
// Ortogonal: The name section is always kept by default and we emit it only
|
||||
// in [WasmOptLevel.full] mode (similar to `--strip` of static symbols in
|
||||
// AOT mode).
|
||||
final String level = !omitTypeChecks ? '-O2' : '-O4';
|
||||
return switch (wasmOpt) {
|
||||
WasmOptLevel.none => <String>['-O0'],
|
||||
WasmOptLevel.debug => <String>[level, '--no-minify'],
|
||||
WasmOptLevel.full => <String>[level, '--no-name-section'],
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Object> get buildEventAnalyticsValues => <String, Object>{
|
||||
|
|
|
@ -30,24 +30,12 @@ const List<String> _kDart2jsLinuxArgs = <String>[
|
|||
];
|
||||
|
||||
const List<String> _kDart2WasmLinuxArgs = <String> [
|
||||
'Artifact.engineDartAotRuntime.TargetPlatform.web_javascript',
|
||||
'--disable-dart-dev',
|
||||
'Artifact.dart2wasmSnapshot.TargetPlatform.web_javascript',
|
||||
'Artifact.engineDartBinary.TargetPlatform.web_javascript',
|
||||
'compile',
|
||||
'wasm',
|
||||
'--packages=.dart_tool/package_config.json',
|
||||
'--dart-sdk=Artifact.engineDartSdkPath.TargetPlatform.web_javascript',
|
||||
'--platform=HostArtifact.webPlatformKernelFolder/dart2wasm_platform.dill',
|
||||
];
|
||||
|
||||
const List<String> _kWasmOptLinuxArgrs = <String> [
|
||||
'Artifact.wasmOptBinary.TargetPlatform.web_javascript',
|
||||
'--all-features',
|
||||
'--closed-world',
|
||||
'--traps-never-happen',
|
||||
'-O3',
|
||||
'--type-ssa',
|
||||
'--gufa',
|
||||
'-O3',
|
||||
'--type-merging',
|
||||
'--extra-compiler-option=--dart-sdk=Artifact.engineDartSdkPath.TargetPlatform.web_javascript',
|
||||
'--extra-compiler-option=--platform=HostArtifact.webPlatformKernelFolder/dart2wasm_platform.dill',
|
||||
];
|
||||
|
||||
void main() {
|
||||
|
@ -920,7 +908,7 @@ void main() {
|
|||
|
||||
final File depFile = environment.buildDir.childFile('dart2wasm.d');
|
||||
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.unopt.mjs');
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.mjs');
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
..._kDart2WasmLinuxArgs,
|
||||
|
@ -929,20 +917,14 @@ void main() {
|
|||
'-DBAZ=qux',
|
||||
'-DFLUTTER_WEB_AUTO_DETECT=false',
|
||||
'-DFLUTTER_WEB_USE_SKIA=true',
|
||||
'--depfile=${depFile.absolute.path}',
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
|
||||
],
|
||||
onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo'))
|
||||
);
|
||||
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
..._kWasmOptLinuxArgrs,
|
||||
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
|
||||
'--extra-compiler-option=--depfile=${depFile.absolute.path}',
|
||||
'-O2',
|
||||
'--no-name-section',
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.wasm').absolute.path,
|
||||
])
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
],
|
||||
onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo'))
|
||||
);
|
||||
|
||||
await Dart2WasmTarget(
|
||||
|
@ -951,10 +933,7 @@ void main() {
|
|||
)
|
||||
).build(environment);
|
||||
|
||||
expect(outputJsFile.existsSync(), isFalse);
|
||||
final File movedJsFile = environment.buildDir.childFile('main.dart.mjs');
|
||||
expect(movedJsFile.existsSync(), isTrue);
|
||||
expect(movedJsFile.readAsStringSync(), 'foo');
|
||||
expect(outputJsFile.existsSync(), isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => processManager,
|
||||
}));
|
||||
|
@ -966,28 +945,21 @@ void main() {
|
|||
|
||||
final File depFile = environment.buildDir.childFile('dart2wasm.d');
|
||||
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.unopt.mjs');
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.mjs');
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
..._kDart2WasmLinuxArgs,
|
||||
'-Ddart.vm.product=true',
|
||||
'-DFLUTTER_WEB_AUTO_DETECT=false',
|
||||
'-DFLUTTER_WEB_USE_SKIA=true',
|
||||
'--omit-type-checks',
|
||||
'--depfile=${depFile.absolute.path}',
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
|
||||
],
|
||||
onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo'))
|
||||
);
|
||||
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
..._kWasmOptLinuxArgrs,
|
||||
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
|
||||
'--extra-compiler-option=--depfile=${depFile.absolute.path}',
|
||||
'-O4',
|
||||
'--no-name-section',
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.wasm').absolute.path,
|
||||
])
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
],
|
||||
onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo'))
|
||||
);
|
||||
|
||||
await Dart2WasmTarget(
|
||||
|
@ -997,10 +969,7 @@ void main() {
|
|||
)
|
||||
).build(environment);
|
||||
|
||||
expect(outputJsFile.existsSync(), isFalse);
|
||||
final File movedJsFile = environment.buildDir.childFile('main.dart.mjs');
|
||||
expect(movedJsFile.existsSync(), isTrue);
|
||||
expect(movedJsFile.readAsStringSync(), 'foo');
|
||||
expect(outputJsFile.existsSync(), isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => processManager,
|
||||
}));
|
||||
|
@ -1011,27 +980,21 @@ void main() {
|
|||
|
||||
final File depFile = environment.buildDir.childFile('dart2wasm.d');
|
||||
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.unopt.mjs');
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.mjs');
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
..._kDart2WasmLinuxArgs,
|
||||
'-Ddart.vm.product=true',
|
||||
'-DFLUTTER_WEB_AUTO_DETECT=false',
|
||||
'-DFLUTTER_WEB_USE_SKIA=true',
|
||||
'--depfile=${depFile.absolute.path}',
|
||||
'--extra-compiler-option=--depfile=${depFile.absolute.path}',
|
||||
'-O2',
|
||||
'--no-minify',
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.wasm').absolute.path,
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
|
||||
], onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo')));
|
||||
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
..._kWasmOptLinuxArgrs,
|
||||
'--debuginfo',
|
||||
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.wasm').absolute.path,
|
||||
]));
|
||||
|
||||
await Dart2WasmTarget(
|
||||
const WasmCompilerConfig(
|
||||
wasmOpt: WasmOptLevel.debug,
|
||||
|
@ -1039,10 +1002,7 @@ void main() {
|
|||
)
|
||||
).build(environment);
|
||||
|
||||
expect(outputJsFile.existsSync(), isFalse);
|
||||
final File movedJsFile = environment.buildDir.childFile('main.dart.mjs');
|
||||
expect(movedJsFile.existsSync(), isTrue);
|
||||
expect(movedJsFile.readAsStringSync(), 'foo');
|
||||
expect(outputJsFile.existsSync(), isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => processManager,
|
||||
}));
|
||||
|
@ -1060,9 +1020,11 @@ void main() {
|
|||
'-Ddart.vm.product=true',
|
||||
'-DFLUTTER_WEB_AUTO_DETECT=false',
|
||||
'-DFLUTTER_WEB_USE_SKIA=true',
|
||||
'--depfile=${depFile.absolute.path}',
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
'--extra-compiler-option=--depfile=${depFile.absolute.path}',
|
||||
'-O0',
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.wasm').absolute.path,
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
], onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo')));
|
||||
|
||||
await Dart2WasmTarget(
|
||||
|
@ -1080,31 +1042,26 @@ void main() {
|
|||
environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.defaultValue.name;
|
||||
final File depFile = environment.buildDir.childFile('dart2wasm.d');
|
||||
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.unopt.mjs');
|
||||
final File outputJsFile = environment.buildDir.childFile('main.dart.mjs');
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
..._kDart2WasmLinuxArgs,
|
||||
'--extra-compiler-option=--import-shared-memory',
|
||||
'--extra-compiler-option=--shared-memory-max-pages=32768',
|
||||
'-Ddart.vm.product=true',
|
||||
'-DFLUTTER_WEB_AUTO_DETECT=false',
|
||||
'-DFLUTTER_WEB_USE_SKIA=false',
|
||||
'-DFLUTTER_WEB_USE_SKWASM=true',
|
||||
'--import-shared-memory',
|
||||
'--shared-memory-max-pages=32768',
|
||||
'--depfile=${depFile.absolute.path}',
|
||||
'--extra-compiler-option=--depfile=${depFile.absolute.path}',
|
||||
'-O2',
|
||||
'--no-name-section',
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.wasm').absolute.path,
|
||||
environment.buildDir.childFile('main.dart').absolute.path,
|
||||
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
|
||||
],
|
||||
onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo'))
|
||||
);
|
||||
|
||||
processManager.addCommand(FakeCommand(
|
||||
command: <String>[
|
||||
..._kWasmOptLinuxArgrs,
|
||||
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
|
||||
'-o',
|
||||
environment.buildDir.childFile('main.dart.wasm').absolute.path,
|
||||
])
|
||||
);
|
||||
|
||||
await Dart2WasmTarget(
|
||||
const WasmCompilerConfig(
|
||||
|
|
Loading…
Reference in a new issue