From: antonm@chromium.org Date: Mon, 26 Apr 2010 14:34:48 +0000 (+0000) Subject: Unify treatment of sorting with and without custom comparator. X-Git-Tag: upstream/4.7.83~21943 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ad9312cdaa0b2e689a4b0e90c7680a8865f891a2;p=platform%2Fupstream%2Fv8.git Unify treatment of sorting with and without custom comparator. Review URL: http://codereview.chromium.org/1706010 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4502 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/array.js b/src/array.js index a718fdc..00010de 100644 --- a/src/array.js +++ b/src/array.js @@ -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