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

Unified Diff: sdk/lib/html/html_common/conversions_dartium.dart

Issue 1817343002: Remove O(n^2) loop in serialized script value conversions (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Moved the code using identity hash down into the Dartium-specific version Created 4 years, 9 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 | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/html/html_common/conversions_dartium.dart
diff --git a/sdk/lib/html/html_common/conversions_dartium.dart b/sdk/lib/html/html_common/conversions_dartium.dart
index ad71852616a530d98e955cbeb415304199d7f0c2..66299a05389fd4c7b79a0ef086ac052eccdd82ec 100644
--- a/sdk/lib/html/html_common/conversions_dartium.dart
+++ b/sdk/lib/html/html_common/conversions_dartium.dart
@@ -14,7 +14,14 @@ class _StructuredCloneDartium extends _StructuredClone {
cloneNotRequired(e) => e is js.JsObject;
}
-class _AcceptStructuredCloneDartium extends _AcceptStructuredClone {
+/// A version of _AcceptStructuredClone, but using a different algorithm
+/// so we can take advantage of an identity HashMap on Dartium without
+/// the bad side-effect of modifying the JS source objects if we do the same in
+/// dart2js.
+///
+/// This no longer inherits anything from _AcceptStructuredClone
+/// and is never used polymorphically with it, so it doesn't inherit.
+class _AcceptStructuredCloneDartium {
newDartList(length) => new List(length);
// JsObjects won't be identical, but will be equal only if the underlying
@@ -28,6 +35,75 @@ class _AcceptStructuredCloneDartium extends _AcceptStructuredClone {
action(key, jsObject[key]);
}
}
+
+ // Keep track of the clones, keyed by the original object. If we're
+ // not copying, these may be the same.
+ var clones = new HashMap.identity();
+ bool mustCopy = false;
+
+ Object findSlot(value) {
+ return clones.putIfAbsent(value, () => null);
+ }
+
+ writeSlot(original, x) { clones[original] = x; }
+
+ walk(e) {
+ if (e == null) return e;
+ if (e is bool) return e;
+ if (e is num) return e;
+ if (e is String) return e;
+
+ if (isJavaScriptDate(e)) {
+ return convertNativeToDart_DateTime(e);
+ }
+
+ if (isJavaScriptRegExp(e)) {
+ // TODO(sra).
+ throw new UnimplementedError('structured clone of RegExp');
+ }
+
+ if (isJavaScriptPromise(e)) {
+ return convertNativePromiseToDartFuture(e);
+ }
+
+ if (isJavaScriptSimpleObject(e)) {
+ // TODO(sra): If mustCopy is false, swizzle the prototype for one of a Map
+ // implementation that uses the properies as storage.
+ var copy = findSlot(e);
+ if (copy != null) return copy;
+ copy = {};
+
+ writeSlot(e, copy);
+ forEachJsField(e, (key, value) => copy[key] = walk(value));
+ return copy;
+ }
+
+ if (isJavaScriptArray(e)) {
+ var copy = findSlot(e);
+ if (copy != null) return copy;
+
+ int length = e.length;
+ // Since a JavaScript Array is an instance of Dart List, we can modify it
+ // in-place unless we must copy.
+ copy = mustCopy ? newDartList(length) : e;
+ writeSlot(e, copy);
+
+ for (int i = 0; i < length; i++) {
+ copy[i] = walk(e[i]);
+ }
+ return copy;
+ }
+
+ // Assume anything else is already a valid Dart object, either by having
+ // already been processed, or e.g. a clonable native class.
+ return e;
+ }
+
+ convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) {
+ this.mustCopy = mustCopy;
+ var copy = walk(object);
+ return copy;
+ }
}
final _dateConstructor = js.context["Date"];
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698