Unify treatment of sorting with and without custom comparator.
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 26 Apr 2010 14:34:48 +0000 (14:34 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 26 Apr 2010 14:34:48 +0000 (14:34 +0000)
Review URL: http://codereview.chromium.org/1706010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4502 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/array.js

index a718fdc..00010de 100644 (file)
@@ -644,77 +644,26 @@ function ArraySort(comparefn) {
   // In-place QuickSort algorithm.
   // For short (length <= 22) arrays, insertion sort is used for efficiency.
 
-  var global_receiver;
-
-  function InsertionSortWithFunc(a, from, to) {
-    for (var i = from + 1; i < to; i++) {
-      var element = a[i];
-      for (var j = i - 1; j >= from; j--) {
-        var tmp = a[j];
-        var order = %_CallFunction(global_receiver, tmp, element, comparefn);
-        if (order > 0) {
-          a[j + 1] = tmp;
-        } else {
-          break;
-        }
+  if (!IS_FUNCTION(comparefn)) {
+    comparefn = function (x, y) {
+      if (x === y) return 0;
+      if (%_IsSmi(x) && %_IsSmi(y)) {
+        return %SmiLexicographicCompare(x, y);
       }
-      a[j + 1] = element;
-    }
+      x = ToString(x);
+      y = ToString(y);
+      if (x == y) return 0;
+      else return x < y ? -1 : 1;
+    };
   }
-
-  function QuickSortWithFunc(a, from, to) {
-    // Insertion sort is faster for short arrays.
-    if (to - from <= 22) {
-      InsertionSortWithFunc(a, from, to);
-      return;
-    }
-    var pivot_index = $floor($random() * (to - from)) + from;
-    var pivot = a[pivot_index];
-    // Issue 95: Keep the pivot element out of the comparisons to avoid
-    // infinite recursion if comparefn(pivot, pivot) != 0.
-    a[pivot_index] = a[from];
-    a[from] = pivot;
-    var low_end = from;   // Upper bound of the elements lower than pivot.
-    var high_start = to;  // Lower bound of the elements greater than pivot.
-    // From low_end to i are elements equal to pivot.
-    // From i to high_start are elements that haven't been compared yet.
-    for (var i = from + 1; i < high_start; ) {
-      var element = a[i];
-      var order = %_CallFunction(global_receiver, element, pivot, comparefn);
-      if (order < 0) {
-        a[i] = a[low_end];
-        a[low_end] = element;
-        i++;
-        low_end++;
-      } else if (order > 0) {
-        high_start--;
-        a[i] = a[high_start];
-        a[high_start] = element;
-      } else {  // order == 0
-        i++;
-      }
-    }
-    QuickSortWithFunc(a, from, low_end);
-    QuickSortWithFunc(a, high_start, to);
-  }
-
-  function Compare(x,y) {
-    if (x === y) return 0;
-    if (%_IsSmi(x) && %_IsSmi(y)) {
-      return %SmiLexicographicCompare(x, y);
-    }
-    x = ToString(x);
-    y = ToString(y);
-    if (x == y) return 0;
-    else return x < y ? -1 : 1;
-  };
+  var global_receiver = %GetGlobalReceiver();
 
   function InsertionSort(a, from, to) {
     for (var i = from + 1; i < to; i++) {
       var element = a[i];
       for (var j = i - 1; j >= from; j--) {
         var tmp = a[j];
-        var order = Compare(tmp, element);
+        var order = %_CallFunction(global_receiver, tmp, element, comparefn);
         if (order > 0) {
           a[j + 1] = tmp;
         } else {
@@ -743,7 +692,7 @@ function ArraySort(comparefn) {
     // From i to high_start are elements that haven't been compared yet.
     for (var i = from + 1; i < high_start; ) {
       var element = a[i];
-      var order = Compare(element, pivot);
+      var order = %_CallFunction(global_receiver, element, pivot, comparefn);
       if (order < 0) {
         a[i] = a[low_end];
         a[low_end] = element;
@@ -903,12 +852,7 @@ function ArraySort(comparefn) {
     num_non_undefined = SafeRemoveArrayHoles(this);
   }
 
-  if(IS_FUNCTION(comparefn)) {
-    global_receiver = %GetGlobalReceiver();
-    QuickSortWithFunc(this, 0, num_non_undefined);
-  } else {
-    QuickSort(this, 0, num_non_undefined);
-  }
+  QuickSort(this, 0, num_non_undefined);
 
   if (!is_array && (num_non_undefined + 1 < max_prototype_element)) {
     // For compatibility with JSC, we shadow any elements in the prototype