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

Side by Side Diff: src/array.js

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 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 | « src/arm/virtual-frame-arm.cc ('k') | src/assembler.h » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 // This file relies on the fact that the following declarations have been made 28 // This file relies on the fact that the following declarations have been made
29 // in runtime.js: 29 // in runtime.js:
30 // const $Array = global.Array; 30 // const $Array = global.Array;
31 31
32 // ------------------------------------------------------------------- 32 // -------------------------------------------------------------------
33 33
34 // Global list of arrays visited during toString, toLocaleString and 34 // Global list of arrays visited during toString, toLocaleString and
35 // join invocations. 35 // join invocations.
36 var visited_arrays = new $Array(); 36 var visited_arrays = new InternalArray();
37 37
38 38
39 // Gets a sorted array of array keys. Useful for operations on sparse 39 // Gets a sorted array of array keys. Useful for operations on sparse
40 // arrays. Dupes have not been removed. 40 // arrays. Dupes have not been removed.
41 function GetSortedArrayKeys(array, intervals) { 41 function GetSortedArrayKeys(array, intervals) {
42 var length = intervals.length; 42 var length = intervals.length;
43 var keys = []; 43 var keys = [];
44 for (var k = 0; k < length; k++) { 44 for (var k = 0; k < length; k++) {
45 var key = intervals[k]; 45 var key = intervals[k];
46 if (key < 0) { 46 if (key < 0) {
(...skipping 19 matching lines...) Expand all
66 return keys; 66 return keys;
67 } 67 }
68 68
69 69
70 // Optimized for sparse arrays if separator is ''. 70 // Optimized for sparse arrays if separator is ''.
71 function SparseJoin(array, len, convert) { 71 function SparseJoin(array, len, convert) {
72 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); 72 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len));
73 var last_key = -1; 73 var last_key = -1;
74 var keys_length = keys.length; 74 var keys_length = keys.length;
75 75
76 var elements = new $Array(keys_length); 76 var elements = new InternalArray(keys_length);
77 var elements_length = 0; 77 var elements_length = 0;
78 78
79 for (var i = 0; i < keys_length; i++) { 79 for (var i = 0; i < keys_length; i++) {
80 var key = keys[i]; 80 var key = keys[i];
81 if (key != last_key) { 81 if (key != last_key) {
82 var e = array[key]; 82 var e = array[key];
83 if (!IS_STRING(e)) e = convert(e); 83 if (!IS_STRING(e)) e = convert(e);
84 elements[elements_length++] = e; 84 elements[elements_length++] = e;
85 last_key = key; 85 last_key = key;
86 } 86 }
(...skipping 28 matching lines...) Expand all
115 } 115 }
116 116
117 // Fast case for one-element arrays. 117 // Fast case for one-element arrays.
118 if (length == 1) { 118 if (length == 1) {
119 var e = array[0]; 119 var e = array[0];
120 if (IS_STRING(e)) return e; 120 if (IS_STRING(e)) return e;
121 return convert(e); 121 return convert(e);
122 } 122 }
123 123
124 // Construct an array for the elements. 124 // Construct an array for the elements.
125 var elements = new $Array(length); 125 var elements = new InternalArray(length);
126 126
127 // We pull the empty separator check outside the loop for speed! 127 // We pull the empty separator check outside the loop for speed!
128 if (separator.length == 0) { 128 if (separator.length == 0) {
129 var elements_length = 0; 129 var elements_length = 0;
130 for (var i = 0; i < length; i++) { 130 for (var i = 0; i < length; i++) {
131 var e = array[i]; 131 var e = array[i];
132 if (!IS_UNDEFINED(e)) { 132 if (!IS_UNDEFINED(e)) {
133 if (!IS_STRING(e)) e = convert(e); 133 if (!IS_STRING(e)) e = convert(e);
134 elements[elements_length++] = e; 134 elements[elements_length++] = e;
135 } 135 }
136 } 136 }
137 elements.length = elements_length; 137 elements.length = elements_length;
138 var result = %_FastAsciiArrayJoin(elements, ''); 138 var result = %_FastAsciiArrayJoin(elements, '');
139 if (!IS_UNDEFINED(result)) return result; 139 if (!IS_UNDEFINED(result)) return result;
140 return %StringBuilderConcat(elements, elements_length, ''); 140 return %StringBuilderConcat(elements, elements_length, '');
141 } 141 }
142 // Non-empty separator case. 142 // Non-empty separator case.
143 // If the first element is a number then use the heuristic that the 143 // If the first element is a number then use the heuristic that the
144 // remaining elements are also likely to be numbers. 144 // remaining elements are also likely to be numbers.
145 if (!IS_NUMBER(array[0])) { 145 if (!IS_NUMBER(array[0])) {
146 for (var i = 0; i < length; i++) { 146 for (var i = 0; i < length; i++) {
147 var e = array[i]; 147 var e = array[i];
148 if (!IS_STRING(e)) e = convert(e); 148 if (!IS_STRING(e)) e = convert(e);
149 elements[i] = e; 149 elements[i] = e;
150 } 150 }
151 } else { 151 } else {
152 for (var i = 0; i < length; i++) { 152 for (var i = 0; i < length; i++) {
153 var e = array[i]; 153 var e = array[i];
154 if (IS_NUMBER(e)) elements[i] = %_NumberToString(e); 154 if (IS_NUMBER(e)) elements[i] = %_NumberToString(e);
155 else { 155 else {
156 if (!IS_STRING(e)) e = convert(e); 156 if (!IS_STRING(e)) e = convert(e);
157 elements[i] = e; 157 elements[i] = e;
158 } 158 }
159 } 159 }
160 } 160 }
161 var result = %_FastAsciiArrayJoin(elements, separator); 161 var result = %_FastAsciiArrayJoin(elements, separator);
162 if (!IS_UNDEFINED(result)) return result; 162 if (!IS_UNDEFINED(result)) return result;
163 163
164 return %StringBuilderJoin(elements, length, separator); 164 return %StringBuilderJoin(elements, length, separator);
165 } finally { 165 } finally {
166 // Make sure to remove the last element of the visited array no 166 // Make sure to remove the last element of the visited array no
167 // matter what happens. 167 // matter what happens.
168 if (is_array) visited_arrays.length = visited_arrays.length - 1; 168 if (is_array) visited_arrays.length = visited_arrays.length - 1;
169 } 169 }
170 } 170 }
171 171
172 172
173 function ConvertToString(x) { 173 function ConvertToString(x) {
174 // Assumes x is a non-string. 174 // Assumes x is a non-string.
175 if (IS_NUMBER(x)) return %_NumberToString(x); 175 if (IS_NUMBER(x)) return %_NumberToString(x);
176 if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; 176 if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
177 return (IS_NULL_OR_UNDEFINED(x)) ? '' : %ToString(%DefaultString(x)); 177 return (IS_NULL_OR_UNDEFINED(x)) ? '' : %ToString(%DefaultString(x));
178 } 178 }
179 179
180 180
181 function ConvertToLocaleString(e) { 181 function ConvertToLocaleString(e) {
182 if (e == null) { 182 if (e == null) {
183 return ''; 183 return '';
184 } else { 184 } else {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } 234 }
235 } 235 }
236 } 236 }
237 } 237 }
238 238
239 239
240 // This function implements the optimized splice implementation that can use 240 // This function implements the optimized splice implementation that can use
241 // special array operations to handle sparse arrays in a sensible fashion. 241 // special array operations to handle sparse arrays in a sensible fashion.
242 function SmartMove(array, start_i, del_count, len, num_additional_args) { 242 function SmartMove(array, start_i, del_count, len, num_additional_args) {
243 // Move data to new array. 243 // Move data to new array.
244 var new_array = new $Array(len - del_count + num_additional_args); 244 var new_array = new InternalArray(len - del_count + num_additional_args);
245 var intervals = %GetArrayKeys(array, len); 245 var intervals = %GetArrayKeys(array, len);
246 var length = intervals.length; 246 var length = intervals.length;
247 for (var k = 0; k < length; k++) { 247 for (var k = 0; k < length; k++) {
248 var key = intervals[k]; 248 var key = intervals[k];
249 if (key < 0) { 249 if (key < 0) {
250 var j = -1 - key; 250 var j = -1 - key;
251 var interval_limit = j + intervals[++k]; 251 var interval_limit = j + intervals[++k];
252 while (j < start_i && j < interval_limit) { 252 while (j < start_i && j < interval_limit) {
253 // The spec could also be interpreted such that 253 // The spec could also be interpreted such that
254 // %HasLocalProperty would be the appropriate test. We follow 254 // %HasLocalProperty would be the appropriate test. We follow
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 var m = %_ArgumentsLength(); 411 var m = %_ArgumentsLength();
412 for (var i = 0; i < m; i++) { 412 for (var i = 0; i < m; i++) {
413 this[i+n] = %_Arguments(i); 413 this[i+n] = %_Arguments(i);
414 } 414 }
415 this.length = n + m; 415 this.length = n + m;
416 return this.length; 416 return this.length;
417 } 417 }
418 418
419 419
420 function ArrayConcat(arg1) { // length == 1 420 function ArrayConcat(arg1) { // length == 1
421 // TODO: can we just use arguments?
422 var arg_count = %_ArgumentsLength(); 421 var arg_count = %_ArgumentsLength();
423 var arrays = new $Array(1 + arg_count); 422 var arrays = new InternalArray(1 + arg_count);
424 arrays[0] = this; 423 arrays[0] = this;
425 for (var i = 0; i < arg_count; i++) { 424 for (var i = 0; i < arg_count; i++) {
426 arrays[i + 1] = %_Arguments(i); 425 arrays[i + 1] = %_Arguments(i);
427 } 426 }
428 427
429 return %ArrayConcat(arrays); 428 return %ArrayConcat(arrays);
430 } 429 }
431 430
432 431
433 // For implementing reverse() on large, sparse arrays. 432 // For implementing reverse() on large, sparse arrays.
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 throw MakeTypeError('called_non_callable', [ f ]); 918 throw MakeTypeError('called_non_callable', [ f ]);
920 } 919 }
921 // Pull out the length so that modifications to the length in the 920 // Pull out the length so that modifications to the length in the
922 // loop will not affect the looping. 921 // loop will not affect the looping.
923 var length = this.length; 922 var length = this.length;
924 var result = []; 923 var result = [];
925 var result_length = 0; 924 var result_length = 0;
926 for (var i = 0; i < length; i++) { 925 for (var i = 0; i < length; i++) {
927 var current = this[i]; 926 var current = this[i];
928 if (!IS_UNDEFINED(current) || i in this) { 927 if (!IS_UNDEFINED(current) || i in this) {
929 if (f.call(receiver, current, i, this)) result[result_length++] = current; 928 if (f.call(receiver, current, i, this)) {
929 result[result_length++] = current;
930 }
930 } 931 }
931 } 932 }
932 return result; 933 return result;
933 } 934 }
934 935
935 936
936 function ArrayForEach(f, receiver) { 937 function ArrayForEach(f, receiver) {
937 if (!IS_FUNCTION(f)) { 938 if (!IS_FUNCTION(f)) {
938 throw MakeTypeError('called_non_callable', [ f ]); 939 throw MakeTypeError('called_non_callable', [ f ]);
939 } 940 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 return true; 985 return true;
985 } 986 }
986 987
987 function ArrayMap(f, receiver) { 988 function ArrayMap(f, receiver) {
988 if (!IS_FUNCTION(f)) { 989 if (!IS_FUNCTION(f)) {
989 throw MakeTypeError('called_non_callable', [ f ]); 990 throw MakeTypeError('called_non_callable', [ f ]);
990 } 991 }
991 // Pull out the length so that modifications to the length in the 992 // Pull out the length so that modifications to the length in the
992 // loop will not affect the looping. 993 // loop will not affect the looping.
993 var length = TO_UINT32(this.length); 994 var length = TO_UINT32(this.length);
994 var result = new $Array(length); 995 var result = new $Array();
996 var accumulator = new InternalArray(length);
995 for (var i = 0; i < length; i++) { 997 for (var i = 0; i < length; i++) {
996 var current = this[i]; 998 var current = this[i];
997 if (!IS_UNDEFINED(current) || i in this) { 999 if (!IS_UNDEFINED(current) || i in this) {
998 result[i] = f.call(receiver, current, i, this); 1000 accumulator[i] = f.call(receiver, current, i, this);
999 } 1001 }
1000 } 1002 }
1003 %MoveArrayContents(accumulator, result);
1001 return result; 1004 return result;
1002 } 1005 }
1003 1006
1004 1007
1005 function ArrayIndexOf(element, index) { 1008 function ArrayIndexOf(element, index) {
1006 var length = TO_UINT32(this.length); 1009 var length = TO_UINT32(this.length);
1007 if (length == 0) return -1; 1010 if (length == 0) return -1;
1008 if (IS_UNDEFINED(index)) { 1011 if (IS_UNDEFINED(index)) {
1009 index = 0; 1012 index = 0;
1010 } else { 1013 } else {
1011 index = TO_INTEGER(index); 1014 index = TO_INTEGER(index);
1012 // If index is negative, index from the end of the array. 1015 // If index is negative, index from the end of the array.
1013 if (index < 0) { 1016 if (index < 0) {
1014 index = length + index; 1017 index = length + index;
1015 // If index is still negative, search the entire array. 1018 // If index is still negative, search the entire array.
1016 if (index < 0) index = 0; 1019 if (index < 0) index = 0;
1017 } 1020 }
1018 } 1021 }
1019 var min = index; 1022 var min = index;
1020 var max = length; 1023 var max = length;
1021 if (UseSparseVariant(this, length, true)) { 1024 if (UseSparseVariant(this, length, IS_ARRAY(this))) {
1022 var intervals = %GetArrayKeys(this, length); 1025 var intervals = %GetArrayKeys(this, length);
1023 if (intervals.length == 2 && intervals[0] < 0) { 1026 if (intervals.length == 2 && intervals[0] < 0) {
1024 // A single interval. 1027 // A single interval.
1025 var intervalMin = -(intervals[0] + 1); 1028 var intervalMin = -(intervals[0] + 1);
1026 var intervalMax = intervalMin + intervals[1]; 1029 var intervalMax = intervalMin + intervals[1];
1027 min = MAX(min, intervalMin); 1030 if (min < intervalMin) min = intervalMin;
1028 max = intervalMax; // Capped by length already. 1031 max = intervalMax; // Capped by length already.
1029 // Fall through to loop below. 1032 // Fall through to loop below.
1030 } else { 1033 } else {
1031 if (intervals.length == 0) return -1; 1034 if (intervals.length == 0) return -1;
1032 // Get all the keys in sorted order. 1035 // Get all the keys in sorted order.
1033 var sortedKeys = GetSortedArrayKeys(this, intervals); 1036 var sortedKeys = GetSortedArrayKeys(this, intervals);
1034 var n = sortedKeys.length; 1037 var n = sortedKeys.length;
1035 var i = 0; 1038 var i = 0;
1036 while (i < n && sortedKeys[i] < index) i++; 1039 while (i < n && sortedKeys[i] < index) i++;
1037 while (i < n) { 1040 while (i < n) {
(...skipping 29 matching lines...) Expand all
1067 } else { 1070 } else {
1068 index = TO_INTEGER(index); 1071 index = TO_INTEGER(index);
1069 // If index is negative, index from end of the array. 1072 // If index is negative, index from end of the array.
1070 if (index < 0) index += length; 1073 if (index < 0) index += length;
1071 // If index is still negative, do not search the array. 1074 // If index is still negative, do not search the array.
1072 if (index < 0) return -1; 1075 if (index < 0) return -1;
1073 else if (index >= length) index = length - 1; 1076 else if (index >= length) index = length - 1;
1074 } 1077 }
1075 var min = 0; 1078 var min = 0;
1076 var max = index; 1079 var max = index;
1077 if (UseSparseVariant(this, length, true)) { 1080 if (UseSparseVariant(this, length, IS_ARRAY(this))) {
1078 var intervals = %GetArrayKeys(this, index + 1); 1081 var intervals = %GetArrayKeys(this, index + 1);
1079 if (intervals.length == 2 && intervals[0] < 0) { 1082 if (intervals.length == 2 && intervals[0] < 0) {
1080 // A single interval. 1083 // A single interval.
1081 var intervalMin = -(intervals[0] + 1); 1084 var intervalMin = -(intervals[0] + 1);
1082 var intervalMax = intervalMin + intervals[1]; 1085 var intervalMax = intervalMin + intervals[1];
1083 min = MAX(min, intervalMin); 1086 if (min < intervalMin) min = intervalMin;
1084 max = intervalMax; // Capped by index already. 1087 max = intervalMax; // Capped by index already.
1085 // Fall through to loop below. 1088 // Fall through to loop below.
1086 } else { 1089 } else {
1087 if (intervals.length == 0) return -1; 1090 if (intervals.length == 0) return -1;
1088 // Get all the keys in sorted order. 1091 // Get all the keys in sorted order.
1089 var sortedKeys = GetSortedArrayKeys(this, intervals); 1092 var sortedKeys = GetSortedArrayKeys(this, intervals);
1090 var i = sortedKeys.length - 1; 1093 var i = sortedKeys.length - 1;
1091 while (i >= 0) { 1094 while (i >= 0) {
1092 var key = sortedKeys[i]; 1095 var key = sortedKeys[i];
1093 if (!IS_UNDEFINED(key) && this[key] === element) return key; 1096 if (!IS_UNDEFINED(key) && this[key] === element) return key;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 "some", getFunction("some", ArraySome, 1), 1222 "some", getFunction("some", ArraySome, 1),
1220 "every", getFunction("every", ArrayEvery, 1), 1223 "every", getFunction("every", ArrayEvery, 1),
1221 "map", getFunction("map", ArrayMap, 1), 1224 "map", getFunction("map", ArrayMap, 1),
1222 "indexOf", getFunction("indexOf", ArrayIndexOf, 1), 1225 "indexOf", getFunction("indexOf", ArrayIndexOf, 1),
1223 "lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1), 1226 "lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1),
1224 "reduce", getFunction("reduce", ArrayReduce, 1), 1227 "reduce", getFunction("reduce", ArrayReduce, 1),
1225 "reduceRight", getFunction("reduceRight", ArrayReduceRight, 1) 1228 "reduceRight", getFunction("reduceRight", ArrayReduceRight, 1)
1226 )); 1229 ));
1227 1230
1228 %FinishArrayPrototypeSetup($Array.prototype); 1231 %FinishArrayPrototypeSetup($Array.prototype);
1232
1233 // The internal Array prototype doesn't need to be fancy, since it's never
1234 // exposed to user code, so no hidden prototypes or DONT_ENUM attributes
1235 // are necessary.
1236 // The null __proto__ ensures that we never inherit any user created
1237 // getters or setters from, e.g., Object.prototype.
1238 InternalArray.prototype.__proto__ = null;
1239 // Adding only the functions that are actually used, and a toString.
1240 InternalArray.prototype.join = getFunction("join", ArrayJoin);
1241 InternalArray.prototype.pop = getFunction("pop", ArrayPop);
1242 InternalArray.prototype.push = getFunction("push", ArrayPush);
1243 InternalArray.prototype.toString = function() {
1244 return "Internal Array, length " + this.length;
1245 };
1229 } 1246 }
1230 1247
1231 1248
1232 SetupArray(); 1249 SetupArray();
OLDNEW
« no previous file with comments | « src/arm/virtual-frame-arm.cc ('k') | src/assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698