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

Side by Side Diff: runtime/tools/kernel-service.dart

Issue 2668503003: VM: [Kernel] Switch to DFE for testing -c dartk configuration. (Closed)
Patch Set: Address comments Created 3 years, 10 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 | « no previous file | runtime/vm/kernel_isolate.cc » ('j') | 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 library runtime.tools.kernel_service; 4 library runtime.tools.kernel_service;
5 5
6 // This is an interface to the Dart Kernel parser and Kernel binary generator. 6 // This is an interface to the Dart Kernel parser and Kernel binary generator.
7 // 7 //
8 // It is used by the kernel-isolate to load Dart source code and generate 8 // It is used by the kernel-isolate to load Dart source code and generate
9 // Kernel binary format. 9 // Kernel binary format.
10 // 10 //
11 // This is either invoked as the root script of the Kernel isolate when used
12 // as a part of
13 //
14 // dart --dfe=runtime/tools/kernel-service.dart ...
15 //
16 // invocation or it is invoked as a standalone script to perform batch mode
17 // compilation requested via an HTTP interface
18 //
19 // dart runtime/tools/kernel-service.dart --batch
20 //
21 // The port for the batch mode worker is controlled by DFE_WORKER_PORT
22 // environment declarations (set by -DDFE_WORKER_PORT=... command line flag).
23 // When not set (or set to 0) an ephemeral port returned by the OS is used
24 // instead.
25 //
26 // When this script is used as a Kernel isolate root script and DFE_WORKER_PORT
27 // is set to non-zero value then Kernel isolate will forward all compilation
28 // requests it receives to the batch worker on the given port.
29 //
11 30
12 import 'dart:async'; 31 import 'dart:async';
13 import 'dart:convert'; 32 import 'dart:convert';
14 import 'dart:io'; 33 import 'dart:io';
15 import 'dart:isolate'; 34 import 'dart:isolate';
16 import 'dart:typed_data'; 35 import 'dart:typed_data';
17 36
18 import 'package:kernel/analyzer/loader.dart'; 37 import 'package:kernel/analyzer/loader.dart';
19 import 'package:kernel/binary/ast_to_binary.dart'; 38 import 'package:kernel/binary/ast_to_binary.dart';
20 import 'package:kernel/kernel.dart'; 39 import 'package:kernel/kernel.dart';
21 import 'package:kernel/target/targets.dart'; 40 import 'package:kernel/target/targets.dart';
22 41
23 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE') ?? false; 42 const bool verbose = true || (const bool.fromEnvironment('DFE_VERBOSE') ?? false );
43 const int workerPort = const int.fromEnvironment('DFE_WORKER_PORT') ?? 0;
24 44
25 class DataSink implements Sink<List<int>> { 45 class DataSink implements Sink<List<int>> {
26 final BytesBuilder builder = new BytesBuilder(); 46 final BytesBuilder builder = new BytesBuilder();
27 47
28 void add(List<int> data) { 48 void add(List<int> data) {
29 builder.add(data); 49 builder.add(data);
30 } 50 }
31 51
32 void close() { 52 void close() {
33 // Nothing to do. 53 // Nothing to do.
(...skipping 14 matching lines...) Expand all
48 68
49 CompilationOk(this.binary); 69 CompilationOk(this.binary);
50 70
51 List toResponse() => [STATUS_OK, binary]; 71 List toResponse() => [STATUS_OK, binary];
52 72
53 String toString() => "CompilationOk(${binary.length} bytes)"; 73 String toString() => "CompilationOk(${binary.length} bytes)";
54 } 74 }
55 75
56 abstract class CompilationFail extends CompilationResult { 76 abstract class CompilationFail extends CompilationResult {
57 String get errorString; 77 String get errorString;
78
79 Map<String, dynamic> toJson();
80
81 static CompilationFail fromJson(Map m) {
82 switch (m['status']) {
83 case STATUS_ERROR:
84 return new CompilationError(m['errors']);
85 case STATUS_CRASH:
86 return new CompilationCrash(m['exception'], m['stack']);
87 }
88 }
58 } 89 }
59 90
60 class CompilationError extends CompilationFail { 91 class CompilationError extends CompilationFail {
61 final List<String> errors; 92 final List<String> errors;
62 93
63 CompilationError(this.errors); 94 CompilationError(this.errors);
64 95
65 List toResponse() => [STATUS_ERROR, errorString]; 96 List toResponse() => [STATUS_ERROR, errorString];
66 97
98 Map<String, dynamic> toJson() => {
99 "status": STATUS_ERROR,
100 "errors": errors,
101 };
102
67 String get errorString => errors.take(10).join('\n'); 103 String get errorString => errors.take(10).join('\n');
68 104
69 String toString() => "CompilationError(${errorString})"; 105 String toString() => "CompilationError(${errorString})";
70 } 106 }
71 107
72 class CompilationCrash extends CompilationFail { 108 class CompilationCrash extends CompilationFail {
73 final String exception; 109 final String exception;
74 final String stack; 110 final String stack;
75 111
76 CompilationCrash(this.exception, this.stack); 112 CompilationCrash(this.exception, this.stack);
77 113
78 List toResponse() => [STATUS_CRASH, errorString]; 114 List toResponse() => [STATUS_CRASH, errorString];
79 115
116 Map<String, dynamic> toJson() => {
117 "status": STATUS_CRASH,
118 "exception": exception,
119 "stack": stack,
120 };
121
80 String get errorString => "${exception}\n${stack}"; 122 String get errorString => "${exception}\n${stack}";
81 123
82 String toString() => "CompilationCrash(${errorString})"; 124 String toString() => "CompilationCrash(${errorString})";
83 } 125 }
84 126
85 Future<CompilationResult> parseScriptImpl(DartLoaderBatch batch_loader, 127 Future<CompilationResult> parseScriptImpl(DartLoaderBatch batch_loader,
86 Uri fileName, String packageConfig, String sdkPath) async { 128 Uri fileName, String packageConfig, String sdkPath) async {
87 if (!FileSystemEntity.isFileSync(fileName.path)) { 129 if (!FileSystemEntity.isFileSync(fileName.path)) {
88 throw "Input file '${fileName.path}' does not exist."; 130 throw "Input file '${fileName.path}' does not exist.";
89 } 131 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 Uri.parse(Platform.resolvedExecutable).resolve("patched_sdk"); 197 Uri.parse(Platform.resolvedExecutable).resolve("patched_sdk");
156 198
157 if (verbose) { 199 if (verbose) {
158 print("""DFE: Requesting compilation { 200 print("""DFE: Requesting compilation {
159 scriptUri: ${scriptUri} 201 scriptUri: ${scriptUri}
160 packagesUri: ${packagesUri} 202 packagesUri: ${packagesUri}
161 patchedSdk: ${patchedSdk} 203 patchedSdk: ${patchedSdk}
162 }"""); 204 }""");
163 } 205 }
164 206
165 return await parseScript( 207 if (workerPort != 0) {
166 new DartLoaderBatch(), scriptUri, packagesUri.path, patchedSdk.path); 208 return await requestParse(scriptUri, packagesUri, patchedSdk);
209 } else {
210 return await parseScript(
211 new DartLoaderBatch(), scriptUri, packagesUri.path, patchedSdk.path);
212 }
167 } 213 }
168 214
215
169 // Process a request from the runtime. See KernelIsolate::CompileToKernel in 216 // Process a request from the runtime. See KernelIsolate::CompileToKernel in
170 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc. 217 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc.
171 Future _processLoadRequest(request) async { 218 Future _processLoadRequest(request) async {
172 if (verbose) { 219 if (verbose) {
173 print("DFE: request: $request"); 220 print("DFE: request: $request");
174 print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); 221 print("DFE: Platform.packageConfig: ${Platform.packageConfig}");
175 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); 222 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}");
176 } 223 }
177 224
178 final int tag = request[0]; 225 final int tag = request[0];
(...skipping 19 matching lines...) Expand all
198 } else { 245 } else {
199 // See loader.cc for the code that handles these replies. 246 // See loader.cc for the code that handles these replies.
200 if (result is CompilationOk) { 247 if (result is CompilationOk) {
201 port.send([tag, inputFileUrl, inputFileUrl, null, result]); 248 port.send([tag, inputFileUrl, inputFileUrl, null, result]);
202 } else { 249 } else {
203 port.send([-tag, inputFileUrl, inputFileUrl, null, result.errorString]); 250 port.send([-tag, inputFileUrl, inputFileUrl, null, result.errorString]);
204 } 251 }
205 } 252 }
206 } 253 }
207 254
208 main() => new RawReceivePort()..handler = _processLoadRequest; 255 Future<CompilationResult> requestParse(
256 Uri scriptUri, Uri packagesUri, Uri patchedSdk) async {
257 if (verbose) {
258 print(
259 "DFE: forwarding request to worker at http://localhost:${workerPort}/");
260 }
261
262 HttpClient client = new HttpClient();
263 final rq = await client
264 .postUrl(new Uri(host: 'localhost', port: workerPort, scheme: 'http'));
265 rq.headers.contentType = ContentType.JSON;
266 rq.write(JSON.encode({
267 "inputFileUrl": scriptUri.toString(),
268 "packagesUri": packagesUri.toString(),
269 "patchedSdk": patchedSdk.toString(),
270 }));
271 final rs = await rq.close();
272 try {
273 if (rs.statusCode == HttpStatus.OK) {
274 final BytesBuilder bb = new BytesBuilder();
275 await rs.forEach(bb.add);
276 return new CompilationOk(bb.takeBytes());
277 } else {
278 return CompilationFail.fromJson(JSON.decode(await UTF8.decodeStream(rs)));
279 }
280 } finally {
281 await client.close();
282 }
283 }
284
285 void startBatchServer() {
286 final loader = new DartLoaderBatch();
287 HttpServer.bind(InternetAddress.LOOPBACK_IP_V6, workerPort).then((server) {
288 print('READY ${server.port}');
289 server.listen((HttpRequest request) async {
290 final rq = JSON.decode(await UTF8.decodeStream(request));
291
292 final Uri scriptUri = Uri.parse(rq['inputFileUrl']);
293 final Uri packagesUri = Uri.parse(rq['packagesUri']);
294 final Uri patchedSdk = Uri.parse(rq['patchedSdk']);
295
296 final CompilationResult result = await parseScript(
297 loader, scriptUri, packagesUri.path, patchedSdk.path);
298
299 if (result is CompilationOk) {
300 request.response.statusCode = HttpStatus.OK;
301 request.response.headers.contentType = ContentType.BINARY;
302 request.response.add(result.binary);
303 request.response.close();
304 } else {
305 request.response.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
306 request.response.headers.contentType = ContentType.TEXT;
307 request.response.write(JSON.encode(result.toJson()));
308 request.response.close();
309 }
310 });
311 ProcessSignal.SIGTERM.watch().first.then((_) => server.close());
312 });
313 }
314
315 main([args]) {
316 if (args?.length == 1 && args[0] == '--batch') {
317 startBatchServer();
318 } else {
319 // Entry point for the Kernel isolate.
320 return new RawReceivePort()..handler = _processLoadRequest;
321 }
322 }
209 323
210 // This duplicates functionality from the Loader which we can't easily 324 // This duplicates functionality from the Loader which we can't easily
211 // access from here. 325 // access from here.
212 Uri _findPackagesFile(Uri base) async { 326 Uri _findPackagesFile(Uri base) async {
213 var dir = new File.fromUri(base).parent; 327 var dir = new File.fromUri(base).parent;
214 while (true) { 328 while (true) {
215 final packagesFile = dir.uri.resolve(".packages"); 329 final packagesFile = dir.uri.resolve(".packages");
216 if (await new File.fromUri(packagesFile).exists()) { 330 if (await new File.fromUri(packagesFile).exists()) {
217 return packagesFile; 331 return packagesFile;
218 } 332 }
219 if (dir.parent == dir) { 333 if (dir.parent.path == dir.path) {
220 break; 334 break;
221 } 335 }
222 dir = dir.parent; 336 dir = dir.parent;
223 } 337 }
224 return null; 338 return null;
225 } 339 }
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/kernel_isolate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698