Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(690)

Side by Side Diff: utils/kernel-service/kernel-service.dart

Issue 2993013002: Introduce IKG into kernel-service to support incremental compilation. (Closed)
Patch Set: Add comment regarding always using incremental compiler. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/unit_test.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// This is an interface to the Dart Kernel parser and Kernel binary generator. 5 /// This is an interface to the Dart Kernel parser and Kernel binary generator.
6 /// 6 ///
7 /// It is used by the kernel-isolate to load Dart source code and generate 7 /// It is used by the kernel-isolate to load Dart source code and generate
8 /// Kernel binary format. 8 /// Kernel binary format.
9 /// 9 ///
10 /// This is either invoked as the root script of the Kernel isolate when used 10 /// This is either invoked as the root script of the Kernel isolate when used
11 /// as a part of 11 /// as a part of
12 /// 12 ///
13 /// dart --dfe=utils/kernel-service/kernel-service.dart ... 13 /// dart --dfe=utils/kernel-service/kernel-service.dart ...
14 /// 14 ///
15 /// invocation or it is invoked as a standalone script to perform training for 15 /// invocation or it is invoked as a standalone script to perform training for
16 /// the app-jit snapshot 16 /// the app-jit snapshot
17 /// 17 ///
18 /// dart utils/kernel-service/kernel-service.dart --train <source-file> 18 /// dart utils/kernel-service/kernel-service.dart --train <source-file>
19 /// 19 ///
20 /// 20 ///
21 library runtime.tools.kernel_service; 21 library runtime.tools.kernel_service;
22 22
23 import 'dart:async' show Future; 23 import 'dart:async' show Future;
24 import 'dart:convert' show JSON;
24 import 'dart:io' show Platform hide FileSystemEntity; 25 import 'dart:io' show Platform hide FileSystemEntity;
25 import 'dart:isolate'; 26 import 'dart:isolate';
26 import 'dart:typed_data' show Uint8List; 27 import 'dart:typed_data' show Uint8List;
27 28
28 import 'package:front_end/file_system.dart'; 29 import 'package:front_end/file_system.dart';
29 import 'package:front_end/front_end.dart'; 30 import 'package:front_end/front_end.dart';
31 import 'package:front_end/incremental_kernel_generator.dart';
30 import 'package:front_end/memory_file_system.dart'; 32 import 'package:front_end/memory_file_system.dart';
31 import 'package:front_end/physical_file_system.dart'; 33 import 'package:front_end/physical_file_system.dart';
32 import 'package:front_end/src/fasta/kernel/utils.dart'; 34 import 'package:front_end/src/fasta/kernel/utils.dart';
33 import 'package:front_end/src/testing/hybrid_file_system.dart'; 35 import 'package:front_end/src/testing/hybrid_file_system.dart';
34 import 'package:kernel/kernel.dart' show Program; 36 import 'package:kernel/kernel.dart' show Program;
35 import 'package:kernel/target/targets.dart' show TargetFlags; 37 import 'package:kernel/target/targets.dart' show TargetFlags;
36 import 'package:kernel/target/vm_fasta.dart' show VmFastaTarget; 38 import 'package:kernel/target/vm_fasta.dart' show VmFastaTarget;
37 39
38 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE'); 40 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE');
39 const bool strongMode = const bool.fromEnvironment('DFE_STRONG_MODE'); 41 const bool strongMode = const bool.fromEnvironment('DFE_STRONG_MODE');
40 42
43 abstract class Compiler {
44 final FileSystem fileSystem;
45 final List<String> errors = new List<String>();
46
47 CompilerOptions options;
48
49 Compiler(this.fileSystem) {
50 Uri packagesUri = (Platform.packageConfig != null)
51 ? Uri.parse(Platform.packageConfig)
52 : null;
53
54 Uri sdkSummary = Uri.base
55 .resolveUri(new Uri.file(Platform.resolvedExecutable))
56 .resolveUri(new Uri.directory("patched_sdk"))
57 // TODO(sigmund): use outline.dill when the mixin transformer is
58 // modular.
59 .resolve('platform.dill');
60
61 if (verbose) {
62 print("DFE: Platform.packageConfig: ${Platform.packageConfig}");
63 print("DFE: packagesUri: ${packagesUri}");
64 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}");
65 print("DFE: sdkSummary: ${sdkSummary}");
66 }
67
68 options = new CompilerOptions()
69 ..strongMode = strongMode
70 ..fileSystem = fileSystem
71 ..target = new VmFastaTarget(new TargetFlags(strongMode: strongMode))
72 ..packagesFileUri = packagesUri
73 ..sdkSummary = sdkSummary
74 ..verbose = verbose
75 ..throwOnErrors = false
76 ..reportMessages = true
77 ..onError = (CompilationMessage e) {
78 if (e.severity == Severity.error) {
79 // TODO(sigmund): support emitting code with errors as long as they
80 // are handled in the generated code (issue #30194).
81 errors.add(e.message);
82 }
83 };
84 }
85
86 Future<Program> compile(Uri script);
87 }
88
89 class IncrementalCompiler extends Compiler {
90 IncrementalKernelGenerator generator;
91
92 IncrementalCompiler(FileSystem fileSystem) : super(fileSystem);
93
94 @override
95 Future<Program> compile(Uri script) async {
96 if (generator == null) {
97 generator = await IncrementalKernelGenerator.newInstance(options, script);
98 }
99 DeltaProgram deltaProgram = await generator.computeDelta();
100 return deltaProgram.newProgram;
101 }
102
103 void invalidate(Uri uri) {
104 generator.invalidate(uri);
105 }
106 }
107
108 class SingleShotCompiler extends Compiler {
109 final bool requireMain;
110
111 SingleShotCompiler(FileSystem fileSystem, this.requireMain)
112 : super(fileSystem);
113
114 @override
115 Future<Program> compile(Uri script) async {
116 return requireMain
117 ? kernelForProgram(script, options)
118 : kernelForBuildUnit([script], options..chaseDependencies = true);
119 }
120 }
121
122 final Map<int, Compiler> isolateCompilers = new Map<int, Compiler>();
123
124 Future<Compiler> lookupOrBuildNewIncrementalCompiler(
125 int isolateId, List sourceFiles) async {
126 IncrementalCompiler compiler;
127 if (isolateCompilers.containsKey(isolateId)) {
128 compiler = isolateCompilers[isolateId];
129 final HybridFileSystem fileSystem = compiler.fileSystem;
130 if (sourceFiles != null) {
131 for (int i = 0; i < sourceFiles.length ~/ 2; i++) {
132 Uri uri = Uri.parse(sourceFiles[i * 2]);
133 fileSystem.memory
134 .entityForUri(uri)
135 .writeAsBytesSync(sourceFiles[i * 2 + 1]);
136 compiler.invalidate(uri);
137 }
138 }
139 } else {
140 final FileSystem fileSystem = sourceFiles == null
141 ? PhysicalFileSystem.instance
142 : _buildFileSystem(sourceFiles);
143
144 // TODO(aam): IncrementalCompiler instance created below have to be
145 // destroyed when corresponding isolate is shut down. To achieve that kernel
146 // isolate needs to receive a message indicating that particular
147 // isolate was shut down. Message should be handled here in this script.
148 compiler = new IncrementalCompiler(fs, librariesUri, librariesJson);
Siggi Cherem (dart-lang) 2017/08/09 15:57:58 delete this line?
aam 2017/08/09 16:17:04 Oops, done. Thanks!
149 compiler = new IncrementalCompiler(fileSystem);
150 isolateCompilers[isolateId] = compiler;
151 }
152 return compiler;
153 }
154
41 // Process a request from the runtime. See KernelIsolate::CompileToKernel in 155 // Process a request from the runtime. See KernelIsolate::CompileToKernel in
42 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc. 156 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc.
43 Future _processLoadRequest(request) async { 157 Future _processLoadRequest(request) async {
44 if (verbose) print("DFE: request: $request"); 158 if (verbose) print("DFE: request: $request");
45 159
46 int tag = request[0]; 160 int tag = request[0];
47 final SendPort port = request[1]; 161 final SendPort port = request[1];
48 final String inputFileUri = request[2]; 162 final String inputFileUri = request[2];
49 final Uri script = Uri.base.resolve(inputFileUri); 163 final Uri script = Uri.base.resolve(inputFileUri);
164 final bool incremental = request[3];
50 165
51 FileSystem fileSystem = PhysicalFileSystem.instance; 166 final List sourceFiles = request.length > 5 ? request[5] : null;
52 bool requireMain = true;
53 167
54 if (request.length > 3) { 168 Compiler compiler;
55 fileSystem = _buildFileSystem(request[3]); 169 // TODO(aam): There should be no need to have an option to choose
56 requireMain = false; 170 // one compiler or another. We should always use an incremental
171 // compiler as its functionality is a super set of the other one. We need to
172 // watch the performance though.
173 if (incremental) {
174 final int isolateId = request[4];
175 compiler =
176 await lookupOrBuildNewIncrementalCompiler(isolateId, sourceFiles);
177 } else {
178 final FileSystem fileSystem = sourceFiles == null
179 ? PhysicalFileSystem.instance
180 : _buildFileSystem(sourceFiles);
181 compiler = new SingleShotCompiler(
182 fileSystem, sourceFiles == null /* requireMain */);
57 } 183 }
58 184
59 Uri packagesUri = (Platform.packageConfig != null)
60 ? Uri.parse(Platform.packageConfig)
61 : null;
62
63 Uri sdkSummary = Uri.base
64 .resolveUri(new Uri.file(Platform.resolvedExecutable))
65 .resolveUri(new Uri.directory("patched_sdk"))
66 // TODO(sigmund): use outline.dill when the mixin transformer is modular.
67 .resolve('platform.dill');
68
69 if (verbose) {
70 print("DFE: scriptUri: ${script}");
71 print("DFE: Platform.packageConfig: ${Platform.packageConfig}");
72 print("DFE: packagesUri: ${packagesUri}");
73 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}");
74 print("DFE: sdkSummary: ${sdkSummary}");
75 }
76
77 var errors = <String>[];
78 var options = new CompilerOptions()
79 ..strongMode = strongMode
80 ..fileSystem = fileSystem
81 ..target = new VmFastaTarget(new TargetFlags(strongMode: strongMode))
82 ..packagesFileUri = packagesUri
83 ..sdkSummary = sdkSummary
84 ..verbose = verbose
85 ..throwOnErrors = false
86 ..reportMessages = true
87 ..onError = (CompilationMessage e) {
88 if (e.severity == Severity.error) {
89 // TODO(sigmund): support emitting code with errors as long as they are
90 // handled in the generated code (issue #30194).
91 errors.add(e.message);
92 }
93 };
94
95 CompilationResult result; 185 CompilationResult result;
96 try { 186 try {
97 Program program = requireMain 187 if (verbose) {
98 ? await kernelForProgram(script, options) 188 print("DFE: scriptUri: ${script}");
99 : await kernelForBuildUnit([script], options..chaseDependencies = true); 189 }
100 190
101 if (errors.isNotEmpty) { 191 Program program = await compiler.compile(script);
192
193 if (compiler.errors.isNotEmpty) {
102 // TODO(sigmund): the compiler prints errors to the console, so we 194 // TODO(sigmund): the compiler prints errors to the console, so we
103 // shouldn't print those messages again here. 195 // shouldn't print those messages again here.
104 result = new CompilationResult.errors(errors); 196 result = new CompilationResult.errors(compiler.errors);
105 } else { 197 } else {
106 // We serialize the program excluding platform.dill because the VM has 198 // We serialize the program excluding platform.dill because the VM has
107 // these sources built-in. Everything loaded as a summary in 199 // these sources built-in. Everything loaded as a summary in
108 // [kernelForProgram] is marked `external`, so we can use that bit to 200 // [kernelForProgram] is marked `external`, so we can use that bit to
109 // decide what to excluce. 201 // decide what to exclude.
110 // TODO(sigmund): remove the following line (Issue #30111) 202 // TODO(sigmund): remove the following line (Issue #30111)
111 program.libraries.forEach((e) => e.isExternal = false); 203 program.libraries.forEach((e) => e.isExternal = false);
112 result = new CompilationResult.ok( 204 result = new CompilationResult.ok(
113 serializeProgram(program, filter: (lib) => !lib.isExternal)); 205 serializeProgram(program, filter: (lib) => !lib.isExternal));
114 } 206 }
115 } catch (error, stack) { 207 } catch (error, stack) {
116 result = new CompilationResult.crash(error, stack); 208 result = new CompilationResult.crash(error, stack);
117 } 209 }
118 210
119 if (verbose) print("DFE:> ${result}"); 211 if (verbose) print("DFE:> ${result}");
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 if (response[0] == tag) { 251 if (response[0] == tag) {
160 // Success. 252 // Success.
161 responsePort.close(); 253 responsePort.close();
162 } else if (response[0] == -tag) { 254 } else if (response[0] == -tag) {
163 // Compilation error. 255 // Compilation error.
164 throw response[4]; 256 throw response[4];
165 } else { 257 } else {
166 throw "Unexpected response: $response"; 258 throw "Unexpected response: $response";
167 } 259 }
168 }; 260 };
169 var request = [tag, responsePort.sendPort, scriptUri]; 261 var request = [
262 tag,
263 responsePort.sendPort,
264 scriptUri,
265 1 /* isolateId chosen randomly */,
266 false /* incremental */
267 ];
170 _processLoadRequest(request); 268 _processLoadRequest(request);
171 } 269 }
172 270
173 main([args]) { 271 main([args]) {
174 if (args?.length == 2 && args[0] == '--train') { 272 if (args?.length == 2 && args[0] == '--train') {
175 // This entry point is used when creating an app snapshot. The argument 273 // This entry point is used when creating an app snapshot. The argument
176 // provides a script to compile to warm-up generated code. 274 // provides a script to compile to warm-up generated code.
177 train(args[1]); 275 train(args[1]);
178 } else { 276 } else {
179 // Entry point for the Kernel isolate. 277 // Entry point for the Kernel isolate.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 _CompilationCrash(this.exception, this.stack); 356 _CompilationCrash(this.exception, this.stack);
259 357
260 @override 358 @override
261 Status get status => Status.crash; 359 Status get status => Status.crash;
262 360
263 @override 361 @override
264 String get errorString => "${exception}\n${stack}"; 362 String get errorString => "${exception}\n${stack}";
265 363
266 String toString() => "_CompilationCrash(${errorString})"; 364 String toString() => "_CompilationCrash(${errorString})";
267 } 365 }
OLDNEW
« no previous file with comments | « runtime/vm/unit_test.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698