Unverified Commit 54c10f44 authored by Stanislav Baranov's avatar Stanislav Baranov Committed by GitHub

Implement build flow for hot updates on Android (#22391)

This also involves switching from Core JIT to App JIT snapshot, and replacing per-isolate VM snapshot with the shared VM snapshot.

For now there is no separate update bundle file, as the generated update gets packaged directly into the APK for testing purposes.
parent b65d3bce
...@@ -307,6 +307,10 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -307,6 +307,10 @@ class FlutterPlugin implements Plugin<Project> {
if (project.hasProperty('precompile')) { if (project.hasProperty('precompile')) {
compilationTraceFilePathValue = project.property('precompile') compilationTraceFilePathValue = project.property('precompile')
} }
Boolean buildHotUpdateValue = false
if (project.hasProperty('hotupdate')) {
buildHotUpdateValue = project.property('hotupdate').toBoolean()
}
String extraFrontEndOptionsValue = null String extraFrontEndOptionsValue = null
if (project.hasProperty('extra-front-end-options')) { if (project.hasProperty('extra-front-end-options')) {
extraFrontEndOptionsValue = project.property('extra-front-end-options') extraFrontEndOptionsValue = project.property('extra-front-end-options')
...@@ -349,6 +353,7 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -349,6 +353,7 @@ class FlutterPlugin implements Plugin<Project> {
fileSystemScheme fileSystemSchemeValue fileSystemScheme fileSystemSchemeValue
trackWidgetCreation trackWidgetCreationValue trackWidgetCreation trackWidgetCreationValue
compilationTraceFilePath compilationTraceFilePathValue compilationTraceFilePath compilationTraceFilePathValue
buildHotUpdate buildHotUpdateValue
buildSharedLibrary buildSharedLibraryValue buildSharedLibrary buildSharedLibraryValue
targetPlatform targetPlatformValue targetPlatform targetPlatformValue
sourceDir project.file(project.flutter.source) sourceDir project.file(project.flutter.source)
...@@ -398,6 +403,8 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -398,6 +403,8 @@ abstract class BaseFlutterTask extends DefaultTask {
@Optional @Input @Optional @Input
String compilationTraceFilePath String compilationTraceFilePath
@Optional @Input @Optional @Input
Boolean buildHotUpdate
@Optional @Input
Boolean buildSharedLibrary Boolean buildSharedLibrary
@Optional @Input @Optional @Input
String targetPlatform String targetPlatform
...@@ -491,6 +498,9 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -491,6 +498,9 @@ abstract class BaseFlutterTask extends DefaultTask {
if (compilationTraceFilePath != null) { if (compilationTraceFilePath != null) {
args "--precompile", compilationTraceFilePath args "--precompile", compilationTraceFilePath
} }
if (buildHotUpdate) {
args "--hotupdate"
}
if (extraFrontEndOptions != null) { if (extraFrontEndOptions != null) {
args "--extra-front-end-options", "${extraFrontEndOptions}" args "--extra-front-end-options", "${extraFrontEndOptions}"
} }
......
...@@ -365,6 +365,8 @@ Future<Null> _buildGradleProjectV2( ...@@ -365,6 +365,8 @@ Future<Null> _buildGradleProjectV2(
command.add('-Ptrack-widget-creation=true'); command.add('-Ptrack-widget-creation=true');
if (buildInfo.compilationTraceFilePath != null) if (buildInfo.compilationTraceFilePath != null)
command.add('-Pprecompile=${buildInfo.compilationTraceFilePath}'); command.add('-Pprecompile=${buildInfo.compilationTraceFilePath}');
if (buildInfo.buildHotUpdate)
command.add('-Photupdate=true');
if (buildInfo.extraFrontEndOptions != null) if (buildInfo.extraFrontEndOptions != null)
command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions}'); command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions}');
if (buildInfo.extraGenSnapshotOptions != null) if (buildInfo.extraGenSnapshotOptions != null)
......
...@@ -338,10 +338,9 @@ class AOTSnapshotter { ...@@ -338,10 +338,9 @@ class AOTSnapshotter {
} }
} }
class CoreJITSnapshotter { class JITSnapshotter {
/// Builds a "Core JIT" VM snapshot of the specified kernel. This snapshot /// Builds a JIT VM snapshot of the specified kernel. This snapshot includes
/// includes data as well as either machine code or DBC, depending on build /// data as well as either machine code or DBC, depending on build configuration.
/// configuration.
Future<int> build({ Future<int> build({
@required TargetPlatform platform, @required TargetPlatform platform,
@required BuildMode buildMode, @required BuildMode buildMode,
...@@ -349,18 +348,28 @@ class CoreJITSnapshotter { ...@@ -349,18 +348,28 @@ class CoreJITSnapshotter {
@required String packagesPath, @required String packagesPath,
@required String outputPath, @required String outputPath,
@required String compilationTraceFilePath, @required String compilationTraceFilePath,
@required bool buildHotUpdate,
List<String> extraGenSnapshotOptions = const <String>[], List<String> extraGenSnapshotOptions = const <String>[],
}) async { }) async {
if (!_isValidCoreJitPlatform(platform)) { if (!_isValidJitPlatform(platform)) {
printError('${getNameForTargetPlatform(platform)} does not support Core JIT compilation.'); printError('${getNameForTargetPlatform(platform)} does not support JIT snapshotting.');
return 1; return 1;
} }
final Directory outputDir = fs.directory(outputPath); final Directory outputDir = fs.directory(outputPath);
outputDir.createSync(recursive: true); outputDir.createSync(recursive: true);
final List<String> inputPaths = <String>[mainPath, compilationTraceFilePath]; final String engineVmSnapshotData = artifacts.getArtifactPath(Artifact.vmSnapshotData);
final Set<String> outputPaths = Set<String>(); final String engineIsolateSnapshotData = artifacts.getArtifactPath(Artifact.isolateSnapshotData);
final String isolateSnapshotData = fs.path.join(outputDir.path, 'isolate_snapshot_data');
final String isolateSnapshotInstructions = fs.path.join(outputDir.path, 'isolate_snapshot_instr');
final List<String> inputPaths = <String>[
mainPath, compilationTraceFilePath, engineVmSnapshotData, engineIsolateSnapshotData,
];
if (buildHotUpdate) {
inputPaths.add(isolateSnapshotInstructions);
}
final String depfilePath = fs.path.join(outputDir.path, 'snapshot.d'); final String depfilePath = fs.path.join(outputDir.path, 'snapshot.d');
final List<String> genSnapshotArgs = <String>[ final List<String> genSnapshotArgs = <String>[
...@@ -376,21 +385,26 @@ class CoreJITSnapshotter { ...@@ -376,21 +385,26 @@ class CoreJITSnapshotter {
genSnapshotArgs.addAll(extraGenSnapshotOptions); genSnapshotArgs.addAll(extraGenSnapshotOptions);
} }
// Blob Core JIT snapshot. final Set<String> outputPaths = Set<String>();
final String vmSnapshotData = fs.path.join(outputDir.path, 'vm_snapshot_data'); outputPaths.addAll(<String>[isolateSnapshotData]);
final String isolateSnapshotData = fs.path.join(outputDir.path, 'isolate_snapshot_data'); if (!buildHotUpdate) {
final String vmSnapshotInstructions = fs.path.join(outputDir.path, 'vm_snapshot_instr'); outputPaths.add(isolateSnapshotInstructions);
final String isolateSnapshotInstructions = fs.path.join(outputDir.path, 'isolate_snapshot_instr'); }
outputPaths.addAll(<String>[vmSnapshotData, isolateSnapshotData, vmSnapshotInstructions, isolateSnapshotInstructions]);
genSnapshotArgs.addAll(<String>[ genSnapshotArgs.addAll(<String>[
'--snapshot_kind=core-jit', '--snapshot_kind=app-jit',
'--vm_snapshot_data=$vmSnapshotData',
'--isolate_snapshot_data=$isolateSnapshotData',
'--vm_snapshot_instructions=$vmSnapshotInstructions',
'--isolate_snapshot_instructions=$isolateSnapshotInstructions',
'--load_compilation_trace=$compilationTraceFilePath', '--load_compilation_trace=$compilationTraceFilePath',
'--load_vm_snapshot_data=$engineVmSnapshotData',
'--load_isolate_snapshot_data=$engineIsolateSnapshotData',
'--isolate_snapshot_data=$isolateSnapshotData',
]); ]);
if (!buildHotUpdate) {
genSnapshotArgs.add('--isolate_snapshot_instructions=$isolateSnapshotInstructions');
} else {
genSnapshotArgs.add('--reused_instructions=$isolateSnapshotInstructions');
}
if (platform == TargetPlatform.android_arm) { if (platform == TargetPlatform.android_arm) {
// Use softfp for Android armv7 devices. // Use softfp for Android armv7 devices.
// TODO(cbracken): eliminate this when we fix https://github.com/flutter/flutter/issues/17489 // TODO(cbracken): eliminate this when we fix https://github.com/flutter/flutter/issues/17489
...@@ -417,12 +431,13 @@ class CoreJITSnapshotter { ...@@ -417,12 +431,13 @@ class CoreJITSnapshotter {
'buildMode': buildMode.toString(), 'buildMode': buildMode.toString(),
'targetPlatform': platform.toString(), 'targetPlatform': platform.toString(),
'entryPoint': mainPath, 'entryPoint': mainPath,
'buildHotUpdate': buildHotUpdate.toString(),
'extraGenSnapshotOptions': extraGenSnapshotOptions.join(' '), 'extraGenSnapshotOptions': extraGenSnapshotOptions.join(' '),
}, },
depfilePaths: <String>[], depfilePaths: <String>[],
); );
if (await fingerprinter.doesFingerprintMatch()) { if (await fingerprinter.doesFingerprintMatch()) {
printTrace('Skipping Core JIT snapshot build. Fingerprint match.'); printTrace('Skipping JIT snapshot build. Fingerprint match.');
return 0; return 0;
} }
...@@ -447,7 +462,7 @@ class CoreJITSnapshotter { ...@@ -447,7 +462,7 @@ class CoreJITSnapshotter {
return 0; return 0;
} }
bool _isValidCoreJitPlatform(TargetPlatform platform) { bool _isValidJitPlatform(TargetPlatform platform) {
return const <TargetPlatform>[ return const <TargetPlatform>[
TargetPlatform.android_arm, TargetPlatform.android_arm,
TargetPlatform.android_arm64, TargetPlatform.android_arm64,
......
...@@ -13,6 +13,7 @@ class BuildInfo { ...@@ -13,6 +13,7 @@ class BuildInfo {
const BuildInfo(this.mode, this.flavor, { const BuildInfo(this.mode, this.flavor, {
this.trackWidgetCreation = false, this.trackWidgetCreation = false,
this.compilationTraceFilePath, this.compilationTraceFilePath,
this.buildHotUpdate,
this.extraFrontEndOptions, this.extraFrontEndOptions,
this.extraGenSnapshotOptions, this.extraGenSnapshotOptions,
this.buildSharedLibrary, this.buildSharedLibrary,
...@@ -42,6 +43,9 @@ class BuildInfo { ...@@ -42,6 +43,9 @@ class BuildInfo {
/// Dart compilation trace file to use for JIT VM snapshot. /// Dart compilation trace file to use for JIT VM snapshot.
final String compilationTraceFilePath; final String compilationTraceFilePath;
/// Build differential snapshot.
final bool buildHotUpdate;
/// Extra command-line options for front-end. /// Extra command-line options for front-end.
final String extraFrontEndOptions; final String extraFrontEndOptions;
...@@ -97,6 +101,7 @@ class BuildInfo { ...@@ -97,6 +101,7 @@ class BuildInfo {
BuildInfo(mode, flavor, BuildInfo(mode, flavor,
trackWidgetCreation: trackWidgetCreation, trackWidgetCreation: trackWidgetCreation,
compilationTraceFilePath: compilationTraceFilePath, compilationTraceFilePath: compilationTraceFilePath,
buildHotUpdate: buildHotUpdate,
extraFrontEndOptions: extraFrontEndOptions, extraFrontEndOptions: extraFrontEndOptions,
extraGenSnapshotOptions: extraGenSnapshotOptions, extraGenSnapshotOptions: extraGenSnapshotOptions,
buildSharedLibrary: buildSharedLibrary, buildSharedLibrary: buildSharedLibrary,
......
...@@ -25,7 +25,6 @@ const String defaultPrivateKeyPath = 'privatekey.der'; ...@@ -25,7 +25,6 @@ const String defaultPrivateKeyPath = 'privatekey.der';
const String _kKernelKey = 'kernel_blob.bin'; const String _kKernelKey = 'kernel_blob.bin';
const String _kVMSnapshotData = 'vm_snapshot_data'; const String _kVMSnapshotData = 'vm_snapshot_data';
const String _kVMSnapshotInstr = 'vm_snapshot_instr';
const String _kIsolateSnapshotData = 'isolate_snapshot_data'; const String _kIsolateSnapshotData = 'isolate_snapshot_data';
const String _kIsolateSnapshotInstr = 'isolate_snapshot_instr'; const String _kIsolateSnapshotInstr = 'isolate_snapshot_instr';
const String _kDylibKey = 'libapp.so'; const String _kDylibKey = 'libapp.so';
...@@ -46,6 +45,7 @@ Future<void> build({ ...@@ -46,6 +45,7 @@ Future<void> build({
bool reportLicensedPackages = false, bool reportLicensedPackages = false,
bool trackWidgetCreation = false, bool trackWidgetCreation = false,
String compilationTraceFilePath, String compilationTraceFilePath,
bool buildHotUpdate = false,
List<String> extraFrontEndOptions = const <String>[], List<String> extraFrontEndOptions = const <String>[],
List<String> extraGenSnapshotOptions = const <String>[], List<String> extraGenSnapshotOptions = const <String>[],
List<String> fileSystemRoots, List<String> fileSystemRoots,
...@@ -85,7 +85,7 @@ Future<void> build({ ...@@ -85,7 +85,7 @@ Future<void> build({
.writeAsString('frontend_server.d: ${artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk)}\n'); .writeAsString('frontend_server.d: ${artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk)}\n');
if (compilationTraceFilePath != null) { if (compilationTraceFilePath != null) {
final CoreJITSnapshotter snapshotter = CoreJITSnapshotter(); final JITSnapshotter snapshotter = JITSnapshotter();
final int snapshotExitCode = await snapshotter.build( final int snapshotExitCode = await snapshotter.build(
platform: platform, platform: platform,
buildMode: buildMode, buildMode: buildMode,
...@@ -94,6 +94,7 @@ Future<void> build({ ...@@ -94,6 +94,7 @@ Future<void> build({
packagesPath: packagesPath, packagesPath: packagesPath,
compilationTraceFilePath: compilationTraceFilePath, compilationTraceFilePath: compilationTraceFilePath,
extraGenSnapshotOptions: extraGenSnapshotOptions, extraGenSnapshotOptions: extraGenSnapshotOptions,
buildHotUpdate: buildHotUpdate,
); );
if (snapshotExitCode != 0) { if (snapshotExitCode != 0) {
throwToolExit('Snapshotting exited with non-zero exit code: $snapshotExitCode'); throwToolExit('Snapshotting exited with non-zero exit code: $snapshotExitCode');
...@@ -160,12 +161,10 @@ Future<void> assemble({ ...@@ -160,12 +161,10 @@ Future<void> assemble({
final Map<String, DevFSContent> assetEntries = Map<String, DevFSContent>.from(assetBundle.entries); final Map<String, DevFSContent> assetEntries = Map<String, DevFSContent>.from(assetBundle.entries);
if (kernelContent != null) { if (kernelContent != null) {
if (compilationTraceFilePath != null) { if (compilationTraceFilePath != null) {
final String vmSnapshotData = fs.path.join(getBuildDirectory(), _kVMSnapshotData); final String vmSnapshotData = artifacts.getArtifactPath(Artifact.vmSnapshotData);
final String vmSnapshotInstr = fs.path.join(getBuildDirectory(), _kVMSnapshotInstr);
final String isolateSnapshotData = fs.path.join(getBuildDirectory(), _kIsolateSnapshotData); final String isolateSnapshotData = fs.path.join(getBuildDirectory(), _kIsolateSnapshotData);
final String isolateSnapshotInstr = fs.path.join(getBuildDirectory(), _kIsolateSnapshotInstr); final String isolateSnapshotInstr = fs.path.join(getBuildDirectory(), _kIsolateSnapshotInstr);
assetEntries[_kVMSnapshotData] = DevFSFileContent(fs.file(vmSnapshotData)); assetEntries[_kVMSnapshotData] = DevFSFileContent(fs.file(vmSnapshotData));
assetEntries[_kVMSnapshotInstr] = DevFSFileContent(fs.file(vmSnapshotInstr));
assetEntries[_kIsolateSnapshotData] = DevFSFileContent(fs.file(isolateSnapshotData)); assetEntries[_kIsolateSnapshotData] = DevFSFileContent(fs.file(isolateSnapshotData));
assetEntries[_kIsolateSnapshotInstr] = DevFSFileContent(fs.file(isolateSnapshotInstr)); assetEntries[_kIsolateSnapshotInstr] = DevFSFileContent(fs.file(isolateSnapshotInstr));
} else { } else {
......
...@@ -40,7 +40,15 @@ class BuildBundleCommand extends BuildSubCommand { ...@@ -40,7 +40,15 @@ class BuildBundleCommand extends BuildSubCommand {
'file produced by the training run of the application. With this\n' 'file produced by the training run of the application. With this\n'
'flag, instead of using default Dart VM snapshot provided by the\n' 'flag, instead of using default Dart VM snapshot provided by the\n'
'engine, the application will use its own snapshot that includes\n' 'engine, the application will use its own snapshot that includes\n'
'additional functions.' 'additional compiled functions.'
)
..addFlag('hotupdate',
hide: !verboseHelp,
help: 'Build differential snapshot based on the last state of the build\n'
'tree and any changes to the application source code since then.\n'
'This flag is only allowed when using --dynamic. With this flag,\n'
'a partial VM snapshot is generated that is loaded on top of the\n'
'original VM snapshot that contains precompiled code.'
) )
..addMultiOption(FlutterOptions.kExtraFrontEndOptions, ..addMultiOption(FlutterOptions.kExtraFrontEndOptions,
splitCommas: true, splitCommas: true,
...@@ -94,6 +102,7 @@ class BuildBundleCommand extends BuildSubCommand { ...@@ -94,6 +102,7 @@ class BuildBundleCommand extends BuildSubCommand {
reportLicensedPackages: argResults['report-licensed-packages'], reportLicensedPackages: argResults['report-licensed-packages'],
trackWidgetCreation: argResults['track-widget-creation'], trackWidgetCreation: argResults['track-widget-creation'],
compilationTraceFilePath: argResults['precompile'], compilationTraceFilePath: argResults['precompile'],
buildHotUpdate: argResults['hotupdate'],
extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions], extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions],
extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions], extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions],
fileSystemScheme: argResults['filesystem-scheme'], fileSystemScheme: argResults['filesystem-scheme'],
......
...@@ -129,6 +129,14 @@ class RunCommand extends RunCommandBase { ...@@ -129,6 +129,14 @@ class RunCommand extends RunCommandBase {
'engine, the application will use its own snapshot that includes\n' 'engine, the application will use its own snapshot that includes\n'
'additional functions.' 'additional functions.'
) )
..addFlag('hotupdate',
hide: !verboseHelp,
help: 'Build differential snapshot based on the last state of the build\n'
'tree and any changes to the application source code since then.\n'
'This flag is only allowed when using --dynamic. With this flag,\n'
'a partial VM snapshot is generated that is loaded on top of the\n'
'original VM snapshot that contains precompiled code.'
)
..addFlag('track-widget-creation', ..addFlag('track-widget-creation',
hide: !verboseHelp, hide: !verboseHelp,
help: 'Track widget creation locations. Requires Dart 2.0 functionality.', help: 'Track widget creation locations. Requires Dart 2.0 functionality.',
......
...@@ -243,6 +243,9 @@ abstract class FlutterCommand extends Command<Null> { ...@@ -243,6 +243,9 @@ abstract class FlutterCommand extends Command<Null> {
compilationTraceFilePath: argParser.options.containsKey('precompile') compilationTraceFilePath: argParser.options.containsKey('precompile')
? argResults['precompile'] ? argResults['precompile']
: null, : null,
buildHotUpdate: argParser.options.containsKey('hotupdate')
? argResults['hotupdate']
: false,
extraFrontEndOptions: argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions) extraFrontEndOptions: argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions)
? argResults[FlutterOptions.kExtraFrontEndOptions] ? argResults[FlutterOptions.kExtraFrontEndOptions]
: null, : null,
...@@ -495,10 +498,15 @@ abstract class FlutterCommand extends Command<Null> { ...@@ -495,10 +498,15 @@ abstract class FlutterCommand extends Command<Null> {
? argResults['dynamic'] : false; ? argResults['dynamic'] : false;
final String compilationTraceFilePath = argParser.options.containsKey('precompile') final String compilationTraceFilePath = argParser.options.containsKey('precompile')
? argResults['precompile'] : null; ? argResults['precompile'] : null;
final bool buildHotUpdate = argParser.options.containsKey('hotupdate')
? argResults['hotupdate'] : false;
if (compilationTraceFilePath != null && getBuildMode() == BuildMode.debug) if (compilationTraceFilePath != null && getBuildMode() == BuildMode.debug)
throw ToolExit('Error: --precompile is not allowed when --debug is specified.'); throw ToolExit('Error: --precompile is not allowed when --debug is specified.');
if (compilationTraceFilePath != null && !dynamicFlag) if (compilationTraceFilePath != null && !dynamicFlag)
throw ToolExit('Error: --precompile is allowed only when --dynamic is specified.'); throw ToolExit('Error: --precompile is allowed only when --dynamic is specified.');
if (buildHotUpdate && compilationTraceFilePath == null)
throw ToolExit('Error: --hotupdate is allowed only when --precompile is specified.');
} }
ApplicationPackageStore applicationPackages; ApplicationPackageStore applicationPackages;
......
...@@ -545,23 +545,29 @@ void main() { ...@@ -545,23 +545,29 @@ void main() {
}); });
group('Snapshotter - Core JIT', () { group('Snapshotter - JIT', () {
const String kTrace = 'trace.txt'; const String kTrace = 'trace.txt';
const String kEngineVmSnapshotData = 'engine_vm_snapshot_data';
const String kEngineIsolateSnapshotData = 'engine_isolate_snapshot_data';
_FakeGenSnapshot genSnapshot; _FakeGenSnapshot genSnapshot;
MemoryFileSystem fs; MemoryFileSystem fs;
CoreJITSnapshotter snapshotter; JITSnapshotter snapshotter;
MockAndroidSdk mockAndroidSdk; MockAndroidSdk mockAndroidSdk;
MockArtifacts mockArtifacts; MockArtifacts mockArtifacts;
setUp(() async { setUp(() async {
fs = MemoryFileSystem(); fs = MemoryFileSystem();
fs.file(kTrace).createSync(); fs.file(kTrace).createSync();
fs.file(kEngineVmSnapshotData).createSync();
fs.file(kEngineIsolateSnapshotData).createSync();
genSnapshot = _FakeGenSnapshot(); genSnapshot = _FakeGenSnapshot();
snapshotter = CoreJITSnapshotter(); snapshotter = JITSnapshotter();
mockAndroidSdk = MockAndroidSdk(); mockAndroidSdk = MockAndroidSdk();
mockArtifacts = MockArtifacts(); mockArtifacts = MockArtifacts();
when(mockArtifacts.getArtifactPath(Artifact.vmSnapshotData)).thenReturn(kEngineVmSnapshotData);
when(mockArtifacts.getArtifactPath(Artifact.isolateSnapshotData)).thenReturn(kEngineIsolateSnapshotData);
}); });
final Map<Type, Generator> contextOverrides = <Type, Generator>{ final Map<Type, Generator> contextOverrides = <Type, Generator>{
...@@ -571,7 +577,7 @@ void main() { ...@@ -571,7 +577,7 @@ void main() {
GenSnapshot: () => genSnapshot, GenSnapshot: () => genSnapshot,
}; };
testUsingContext('iOS debug Core JIT snapshot is invalid', () async { testUsingContext('iOS debug JIT snapshot is invalid', () async {
final String outputPath = fs.path.join('build', 'foo'); final String outputPath = fs.path.join('build', 'foo');
expect(await snapshotter.build( expect(await snapshotter.build(
platform: TargetPlatform.ios, platform: TargetPlatform.ios,
...@@ -580,19 +586,18 @@ void main() { ...@@ -580,19 +586,18 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
outputPath: outputPath, outputPath: outputPath,
compilationTraceFilePath: kTrace, compilationTraceFilePath: kTrace,
buildHotUpdate: false,
), isNot(equals(0))); ), isNot(equals(0)));
}, overrides: contextOverrides); }, overrides: contextOverrides);
testUsingContext('builds Android arm debug Core JIT snapshot', () async { testUsingContext('builds Android arm debug JIT snapshot', () async {
fs.file('main.dill').writeAsStringSync('binary magic'); fs.file('main.dill').writeAsStringSync('binary magic');
final String outputPath = fs.path.join('build', 'foo'); final String outputPath = fs.path.join('build', 'foo');
fs.directory(outputPath).createSync(recursive: true); fs.directory(outputPath).createSync(recursive: true);
genSnapshot.outputs = <String, String>{ genSnapshot.outputs = <String, String>{
fs.path.join(outputPath, 'vm_snapshot_data'): '',
fs.path.join(outputPath, 'isolate_snapshot_data'): '', fs.path.join(outputPath, 'isolate_snapshot_data'): '',
fs.path.join(outputPath, 'vm_snapshot_instr'): '',
fs.path.join(outputPath, 'isolate_snapshot_instr'): '', fs.path.join(outputPath, 'isolate_snapshot_instr'): '',
fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ', fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ',
}; };
...@@ -604,6 +609,7 @@ void main() { ...@@ -604,6 +609,7 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
outputPath: outputPath, outputPath: outputPath,
compilationTraceFilePath: kTrace, compilationTraceFilePath: kTrace,
buildHotUpdate: false,
); );
expect(genSnapshotExitCode, 0); expect(genSnapshotExitCode, 0);
...@@ -616,28 +622,26 @@ void main() { ...@@ -616,28 +622,26 @@ void main() {
'--strong', '--strong',
'--sync-async', '--sync-async',
'--enable_asserts', '--enable_asserts',
'--snapshot_kind=core-jit', '--snapshot_kind=app-jit',
'--vm_snapshot_data=build/foo/vm_snapshot_data', '--load_compilation_trace=$kTrace',
'--load_vm_snapshot_data=$kEngineVmSnapshotData',
'--load_isolate_snapshot_data=$kEngineIsolateSnapshotData',
'--isolate_snapshot_data=build/foo/isolate_snapshot_data', '--isolate_snapshot_data=build/foo/isolate_snapshot_data',
'--vm_snapshot_instructions=build/foo/vm_snapshot_instr',
'--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr', '--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr',
'--load_compilation_trace=trace.txt',
'--no-sim-use-hardfp', '--no-sim-use-hardfp',
'--no-use-integer-division', '--no-use-integer-division',
'main.dill', 'main.dill',
]); ]);
}, overrides: contextOverrides); }, overrides: contextOverrides);
testUsingContext('builds Android arm64 debug Core JIT snapshot', () async { testUsingContext('builds Android arm64 debug JIT snapshot', () async {
fs.file('main.dill').writeAsStringSync('binary magic'); fs.file('main.dill').writeAsStringSync('binary magic');
final String outputPath = fs.path.join('build', 'foo'); final String outputPath = fs.path.join('build', 'foo');
fs.directory(outputPath).createSync(recursive: true); fs.directory(outputPath).createSync(recursive: true);
genSnapshot.outputs = <String, String>{ genSnapshot.outputs = <String, String>{
fs.path.join(outputPath, 'vm_snapshot_data'): '',
fs.path.join(outputPath, 'isolate_snapshot_data'): '', fs.path.join(outputPath, 'isolate_snapshot_data'): '',
fs.path.join(outputPath, 'vm_snapshot_instr'): '',
fs.path.join(outputPath, 'isolate_snapshot_instr'): '', fs.path.join(outputPath, 'isolate_snapshot_instr'): '',
fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ', fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ',
}; };
...@@ -649,6 +653,7 @@ void main() { ...@@ -649,6 +653,7 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
outputPath: outputPath, outputPath: outputPath,
compilationTraceFilePath: kTrace, compilationTraceFilePath: kTrace,
buildHotUpdate: false,
); );
expect(genSnapshotExitCode, 0); expect(genSnapshotExitCode, 0);
...@@ -661,17 +666,17 @@ void main() { ...@@ -661,17 +666,17 @@ void main() {
'--strong', '--strong',
'--sync-async', '--sync-async',
'--enable_asserts', '--enable_asserts',
'--snapshot_kind=core-jit', '--snapshot_kind=app-jit',
'--vm_snapshot_data=build/foo/vm_snapshot_data', '--load_compilation_trace=$kTrace',
'--load_vm_snapshot_data=$kEngineVmSnapshotData',
'--load_isolate_snapshot_data=$kEngineIsolateSnapshotData',
'--isolate_snapshot_data=build/foo/isolate_snapshot_data', '--isolate_snapshot_data=build/foo/isolate_snapshot_data',
'--vm_snapshot_instructions=build/foo/vm_snapshot_instr',
'--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr', '--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr',
'--load_compilation_trace=trace.txt',
'main.dill', 'main.dill',
]); ]);
}, overrides: contextOverrides); }, overrides: contextOverrides);
testUsingContext('iOS release Core JIT snapshot is invalid', () async { testUsingContext('iOS release JIT snapshot is invalid', () async {
final String outputPath = fs.path.join('build', 'foo'); final String outputPath = fs.path.join('build', 'foo');
expect(await snapshotter.build( expect(await snapshotter.build(
platform: TargetPlatform.ios, platform: TargetPlatform.ios,
...@@ -680,19 +685,18 @@ void main() { ...@@ -680,19 +685,18 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
outputPath: outputPath, outputPath: outputPath,
compilationTraceFilePath: kTrace, compilationTraceFilePath: kTrace,
buildHotUpdate: false,
), isNot(equals(0))); ), isNot(equals(0)));
}, overrides: contextOverrides); }, overrides: contextOverrides);
testUsingContext('builds Android arm profile Core JIT snapshot', () async { testUsingContext('builds Android arm profile JIT snapshot', () async {
fs.file('main.dill').writeAsStringSync('binary magic'); fs.file('main.dill').writeAsStringSync('binary magic');
final String outputPath = fs.path.join('build', 'foo'); final String outputPath = fs.path.join('build', 'foo');
fs.directory(outputPath).createSync(recursive: true); fs.directory(outputPath).createSync(recursive: true);
genSnapshot.outputs = <String, String>{ genSnapshot.outputs = <String, String>{
fs.path.join(outputPath, 'vm_snapshot_data'): '',
fs.path.join(outputPath, 'isolate_snapshot_data'): '', fs.path.join(outputPath, 'isolate_snapshot_data'): '',
fs.path.join(outputPath, 'vm_snapshot_instr'): '',
fs.path.join(outputPath, 'isolate_snapshot_instr'): '', fs.path.join(outputPath, 'isolate_snapshot_instr'): '',
fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ', fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ',
}; };
...@@ -704,6 +708,7 @@ void main() { ...@@ -704,6 +708,7 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
outputPath: outputPath, outputPath: outputPath,
compilationTraceFilePath: kTrace, compilationTraceFilePath: kTrace,
buildHotUpdate: false,
); );
expect(genSnapshotExitCode, 0); expect(genSnapshotExitCode, 0);
...@@ -715,28 +720,26 @@ void main() { ...@@ -715,28 +720,26 @@ void main() {
'--reify-generic-functions', '--reify-generic-functions',
'--strong', '--strong',
'--sync-async', '--sync-async',
'--snapshot_kind=core-jit', '--snapshot_kind=app-jit',
'--vm_snapshot_data=build/foo/vm_snapshot_data', '--load_compilation_trace=$kTrace',
'--load_vm_snapshot_data=$kEngineVmSnapshotData',
'--load_isolate_snapshot_data=$kEngineIsolateSnapshotData',
'--isolate_snapshot_data=build/foo/isolate_snapshot_data', '--isolate_snapshot_data=build/foo/isolate_snapshot_data',
'--vm_snapshot_instructions=build/foo/vm_snapshot_instr',
'--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr', '--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr',
'--load_compilation_trace=trace.txt',
'--no-sim-use-hardfp', '--no-sim-use-hardfp',
'--no-use-integer-division', '--no-use-integer-division',
'main.dill', 'main.dill',
]); ]);
}, overrides: contextOverrides); }, overrides: contextOverrides);
testUsingContext('builds Android arm64 profile Core JIT snapshot', () async { testUsingContext('builds Android arm64 profile JIT snapshot', () async {
fs.file('main.dill').writeAsStringSync('binary magic'); fs.file('main.dill').writeAsStringSync('binary magic');
final String outputPath = fs.path.join('build', 'foo'); final String outputPath = fs.path.join('build', 'foo');
fs.directory(outputPath).createSync(recursive: true); fs.directory(outputPath).createSync(recursive: true);
genSnapshot.outputs = <String, String>{ genSnapshot.outputs = <String, String>{
fs.path.join(outputPath, 'vm_snapshot_data'): '',
fs.path.join(outputPath, 'isolate_snapshot_data'): '', fs.path.join(outputPath, 'isolate_snapshot_data'): '',
fs.path.join(outputPath, 'vm_snapshot_instr'): '',
fs.path.join(outputPath, 'isolate_snapshot_instr'): '', fs.path.join(outputPath, 'isolate_snapshot_instr'): '',
fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ', fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ',
}; };
...@@ -748,6 +751,7 @@ void main() { ...@@ -748,6 +751,7 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
outputPath: outputPath, outputPath: outputPath,
compilationTraceFilePath: kTrace, compilationTraceFilePath: kTrace,
buildHotUpdate: false,
); );
expect(genSnapshotExitCode, 0); expect(genSnapshotExitCode, 0);
...@@ -759,17 +763,17 @@ void main() { ...@@ -759,17 +763,17 @@ void main() {
'--reify-generic-functions', '--reify-generic-functions',
'--strong', '--strong',
'--sync-async', '--sync-async',
'--snapshot_kind=core-jit', '--snapshot_kind=app-jit',
'--vm_snapshot_data=build/foo/vm_snapshot_data', '--load_compilation_trace=$kTrace',
'--load_vm_snapshot_data=$kEngineVmSnapshotData',
'--load_isolate_snapshot_data=$kEngineIsolateSnapshotData',
'--isolate_snapshot_data=build/foo/isolate_snapshot_data', '--isolate_snapshot_data=build/foo/isolate_snapshot_data',
'--vm_snapshot_instructions=build/foo/vm_snapshot_instr',
'--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr', '--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr',
'--load_compilation_trace=trace.txt',
'main.dill', 'main.dill',
]); ]);
}, overrides: contextOverrides); }, overrides: contextOverrides);
testUsingContext('iOS release Core JIT snapshot is invalid', () async { testUsingContext('iOS release JIT snapshot is invalid', () async {
final String outputPath = fs.path.join('build', 'foo'); final String outputPath = fs.path.join('build', 'foo');
expect(await snapshotter.build( expect(await snapshotter.build(
platform: TargetPlatform.ios, platform: TargetPlatform.ios,
...@@ -778,19 +782,18 @@ void main() { ...@@ -778,19 +782,18 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
outputPath: outputPath, outputPath: outputPath,
compilationTraceFilePath: kTrace, compilationTraceFilePath: kTrace,
buildHotUpdate: false,
), isNot(equals(0))); ), isNot(equals(0)));
}, overrides: contextOverrides); }, overrides: contextOverrides);
testUsingContext('builds Android arm release Core JIT snapshot', () async { testUsingContext('builds Android arm release JIT snapshot', () async {
fs.file('main.dill').writeAsStringSync('binary magic'); fs.file('main.dill').writeAsStringSync('binary magic');
final String outputPath = fs.path.join('build', 'foo'); final String outputPath = fs.path.join('build', 'foo');
fs.directory(outputPath).createSync(recursive: true); fs.directory(outputPath).createSync(recursive: true);
genSnapshot.outputs = <String, String>{ genSnapshot.outputs = <String, String>{
fs.path.join(outputPath, 'vm_snapshot_data'): '',
fs.path.join(outputPath, 'isolate_snapshot_data'): '', fs.path.join(outputPath, 'isolate_snapshot_data'): '',
fs.path.join(outputPath, 'vm_snapshot_instr'): '',
fs.path.join(outputPath, 'isolate_snapshot_instr'): '', fs.path.join(outputPath, 'isolate_snapshot_instr'): '',
fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ', fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ',
}; };
...@@ -802,6 +805,7 @@ void main() { ...@@ -802,6 +805,7 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
outputPath: outputPath, outputPath: outputPath,
compilationTraceFilePath: kTrace, compilationTraceFilePath: kTrace,
buildHotUpdate: false,
); );
expect(genSnapshotExitCode, 0); expect(genSnapshotExitCode, 0);
...@@ -813,28 +817,26 @@ void main() { ...@@ -813,28 +817,26 @@ void main() {
'--reify-generic-functions', '--reify-generic-functions',
'--strong', '--strong',
'--sync-async', '--sync-async',
'--snapshot_kind=core-jit', '--snapshot_kind=app-jit',
'--vm_snapshot_data=build/foo/vm_snapshot_data', '--load_compilation_trace=$kTrace',
'--load_vm_snapshot_data=$kEngineVmSnapshotData',
'--load_isolate_snapshot_data=$kEngineIsolateSnapshotData',
'--isolate_snapshot_data=build/foo/isolate_snapshot_data', '--isolate_snapshot_data=build/foo/isolate_snapshot_data',
'--vm_snapshot_instructions=build/foo/vm_snapshot_instr',
'--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr', '--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr',
'--load_compilation_trace=trace.txt',
'--no-sim-use-hardfp', '--no-sim-use-hardfp',
'--no-use-integer-division', '--no-use-integer-division',
'main.dill', 'main.dill',
]); ]);
}, overrides: contextOverrides); }, overrides: contextOverrides);
testUsingContext('builds Android arm64 release Core JIT snapshot', () async { testUsingContext('builds Android arm64 release JIT snapshot', () async {
fs.file('main.dill').writeAsStringSync('binary magic'); fs.file('main.dill').writeAsStringSync('binary magic');
final String outputPath = fs.path.join('build', 'foo'); final String outputPath = fs.path.join('build', 'foo');
fs.directory(outputPath).createSync(recursive: true); fs.directory(outputPath).createSync(recursive: true);
genSnapshot.outputs = <String, String>{ genSnapshot.outputs = <String, String>{
fs.path.join(outputPath, 'vm_snapshot_data'): '',
fs.path.join(outputPath, 'isolate_snapshot_data'): '', fs.path.join(outputPath, 'isolate_snapshot_data'): '',
fs.path.join(outputPath, 'vm_snapshot_instr'): '',
fs.path.join(outputPath, 'isolate_snapshot_instr'): '', fs.path.join(outputPath, 'isolate_snapshot_instr'): '',
fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ', fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ',
}; };
...@@ -846,6 +848,7 @@ void main() { ...@@ -846,6 +848,7 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
outputPath: outputPath, outputPath: outputPath,
compilationTraceFilePath: kTrace, compilationTraceFilePath: kTrace,
buildHotUpdate: false,
); );
expect(genSnapshotExitCode, 0); expect(genSnapshotExitCode, 0);
...@@ -857,12 +860,55 @@ void main() { ...@@ -857,12 +860,55 @@ void main() {
'--reify-generic-functions', '--reify-generic-functions',
'--strong', '--strong',
'--sync-async', '--sync-async',
'--snapshot_kind=core-jit', '--snapshot_kind=app-jit',
'--vm_snapshot_data=build/foo/vm_snapshot_data', '--load_compilation_trace=$kTrace',
'--load_vm_snapshot_data=$kEngineVmSnapshotData',
'--load_isolate_snapshot_data=$kEngineIsolateSnapshotData',
'--isolate_snapshot_data=build/foo/isolate_snapshot_data', '--isolate_snapshot_data=build/foo/isolate_snapshot_data',
'--vm_snapshot_instructions=build/foo/vm_snapshot_instr',
'--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr', '--isolate_snapshot_instructions=build/foo/isolate_snapshot_instr',
'--load_compilation_trace=trace.txt', 'main.dill',
]);
}, overrides: contextOverrides);
testUsingContext('builds Android arm release JIT snapshot for hot update', () async {
fs.file('main.dill').writeAsStringSync('binary magic');
final String outputPath = fs.path.join('build', 'foo');
fs.directory(outputPath).createSync(recursive: true);
fs.file(fs.path.join(outputPath, 'isolate_snapshot_instr')).createSync();
genSnapshot.outputs = <String, String>{
fs.path.join(outputPath, 'isolate_snapshot_data'): '',
fs.path.join(outputPath, 'snapshot.d'): '${fs.path.join(outputPath, 'vm_snapshot_data')} : ',
};
final int genSnapshotExitCode = await snapshotter.build(
platform: TargetPlatform.android_arm,
buildMode: BuildMode.release,
mainPath: 'main.dill',
packagesPath: '.packages',
outputPath: outputPath,
compilationTraceFilePath: kTrace,
buildHotUpdate: true,
);
expect(genSnapshotExitCode, 0);
expect(genSnapshot.callCount, 1);
expect(genSnapshot.snapshotType.platform, TargetPlatform.android_arm);
expect(genSnapshot.snapshotType.mode, BuildMode.release);
expect(genSnapshot.packagesPath, '.packages');
expect(genSnapshot.additionalArgs, <String>[
'--reify-generic-functions',
'--strong',
'--sync-async',
'--snapshot_kind=app-jit',
'--load_compilation_trace=$kTrace',
'--load_vm_snapshot_data=$kEngineVmSnapshotData',
'--load_isolate_snapshot_data=$kEngineIsolateSnapshotData',
'--isolate_snapshot_data=build/foo/isolate_snapshot_data',
'--reused_instructions=build/foo/isolate_snapshot_instr',
'--no-sim-use-hardfp',
'--no-use-integer-division',
'main.dill', 'main.dill',
]); ]);
}, overrides: contextOverrides); }, overrides: contextOverrides);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment