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

Unified 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, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/kernel_isolate.cc » ('j') | tests/language/language_kernel.status » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/tools/kernel-service.dart
diff --git a/runtime/tools/kernel-service.dart b/runtime/tools/kernel-service.dart
index b1b441db2ed5e7d1f6efe595150f09d973bb1c93..0d123ff907b7e183d6560ddee22429a136798468 100644
--- a/runtime/tools/kernel-service.dart
+++ b/runtime/tools/kernel-service.dart
@@ -8,6 +8,24 @@ library runtime.tools.kernel_service;
// It is used by the kernel-isolate to load Dart source code and generate
// Kernel binary format.
//
+// This is either invoked as the root script of the Kernel isolate when used
+// as a part of
+//
+// dart --dfe=runtime/tools/kernel-service.dart ...
+//
+// invocation or it is invoked as a standalone script to perform batch mode
+// compilation requested via an HTTP interface
+//
+// 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.
+//
+// The port for the batch mode worker is controlled by DFE_WORKER_PORT
+// 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.
+// by the OS is used instead.
+//
+// When this script is used as a Kernel isolate root script and DFE_WORKER_PORT
+// is set to non-zero value then Kernel isolate will forward all compilation
+// requests it receives to the batch worker on the given port.
+//
import 'dart:async';
import 'dart:convert';
@@ -21,6 +39,7 @@ import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
const bool verbose = const bool.fromEnvironment('DFE_VERBOSE') ?? false;
+const int workerPort = const int.fromEnvironment('DFE_WORKER_PORT') ?? 0;
class DataSink implements Sink<List<int>> {
final BytesBuilder builder = new BytesBuilder();
@@ -55,6 +74,17 @@ class CompilationOk extends CompilationResult {
abstract class CompilationFail extends CompilationResult {
String get errorString;
+
+ Map<String, dynamic> toJson();
+
+ static CompilationFail fromJson(Map m) {
+ switch (m['status']) {
+ case STATUS_ERROR:
+ return new CompilationError(m['errors']);
+ case STATUS_CRASH:
+ return new CompilationCrash(m['exception'], m['stack']);
+ }
+ }
}
class CompilationError extends CompilationFail {
@@ -64,6 +94,11 @@ class CompilationError extends CompilationFail {
List toResponse() => [STATUS_ERROR, errorString];
+ Map<String, dynamic> toJson() => {
+ "status": STATUS_ERROR,
+ "errors": errors,
+ };
+
String get errorString => errors.take(10).join('\n');
String toString() => "CompilationError(${errorString})";
@@ -77,6 +112,12 @@ class CompilationCrash extends CompilationFail {
List toResponse() => [STATUS_CRASH, errorString];
+ Map<String, dynamic> toJson() => {
+ "status": STATUS_CRASH,
+ "exception": exception,
+ "stack": stack,
+ };
+
String get errorString => "${exception}\n${stack}";
String toString() => "CompilationCrash(${errorString})";
@@ -162,10 +203,15 @@ Future _processLoadRequestImpl(String inputFileUrl) async {
}""");
}
- return await parseScript(
- new DartLoaderBatch(), scriptUri, packagesUri.path, patchedSdk.path);
+ if (workerPort != 0) {
+ return await requestParse(scriptUri, packagesUri, patchedSdk);
+ } else {
+ return await parseScript(
+ new DartLoaderBatch(), scriptUri, packagesUri.path, patchedSdk.path);
+ }
}
+
// Process a request from the runtime. See KernelIsolate::CompileToKernel in
// kernel_isolate.cc and Loader::SendKernelRequest in loader.cc.
Future _processLoadRequest(request) async {
@@ -205,7 +251,72 @@ Future _processLoadRequest(request) async {
}
}
-main() => new RawReceivePort()..handler = _processLoadRequest;
+Future<CompilationResult> requestParse(
+ Uri scriptUri, Uri packagesUri, Uri patchedSdk) async {
+ if (verbose) {
+ print(
+ "DFE: forwarding request to worker at http://localhost:${workerPort}/");
+ }
+
+ HttpClient client = new HttpClient();
+ final rq = await client
+ .postUrl(new Uri(host: 'localhost', port: workerPort, scheme: 'http'));
+ rq.headers.contentType =
+ 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.
+ rq.write(JSON.encode({
+ "inputFileUrl": scriptUri.toString(),
+ "packagesUri": packagesUri.toString(),
+ "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.
+ }));
+ final rs = await rq.close();
+ try {
+ if (rs.statusCode == HttpStatus.OK) {
+ final ds = new DataSink();
+ 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.
+ return new CompilationOk(ds.builder.takeBytes());
+ } else {
+ return CompilationFail.fromJson(JSON.decode(await UTF8.decodeStream(rs)));
+ }
+ } finally {
+ client.close();
kustermann 2017/01/31 15:38:59 await client.close()
Vyacheslav Egorov (Google) 2017/01/31 17:06:55 Done.
+ }
+}
+
+void startBatchServer() {
+ final loader = new DartLoaderBatch();
+ HttpServer.bind(InternetAddress.LOOPBACK_IP_V6, workerPort).then((server) {
+ print('READY ${server.port}');
+ 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.
+ final rq = JSON.decode(await UTF8.decodeStream(request));
+
+ final Uri scriptUri = Uri.parse(rq['inputFileUrl']);
+ final Uri packagesUri = Uri.parse(rq['packagesUri']);
+ final Uri patchedSdk = Uri.parse(rq['patchedSdk']);
+
+ final CompilationResult result = await parseScript(
+ loader, scriptUri, packagesUri.path, patchedSdk.path);
+
+ if (result is CompilationOk) {
+ request.response.headers.contentType = ContentType.BINARY;
+ request.response.add(result.binary);
+ request.response.close();
+ } else {
+ request.response.headers.contentType = ContentType.TEXT;
+ 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.
+ request.response.write(JSON.encode(result.toJson()));
+ request.response.close();
+ }
+ });
+ });
+}
+
+main([args]) {
+ if (args?.length == 1 && args[0] == '--batch') {
+ return startBatchServer();
+ }
+
+ 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.
+}
// This duplicates functionality from the Loader which we can't easily
// access from here.
@@ -216,7 +327,7 @@ Uri _findPackagesFile(Uri base) async {
if (await new File.fromUri(packagesFile).exists()) {
return packagesFile;
}
- if (dir.parent == dir) {
+ if (dir.parent.path == dir.path) {
break;
}
dir = dir.parent;
« 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