Commit ad9312cd authored by antonm@chromium.org's avatar antonm@chromium.org

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
parent 507e9b26
...@@ -644,77 +644,26 @@ function ArraySort(comparefn) { ...@@ -644,77 +644,26 @@ function ArraySort(comparefn) {
// In-place QuickSort algorithm. // In-place QuickSort algorithm.
// For short (length <= 22) arrays, insertion sort is used for efficiency. // For short (length <= 22) arrays, insertion sort is used for efficiency.
var global_receiver; if (!IS_FUNCTION(comparefn)) {
comparefn = function (x, y) {
function InsertionSortWithFunc(a, from, to) { if (x === y) return 0;
for (var i = from + 1; i < to; i++) { if (%_IsSmi(x) && %_IsSmi(y)) {
var element = a[i]; return %SmiLexicographicCompare(x, y);
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;
}
} }
a[j + 1] = element; x = ToString(x);
} y = ToString(y);
if (x == y) return 0;
else return x < y ? -1 : 1;
};
} }
var global_receiver = %GetGlobalReceiver();
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;
};
function InsertionSort(a, from, to) { function InsertionSort(a, from, to) {
for (var i = from + 1; i < to; i++) { for (var i = from + 1; i < to; i++) {
var element = a[i]; var element = a[i];
for (var j = i - 1; j >= from; j--) { for (var j = i - 1; j >= from; j--) {
var tmp = a[j]; var tmp = a[j];
var order = Compare(tmp, element); var order = %_CallFunction(global_receiver, tmp, element, comparefn);
if (order > 0) { if (order > 0) {
a[j + 1] = tmp; a[j + 1] = tmp;
} else { } else {
...@@ -743,7 +692,7 @@ function ArraySort(comparefn) { ...@@ -743,7 +692,7 @@ function ArraySort(comparefn) {
// From i to high_start are elements that haven't been compared yet. // From i to high_start are elements that haven't been compared yet.
for (var i = from + 1; i < high_start; ) { for (var i = from + 1; i < high_start; ) {
var element = a[i]; var element = a[i];
var order = Compare(element, pivot); var order = %_CallFunction(global_receiver, element, pivot, comparefn);
if (order < 0) { if (order < 0) {
a[i] = a[low_end]; a[i] = a[low_end];
a[low_end] = element; a[low_end] = element;
...@@ -903,12 +852,7 @@ function ArraySort(comparefn) { ...@@ -903,12 +852,7 @@ function ArraySort(comparefn) {
num_non_undefined = SafeRemoveArrayHoles(this); num_non_undefined = SafeRemoveArrayHoles(this);
} }
if(IS_FUNCTION(comparefn)) { QuickSort(this, 0, num_non_undefined);
global_receiver = %GetGlobalReceiver();
QuickSortWithFunc(this, 0, num_non_undefined);
} else {
QuickSort(this, 0, num_non_undefined);
}
if (!is_array && (num_non_undefined + 1 < max_prototype_element)) { if (!is_array && (num_non_undefined + 1 < max_prototype_element)) {
// For compatibility with JSC, we shadow any elements in the prototype // For compatibility with JSC, we shadow any elements in the prototype
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment