OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 if (!maybe_result->ToObject(&result)) return maybe_result; | 170 if (!maybe_result->ToObject(&result)) return maybe_result; |
171 } | 171 } |
172 } | 172 } |
173 } | 173 } |
174 } | 174 } |
175 | 175 |
176 // Deep copy local elements. | 176 // Deep copy local elements. |
177 // Pixel elements cannot be created using an object literal. | 177 // Pixel elements cannot be created using an object literal. |
178 ASSERT(!copy->HasExternalArrayElements()); | 178 ASSERT(!copy->HasExternalArrayElements()); |
179 switch (copy->GetElementsKind()) { | 179 switch (copy->GetElementsKind()) { |
| 180 case FAST_SMI_ONLY_ELEMENTS: |
180 case FAST_ELEMENTS: { | 181 case FAST_ELEMENTS: { |
181 FixedArray* elements = FixedArray::cast(copy->elements()); | 182 FixedArray* elements = FixedArray::cast(copy->elements()); |
182 if (elements->map() == heap->fixed_cow_array_map()) { | 183 if (elements->map() == heap->fixed_cow_array_map()) { |
183 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 184 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
184 #ifdef DEBUG | 185 #ifdef DEBUG |
185 for (int i = 0; i < elements->length(); i++) { | 186 for (int i = 0; i < elements->length(); i++) { |
186 ASSERT(!elements->get(i)->IsJSObject()); | 187 ASSERT(!elements->get(i)->IsJSObject()); |
187 } | 188 } |
188 #endif | 189 #endif |
189 } else { | 190 } else { |
190 for (int i = 0; i < elements->length(); i++) { | 191 for (int i = 0; i < elements->length(); i++) { |
191 Object* value = elements->get(i); | 192 Object* value = elements->get(i); |
| 193 ASSERT(value->IsSmi() || |
| 194 value->IsTheHole() || |
| 195 (copy->GetElementsKind() == FAST_ELEMENTS)); |
192 if (value->IsJSObject()) { | 196 if (value->IsJSObject()) { |
193 JSObject* js_object = JSObject::cast(value); | 197 JSObject* js_object = JSObject::cast(value); |
194 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, | 198 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, |
195 js_object); | 199 js_object); |
196 if (!maybe_result->ToObject(&result)) return maybe_result; | 200 if (!maybe_result->ToObject(&result)) return maybe_result; |
197 } | 201 } |
198 elements->set(i, result); | 202 elements->set(i, result); |
199 } | 203 } |
200 } | 204 } |
201 } | 205 } |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 Handle<JSFunction> constructor( | 429 Handle<JSFunction> constructor( |
426 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); | 430 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
427 Handle<Object> object = isolate->factory()->NewJSObject(constructor); | 431 Handle<Object> object = isolate->factory()->NewJSObject(constructor); |
428 | 432 |
429 const bool is_cow = | 433 const bool is_cow = |
430 (elements->map() == isolate->heap()->fixed_cow_array_map()); | 434 (elements->map() == isolate->heap()->fixed_cow_array_map()); |
431 Handle<FixedArray> copied_elements = | 435 Handle<FixedArray> copied_elements = |
432 is_cow ? elements : isolate->factory()->CopyFixedArray(elements); | 436 is_cow ? elements : isolate->factory()->CopyFixedArray(elements); |
433 | 437 |
434 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); | 438 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); |
| 439 bool has_non_smi = false; |
435 if (is_cow) { | 440 if (is_cow) { |
436 #ifdef DEBUG | |
437 // Copy-on-write arrays must be shallow (and simple). | 441 // Copy-on-write arrays must be shallow (and simple). |
438 for (int i = 0; i < content->length(); i++) { | 442 if (FLAG_smi_only_arrays) { |
439 ASSERT(!content->get(i)->IsFixedArray()); | 443 for (int i = 0; i < content->length(); i++) { |
| 444 Object* current = content->get(i); |
| 445 ASSERT(!current->IsFixedArray()); |
| 446 if (!current->IsSmi()) { |
| 447 has_non_smi = true; |
| 448 } |
| 449 } |
| 450 } else { |
| 451 #if DEBUG |
| 452 for (int i = 0; i < content->length(); i++) { |
| 453 ASSERT(!content->get(i)->IsFixedArray()); |
| 454 } |
| 455 #endif |
440 } | 456 } |
441 #endif | |
442 } else { | 457 } else { |
443 for (int i = 0; i < content->length(); i++) { | 458 for (int i = 0; i < content->length(); i++) { |
444 if (content->get(i)->IsFixedArray()) { | 459 Object* current = content->get(i); |
| 460 if (current->IsFixedArray()) { |
445 // The value contains the constant_properties of a | 461 // The value contains the constant_properties of a |
446 // simple object or array literal. | 462 // simple object or array literal. |
447 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); | 463 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); |
448 Handle<Object> result = | 464 Handle<Object> result = |
449 CreateLiteralBoilerplate(isolate, literals, fa); | 465 CreateLiteralBoilerplate(isolate, literals, fa); |
450 if (result.is_null()) return result; | 466 if (result.is_null()) return result; |
451 content->set(i, *result); | 467 content->set(i, *result); |
| 468 has_non_smi = true; |
| 469 } else { |
| 470 if (!current->IsSmi()) { |
| 471 has_non_smi = true; |
| 472 } |
452 } | 473 } |
453 } | 474 } |
454 } | 475 } |
455 | 476 |
456 // Set the elements. | 477 // Set the elements. |
457 Handle<JSArray>::cast(object)->SetContent(*content); | 478 Handle<JSArray> js_object(Handle<JSArray>::cast(object)); |
| 479 isolate->factory()->SetContent(js_object, content); |
| 480 |
| 481 if (FLAG_smi_only_arrays) { |
| 482 if (has_non_smi && js_object->HasFastSmiOnlyElements()) { |
| 483 isolate->factory()->EnsureCanContainNonSmiElements(js_object); |
| 484 } |
| 485 } |
| 486 |
458 return object; | 487 return object; |
459 } | 488 } |
460 | 489 |
461 | 490 |
462 static Handle<Object> CreateLiteralBoilerplate( | 491 static Handle<Object> CreateLiteralBoilerplate( |
463 Isolate* isolate, | 492 Isolate* isolate, |
464 Handle<FixedArray> literals, | 493 Handle<FixedArray> literals, |
465 Handle<FixedArray> array) { | 494 Handle<FixedArray> array) { |
466 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | 495 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
467 const bool kHasNoFunctionLiteral = false; | 496 const bool kHasNoFunctionLiteral = false; |
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 ASSERT(args.length() == 2); | 1653 ASSERT(args.length() == 2); |
1625 CONVERT_ARG_CHECKED(JSObject, object, 0); | 1654 CONVERT_ARG_CHECKED(JSObject, object, 0); |
1626 CONVERT_SMI_ARG_CHECKED(properties, 1); | 1655 CONVERT_SMI_ARG_CHECKED(properties, 1); |
1627 if (object->HasFastProperties()) { | 1656 if (object->HasFastProperties()) { |
1628 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); | 1657 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); |
1629 } | 1658 } |
1630 return *object; | 1659 return *object; |
1631 } | 1660 } |
1632 | 1661 |
1633 | 1662 |
| 1663 RUNTIME_FUNCTION(MaybeObject*, Runtime_NonSmiElementStored) { |
| 1664 ASSERT(args.length() == 1); |
| 1665 CONVERT_ARG_CHECKED(JSObject, object, 0); |
| 1666 if (FLAG_smi_only_arrays && object->HasFastSmiOnlyElements()) { |
| 1667 MaybeObject* maybe_map = object->GetElementsTransitionMap(FAST_ELEMENTS); |
| 1668 Map* map; |
| 1669 if (!maybe_map->To<Map>(&map)) return maybe_map; |
| 1670 object->set_map(Map::cast(map)); |
| 1671 } |
| 1672 return *object; |
| 1673 } |
| 1674 |
| 1675 |
1634 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { | 1676 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { |
1635 HandleScope scope(isolate); | 1677 HandleScope scope(isolate); |
1636 ASSERT(args.length() == 4); | 1678 ASSERT(args.length() == 4); |
1637 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); | 1679 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); |
1638 CONVERT_ARG_CHECKED(String, subject, 1); | 1680 CONVERT_ARG_CHECKED(String, subject, 1); |
1639 // Due to the way the JS calls are constructed this must be less than the | 1681 // Due to the way the JS calls are constructed this must be less than the |
1640 // length of a string, i.e. it is always a Smi. We check anyway for security. | 1682 // length of a string, i.e. it is always a Smi. We check anyway for security. |
1641 CONVERT_SMI_ARG_CHECKED(index, 2); | 1683 CONVERT_SMI_ARG_CHECKED(index, 2); |
1642 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); | 1684 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); |
1643 RUNTIME_ASSERT(last_match_info->HasFastElements()); | 1685 RUNTIME_ASSERT(last_match_info->HasFastElements()); |
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 NoHandleAllocation ha; | 2249 NoHandleAllocation ha; |
2208 ASSERT(args.length() == 1); | 2250 ASSERT(args.length() == 1); |
2209 return CharFromCode(isolate, args[0]); | 2251 return CharFromCode(isolate, args[0]); |
2210 } | 2252 } |
2211 | 2253 |
2212 | 2254 |
2213 class FixedArrayBuilder { | 2255 class FixedArrayBuilder { |
2214 public: | 2256 public: |
2215 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) | 2257 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) |
2216 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), | 2258 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), |
2217 length_(0) { | 2259 length_(0), |
| 2260 has_non_smi_elements_(false) { |
2218 // Require a non-zero initial size. Ensures that doubling the size to | 2261 // Require a non-zero initial size. Ensures that doubling the size to |
2219 // extend the array will work. | 2262 // extend the array will work. |
2220 ASSERT(initial_capacity > 0); | 2263 ASSERT(initial_capacity > 0); |
2221 } | 2264 } |
2222 | 2265 |
2223 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) | 2266 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) |
2224 : array_(backing_store), | 2267 : array_(backing_store), |
2225 length_(0) { | 2268 length_(0), |
| 2269 has_non_smi_elements_(false) { |
2226 // Require a non-zero initial size. Ensures that doubling the size to | 2270 // Require a non-zero initial size. Ensures that doubling the size to |
2227 // extend the array will work. | 2271 // extend the array will work. |
2228 ASSERT(backing_store->length() > 0); | 2272 ASSERT(backing_store->length() > 0); |
2229 } | 2273 } |
2230 | 2274 |
2231 bool HasCapacity(int elements) { | 2275 bool HasCapacity(int elements) { |
2232 int length = array_->length(); | 2276 int length = array_->length(); |
2233 int required_length = length_ + elements; | 2277 int required_length = length_ + elements; |
2234 return (length >= required_length); | 2278 return (length >= required_length); |
2235 } | 2279 } |
2236 | 2280 |
2237 void EnsureCapacity(int elements) { | 2281 void EnsureCapacity(int elements) { |
2238 int length = array_->length(); | 2282 int length = array_->length(); |
2239 int required_length = length_ + elements; | 2283 int required_length = length_ + elements; |
2240 if (length < required_length) { | 2284 if (length < required_length) { |
2241 int new_length = length; | 2285 int new_length = length; |
2242 do { | 2286 do { |
2243 new_length *= 2; | 2287 new_length *= 2; |
2244 } while (new_length < required_length); | 2288 } while (new_length < required_length); |
2245 Handle<FixedArray> extended_array = | 2289 Handle<FixedArray> extended_array = |
2246 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); | 2290 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); |
2247 array_->CopyTo(0, *extended_array, 0, length_); | 2291 array_->CopyTo(0, *extended_array, 0, length_); |
2248 array_ = extended_array; | 2292 array_ = extended_array; |
2249 } | 2293 } |
2250 } | 2294 } |
2251 | 2295 |
2252 void Add(Object* value) { | 2296 void Add(Object* value) { |
| 2297 ASSERT(!value->IsSmi()); |
2253 ASSERT(length_ < capacity()); | 2298 ASSERT(length_ < capacity()); |
2254 array_->set(length_, value); | 2299 array_->set(length_, value); |
2255 length_++; | 2300 length_++; |
| 2301 has_non_smi_elements_ = true; |
2256 } | 2302 } |
2257 | 2303 |
2258 void Add(Smi* value) { | 2304 void Add(Smi* value) { |
| 2305 ASSERT(value->IsSmi()); |
2259 ASSERT(length_ < capacity()); | 2306 ASSERT(length_ < capacity()); |
2260 array_->set(length_, value); | 2307 array_->set(length_, value); |
2261 length_++; | 2308 length_++; |
2262 } | 2309 } |
2263 | 2310 |
2264 Handle<FixedArray> array() { | 2311 Handle<FixedArray> array() { |
2265 return array_; | 2312 return array_; |
2266 } | 2313 } |
2267 | 2314 |
2268 int length() { | 2315 int length() { |
2269 return length_; | 2316 return length_; |
2270 } | 2317 } |
2271 | 2318 |
2272 int capacity() { | 2319 int capacity() { |
2273 return array_->length(); | 2320 return array_->length(); |
2274 } | 2321 } |
2275 | 2322 |
2276 Handle<JSArray> ToJSArray() { | 2323 Handle<JSArray> ToJSArray() { |
2277 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_); | 2324 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_); |
2278 result_array->set_length(Smi::FromInt(length_)); | 2325 result_array->set_length(Smi::FromInt(length_)); |
2279 return result_array; | 2326 return result_array; |
2280 } | 2327 } |
2281 | 2328 |
2282 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { | 2329 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { |
2283 target_array->set_elements(*array_); | 2330 FACTORY->SetContent(target_array, array_); |
2284 target_array->set_length(Smi::FromInt(length_)); | 2331 target_array->set_length(Smi::FromInt(length_)); |
2285 return target_array; | 2332 return target_array; |
2286 } | 2333 } |
2287 | 2334 |
2288 private: | 2335 private: |
2289 Handle<FixedArray> array_; | 2336 Handle<FixedArray> array_; |
2290 int length_; | 2337 int length_; |
| 2338 bool has_non_smi_elements_; |
2291 }; | 2339 }; |
2292 | 2340 |
2293 | 2341 |
2294 // Forward declarations. | 2342 // Forward declarations. |
2295 const int kStringBuilderConcatHelperLengthBits = 11; | 2343 const int kStringBuilderConcatHelperLengthBits = 11; |
2296 const int kStringBuilderConcatHelperPositionBits = 19; | 2344 const int kStringBuilderConcatHelperPositionBits = 19; |
2297 | 2345 |
2298 template <typename schar> | 2346 template <typename schar> |
2299 static inline void StringBuilderConcatHelper(String*, | 2347 static inline void StringBuilderConcatHelper(String*, |
2300 schar*, | 2348 schar*, |
(...skipping 3813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6114 if (static_cast<uint32_t>(indices.length()) < limit) { | 6162 if (static_cast<uint32_t>(indices.length()) < limit) { |
6115 indices.Add(subject_length); | 6163 indices.Add(subject_length); |
6116 } | 6164 } |
6117 | 6165 |
6118 // The list indices now contains the end of each part to create. | 6166 // The list indices now contains the end of each part to create. |
6119 | 6167 |
6120 // Create JSArray of substrings separated by separator. | 6168 // Create JSArray of substrings separated by separator. |
6121 int part_count = indices.length(); | 6169 int part_count = indices.length(); |
6122 | 6170 |
6123 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); | 6171 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); |
| 6172 MaybeObject* maybe_result = result->EnsureCanContainNonSmiElements(); |
| 6173 if (maybe_result->IsFailure()) return maybe_result; |
6124 result->set_length(Smi::FromInt(part_count)); | 6174 result->set_length(Smi::FromInt(part_count)); |
6125 | 6175 |
6126 ASSERT(result->HasFastElements()); | 6176 ASSERT(result->HasFastElements()); |
6127 | 6177 |
6128 if (part_count == 1 && indices.at(0) == subject_length) { | 6178 if (part_count == 1 && indices.at(0) == subject_length) { |
6129 FixedArray::cast(result->elements())->set(0, *subject); | 6179 FixedArray::cast(result->elements())->set(0, *subject); |
6130 return *result; | 6180 return *result; |
6131 } | 6181 } |
6132 | 6182 |
6133 Handle<FixedArray> elements(FixedArray::cast(result->elements())); | 6183 Handle<FixedArray> elements(FixedArray::cast(result->elements())); |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6488 if (!args[1]->IsSmi()) { | 6538 if (!args[1]->IsSmi()) { |
6489 isolate->context()->mark_out_of_memory(); | 6539 isolate->context()->mark_out_of_memory(); |
6490 return Failure::OutOfMemoryException(); | 6540 return Failure::OutOfMemoryException(); |
6491 } | 6541 } |
6492 int array_length = args.smi_at(1); | 6542 int array_length = args.smi_at(1); |
6493 CONVERT_CHECKED(String, special, args[2]); | 6543 CONVERT_CHECKED(String, special, args[2]); |
6494 | 6544 |
6495 // This assumption is used by the slice encoding in one or two smis. | 6545 // This assumption is used by the slice encoding in one or two smis. |
6496 ASSERT(Smi::kMaxValue >= String::kMaxLength); | 6546 ASSERT(Smi::kMaxValue >= String::kMaxLength); |
6497 | 6547 |
| 6548 MaybeObject* maybe_result = array->EnsureCanContainNonSmiElements(); |
| 6549 if (maybe_result->IsFailure()) return maybe_result; |
| 6550 |
6498 int special_length = special->length(); | 6551 int special_length = special->length(); |
6499 if (!array->HasFastElements()) { | 6552 if (!array->HasFastElements()) { |
6500 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); | 6553 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
6501 } | 6554 } |
6502 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6555 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
6503 if (fixed_array->length() < array_length) { | 6556 if (fixed_array->length() < array_length) { |
6504 array_length = fixed_array->length(); | 6557 array_length = fixed_array->length(); |
6505 } | 6558 } |
6506 | 6559 |
6507 if (array_length == 0) { | 6560 if (array_length == 0) { |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6715 } | 6768 } |
6716 } | 6769 } |
6717 ASSERT(cursor <= buffer.length()); | 6770 ASSERT(cursor <= buffer.length()); |
6718 } | 6771 } |
6719 | 6772 |
6720 | 6773 |
6721 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { | 6774 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { |
6722 NoHandleAllocation ha; | 6775 NoHandleAllocation ha; |
6723 ASSERT(args.length() == 3); | 6776 ASSERT(args.length() == 3); |
6724 CONVERT_CHECKED(JSArray, elements_array, args[0]); | 6777 CONVERT_CHECKED(JSArray, elements_array, args[0]); |
6725 RUNTIME_ASSERT(elements_array->HasFastElements()); | 6778 RUNTIME_ASSERT(elements_array->HasFastElements() || |
| 6779 elements_array->HasFastSmiOnlyElements()); |
6726 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); | 6780 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); |
6727 CONVERT_CHECKED(String, separator, args[2]); | 6781 CONVERT_CHECKED(String, separator, args[2]); |
6728 // elements_array is fast-mode JSarray of alternating positions | 6782 // elements_array is fast-mode JSarray of alternating positions |
6729 // (increasing order) and strings. | 6783 // (increasing order) and strings. |
6730 // array_length is length of original array (used to add separators); | 6784 // array_length is length of original array (used to add separators); |
6731 // separator is string to put between elements. Assumed to be non-empty. | 6785 // separator is string to put between elements. Assumed to be non-empty. |
6732 | 6786 |
6733 // Find total length of join result. | 6787 // Find total length of join result. |
6734 int string_length = 0; | 6788 int string_length = 0; |
6735 bool is_ascii = true; | 6789 bool is_ascii = true; |
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7882 HandleScope scope(isolate); | 7936 HandleScope scope(isolate); |
7883 ASSERT(args.length() == 2); | 7937 ASSERT(args.length() == 2); |
7884 // First argument is a function to use as a constructor. | 7938 // First argument is a function to use as a constructor. |
7885 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 7939 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
7886 | 7940 |
7887 // Second argument is either null or an array of bound arguments. | 7941 // Second argument is either null or an array of bound arguments. |
7888 Handle<FixedArray> bound_args; | 7942 Handle<FixedArray> bound_args; |
7889 int bound_argc = 0; | 7943 int bound_argc = 0; |
7890 if (!args[1]->IsNull()) { | 7944 if (!args[1]->IsNull()) { |
7891 CONVERT_ARG_CHECKED(JSArray, params, 1); | 7945 CONVERT_ARG_CHECKED(JSArray, params, 1); |
7892 RUNTIME_ASSERT(params->HasFastElements()); | 7946 RUNTIME_ASSERT(params->HasFastTypeElements()); |
7893 bound_args = Handle<FixedArray>(FixedArray::cast(params->elements())); | 7947 bound_args = Handle<FixedArray>(FixedArray::cast(params->elements())); |
7894 bound_argc = Smi::cast(params->length())->value(); | 7948 bound_argc = Smi::cast(params->length())->value(); |
7895 } | 7949 } |
7896 | 7950 |
7897 int total_argc = 0; | 7951 int total_argc = 0; |
7898 SmartArrayPointer<Object**> param_data = | 7952 SmartArrayPointer<Object**> param_data = |
7899 GetNonBoundArguments(bound_argc, &total_argc); | 7953 GetNonBoundArguments(bound_argc, &total_argc); |
7900 for (int i = 0; i < bound_argc; i++) { | 7954 for (int i = 0; i < bound_argc; i++) { |
7901 Handle<Object> val = Handle<Object>(bound_args->get(i)); | 7955 Handle<Object> val = Handle<Object>(bound_args->get(i)); |
7902 param_data[i] = val.location(); | 7956 param_data[i] = val.location(); |
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8977 | 9031 |
8978 | 9032 |
8979 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) { | 9033 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) { |
8980 HandleScope scope(isolate); | 9034 HandleScope scope(isolate); |
8981 ASSERT(args.length() == 2); | 9035 ASSERT(args.length() == 2); |
8982 | 9036 |
8983 CONVERT_ARG_CHECKED(String, str, 0); | 9037 CONVERT_ARG_CHECKED(String, str, 0); |
8984 FlattenString(str); | 9038 FlattenString(str); |
8985 | 9039 |
8986 CONVERT_ARG_CHECKED(JSArray, output, 1); | 9040 CONVERT_ARG_CHECKED(JSArray, output, 1); |
| 9041 |
| 9042 MaybeObject* maybe_result_array = |
| 9043 output->EnsureCanContainNonSmiElements(); |
| 9044 if (maybe_result_array->IsFailure()) return maybe_result_array; |
8987 RUNTIME_ASSERT(output->HasFastElements()); | 9045 RUNTIME_ASSERT(output->HasFastElements()); |
8988 | 9046 |
8989 AssertNoAllocation no_allocation; | 9047 AssertNoAllocation no_allocation; |
8990 | 9048 |
8991 FixedArray* output_array = FixedArray::cast(output->elements()); | 9049 FixedArray* output_array = FixedArray::cast(output->elements()); |
8992 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 9050 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
8993 bool result; | 9051 bool result; |
8994 String::FlatContent str_content = str->GetFlatContent(); | 9052 String::FlatContent str_content = str->GetFlatContent(); |
8995 if (str_content.IsAscii()) { | 9053 if (str_content.IsAscii()) { |
8996 result = DateParser::Parse(str_content.ToAsciiVector(), | 9054 result = DateParser::Parse(str_content.ToAsciiVector(), |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9280 } | 9338 } |
9281 | 9339 |
9282 | 9340 |
9283 // Push an object unto an array of objects if it is not already in the | 9341 // Push an object unto an array of objects if it is not already in the |
9284 // array. Returns true if the element was pushed on the stack and | 9342 // array. Returns true if the element was pushed on the stack and |
9285 // false otherwise. | 9343 // false otherwise. |
9286 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { | 9344 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { |
9287 ASSERT(args.length() == 2); | 9345 ASSERT(args.length() == 2); |
9288 CONVERT_CHECKED(JSArray, array, args[0]); | 9346 CONVERT_CHECKED(JSArray, array, args[0]); |
9289 CONVERT_CHECKED(JSObject, element, args[1]); | 9347 CONVERT_CHECKED(JSObject, element, args[1]); |
9290 RUNTIME_ASSERT(array->HasFastElements()); | 9348 RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
9291 int length = Smi::cast(array->length())->value(); | 9349 int length = Smi::cast(array->length())->value(); |
9292 FixedArray* elements = FixedArray::cast(array->elements()); | 9350 FixedArray* elements = FixedArray::cast(array->elements()); |
9293 for (int i = 0; i < length; i++) { | 9351 for (int i = 0; i < length; i++) { |
9294 if (elements->get(i) == element) return isolate->heap()->false_value(); | 9352 if (elements->get(i) == element) return isolate->heap()->false_value(); |
9295 } | 9353 } |
9296 Object* obj; | 9354 Object* obj; |
9297 // Strict not needed. Used for cycle detection in Array join implementation. | 9355 // Strict not needed. Used for cycle detection in Array join implementation. |
9298 { MaybeObject* maybe_obj = | 9356 { MaybeObject* maybe_obj = |
9299 array->SetFastElement(length, element, kNonStrictMode, true); | 9357 array->SetFastElement(length, element, kNonStrictMode, true); |
9300 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9358 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9511 uint32_t b = *bp; | 9569 uint32_t b = *bp; |
9512 return (a == b) ? 0 : (a < b) ? -1 : 1; | 9570 return (a == b) ? 0 : (a < b) ? -1 : 1; |
9513 } | 9571 } |
9514 | 9572 |
9515 | 9573 |
9516 static void CollectElementIndices(Handle<JSObject> object, | 9574 static void CollectElementIndices(Handle<JSObject> object, |
9517 uint32_t range, | 9575 uint32_t range, |
9518 List<uint32_t>* indices) { | 9576 List<uint32_t>* indices) { |
9519 ElementsKind kind = object->GetElementsKind(); | 9577 ElementsKind kind = object->GetElementsKind(); |
9520 switch (kind) { | 9578 switch (kind) { |
| 9579 case FAST_SMI_ONLY_ELEMENTS: |
9521 case FAST_ELEMENTS: { | 9580 case FAST_ELEMENTS: { |
9522 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 9581 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
9523 uint32_t length = static_cast<uint32_t>(elements->length()); | 9582 uint32_t length = static_cast<uint32_t>(elements->length()); |
9524 if (range < length) length = range; | 9583 if (range < length) length = range; |
9525 for (uint32_t i = 0; i < length; i++) { | 9584 for (uint32_t i = 0; i < length; i++) { |
9526 if (!elements->get(i)->IsTheHole()) { | 9585 if (!elements->get(i)->IsTheHole()) { |
9527 indices->Add(i); | 9586 indices->Add(i); |
9528 } | 9587 } |
9529 } | 9588 } |
9530 break; | 9589 break; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9630 * with the element index and the element's value. | 9689 * with the element index and the element's value. |
9631 * Afterwards it increments the base-index of the visitor by the array | 9690 * Afterwards it increments the base-index of the visitor by the array |
9632 * length. | 9691 * length. |
9633 * Returns false if any access threw an exception, otherwise true. | 9692 * Returns false if any access threw an exception, otherwise true. |
9634 */ | 9693 */ |
9635 static bool IterateElements(Isolate* isolate, | 9694 static bool IterateElements(Isolate* isolate, |
9636 Handle<JSArray> receiver, | 9695 Handle<JSArray> receiver, |
9637 ArrayConcatVisitor* visitor) { | 9696 ArrayConcatVisitor* visitor) { |
9638 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); | 9697 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); |
9639 switch (receiver->GetElementsKind()) { | 9698 switch (receiver->GetElementsKind()) { |
| 9699 case FAST_SMI_ONLY_ELEMENTS: |
9640 case FAST_ELEMENTS: { | 9700 case FAST_ELEMENTS: { |
9641 // Run through the elements FixedArray and use HasElement and GetElement | 9701 // Run through the elements FixedArray and use HasElement and GetElement |
9642 // to check the prototype for missing elements. | 9702 // to check the prototype for missing elements. |
9643 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); | 9703 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); |
9644 int fast_length = static_cast<int>(length); | 9704 int fast_length = static_cast<int>(length); |
9645 ASSERT(fast_length <= elements->length()); | 9705 ASSERT(fast_length <= elements->length()); |
9646 for (int j = 0; j < fast_length; j++) { | 9706 for (int j = 0; j < fast_length; j++) { |
9647 HandleScope loop_scope(isolate); | 9707 HandleScope loop_scope(isolate); |
9648 Handle<Object> element_value(elements->get(j), isolate); | 9708 Handle<Object> element_value(elements->get(j), isolate); |
9649 if (!element_value->IsTheHole()) { | 9709 if (!element_value->IsTheHole()) { |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9953 for (int i = 0; i < keys_length; i++) { | 10013 for (int i = 0; i < keys_length; i++) { |
9954 Object* key = keys->get(i); | 10014 Object* key = keys->get(i); |
9955 uint32_t index = 0; | 10015 uint32_t index = 0; |
9956 if (!key->ToArrayIndex(&index) || index >= length) { | 10016 if (!key->ToArrayIndex(&index) || index >= length) { |
9957 // Zap invalid keys. | 10017 // Zap invalid keys. |
9958 keys->set_undefined(i); | 10018 keys->set_undefined(i); |
9959 } | 10019 } |
9960 } | 10020 } |
9961 return *isolate->factory()->NewJSArrayWithElements(keys); | 10021 return *isolate->factory()->NewJSArrayWithElements(keys); |
9962 } else { | 10022 } else { |
9963 ASSERT(array->HasFastElements() || array->HasFastDoubleElements()); | 10023 ASSERT(array->HasFastElements() || |
| 10024 array->HasFastSmiOnlyElements() || |
| 10025 array->HasFastDoubleElements()); |
9964 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); | 10026 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); |
9965 // -1 means start of array. | 10027 // -1 means start of array. |
9966 single_interval->set(0, Smi::FromInt(-1)); | 10028 single_interval->set(0, Smi::FromInt(-1)); |
9967 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); | 10029 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); |
9968 uint32_t actual_length = | 10030 uint32_t actual_length = |
9969 static_cast<uint32_t>(elements->length()); | 10031 static_cast<uint32_t>(elements->length()); |
9970 uint32_t min_length = actual_length < length ? actual_length : length; | 10032 uint32_t min_length = actual_length < length ? actual_length : length; |
9971 Handle<Object> length_object = | 10033 Handle<Object> length_object = |
9972 isolate->factory()->NewNumber(static_cast<double>(min_length)); | 10034 isolate->factory()->NewNumber(static_cast<double>(min_length)); |
9973 single_interval->set(1, *length_object); | 10035 single_interval->set(1, *length_object); |
(...skipping 1889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11863 // instances->set(i, *GetScriptWrapper(script)) | 11925 // instances->set(i, *GetScriptWrapper(script)) |
11864 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might | 11926 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might |
11865 // already have deferenced the instances handle. | 11927 // already have deferenced the instances handle. |
11866 Handle<JSValue> wrapper = GetScriptWrapper(script); | 11928 Handle<JSValue> wrapper = GetScriptWrapper(script); |
11867 instances->set(i, *wrapper); | 11929 instances->set(i, *wrapper); |
11868 } | 11930 } |
11869 | 11931 |
11870 // Return result as a JS array. | 11932 // Return result as a JS array. |
11871 Handle<JSObject> result = | 11933 Handle<JSObject> result = |
11872 isolate->factory()->NewJSObject(isolate->array_function()); | 11934 isolate->factory()->NewJSObject(isolate->array_function()); |
11873 Handle<JSArray>::cast(result)->SetContent(*instances); | 11935 isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances); |
11874 return *result; | 11936 return *result; |
11875 } | 11937 } |
11876 | 11938 |
11877 | 11939 |
11878 // Helper function used by Runtime_DebugReferencedBy below. | 11940 // Helper function used by Runtime_DebugReferencedBy below. |
11879 static int DebugReferencedBy(HeapIterator* iterator, | 11941 static int DebugReferencedBy(HeapIterator* iterator, |
11880 JSObject* target, | 11942 JSObject* target, |
11881 Object* instance_filter, int max_references, | 11943 Object* instance_filter, int max_references, |
11882 FixedArray* instances, int instances_size, | 11944 FixedArray* instances, int instances_size, |
11883 JSFunction* arguments_function) { | 11945 JSFunction* arguments_function) { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11991 // Fill the referencing objects. | 12053 // Fill the referencing objects. |
11992 // AllocateFixedArray above does not make the heap non-iterable. | 12054 // AllocateFixedArray above does not make the heap non-iterable. |
11993 ASSERT(HEAP->IsHeapIterable()); | 12055 ASSERT(HEAP->IsHeapIterable()); |
11994 HeapIterator heap_iterator2; | 12056 HeapIterator heap_iterator2; |
11995 count = DebugReferencedBy(&heap_iterator2, | 12057 count = DebugReferencedBy(&heap_iterator2, |
11996 target, instance_filter, max_references, | 12058 target, instance_filter, max_references, |
11997 instances, count, arguments_function); | 12059 instances, count, arguments_function); |
11998 | 12060 |
11999 // Return result as JS array. | 12061 // Return result as JS array. |
12000 Object* result; | 12062 Object* result; |
12001 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( | 12063 MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
12002 isolate->context()->global_context()->array_function()); | 12064 isolate->context()->global_context()->array_function()); |
12003 if (!maybe_result->ToObject(&result)) return maybe_result; | 12065 if (!maybe_result->ToObject(&result)) return maybe_result; |
12004 } | 12066 return JSArray::cast(result)->SetContent(instances); |
12005 JSArray::cast(result)->SetContent(instances); | |
12006 return result; | |
12007 } | 12067 } |
12008 | 12068 |
12009 | 12069 |
12010 // Helper function used by Runtime_DebugConstructedBy below. | 12070 // Helper function used by Runtime_DebugConstructedBy below. |
12011 static int DebugConstructedBy(HeapIterator* iterator, | 12071 static int DebugConstructedBy(HeapIterator* iterator, |
12012 JSFunction* constructor, | 12072 JSFunction* constructor, |
12013 int max_references, | 12073 int max_references, |
12014 FixedArray* instances, | 12074 FixedArray* instances, |
12015 int instances_size) { | 12075 int instances_size) { |
12016 AssertNoAllocation no_alloc; | 12076 AssertNoAllocation no_alloc; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12077 max_references, | 12137 max_references, |
12078 instances, | 12138 instances, |
12079 count); | 12139 count); |
12080 | 12140 |
12081 // Return result as JS array. | 12141 // Return result as JS array. |
12082 Object* result; | 12142 Object* result; |
12083 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( | 12143 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
12084 isolate->context()->global_context()->array_function()); | 12144 isolate->context()->global_context()->array_function()); |
12085 if (!maybe_result->ToObject(&result)) return maybe_result; | 12145 if (!maybe_result->ToObject(&result)) return maybe_result; |
12086 } | 12146 } |
12087 JSArray::cast(result)->SetContent(instances); | 12147 return JSArray::cast(result)->SetContent(instances); |
12088 return result; | |
12089 } | 12148 } |
12090 | 12149 |
12091 | 12150 |
12092 // Find the effective prototype object as returned by __proto__. | 12151 // Find the effective prototype object as returned by __proto__. |
12093 // args[0]: the object to find the prototype for. | 12152 // args[0]: the object to find the prototype for. |
12094 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { | 12153 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { |
12095 ASSERT(args.length() == 1); | 12154 ASSERT(args.length() == 1); |
12096 | 12155 |
12097 CONVERT_CHECKED(JSObject, obj, args[0]); | 12156 CONVERT_CHECKED(JSObject, obj, args[0]); |
12098 | 12157 |
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13050 return NULL; | 13109 return NULL; |
13051 } | 13110 } |
13052 | 13111 |
13053 | 13112 |
13054 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ | 13113 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ |
13055 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ | 13114 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ |
13056 CONVERT_CHECKED(JSObject, obj, args[0]); \ | 13115 CONVERT_CHECKED(JSObject, obj, args[0]); \ |
13057 return isolate->heap()->ToBoolean(obj->Has##Name()); \ | 13116 return isolate->heap()->ToBoolean(obj->Has##Name()); \ |
13058 } | 13117 } |
13059 | 13118 |
| 13119 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements) |
13060 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) | 13120 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) |
13061 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) | 13121 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) |
13062 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) | 13122 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) |
13063 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) | 13123 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) |
13064 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) | 13124 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) |
13065 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) | 13125 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) |
13066 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) | 13126 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) |
13067 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) | 13127 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) |
13068 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) | 13128 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) |
13069 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) | 13129 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13149 } else { | 13209 } else { |
13150 // Handle last resort GC and make sure to allow future allocations | 13210 // Handle last resort GC and make sure to allow future allocations |
13151 // to grow the heap without causing GCs (if possible). | 13211 // to grow the heap without causing GCs (if possible). |
13152 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13212 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13153 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13213 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
13154 } | 13214 } |
13155 } | 13215 } |
13156 | 13216 |
13157 | 13217 |
13158 } } // namespace v8::internal | 13218 } } // namespace v8::internal |
OLD | NEW |