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

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

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

Powered by Google App Engine
This is Rietveld 408576698