From 9ae893bd456c76dbc5e996d326cd286ecb2baf72 Mon Sep 17 00:00:00 2001 From: Alexander Aprelev Date: Fri, 10 Nov 2017 10:09:37 -0800 Subject: [PATCH] Use IKG for restarts, use IKG with ProtectedFileByteStore. (#12953) * Use IKG for restarts, use IKG with ProtectedFileByteStore. * Fix comment, add end of file newline. * Remove unused import --- packages/flutter_tools/lib/src/build_info.dart | 6 ++++++ packages/flutter_tools/lib/src/compile.dart | 10 +++++++++- packages/flutter_tools/lib/src/devfs.dart | 16 +++++----------- packages/flutter_tools/lib/src/flx.dart | 1 + packages/flutter_tools/lib/src/run_hot.dart | 15 +++++++++++++-- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart index 672c43bc56d..345455216f5 100644 --- a/packages/flutter_tools/lib/src/build_info.dart +++ b/packages/flutter_tools/lib/src/build_info.dart @@ -205,3 +205,9 @@ String getAssetBuildDirectory() { String getIosBuildDirectory() { return fs.path.join(getBuildDirectory(), 'ios'); } + +/// Returns directory used by incremental compiler (IKG - incremental kernel +/// generator) to store cached intermediate state. +String getIncrementalCompilerByteStoreDirectory() { + return fs.path.join(getBuildDirectory(), 'ikg_byte_store'); +} diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart index d2b6607b51e..c105c7013a1 100644 --- a/packages/flutter_tools/lib/src/compile.dart +++ b/packages/flutter_tools/lib/src/compile.dart @@ -60,7 +60,8 @@ Future compile( {String sdkRoot, String mainPath, bool linkPlatformKernelIn : false, - List extraFrontEndOptions}) async { + List extraFrontEndOptions, + String incrementalCompilerByteStorePath}) async { final String frontendServer = artifacts.getArtifactPath( Artifact.frontendServerSnapshotForEngineDartSdk ); @@ -76,6 +77,13 @@ Future compile( ]; if (!linkPlatformKernelIn) command.add('--no-link-platform'); + if (incrementalCompilerByteStorePath != null) { + command.addAll([ + '--incremental', + '--byte-store', + incrementalCompilerByteStorePath]); + fs.directory(incrementalCompilerByteStorePath).createSync(recursive: true); + } if (extraFrontEndOptions != null) command.addAll(extraFrontEndOptions); command.add(mainPath); diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart index f94de198d23..96711f61ff2 100644 --- a/packages/flutter_tools/lib/src/devfs.dart +++ b/packages/flutter_tools/lib/src/devfs.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'dart:convert' show BASE64, UTF8; -import 'package:flutter_tools/src/artifacts.dart'; import 'package:json_rpc_2/json_rpc_2.dart' as rpc; import 'asset.dart'; @@ -446,11 +445,6 @@ class DevFS { // that isModified does not reset last check timestamp because we // want to report all modified files to incremental compiler next time // user does hot reload. - // TODO(aam): Remove this logic once we switch to using incremental - // compiler for full application compilation when doing full restart. - if (fullRestart && generator != null && content is DevFSFileContent) { - content = DevFSFileContent.clone(content); - } if (content.isModified || (bundleDirty && archivePath != null)) { dirtyEntries[deviceUri] = content; numBytes += content.size; @@ -480,11 +474,11 @@ class DevFS { // host and result of compilation is single kernel file. filesUris.forEach(dirtyEntries.remove); printTrace('Compiling dart to kernel with ${invalidatedFiles.length} updated files'); - final String compiledBinary = fullRestart - ? await compile( - sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath), - mainPath: mainPath) - : await generator.recompile(mainPath, invalidatedFiles); + if (fullRestart) { + generator.reset(); + } + final String compiledBinary = + await generator.recompile(mainPath, invalidatedFiles); if (compiledBinary != null && compiledBinary.isNotEmpty) dirtyEntries.putIfAbsent( Uri.parse(target + '.dill'), diff --git a/packages/flutter_tools/lib/src/flx.dart b/packages/flutter_tools/lib/src/flx.dart index f51ff1ea8aa..c42fa425ce7 100644 --- a/packages/flutter_tools/lib/src/flx.dart +++ b/packages/flutter_tools/lib/src/flx.dart @@ -71,6 +71,7 @@ Future build({ if (!precompiledSnapshot && previewDart2) { final String kernelBinaryFilename = await compile( sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath), + incrementalCompilerByteStorePath: fs.path.absolute(getIncrementalCompilerByteStoreDirectory()), mainPath: fs.file(mainPath).absolute.path ); kernelContent = new DevFSFileContent(fs.file(kernelBinaryFilename)); diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 0876a791450..79b93a7df20 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -353,9 +353,20 @@ class HotRunner extends ResidentRunner { // TODO(aam): Add generator reset logic once we switch to using incremental // compiler for full application recompilation on restart. final bool updatedDevFS = await _updateDevFS(fullRestart: true); - _resetDirtyAssets(); - if (!updatedDevFS) + if (!updatedDevFS) { + for (FlutterDevice device in flutterDevices) { + if (device.generator != null) + device.generator.reject(); + } return new OperationResult(1, 'DevFS synchronization failed'); + } + _resetDirtyAssets(); + for (FlutterDevice device in flutterDevices) { + // VM must have accepted the kernel binary, there will be no reload + // report, so we let incremental compiler know that source code was accepted. + if (device.generator != null) + device.generator.accept(); + } // Check if the isolate is paused and resume it. for (FlutterDevice device in flutterDevices) { for (FlutterView view in device.views) {