Bug 1259600 - Divert typed arrays passed to Array.sort to a typed array specific sort; r=till, a=ritu
authorMorgan Phillips <winter2718@gmail.com>
Mon, 28 Mar 2016 13:02:17 -0700
changeset 325654 91c342287837245f07765f1dd5d7187fc26022e7
parent 325653 b7488a21db02bf622a430884c0937e215a33b3a2
child 325655 e082f0ae85f259f037b303e35883c02fc6d0bdd1
push id1128
push userjlund@mozilla.com
push dateWed, 01 Jun 2016 01:31:59 +0000
treeherdermozilla-release@fe0d30de989d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill, ritu
bugs1259600
milestone47.0a2
Bug 1259600 - Divert typed arrays passed to Array.sort to a typed array specific sort; r=till, a=ritu
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);