Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: src/array.js

Issue 10561017: Avoid arbitrarily deep recursion in Array.sort. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-2185.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 a[j + 1] = tmp; 771 a[j + 1] = tmp;
772 } else { 772 } else {
773 break; 773 break;
774 } 774 }
775 } 775 }
776 a[j + 1] = element; 776 a[j + 1] = element;
777 } 777 }
778 }; 778 };
779 779
780 var QuickSort = function QuickSort(a, from, to) { 780 var QuickSort = function QuickSort(a, from, to) {
781 // Insertion sort is faster for short arrays. 781 while (true) {
782 if (to - from <= 10) { 782 // Insertion sort is faster for short arrays.
783 InsertionSort(a, from, to); 783 if (to - from <= 10) {
784 return; 784 InsertionSort(a, from, to);
785 } 785 return;
786 // Find a pivot as the median of first, last and middle element.
787 var v0 = a[from];
788 var v1 = a[to - 1];
789 var middle_index = from + ((to - from) >> 1);
790 var v2 = a[middle_index];
791 var c01 = %_CallFunction(receiver, v0, v1, comparefn);
792 if (c01 > 0) {
793 // v1 < v0, so swap them.
794 var tmp = v0;
795 v0 = v1;
796 v1 = tmp;
797 } // v0 <= v1.
798 var c02 = %_CallFunction(receiver, v0, v2, comparefn);
799 if (c02 >= 0) {
800 // v2 <= v0 <= v1.
801 var tmp = v0;
802 v0 = v2;
803 v2 = v1;
804 v1 = tmp;
805 } else {
806 // v0 <= v1 && v0 < v2
807 var c12 = %_CallFunction(receiver, v1, v2, comparefn);
808 if (c12 > 0) {
809 // v0 <= v2 < v1
810 var tmp = v1;
811 v1 = v2;
812 v2 = tmp;
813 } 786 }
814 } 787 // Find a pivot as the median of first, last and middle element.
815 // v0 <= v1 <= v2 788 var v0 = a[from];
816 a[from] = v0; 789 var v1 = a[to - 1];
817 a[to - 1] = v2; 790 var middle_index = from + ((to - from) >> 1);
818 var pivot = v1; 791 var v2 = a[middle_index];
819 var low_end = from + 1; // Upper bound of elements lower than pivot. 792 var c01 = %_CallFunction(receiver, v0, v1, comparefn);
820 var high_start = to - 1; // Lower bound of elements greater than pivot. 793 if (c01 > 0) {
821 a[middle_index] = a[low_end]; 794 // v1 < v0, so swap them.
822 a[low_end] = pivot; 795 var tmp = v0;
796 v0 = v1;
797 v1 = tmp;
798 } // v0 <= v1.
799 var c02 = %_CallFunction(receiver, v0, v2, comparefn);
800 if (c02 >= 0) {
801 // v2 <= v0 <= v1.
802 var tmp = v0;
803 v0 = v2;
804 v2 = v1;
805 v1 = tmp;
806 } else {
807 // v0 <= v1 && v0 < v2
808 var c12 = %_CallFunction(receiver, v1, v2, comparefn);
809 if (c12 > 0) {
810 // v0 <= v2 < v1
811 var tmp = v1;
812 v1 = v2;
813 v2 = tmp;
814 }
815 }
816 // v0 <= v1 <= v2
817 a[from] = v0;
818 a[to - 1] = v2;
819 var pivot = v1;
820 var low_end = from + 1; // Upper bound of elements lower than pivot.
821 var high_start = to - 1; // Lower bound of elements greater than pivot.
822 a[middle_index] = a[low_end];
823 a[low_end] = pivot;
823 824
824 // From low_end to i are elements equal to pivot. 825 // From low_end to i are elements equal to pivot.
825 // From i to high_start are elements that haven't been compared yet. 826 // From i to high_start are elements that haven't been compared yet.
826 partition: for (var i = low_end + 1; i < high_start; i++) { 827 partition: for (var i = low_end + 1; i < high_start; i++) {
827 var element = a[i]; 828 var element = a[i];
828 var order = %_CallFunction(receiver, element, pivot, comparefn); 829 var order = %_CallFunction(receiver, element, pivot, comparefn);
829 if (order < 0) {
830 a[i] = a[low_end];
831 a[low_end] = element;
832 low_end++;
833 } else if (order > 0) {
834 do {
835 high_start--;
836 if (high_start == i) break partition;
837 var top_elem = a[high_start];
838 order = %_CallFunction(receiver, top_elem, pivot, comparefn);
839 } while (order > 0);
840 a[i] = a[high_start];
841 a[high_start] = element;
842 if (order < 0) { 830 if (order < 0) {
843 element = a[i];
844 a[i] = a[low_end]; 831 a[i] = a[low_end];
845 a[low_end] = element; 832 a[low_end] = element;
846 low_end++; 833 low_end++;
834 } else if (order > 0) {
835 do {
836 high_start--;
837 if (high_start == i) break partition;
838 var top_elem = a[high_start];
839 order = %_CallFunction(receiver, top_elem, pivot, comparefn);
840 } while (order > 0);
841 a[i] = a[high_start];
842 a[high_start] = element;
843 if (order < 0) {
844 element = a[i];
845 a[i] = a[low_end];
846 a[low_end] = element;
847 low_end++;
848 }
847 } 849 }
848 } 850 }
851 if (to - high_start < low_end - from) {
852 QuickSort(a, high_start, to);
853 to = low_end;
854 } else {
855 QuickSort(a, from, low_end);
856 from = high_start;
857 }
849 } 858 }
850 QuickSort(a, from, low_end);
851 QuickSort(a, high_start, to);
852 }; 859 };
853 860
854 // Copy elements in the range 0..length from obj's prototype chain 861 // Copy elements in the range 0..length from obj's prototype chain
855 // to obj itself, if obj has holes. Return one more than the maximal index 862 // to obj itself, if obj has holes. Return one more than the maximal index
856 // of a prototype property. 863 // of a prototype property.
857 var CopyFromPrototype = function CopyFromPrototype(obj, length) { 864 var CopyFromPrototype = function CopyFromPrototype(obj, length) {
858 var max = 0; 865 var max = 0;
859 for (var proto = obj.__proto__; proto; proto = proto.__proto__) { 866 for (var proto = obj.__proto__; proto; proto = proto.__proto__) {
860 var indices = %GetArrayKeys(proto, length); 867 var indices = %GetArrayKeys(proto, length);
861 if (indices.length > 0) { 868 if (indices.length > 0) {
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
1524 // exposed to user code. 1531 // exposed to user code.
1525 // Adding only the functions that are actually used. 1532 // Adding only the functions that are actually used.
1526 SetUpLockedPrototype(InternalArray, $Array(), $Array( 1533 SetUpLockedPrototype(InternalArray, $Array(), $Array(
1527 "join", getFunction("join", ArrayJoin), 1534 "join", getFunction("join", ArrayJoin),
1528 "pop", getFunction("pop", ArrayPop), 1535 "pop", getFunction("pop", ArrayPop),
1529 "push", getFunction("push", ArrayPush) 1536 "push", getFunction("push", ArrayPush)
1530 )); 1537 ));
1531 } 1538 }
1532 1539
1533 SetUpArray(); 1540 SetUpArray();
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-2185.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698