diff --git a/benchmarks/tool/compile_benchmarks.dart b/benchmarks/tool/compile_benchmarks.dart index 92fee98b8..2c7c11965 100755 --- a/benchmarks/tool/compile_benchmarks.dart +++ b/benchmarks/tool/compile_benchmarks.dart @@ -9,10 +9,12 @@ import 'package:pool/pool.dart' show Pool; Future main(List args) async { final argParser = ArgParser() ..addOption('target', - mandatory: false, defaultsTo: 'aot,exe,jit,js,js-production') - ..addOption('jobs', abbr: 'j', mandatory: false); + mandatory: false, defaultsTo: 'exe,jit,js,js-production') + ..addOption('jobs', abbr: 'j', mandatory: false) + ..addOption('aot-target', mandatory: false, defaultsTo: 'x64'); final parsedArgs = argParser.parse(args); + final env = Platform.environment; var jobs = Platform.numberOfProcessors; if (parsedArgs['jobs'] != null) { @@ -23,7 +25,23 @@ Future main(List args) async { for (final targetStr in parsedArgs['target'].split(',')) { switch (targetStr) { case 'aot': - targets.add(aotTarget); + final dartSdkPath = env["DART_SDK"]; + + if (dartSdkPath == null) { + print('\$DART_SDK needs to be set when generating aot snapshots'); + exit(1); + } + + final parsedAotTarget = parsedArgs['aot-target']; + final aotTarget = aotTargets[parsedAotTarget]; + if (aotTarget == null) { + print('Unsupported aot target: $parsedAotTarget'); + print( + 'Supported aot targets: ${aotTargets.keys.toList().join(', ')}'); + exit(1); + } + + targets.add(makeAotTarget(dartSdkPath, aotTarget)); break; case 'exe': @@ -60,7 +78,7 @@ Future main(List args) async { .toList(); } - final commands = >[]; + final commands = []; if (sourceFiles.isNotEmpty && targets.isNotEmpty) { try { @@ -79,11 +97,21 @@ Future main(List args) async { final pool = Pool(jobs); - final stream = pool.forEach, CompileProcess>(commands, - (List command) async { - final commandStr = command.join(' '); + final stream = pool.forEach(commands, + (ProcessInstructions command) async { + var envStr = ''; + if (command.environment != null) { + envStr = command.environment!.entries + .map((entry) => '${entry.key}=${entry.value}') + .join(' ') + + ' '; + } + final commandStr = + '$envStr${command.executable} ${command.arguments.join(' ')}'; print(commandStr); - final result = await Process.run(command[0], command.sublist(1)); + + final result = await Process.run(command.executable, command.arguments, + environment: command.environment); return CompileProcess(commandStr, result); }); @@ -107,6 +135,39 @@ Future main(List args) async { await pool.done; } +/// Stores [Process.run] arguments +class ProcessInstructions { + final String executable; + final List arguments; + final Map? environment; + + ProcessInstructions(this.executable, this.arguments, {this.environment}); +} + +/// Supported aot snapshot targets +enum AotTarget { + x64, + armv7hf, + armv8, +} + +/// Maps `--aot-target` arguments to their [AotTarget]s +const aotTargets = { + 'x64': AotTarget.x64, + 'armv7hf': AotTarget.armv7hf, + 'armv8': AotTarget.armv8, +}; + +/// Maps [AotTarget]s to `DART_CONFIGURATION` env values when invoking `precompiler2` +// TODO: Product or release? +const aotTargetDartConfiguration = { + AotTarget.x64: "ProductX64", + AotTarget.armv7hf: "ProductXARM/clang_x86", + AotTarget.armv8: "ProductXARM64/clang_x64", +}; + +/// Packs a debug string for a command being run to the command's result, to be +/// able to show which command failed and why class CompileProcess { final String command; final ProcessResult result; @@ -116,7 +177,7 @@ class CompileProcess { class Target { final String _name; - final List Function(String) _processArgs; + final ProcessInstructions Function(String sourceFile) _processArgs; const Target(this._name, this._processArgs); @@ -125,63 +186,71 @@ class Target { return 'Target($_name)'; } - List compileArgs(String sourceFile) { + ProcessInstructions compileArgs(String sourceFile) { return _processArgs(sourceFile); } } +Target makeAotTarget(String dartSdkPath, AotTarget aotTarget) { + return Target('aot', (sourceFile) { + final baseName = path.basename(sourceFile); + final baseNameNoExt = path.withoutExtension(baseName); + // TODO: Do we need `-Ddart.vm.product=true`? + return ProcessInstructions('$dartSdkPath/pkg/vm/tool/precompiler2', [ + sourceFile, + 'out/$baseNameNoExt.aot' + ], environment: { + 'DART_CONFIGURATION': aotTargetDartConfiguration[aotTarget]! + }); + }); +} + const aotTarget = Target('aot', aotProcessArgs); const exeTarget = Target('exe', exeProcessArgs); const jitTarget = Target('jit', jitProcessArgs); const jsTarget = Target('js', jsProcessArgs); const jsProductionTarget = Target('js-production', jsProductionProcessArgs); -List aotProcessArgs(String sourceFile) { +ProcessInstructions aotProcessArgs(String sourceFile) { final baseName = path.basename(sourceFile); final baseNameNoExt = path.withoutExtension(baseName); - return [ - 'dart', - 'compile', - 'aot-snapshot', - sourceFile, - '-o', - 'out/$baseNameNoExt.aot' - ]; + return ProcessInstructions('dart', + ['compile', 'aot-snapshot', sourceFile, '-o', 'out/$baseNameNoExt.aot']); } -List exeProcessArgs(String sourceFile) { +ProcessInstructions exeProcessArgs(String sourceFile) { final baseName = path.basename(sourceFile); final baseNameNoExt = path.withoutExtension(baseName); - return ['dart', 'compile', 'exe', sourceFile, '-o', 'out/$baseNameNoExt.exe']; + return ProcessInstructions( + 'dart', ['compile', 'exe', sourceFile, '-o', 'out/$baseNameNoExt.exe']); } -List jitProcessArgs(String sourceFile) { +ProcessInstructions jitProcessArgs(String sourceFile) { final baseName = path.basename(sourceFile); final baseNameNoExt = path.withoutExtension(baseName); - return [ - 'dart', + return ProcessInstructions('dart', [ '--snapshot-kind=kernel', '--snapshot=out/$baseNameNoExt.dill', sourceFile - ]; + ]); } -List jsProcessArgs(String sourceFile) { +ProcessInstructions jsProcessArgs(String sourceFile) { final baseName = path.basename(sourceFile); final baseNameNoExt = path.withoutExtension(baseName); - return ['dart', 'compile', 'js', sourceFile, '-o', 'out/$baseNameNoExt.js']; + return ProcessInstructions( + 'dart', ['compile', 'js', sourceFile, '-o', 'out/$baseNameNoExt.js']); } -List jsProductionProcessArgs(String sourceFile) { +ProcessInstructions jsProductionProcessArgs(String sourceFile) { final baseName = path.basename(sourceFile); final baseNameNoExt = path.withoutExtension(baseName); - return [ - 'dart', + return ProcessInstructions('dart', [ 'compile', 'js', sourceFile, '-O4', '-o', 'out/$baseNameNoExt.production.js' - ]; + ]); }