Bug 1259600 - Divert typed arrays passed to Array.sort to a typed array specific sort; r=till
authorMorgan Phillips <winter2718@gmail.com>
Mon, 28 Mar 2016 13:02:17 -0700
changeset 290759 67e4eb38e3b818ab71bcfa170cab353b05c39a98
parent 290758 b1d8eaeee18bfbe86d0ac4130dd92e42d47f5def
child 290760 a0c84b4e0da24309d3a2a764202ca24e66f2d9ee
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1259600
milestone48.0a1
Bug 1259600 - Divert typed arrays passed to Array.sort to a typed array specific sort; r=till
js/src/builtin/Sorting.js
js/src/tests/ecma_6/Array/sort_basics.js
--- a/js/src/builtin/Sorting.js
+++ b/js/src/builtin/Sorting.js
@@ -227,16 +227,25 @@ function MoveHoles(sparse, sparseLen, de
 
 // Iterative, bottom up, mergesort.
 function MergeSort(array, len, comparefn) {
     // To save effort we will do all of our work on a dense list,
     // then create holes at the end.
     var denseList = new List();
     var denseLen = 0;
 
+    // Until recently typed arrays had no sort method. To work around that
+    // many users passed them to Array.prototype.sort. Now that we have a
+    // typed array specific sorting method it makes sense to divert to it
+    // when possible. Further, the MoveHoles utility function (used within
+    // MergeSort) is not currently compatible with typed arrays.
+    if (IsPossiblyWrappedTypedArray(array)) {
+        return TypedArraySort.call(array, comparefn);
+    }
+
     for (var i = 0; i < len; i++) {
         if (i in array)
             denseList[denseLen++] = array[i];
     }
 
     if (denseLen < 1)
         return array;
 
--- a/js/src/tests/ecma_6/Array/sort_basics.js
+++ b/js/src/tests/ecma_6/Array/sort_basics.js
@@ -5,30 +5,42 @@ const SEED = (Math.random() * 10) + 1;
 // Create an array filled with random values, 'size' is the desired length of
 // the array and 'seed' is an initial value supplied to a pseudo-random number
 // generator.
 function genRandomArray(size, seed) {
     return Array.from(XorShiftGenerator(seed, size));
 }
 
 function SortTest(size, seed) {
-    let arrOne    = genRandomArray(size, seed);
-    let arrTwo    = Array.from(arrOne);
-    let arrThree  = Array.from(arrOne);
+    let arrOne       = genRandomArray(size, seed);
+    let arrTwo       = Array.from(arrOne);
+    let arrThree     = Array.from(arrOne);
+    let typedArrays  = [
+        new Uint8Array(arrOne),
+        new Int32Array(arrOne),
+        new Float32Array(arrOne)
+    ];
+
+    let sorted = Array.from((Int32Array.from(arrOne)).sort());
 
     // Test numeric comparators against typed array sort.
-    assertDeepEq(Array.from((Int32Array.from(arrOne)).sort()),
-                 arrTwo.sort((x, y) => (x - y)),
-                 `The arr is not properly sorted! seed: ${SEED}`);
+    assertDeepEq(sorted, arrTwo.sort((x, y) => (x - y)),
+                 `The array is not properly sorted! seed: ${SEED}`);
 
     // Use multiplication to kill comparator optimization and trigger
     // self-hosted sorting.
-    assertDeepEq(Array.from((Int32Array.from(arrOne)).sort()),
-                 arrThree.sort((x, y) => (1*x - 1*y)),
-                 `The arr is not properly sorted! seed: ${SEED}`);
+    assertDeepEq(sorted, arrThree.sort((x, y) => (1*x - 1*y)),
+                 `The array is not properly sorted! seed: ${SEED}`);
+
+    // Ensure that typed arrays are also sorted property.
+    for (typedArr of typedArrays) {
+        let sortedTypedArray = Array.prototype.sort.call(typedArr, (x, y) => (1*x - 1*y))
+        assertDeepEq(sorted, Array.from(sortedTypedArray),
+                     `The array is not properly sorted! seed: ${SEED}`);
+    }
 }
 
 SortTest(2048, SEED);
 SortTest(16, SEED);
 SortTest(0, SEED);
 
 if (typeof reportCompare === "function")
     reportCompare(true, true);