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

Unified Diff: sdk/lib/html/html_common/conversions.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: 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.dart
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index de0d423258d971447938882f573cc9e49e86fd09..fa7f43c0e55fff2aa9fd49cc3886c423bd2d4c7d 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -58,21 +58,15 @@ convertNativeToDart_SerializedScriptValue(object) {
*/
abstract class _StructuredClone {
- // TODO(sra): Replace slots with identity hash table.
- var values = [];
- var copies = []; // initially 'null', 'true' during initial DFS, then a copy.
-
- int findSlot(value) {
- int length = values.length;
- for (int i = 0; i < length; i++) {
- if (identical(values[i], value)) return i;
- }
- values.add(value);
- copies.add(null);
- return length;
+ // 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();
sra1 2016/03/22 00:54:21 Be careful here. The implementation of identityHa
Alan Knight 2016/03/22 18:00:01 OK, I moved the code to use an identity map down i
+
+ Object findSlot(value) {
+ return clones.putIfAbsent(value, () => null);
}
- readSlot(int i) => copies[i];
- writeSlot(int i, x) { copies[i] = x; }
+ readSlot(Object original) => clones[original];
+ writeSlot(Object original, clone) { clones[original] = clone; }
cleanupSlots() {} // Will be needed if we mark objects with a property.
bool cloneNotRequired(object);
newJsMap();
@@ -109,11 +103,10 @@ abstract class _StructuredClone {
if (cloneNotRequired(e)) return e;
if (e is Map) {
- var slot = findSlot(e);
- var copy = readSlot(slot);
+ var copy = findSlot(e);
if (copy != null) return copy;
copy = newJsMap();
- writeSlot(slot, copy);
+ writeSlot(e, copy);
e.forEach((key, value) {
putIntoMap(copy, key, walk(value));
});
@@ -126,21 +119,20 @@ abstract class _StructuredClone {
// to copy anything reachable from the array. However, the list may have
// non-native properties or methods from interceptors and such, e.g.
// an immutability marker. So we had to stop doing that.
- var slot = findSlot(e);
- var copy = readSlot(slot);
+ var copy = findSlot(e);
if (copy != null) return copy;
- copy = copyList(e, slot);
+ copy = copyList(e);
return copy;
}
throw new UnimplementedError('structured clone of other type');
}
- copyList(List e, int slot) {
+ copyList(List e) {
int i = 0;
int length = e.length;
var copy = newJsList(length);
- writeSlot(slot, copy);
+ writeSlot(e, copy);
for ( ; i < length; i++) {
copy[i] = walk(e[i]);
}
@@ -174,26 +166,19 @@ abstract class _StructuredClone {
*/
abstract class _AcceptStructuredClone {
- // TODO(sra): Replace slots with identity hash table.
- var values = [];
- var copies = []; // initially 'null', 'true' during initial DFS, then a copy.
+ // 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;
- int findSlot(value) {
- int length = values.length;
- for (int i = 0; i < length; i++) {
- if (identicalInJs(values[i], value)) return i;
- }
- values.add(value);
- copies.add(null);
- return length;
+ Object findSlot(value) {
+ return clones.putIfAbsent(value, () => null);
}
/// Are the two objects identical, but taking into account that two JsObject
/// wrappers may not be identical, but their underlying Js Object might be.
bool identicalInJs(a, b);
- readSlot(int i) => copies[i];
- writeSlot(int i, x) { copies[i] = x; }
+ writeSlot(original, x) { clones[original] = x; }
/// Iterate over the JS properties.
forEachJsField(object, action);
@@ -224,26 +209,24 @@ abstract class _AcceptStructuredClone {
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 slot = findSlot(e);
- var copy = readSlot(slot);
+ var copy = findSlot(e);
if (copy != null) return copy;
copy = {};
- writeSlot(slot, copy);
+ writeSlot(e, copy);
forEachJsField(e, (key, value) => copy[key] = walk(value));
return copy;
}
if (isJavaScriptArray(e)) {
- var slot = findSlot(e);
- var copy = readSlot(slot);
+ 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(slot, copy);
+ writeSlot(e, copy);
for (int i = 0; i < length; i++) {
copy[i] = walk(e[i]);
« 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