Friendlier flags for Dart compilation training. (#25645)
* Renamed --save-compilation-trace to flutter run --train.
* Renamed --precompile=<file> to --compilation-trace-file=<file>.
* In dynamic mode, made JIT snapshot the default, instead of kernel file.
diff --git a/packages/flutter_tools/gradle/flutter.gradle b/packages/flutter_tools/gradle/flutter.gradle
index 6feec96..0fcf949 100644
--- a/packages/flutter_tools/gradle/flutter.gradle
+++ b/packages/flutter_tools/gradle/flutter.gradle
@@ -318,8 +318,8 @@
trackWidgetCreationValue = project.property('track-widget-creation').toBoolean()
}
String compilationTraceFilePathValue = null
- if (project.hasProperty('precompile')) {
- compilationTraceFilePathValue = project.property('precompile')
+ if (project.hasProperty('compilation-trace-file')) {
+ compilationTraceFilePathValue = project.property('compilation-trace-file')
}
Boolean createPatchValue = false
if (project.hasProperty('patch')) {
@@ -535,7 +535,7 @@
args "--track-widget-creation"
}
if (compilationTraceFilePath != null) {
- args "--precompile", compilationTraceFilePath
+ args "--compilation-trace-file", compilationTraceFilePath
}
if (createPatch) {
args "--patch"
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index 507446e..d07dbde 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -387,7 +387,7 @@
assert(buildInfo.trackWidgetCreation != null);
command.add('-Ptrack-widget-creation=${buildInfo.trackWidgetCreation}');
if (buildInfo.compilationTraceFilePath != null)
- command.add('-Pprecompile=${buildInfo.compilationTraceFilePath}');
+ command.add('-Pcompilation-trace-file=${buildInfo.compilationTraceFilePath}');
if (buildInfo.createPatch)
command.add('-Ppatch=true');
if (buildInfo.extraFrontEndOptions != null)
diff --git a/packages/flutter_tools/lib/src/bundle.dart b/packages/flutter_tools/lib/src/bundle.dart
index 8f3ed1a..268ea49 100644
--- a/packages/flutter_tools/lib/src/bundle.dart
+++ b/packages/flutter_tools/lib/src/bundle.dart
@@ -73,6 +73,28 @@
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
applicationKernelFilePath ??= getDefaultApplicationKernelPath(trackWidgetCreation: trackWidgetCreation);
+ if (compilationTraceFilePath != null) {
+ if (buildMode != BuildMode.dynamicProfile && buildMode != BuildMode.dynamicRelease) {
+ // Silently ignore JIT snapshotting for those builds that don't support it.
+ compilationTraceFilePath = null;
+
+ } else if (compilationTraceFilePath.isEmpty) {
+ // Disable JIT snapshotting if flag is empty.
+ printStatus('JIT snapshot will be disabled for this build...');
+ compilationTraceFilePath = null;
+
+ } else if (!fs.file(compilationTraceFilePath).existsSync()) {
+ // Be forgiving if compilation trace file is missing.
+ printError('Warning: Ignoring missing compiler training file $compilationTraceFilePath...');
+ printStatus('JIT snapshot will not use compiler training...');
+ final File tmp = fs.systemTempDirectory.childFile('flutterEmptyCompilationTrace.txt');
+ compilationTraceFilePath = (tmp..createSync(recursive: true)).path;
+
+ } else {
+ printStatus('JIT snapshot will use compiler training file $compilationTraceFilePath...');
+ }
+ }
+
DevFSContent kernelContent;
if (!precompiledSnapshot) {
if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
diff --git a/packages/flutter_tools/lib/src/commands/build_bundle.dart b/packages/flutter_tools/lib/src/commands/build_bundle.dart
index c47c34c..6e2177f 100644
--- a/packages/flutter_tools/lib/src/commands/build_bundle.dart
+++ b/packages/flutter_tools/lib/src/commands/build_bundle.dart
@@ -94,7 +94,7 @@
precompiledSnapshot: argResults['precompiled'],
reportLicensedPackages: argResults['report-licensed-packages'],
trackWidgetCreation: argResults['track-widget-creation'],
- compilationTraceFilePath: argResults['precompile'],
+ compilationTraceFilePath: argResults['compilation-trace-file'],
createPatch: argResults['patch'],
buildNumber: buildNumber,
baselineDir: argResults['baseline-dir'],
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart
index 138daa1..8964018 100644
--- a/packages/flutter_tools/lib/src/commands/run.dart
+++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -35,17 +35,17 @@
..addOption('route',
help: 'Which route to load when running the app.',
)
- ..addFlag('save-compilation-trace',
+ ..addFlag('train',
hide: !verboseHelp,
negatable: false,
- help: 'Save runtime compilation trace to a file.\n'
- 'Compilation trace will be saved to compilation.txt when \'flutter run\' exits. '
+ help: 'Save Dart runtime compilation trace to a file. '
+ 'Compilation trace will be saved to a file specified by --compilation-trace-file '
+ 'when \'flutter run --dynamic --profile --train\' exits. '
'This file contains a list of Dart symbols that were compiled by the runtime JIT '
- 'compiler up to that point. This file can be used in later --dynamic builds to '
- 'precompile some code by the offline compiler, thus reducing application startup '
- 'latency at the cost of larger application package.\n'
- 'This flag is only allowed when running --dynamic --profile (recommended) or '
- '--debug mode.\n'
+ 'compiler up to that point. This file can be used in subsequent --dynamic builds '
+ 'to precompile some code by the offline compiler. '
+ 'This flag is only allowed when running as --dynamic --profile (recommended) or '
+ '--debug (may include unwanted debug symbols).'
)
..addOption('target-platform',
defaultsTo: 'default',
@@ -315,10 +315,10 @@
}
}
- if (argResults['save-compilation-trace'] &&
+ if (argResults['train'] &&
getBuildMode() != BuildMode.debug && getBuildMode() != BuildMode.dynamicProfile)
- throwToolExit('Error: --save-compilation-trace is only allowed when running '
- '--dynamic --profile (recommended) or --debug mode.');
+ throwToolExit('Error: --train is only allowed when running as --dynamic --profile '
+ '(recommended) or --debug (may include unwanted debug symbols).');
final List<FlutterDevice> flutterDevices = devices.map<FlutterDevice>((Device device) {
return FlutterDevice(
@@ -345,7 +345,7 @@
projectRootPath: argResults['project-root'],
packagesFilePath: globalResults['packages'],
dillOutputPath: argResults['output-dill'],
- saveCompilationTrace: argResults['save-compilation-trace'],
+ saveCompilationTrace: argResults['train'],
stayResident: stayResident,
ipv6: ipv6,
);
@@ -358,7 +358,7 @@
applicationBinary: applicationBinaryPath == null
? null
: fs.file(applicationBinaryPath),
- saveCompilationTrace: argResults['save-compilation-trace'],
+ saveCompilationTrace: argResults['train'],
stayResident: stayResident,
ipv6: ipv6,
);
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index 9f05b00..06764b6 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -242,14 +242,13 @@
}
void addDynamicModeFlags({bool verboseHelp = false}) {
- argParser.addOption('precompile',
+ argParser.addOption('compilation-trace-file',
+ defaultsTo: 'compilation.txt',
hide: !verboseHelp,
- help: 'Precompile functions specified in input file. This flag is only '
- 'allowed when using --dynamic. It takes a Dart compilation trace '
- 'file produced by the training run of the application. With this '
- 'flag, instead of using default Dart VM snapshot provided by the '
- 'engine, the application will use its own snapshot that includes '
- 'additional compiled functions.'
+ help: 'Filename of Dart compilation trace file. This file will be produced\n'
+ 'by \'flutter run --dynamic --profile --train\' and consumed by subsequent\n'
+ '--dynamic builds such as \'flutter build apk --dynamic\' to precompile\n'
+ 'some code by the offline compiler.'
);
argParser.addFlag('patch',
hide: !verboseHelp,
@@ -381,8 +380,8 @@
? argResults['flavor']
: null,
trackWidgetCreation: trackWidgetCreation,
- compilationTraceFilePath: argParser.options.containsKey('precompile')
- ? argResults['precompile']
+ compilationTraceFilePath: argParser.options.containsKey('compilation-trace-file')
+ ? argResults['compilation-trace-file']
: null,
createBaseline: argParser.options.containsKey('baseline')
? argResults['baseline']
@@ -647,23 +646,23 @@
final bool dynamicFlag = argParser.options.containsKey('dynamic')
? argResults['dynamic'] : false;
- final String compilationTraceFilePath = argParser.options.containsKey('precompile')
- ? argResults['precompile'] : null;
+ final String compilationTraceFilePath = argParser.options.containsKey('compilation-trace-file')
+ ? argResults['compilation-trace-file'] : null;
final bool createBaseline = argParser.options.containsKey('baseline')
? argResults['baseline'] : false;
final bool createPatch = argParser.options.containsKey('patch')
? argResults['patch'] : false;
- if (compilationTraceFilePath != null && getBuildMode() == BuildMode.debug)
- throw ToolExit('Error: --precompile is not allowed when --debug is specified.');
- if (compilationTraceFilePath != null && !dynamicFlag)
- throw ToolExit('Error: --precompile is allowed only when --dynamic is specified.');
if (createBaseline && createPatch)
throw ToolExit('Error: Only one of --baseline, --patch is allowed.');
+ if (createBaseline && !dynamicFlag)
+ throw ToolExit('Error: --baseline is allowed only when --dynamic is specified.');
if (createBaseline && compilationTraceFilePath == null)
- throw ToolExit('Error: --baseline is allowed only when --precompile is specified.');
+ throw ToolExit('Error: --baseline requires --compilation-trace-file to be specified.');
+ if (createPatch && !dynamicFlag)
+ throw ToolExit('Error: --patch is allowed only when --dynamic is specified.');
if (createPatch && compilationTraceFilePath == null)
- throw ToolExit('Error: --patch is allowed only when --precompile is specified.');
+ throw ToolExit('Error: --patch requires --compilation-trace-file to be specified.');
}
ApplicationPackageStore applicationPackages;