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

Unified Diff: runtime/bin/builtin.dart

Issue 1154173006: - Avoid using a streamed receive port for single messages. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address review comments. Created 5 years, 7 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/bin/vmservice/loader.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/builtin.dart
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index fe18de3a0bd078eaa756c8d0d143b65242f0a04c..d2f24e8d193732ab19b8c3d775cec6fabeac9c19 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -4,6 +4,7 @@
library builtin;
// NOTE: Do not import 'dart:io' in builtin.
+import 'dart:collection';
import 'dart:isolate';
import 'dart:typed_data';
@@ -59,9 +60,17 @@ bool _traceLoading = false;
// A port for communicating with the service isolate for I/O.
SendPort _loadPort;
-// Maintain a number of outstanding load requests. Current loading request is
-// finished once there are no outstanding requests.
-int _numOutstandingLoadRequests = 0;
+// The receive port for a load request. Multiple sources can be fetched in
+// a single load request.
+RawReceivePort _receivePort;
+SendPort _sendPort;
+// A request id valid only for the current load cycle (while the number of
+// outstanding load requests is greater than 0). Can be reset when loading is
+// completed.
+int _reqId = 0;
+// An unordered hash map mapping from request id to a particular load request.
+// Once there are no outstanding load requests the current load has finished.
+HashMap _reqMap = new HashMap();
// The current working directory when the embedder was launched.
Uri _workingDirectory;
@@ -80,13 +89,23 @@ bool _isWindows = false;
// A class wrapping the load error message in an Error object.
-class LoadError extends Error {
+class _LoadError extends Error {
final String message;
- LoadError(this.message);
+ _LoadError(this.message);
String toString() => 'Load Error: $message';
}
+// Class collecting all of the information about a particular load request.
+class _LoadRequest {
+ final int _id;
+ final int _tag;
+ final String _uri;
+ final String _libraryUri;
+
+ _LoadRequest(this._id, this._tag, this._uri, this._libraryUri);
+}
+
// Native calls provided by the embedder.
void _signalDoneLoading() native "Builtin_DoneLoading";
@@ -229,49 +248,103 @@ Uri _resolveScriptUri(String scriptName) {
}
-void _finishLoadRequest(String uri) {
- assert(_numOutstandingLoadRequests > 0);
- _numOutstandingLoadRequests--;
+void _finishLoadRequest(_LoadRequest req) {
+ // Now that we are done with loading remove the request from the map.
+ var tmp = _reqMap.remove(req._id);
+ assert(tmp == req);
if (_traceLoading) {
- _print("Loading of $uri finished, "
- "${_numOutstandingLoadRequests} requests remaining");
+ _print("Loading of ${req._uri} finished, "
+ "${_reqMap.length} requests remaining");
}
- if (_numOutstandingLoadRequests == 0) {
+
+ if (_reqMap.isEmpty) {
+ if (_traceLoading) {
+ _print("Closing loading port.");
+ }
+ _receivePort.close();
+ _receivePort = null;
+ _sendPort = null;
+ _reqId = 0;
_signalDoneLoading();
}
}
-void _startLoadRequest(String uri, Uri resourceUri) {
- assert(_numOutstandingLoadRequests >= 0);
- _numOutstandingLoadRequests++;
+void _handleLoaderReply(msg) {
+ int id = msg[0];
+ var dataOrError = msg[1];
+ assert((id >= 0) && (id < _reqId));
+ var req = _reqMap[id];
+ try {
+ if (dataOrError is Uint8List) {
+ _loadScript(req, dataOrError);
+ } else {
+ assert(dataOrError is String);
+ var error = new _LoadError(dataOrError.toString());
+ _asyncLoadError(req, error);
+ }
+ } catch(e, s) {
+ // Wrap inside a _LoadError unless we are already propagating a
+ // previous _LoadError.
+ var error = (e is _LoadError) ? e : new _LoadError(e.toString());
+ assert(req != null);
+ _asyncLoadError(req, error);
+ }
+}
+
+
+void _startLoadRequest(int tag,
+ String uri,
+ String libraryUri,
+ Uri resourceUri) {
+ if (_reqMap.isEmpty) {
+ if (_traceLoading) {
+ _print("Initializing load port.");
+ }
+ assert(_receivePort == null);
+ assert(_sendPort == null);
+ _receivePort = new RawReceivePort(_handleLoaderReply);
+ _sendPort = _receivePort.sendPort;
+ }
+ // Register the load request and send it to the VM service isolate.
+ var curId = _reqId++;
+
+ assert(_reqMap[curId] == null);
+ _reqMap[curId] = new _LoadRequest(curId, tag, uri, libraryUri);
+
+ var msg = new List(3);
+ msg[0] = _sendPort;
+ msg[1] = curId;
+ msg[2] = resourceUri.toString();
+ _loadPort.send(msg);
+
if (_traceLoading) {
- _print("Loading of $resourceUri for $uri started, "
- "${_numOutstandingLoadRequests} requests outstanding");
+ _print("Loading of $resourceUri for $uri started with id: $curId, "
+ "${_reqMap.length} requests outstanding");
}
}
-void _loadScript(int tag, String uri, String libraryUri, Uint8List data) {
+void _loadScript(_LoadRequest req, Uint8List data) {
// TODO: Currently a compilation error while loading the script is
// fatal for the isolate. _loadScriptCallback() does not return and
- // the _numOutstandingLoadRequests counter remains out of sync.
- _loadScriptCallback(tag, uri, libraryUri, data);
- _finishLoadRequest(uri);
+ // the number of requests remains out of sync.
+ _loadScriptCallback(req._tag, req._uri, req._libraryUri, data);
+ _finishLoadRequest(req);
}
-void _asyncLoadError(int tag, String uri, String libraryUri, LoadError error) {
+void _asyncLoadError(_LoadRequest req, _LoadError error) {
if (_traceLoading) {
- _print("_asyncLoadError($uri), error: $error");
+ _print("_asyncLoadError(${req._uri}), error: $error");
}
- if (tag == Dart_kImportTag) {
+ if (req._tag == Dart_kImportTag) {
// When importing a library, the libraryUri is the imported
// uri.
- libraryUri = uri;
+ req._libraryUri = req._uri;
}
- _asyncLoadErrorCallback(uri, libraryUri, error);
- _finishLoadRequest(uri);
+ _asyncLoadErrorCallback(req._uri, req._libraryUri, error);
+ _finishLoadRequest(req);
}
@@ -279,37 +352,16 @@ _loadDataFromLoadPort(int tag,
String uri,
String libraryUri,
Uri resourceUri) {
- var receivePort = new ReceivePort();
- receivePort.first.then((dataOrError) {
- receivePort.close();
- if (dataOrError is Uint8List) {
- _loadScript(tag, uri, libraryUri, dataOrError);
- } else {
- assert(dataOrError is String);
- var error = new LoadError(dataOrError.toString());
- _asyncLoadError(tag, uri, libraryUri, error);
- }
- }).catchError((e) {
- receivePort.close();
- // Wrap inside a LoadError unless we are already propagating a previously
- // seen LoadError.
- var error = (e is LoadError) ? e : new LoadError(e.toString);
- _asyncLoadError(tag, uri, libraryUri, error);
- });
-
try {
- var msg = [receivePort.sendPort, resourceUri.toString()];
- _loadPort.send(msg);
- _startLoadRequest(uri, resourceUri);
+ _startLoadRequest(tag, uri, libraryUri, resourceUri);
} catch (e) {
if (_traceLoading) {
_print("Exception when communicating with service isolate: $e");
}
- // Wrap inside a LoadError unless we are already propagating a previously
- // seen LoadError.
- var error = (e is LoadError) ? e : new LoadError(e.toString);
+ // Wrap inside a _LoadError unless we are already propagating a previously
+ // seen _LoadError.
+ var error = (e is _LoadError) ? e : new _LoadError(e.toString());
_asyncLoadError(tag, uri, libraryUri, error);
- receivePort.close();
}
}
« no previous file with comments | « no previous file | runtime/bin/vmservice/loader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698