Reviewers: adamk, rossberg,

Description:
Make (Object.)observed Arrays use SafeRemoveArrayHoles during sort

R=adamk,rossberg
BUG=

Please review this at https://codereview.chromium.org/15837006/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/array.js
  M src/objects.cc
  M test/mjsunit/harmony/object-observe.js


Index: src/array.js
diff --git a/src/array.js b/src/array.js
index 599fd5cfe98e97e484926ed697966041cb464561..a3674e837d3ade7a59e7ddc159ff77b6b745ebd5 100644
--- a/src/array.js
+++ b/src/array.js
@@ -1001,11 +1001,13 @@ function ArraySort(comparefn) {
     max_prototype_element = CopyFromPrototype(this, length);
   }

-  var num_non_undefined = %RemoveArrayHoles(this, length);
+  var num_non_undefined = %IsObserved(this) ?
+      -1 : %RemoveArrayHoles(this, length);
+
   if (num_non_undefined == -1) {
-    // There were indexed accessors in the array.  Move array holes and
-    // undefineds to the end using a Javascript function that is safe
-    // in the presence of accessors.
+    // The array is observed, or there were indexed accessors in the array.
+ // Move array holes and undefineds to the end using a Javascript function
+    // that is safe in the presence of accessors and is observable.
     num_non_undefined = SafeRemoveArrayHoles(this);
   }

Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 99fd8e21f0a6dfd0ba2019289caf06c770f241a0..85ac44b0999e29949e3ee6df5f4cb8a1e127f86d 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -13755,12 +13755,13 @@ MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
   Heap* heap = GetHeap();

+  ASSERT(!map()->is_observed());
   if (HasDictionaryElements()) {
     // Convert to fast elements containing only the existing properties.
     // Ordering is irrelevant, since we are going to sort anyway.
     SeededNumberDictionary* dict = element_dictionary();
     if (IsJSArray() || dict->requires_slow_elements() ||
-        dict->max_number_key() >= limit || map()->is_observed()) {
+        dict->max_number_key() >= limit) {
       return PrepareSlowElementsForSort(limit);
     }
     // Convert to fast elements.
Index: test/mjsunit/harmony/object-observe.js
diff --git a/test/mjsunit/harmony/object-observe.js b/test/mjsunit/harmony/object-observe.js index 372ffdbdb7068240dfd441dd28baba2f5209d22b..47b5d8cd5e47575c783713a4afe180343626ff6c 100644
--- a/test/mjsunit/harmony/object-observe.js
+++ b/test/mjsunit/harmony/object-observe.js
@@ -1142,6 +1142,22 @@ observer.assertCallbackRecords([
   { object: array, name: '2', type: 'updated', oldValue: 3 },
 ]);

+// Sort
+reset();
+var array = [3, 2, 1];
+Object.observe(array, observer.callback);
+array.sort();
+assertEquals(1, array[0]);
+assertEquals(2, array[1]);
+assertEquals(3, array[2]);
+Object.deliverChangeRecords(observer.callback);
+observer.assertCallbackRecords([
+  { object: array, name: '1', type: 'updated', oldValue: 2 },
+  { object: array, name: '0', type: 'updated', oldValue: 3 },
+  { object: array, name: '2', type: 'updated', oldValue: 1 },
+  { object: array, name: '1', type: 'updated', oldValue: 3 },
+  { object: array, name: '0', type: 'updated', oldValue: 2 },
+]);

 //
 // === PLAIN OBJECTS ===


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to