OLD | NEW |
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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 if (!maybe_result->ToObject(&result)) return maybe_result; | 201 if (!maybe_result->ToObject(&result)) return maybe_result; |
202 } | 202 } |
203 } | 203 } |
204 } | 204 } |
205 } | 205 } |
206 | 206 |
207 // Deep copy local elements. | 207 // Deep copy local elements. |
208 // Pixel elements cannot be created using an object literal. | 208 // Pixel elements cannot be created using an object literal. |
209 ASSERT(!copy->HasExternalArrayElements()); | 209 ASSERT(!copy->HasExternalArrayElements()); |
210 switch (copy->GetElementsKind()) { | 210 switch (copy->GetElementsKind()) { |
211 case FAST_SMI_ELEMENTS: | 211 case FAST_SMI_ONLY_ELEMENTS: |
212 case FAST_ELEMENTS: | 212 case FAST_ELEMENTS: { |
213 case FAST_HOLEY_SMI_ELEMENTS: | |
214 case FAST_HOLEY_ELEMENTS: { | |
215 FixedArray* elements = FixedArray::cast(copy->elements()); | 213 FixedArray* elements = FixedArray::cast(copy->elements()); |
216 if (elements->map() == heap->fixed_cow_array_map()) { | 214 if (elements->map() == heap->fixed_cow_array_map()) { |
217 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 215 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
218 #ifdef DEBUG | 216 #ifdef DEBUG |
219 for (int i = 0; i < elements->length(); i++) { | 217 for (int i = 0; i < elements->length(); i++) { |
220 ASSERT(!elements->get(i)->IsJSObject()); | 218 ASSERT(!elements->get(i)->IsJSObject()); |
221 } | 219 } |
222 #endif | 220 #endif |
223 } else { | 221 } else { |
224 for (int i = 0; i < elements->length(); i++) { | 222 for (int i = 0; i < elements->length(); i++) { |
225 Object* value = elements->get(i); | 223 Object* value = elements->get(i); |
226 ASSERT(value->IsSmi() || | 224 ASSERT(value->IsSmi() || |
227 value->IsTheHole() || | 225 value->IsTheHole() || |
228 (IsFastObjectElementsKind(copy->GetElementsKind()))); | 226 (copy->GetElementsKind() == FAST_ELEMENTS)); |
229 if (value->IsJSObject()) { | 227 if (value->IsJSObject()) { |
230 JSObject* js_object = JSObject::cast(value); | 228 JSObject* js_object = JSObject::cast(value); |
231 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, | 229 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, |
232 js_object); | 230 js_object); |
233 if (!maybe_result->ToObject(&result)) return maybe_result; | 231 if (!maybe_result->ToObject(&result)) return maybe_result; |
234 } | 232 } |
235 elements->set(i, result); | 233 elements->set(i, result); |
236 } | 234 } |
237 } | 235 } |
238 } | 236 } |
(...skipping 24 matching lines...) Expand all Loading... |
263 case EXTERNAL_PIXEL_ELEMENTS: | 261 case EXTERNAL_PIXEL_ELEMENTS: |
264 case EXTERNAL_BYTE_ELEMENTS: | 262 case EXTERNAL_BYTE_ELEMENTS: |
265 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 263 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
266 case EXTERNAL_SHORT_ELEMENTS: | 264 case EXTERNAL_SHORT_ELEMENTS: |
267 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 265 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
268 case EXTERNAL_INT_ELEMENTS: | 266 case EXTERNAL_INT_ELEMENTS: |
269 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 267 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
270 case EXTERNAL_FLOAT_ELEMENTS: | 268 case EXTERNAL_FLOAT_ELEMENTS: |
271 case EXTERNAL_DOUBLE_ELEMENTS: | 269 case EXTERNAL_DOUBLE_ELEMENTS: |
272 case FAST_DOUBLE_ELEMENTS: | 270 case FAST_DOUBLE_ELEMENTS: |
273 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
274 // No contained objects, nothing to do. | 271 // No contained objects, nothing to do. |
275 break; | 272 break; |
276 } | 273 } |
277 return copy; | 274 return copy; |
278 } | 275 } |
279 | 276 |
280 | 277 |
281 static Handle<Map> ComputeObjectLiteralMap( | 278 static Handle<Map> ComputeObjectLiteralMap( |
282 Handle<Context> context, | 279 Handle<Context> context, |
283 Handle<FixedArray> constant_properties, | 280 Handle<FixedArray> constant_properties, |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 if (Map::IsValidElementsTransition(from_kind, to_kind)) { | 445 if (Map::IsValidElementsTransition(from_kind, to_kind)) { |
449 Handle<Object> result = JSObject::TransitionElementsKind( | 446 Handle<Object> result = JSObject::TransitionElementsKind( |
450 Handle<JSObject>::cast(object), to_kind); | 447 Handle<JSObject>::cast(object), to_kind); |
451 if (result.is_null()) return isolate->ThrowIllegalOperation(); | 448 if (result.is_null()) return isolate->ThrowIllegalOperation(); |
452 return *result; | 449 return *result; |
453 } | 450 } |
454 return isolate->ThrowIllegalOperation(); | 451 return isolate->ThrowIllegalOperation(); |
455 } | 452 } |
456 | 453 |
457 | 454 |
458 static const int kSmiLiteralMinimumLength = 1024; | 455 static const int kSmiOnlyLiteralMinimumLength = 1024; |
459 | 456 |
460 | 457 |
461 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( | 458 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( |
462 Isolate* isolate, | 459 Isolate* isolate, |
463 Handle<FixedArray> literals, | 460 Handle<FixedArray> literals, |
464 Handle<FixedArray> elements) { | 461 Handle<FixedArray> elements) { |
465 // Create the JSArray. | 462 // Create the JSArray. |
466 Handle<JSFunction> constructor( | 463 Handle<JSFunction> constructor( |
467 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); | 464 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
468 Handle<JSArray> object = | 465 Handle<JSArray> object = |
469 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); | 466 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); |
470 | 467 |
471 ElementsKind constant_elements_kind = | 468 ElementsKind constant_elements_kind = |
472 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); | 469 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); |
473 Handle<FixedArrayBase> constant_elements_values( | 470 Handle<FixedArrayBase> constant_elements_values( |
474 FixedArrayBase::cast(elements->get(1))); | 471 FixedArrayBase::cast(elements->get(1))); |
475 | 472 |
476 ASSERT(IsFastElementsKind(constant_elements_kind)); | |
477 Context* global_context = isolate->context()->global_context(); | 473 Context* global_context = isolate->context()->global_context(); |
478 Object* maybe_maps_array = global_context->js_array_maps(); | 474 if (constant_elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
479 ASSERT(!maybe_maps_array->IsUndefined()); | 475 object->set_map(Map::cast(global_context->smi_js_array_map())); |
480 Object* maybe_map = FixedArray::cast(maybe_maps_array)->get( | 476 } else if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { |
481 constant_elements_kind); | 477 object->set_map(Map::cast(global_context->double_js_array_map())); |
482 ASSERT(maybe_map->IsMap()); | 478 } else { |
483 object->set_map(Map::cast(maybe_map)); | 479 object->set_map(Map::cast(global_context->object_js_array_map())); |
| 480 } |
484 | 481 |
485 Handle<FixedArrayBase> copied_elements_values; | 482 Handle<FixedArrayBase> copied_elements_values; |
486 if (IsFastDoubleElementsKind(constant_elements_kind)) { | 483 if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { |
487 ASSERT(FLAG_smi_only_arrays); | 484 ASSERT(FLAG_smi_only_arrays); |
488 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( | 485 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( |
489 Handle<FixedDoubleArray>::cast(constant_elements_values)); | 486 Handle<FixedDoubleArray>::cast(constant_elements_values)); |
490 } else { | 487 } else { |
491 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind)); | 488 ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS || |
| 489 constant_elements_kind == FAST_ELEMENTS); |
492 const bool is_cow = | 490 const bool is_cow = |
493 (constant_elements_values->map() == | 491 (constant_elements_values->map() == |
494 isolate->heap()->fixed_cow_array_map()); | 492 isolate->heap()->fixed_cow_array_map()); |
495 if (is_cow) { | 493 if (is_cow) { |
496 copied_elements_values = constant_elements_values; | 494 copied_elements_values = constant_elements_values; |
497 #if DEBUG | 495 #if DEBUG |
498 Handle<FixedArray> fixed_array_values = | 496 Handle<FixedArray> fixed_array_values = |
499 Handle<FixedArray>::cast(copied_elements_values); | 497 Handle<FixedArray>::cast(copied_elements_values); |
500 for (int i = 0; i < fixed_array_values->length(); i++) { | 498 for (int i = 0; i < fixed_array_values->length(); i++) { |
501 ASSERT(!fixed_array_values->get(i)->IsFixedArray()); | 499 ASSERT(!fixed_array_values->get(i)->IsFixedArray()); |
(...skipping 15 matching lines...) Expand all Loading... |
517 CreateLiteralBoilerplate(isolate, literals, fa); | 515 CreateLiteralBoilerplate(isolate, literals, fa); |
518 if (result.is_null()) return result; | 516 if (result.is_null()) return result; |
519 fixed_array_values_copy->set(i, *result); | 517 fixed_array_values_copy->set(i, *result); |
520 } | 518 } |
521 } | 519 } |
522 } | 520 } |
523 } | 521 } |
524 object->set_elements(*copied_elements_values); | 522 object->set_elements(*copied_elements_values); |
525 object->set_length(Smi::FromInt(copied_elements_values->length())); | 523 object->set_length(Smi::FromInt(copied_elements_values->length())); |
526 | 524 |
527 // Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is | 525 // Ensure that the boilerplate object has FAST_ELEMENTS, unless the flag is |
528 // on or the object is larger than the threshold. | 526 // on or the object is larger than the threshold. |
529 if (!FLAG_smi_only_arrays && | 527 if (!FLAG_smi_only_arrays && |
530 constant_elements_values->length() < kSmiLiteralMinimumLength) { | 528 constant_elements_values->length() < kSmiOnlyLiteralMinimumLength) { |
531 ElementsKind elements_kind = object->GetElementsKind(); | 529 if (object->GetElementsKind() != FAST_ELEMENTS) { |
532 if (!IsFastObjectElementsKind(elements_kind)) { | 530 CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure()); |
533 if (IsFastHoleyElementsKind(elements_kind)) { | |
534 CHECK(!TransitionElements(object, FAST_HOLEY_ELEMENTS, | |
535 isolate)->IsFailure()); | |
536 } else { | |
537 CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure()); | |
538 } | |
539 } | 531 } |
540 } | 532 } |
541 | 533 |
542 object->ValidateElements(); | |
543 return object; | 534 return object; |
544 } | 535 } |
545 | 536 |
546 | 537 |
547 static Handle<Object> CreateLiteralBoilerplate( | 538 static Handle<Object> CreateLiteralBoilerplate( |
548 Isolate* isolate, | 539 Isolate* isolate, |
549 Handle<FixedArray> literals, | 540 Handle<FixedArray> literals, |
550 Handle<FixedArray> array) { | 541 Handle<FixedArray> array) { |
551 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | 542 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
552 const bool kHasNoFunctionLiteral = false; | 543 const bool kHasNoFunctionLiteral = false; |
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1732 | 1723 |
1733 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { | 1724 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { |
1734 HandleScope scope(isolate); | 1725 HandleScope scope(isolate); |
1735 ASSERT(args.length() == 4); | 1726 ASSERT(args.length() == 4); |
1736 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); | 1727 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
1737 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); | 1728 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); |
1738 // Due to the way the JS calls are constructed this must be less than the | 1729 // Due to the way the JS calls are constructed this must be less than the |
1739 // length of a string, i.e. it is always a Smi. We check anyway for security. | 1730 // length of a string, i.e. it is always a Smi. We check anyway for security. |
1740 CONVERT_SMI_ARG_CHECKED(index, 2); | 1731 CONVERT_SMI_ARG_CHECKED(index, 2); |
1741 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); | 1732 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); |
1742 RUNTIME_ASSERT(last_match_info->HasFastObjectElements()); | 1733 RUNTIME_ASSERT(last_match_info->HasFastElements()); |
1743 RUNTIME_ASSERT(index >= 0); | 1734 RUNTIME_ASSERT(index >= 0); |
1744 RUNTIME_ASSERT(index <= subject->length()); | 1735 RUNTIME_ASSERT(index <= subject->length()); |
1745 isolate->counters()->regexp_entry_runtime()->Increment(); | 1736 isolate->counters()->regexp_entry_runtime()->Increment(); |
1746 Handle<Object> result = RegExpImpl::Exec(regexp, | 1737 Handle<Object> result = RegExpImpl::Exec(regexp, |
1747 subject, | 1738 subject, |
1748 index, | 1739 index, |
1749 last_match_info); | 1740 last_match_info); |
1750 if (result.is_null()) return Failure::Exception(); | 1741 if (result.is_null()) return Failure::Exception(); |
1751 return *result; | 1742 return *result; |
1752 } | 1743 } |
(...skipping 1353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3106 | 3097 |
3107 // Index of end of last match. | 3098 // Index of end of last match. |
3108 int prev = 0; | 3099 int prev = 0; |
3109 | 3100 |
3110 // Number of parts added by compiled replacement plus preceeding | 3101 // Number of parts added by compiled replacement plus preceeding |
3111 // string and possibly suffix after last match. It is possible for | 3102 // string and possibly suffix after last match. It is possible for |
3112 // all components to use two elements when encoded as two smis. | 3103 // all components to use two elements when encoded as two smis. |
3113 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2); | 3104 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2); |
3114 bool matched = true; | 3105 bool matched = true; |
3115 do { | 3106 do { |
3116 ASSERT(last_match_info_handle->HasFastObjectElements()); | 3107 ASSERT(last_match_info_handle->HasFastElements()); |
3117 // Increase the capacity of the builder before entering local handle-scope, | 3108 // Increase the capacity of the builder before entering local handle-scope, |
3118 // so its internal buffer can safely allocate a new handle if it grows. | 3109 // so its internal buffer can safely allocate a new handle if it grows. |
3119 builder.EnsureCapacity(parts_added_per_loop); | 3110 builder.EnsureCapacity(parts_added_per_loop); |
3120 | 3111 |
3121 HandleScope loop_scope(isolate); | 3112 HandleScope loop_scope(isolate); |
3122 int start, end; | 3113 int start, end; |
3123 { | 3114 { |
3124 AssertNoAllocation match_info_array_is_not_in_a_handle; | 3115 AssertNoAllocation match_info_array_is_not_in_a_handle; |
3125 FixedArray* match_info_array = | 3116 FixedArray* match_info_array = |
3126 FixedArray::cast(last_match_info_handle->elements()); | 3117 FixedArray::cast(last_match_info_handle->elements()); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3203 } | 3194 } |
3204 } | 3195 } |
3205 | 3196 |
3206 Handle<Object> match = RegExpImpl::Exec(regexp_handle, | 3197 Handle<Object> match = RegExpImpl::Exec(regexp_handle, |
3207 subject_handle, | 3198 subject_handle, |
3208 0, | 3199 0, |
3209 last_match_info_handle); | 3200 last_match_info_handle); |
3210 if (match.is_null()) return Failure::Exception(); | 3201 if (match.is_null()) return Failure::Exception(); |
3211 if (match->IsNull()) return *subject_handle; | 3202 if (match->IsNull()) return *subject_handle; |
3212 | 3203 |
3213 ASSERT(last_match_info_handle->HasFastObjectElements()); | 3204 ASSERT(last_match_info_handle->HasFastElements()); |
3214 | 3205 |
3215 int start, end; | 3206 int start, end; |
3216 { | 3207 { |
3217 AssertNoAllocation match_info_array_is_not_in_a_handle; | 3208 AssertNoAllocation match_info_array_is_not_in_a_handle; |
3218 FixedArray* match_info_array = | 3209 FixedArray* match_info_array = |
3219 FixedArray::cast(last_match_info_handle->elements()); | 3210 FixedArray::cast(last_match_info_handle->elements()); |
3220 | 3211 |
3221 start = RegExpImpl::GetCapture(match_info_array, 0); | 3212 start = RegExpImpl::GetCapture(match_info_array, 0); |
3222 end = RegExpImpl::GetCapture(match_info_array, 1); | 3213 end = RegExpImpl::GetCapture(match_info_array, 1); |
3223 } | 3214 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3277 next++; | 3268 next++; |
3278 if (next > length) break; | 3269 if (next > length) break; |
3279 } | 3270 } |
3280 match = RegExpImpl::Exec(regexp_handle, | 3271 match = RegExpImpl::Exec(regexp_handle, |
3281 subject_handle, | 3272 subject_handle, |
3282 next, | 3273 next, |
3283 last_match_info_handle); | 3274 last_match_info_handle); |
3284 if (match.is_null()) return Failure::Exception(); | 3275 if (match.is_null()) return Failure::Exception(); |
3285 if (match->IsNull()) break; | 3276 if (match->IsNull()) break; |
3286 | 3277 |
3287 ASSERT(last_match_info_handle->HasFastObjectElements()); | 3278 ASSERT(last_match_info_handle->HasFastElements()); |
3288 HandleScope loop_scope(isolate); | 3279 HandleScope loop_scope(isolate); |
3289 { | 3280 { |
3290 AssertNoAllocation match_info_array_is_not_in_a_handle; | 3281 AssertNoAllocation match_info_array_is_not_in_a_handle; |
3291 FixedArray* match_info_array = | 3282 FixedArray* match_info_array = |
3292 FixedArray::cast(last_match_info_handle->elements()); | 3283 FixedArray::cast(last_match_info_handle->elements()); |
3293 start = RegExpImpl::GetCapture(match_info_array, 0); | 3284 start = RegExpImpl::GetCapture(match_info_array, 0); |
3294 end = RegExpImpl::GetCapture(match_info_array, 1); | 3285 end = RegExpImpl::GetCapture(match_info_array, 1); |
3295 } | 3286 } |
3296 } while (true); | 3287 } while (true); |
3297 | 3288 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3347 if (!maybe_flat_replacement->ToObject(&flat_replacement)) { | 3338 if (!maybe_flat_replacement->ToObject(&flat_replacement)) { |
3348 return maybe_flat_replacement; | 3339 return maybe_flat_replacement; |
3349 } | 3340 } |
3350 } | 3341 } |
3351 replacement = String::cast(flat_replacement); | 3342 replacement = String::cast(flat_replacement); |
3352 } | 3343 } |
3353 | 3344 |
3354 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); | 3345 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); |
3355 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); | 3346 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); |
3356 | 3347 |
3357 ASSERT(last_match_info->HasFastObjectElements()); | 3348 ASSERT(last_match_info->HasFastElements()); |
3358 | 3349 |
3359 if (replacement->length() == 0) { | 3350 if (replacement->length() == 0) { |
3360 if (subject->HasOnlyAsciiChars()) { | 3351 if (subject->HasOnlyAsciiChars()) { |
3361 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( | 3352 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( |
3362 isolate, subject, regexp, last_match_info); | 3353 isolate, subject, regexp, last_match_info); |
3363 } else { | 3354 } else { |
3364 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( | 3355 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( |
3365 isolate, subject, regexp, last_match_info); | 3356 isolate, subject, regexp, last_match_info); |
3366 } | 3357 } |
3367 } | 3358 } |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4030 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) { | 4021 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) { |
4031 ASSERT(args.length() == 4); | 4022 ASSERT(args.length() == 4); |
4032 HandleScope handles(isolate); | 4023 HandleScope handles(isolate); |
4033 | 4024 |
4034 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); | 4025 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); |
4035 if (!subject->IsFlat()) FlattenString(subject); | 4026 if (!subject->IsFlat()) FlattenString(subject); |
4036 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); | 4027 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
4037 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); | 4028 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); |
4038 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); | 4029 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); |
4039 | 4030 |
4040 ASSERT(last_match_info->HasFastObjectElements()); | 4031 ASSERT(last_match_info->HasFastElements()); |
4041 ASSERT(regexp->GetFlags().is_global()); | 4032 ASSERT(regexp->GetFlags().is_global()); |
4042 Handle<FixedArray> result_elements; | 4033 Handle<FixedArray> result_elements; |
4043 if (result_array->HasFastObjectElements()) { | 4034 if (result_array->HasFastElements()) { |
4044 result_elements = | 4035 result_elements = |
4045 Handle<FixedArray>(FixedArray::cast(result_array->elements())); | 4036 Handle<FixedArray>(FixedArray::cast(result_array->elements())); |
4046 } | 4037 } |
4047 if (result_elements.is_null() || result_elements->length() < 16) { | 4038 if (result_elements.is_null() || result_elements->length() < 16) { |
4048 result_elements = isolate->factory()->NewFixedArrayWithHoles(16); | 4039 result_elements = isolate->factory()->NewFixedArrayWithHoles(16); |
4049 } | 4040 } |
4050 FixedArrayBuilder builder(result_elements); | 4041 FixedArrayBuilder builder(result_elements); |
4051 | 4042 |
4052 if (regexp->TypeTag() == JSRegExp::ATOM) { | 4043 if (regexp->TypeTag() == JSRegExp::ATOM) { |
4053 Handle<String> pattern( | 4044 Handle<String> pattern( |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4335 if (!receiver->IsGlobalObject()) return value; | 4326 if (!receiver->IsGlobalObject()) return value; |
4336 value = JSGlobalPropertyCell::cast(value)->value(); | 4327 value = JSGlobalPropertyCell::cast(value)->value(); |
4337 if (!value->IsTheHole()) return value; | 4328 if (!value->IsTheHole()) return value; |
4338 // If value is the hole do the general lookup. | 4329 // If value is the hole do the general lookup. |
4339 } | 4330 } |
4340 } | 4331 } |
4341 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { | 4332 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { |
4342 // JSObject without a string key. If the key is a Smi, check for a | 4333 // JSObject without a string key. If the key is a Smi, check for a |
4343 // definite out-of-bounds access to elements, which is a strong indicator | 4334 // definite out-of-bounds access to elements, which is a strong indicator |
4344 // that subsequent accesses will also call the runtime. Proactively | 4335 // that subsequent accesses will also call the runtime. Proactively |
4345 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of | 4336 // transition elements to FAST_ELEMENTS to avoid excessive boxing of |
4346 // doubles for those future calls in the case that the elements would | 4337 // doubles for those future calls in the case that the elements would |
4347 // become FAST_DOUBLE_ELEMENTS. | 4338 // become FAST_DOUBLE_ELEMENTS. |
4348 Handle<JSObject> js_object(args.at<JSObject>(0)); | 4339 Handle<JSObject> js_object(args.at<JSObject>(0)); |
4349 ElementsKind elements_kind = js_object->GetElementsKind(); | 4340 ElementsKind elements_kind = js_object->GetElementsKind(); |
4350 if (IsFastElementsKind(elements_kind) && | 4341 if (elements_kind == FAST_SMI_ONLY_ELEMENTS || |
4351 !IsFastObjectElementsKind(elements_kind)) { | 4342 elements_kind == FAST_DOUBLE_ELEMENTS) { |
4352 FixedArrayBase* elements = js_object->elements(); | 4343 FixedArrayBase* elements = js_object->elements(); |
4353 if (args.at<Smi>(1)->value() >= elements->length()) { | 4344 if (args.at<Smi>(1)->value() >= elements->length()) { |
4354 if (IsFastHoleyElementsKind(elements_kind)) { | |
4355 elements_kind = FAST_HOLEY_ELEMENTS; | |
4356 } else { | |
4357 elements_kind = FAST_ELEMENTS; | |
4358 } | |
4359 MaybeObject* maybe_object = TransitionElements(js_object, | 4345 MaybeObject* maybe_object = TransitionElements(js_object, |
4360 elements_kind, | 4346 FAST_ELEMENTS, |
4361 isolate); | 4347 isolate); |
4362 if (maybe_object->IsFailure()) return maybe_object; | 4348 if (maybe_object->IsFailure()) return maybe_object; |
4363 } | 4349 } |
4364 } | 4350 } |
4365 } | 4351 } |
4366 } else if (args[0]->IsString() && args[1]->IsSmi()) { | 4352 } else if (args[0]->IsString() && args[1]->IsSmi()) { |
4367 // Fast case for string indexing using [] with a smi index. | 4353 // Fast case for string indexing using [] with a smi index. |
4368 HandleScope scope(isolate); | 4354 HandleScope scope(isolate); |
4369 Handle<String> str = args.at<String>(0); | 4355 Handle<String> str = args.at<String>(0); |
4370 int index = args.smi_at(1); | 4356 int index = args.smi_at(1); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4520 // of a string using [] notation. We need to support this too in | 4506 // of a string using [] notation. We need to support this too in |
4521 // JavaScript. | 4507 // JavaScript. |
4522 // In the case of a String object we just need to redirect the assignment to | 4508 // In the case of a String object we just need to redirect the assignment to |
4523 // the underlying string if the index is in range. Since the underlying | 4509 // the underlying string if the index is in range. Since the underlying |
4524 // string does nothing with the assignment then we can ignore such | 4510 // string does nothing with the assignment then we can ignore such |
4525 // assignments. | 4511 // assignments. |
4526 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4512 if (js_object->IsStringObjectWithCharacterAt(index)) { |
4527 return *value; | 4513 return *value; |
4528 } | 4514 } |
4529 | 4515 |
4530 js_object->ValidateElements(); | |
4531 Handle<Object> result = JSObject::SetElement( | 4516 Handle<Object> result = JSObject::SetElement( |
4532 js_object, index, value, attr, strict_mode, set_mode); | 4517 js_object, index, value, attr, strict_mode, set_mode); |
4533 js_object->ValidateElements(); | |
4534 if (result.is_null()) return Failure::Exception(); | 4518 if (result.is_null()) return Failure::Exception(); |
4535 return *value; | 4519 return *value; |
4536 } | 4520 } |
4537 | 4521 |
4538 if (key->IsString()) { | 4522 if (key->IsString()) { |
4539 Handle<Object> result; | 4523 Handle<Object> result; |
4540 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 4524 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
4541 result = JSObject::SetElement( | 4525 result = JSObject::SetElement( |
4542 js_object, index, value, attr, strict_mode, set_mode); | 4526 js_object, index, value, attr, strict_mode, set_mode); |
4543 } else { | 4527 } else { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4681 value, | 4665 value, |
4682 attributes, | 4666 attributes, |
4683 strict_mode); | 4667 strict_mode); |
4684 } | 4668 } |
4685 | 4669 |
4686 | 4670 |
4687 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) { | 4671 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) { |
4688 NoHandleAllocation ha; | 4672 NoHandleAllocation ha; |
4689 RUNTIME_ASSERT(args.length() == 1); | 4673 RUNTIME_ASSERT(args.length() == 1); |
4690 Handle<Object> object = args.at<Object>(0); | 4674 Handle<Object> object = args.at<Object>(0); |
4691 if (object->IsJSObject()) { | 4675 return TransitionElements(object, FAST_DOUBLE_ELEMENTS, isolate); |
4692 Handle<JSObject> js_object(Handle<JSObject>::cast(object)); | |
4693 ElementsKind new_kind = js_object->HasFastHoleyElements() | |
4694 ? FAST_HOLEY_DOUBLE_ELEMENTS | |
4695 : FAST_DOUBLE_ELEMENTS; | |
4696 return TransitionElements(object, new_kind, isolate); | |
4697 } else { | |
4698 return *object; | |
4699 } | |
4700 } | 4676 } |
4701 | 4677 |
4702 | 4678 |
4703 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) { | 4679 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) { |
4704 NoHandleAllocation ha; | 4680 NoHandleAllocation ha; |
4705 RUNTIME_ASSERT(args.length() == 1); | 4681 RUNTIME_ASSERT(args.length() == 1); |
4706 Handle<Object> object = args.at<Object>(0); | 4682 Handle<Object> object = args.at<Object>(0); |
4707 if (object->IsJSObject()) { | 4683 return TransitionElements(object, FAST_ELEMENTS, isolate); |
4708 Handle<JSObject> js_object(Handle<JSObject>::cast(object)); | |
4709 ElementsKind new_kind = js_object->HasFastHoleyElements() | |
4710 ? FAST_HOLEY_ELEMENTS | |
4711 : FAST_ELEMENTS; | |
4712 return TransitionElements(object, new_kind, isolate); | |
4713 } else { | |
4714 return *object; | |
4715 } | |
4716 } | 4684 } |
4717 | 4685 |
4718 | 4686 |
4719 // Set the native flag on the function. | 4687 // Set the native flag on the function. |
4720 // This is used to decide if we should transform null and undefined | 4688 // This is used to decide if we should transform null and undefined |
4721 // into the global object when doing call and apply. | 4689 // into the global object when doing call and apply. |
4722 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { | 4690 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { |
4723 NoHandleAllocation ha; | 4691 NoHandleAllocation ha; |
4724 RUNTIME_ASSERT(args.length() == 1); | 4692 RUNTIME_ASSERT(args.length() == 1); |
4725 | 4693 |
(...skipping 10 matching lines...) Expand all Loading... |
4736 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { | 4704 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { |
4737 RUNTIME_ASSERT(args.length() == 5); | 4705 RUNTIME_ASSERT(args.length() == 5); |
4738 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 4706 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
4739 CONVERT_SMI_ARG_CHECKED(store_index, 1); | 4707 CONVERT_SMI_ARG_CHECKED(store_index, 1); |
4740 Handle<Object> value = args.at<Object>(2); | 4708 Handle<Object> value = args.at<Object>(2); |
4741 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); | 4709 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); |
4742 CONVERT_SMI_ARG_CHECKED(literal_index, 4); | 4710 CONVERT_SMI_ARG_CHECKED(literal_index, 4); |
4743 HandleScope scope; | 4711 HandleScope scope; |
4744 | 4712 |
4745 Object* raw_boilerplate_object = literals->get(literal_index); | 4713 Object* raw_boilerplate_object = literals->get(literal_index); |
4746 Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object)); | 4714 Handle<JSArray> boilerplate(JSArray::cast(raw_boilerplate_object)); |
| 4715 #if DEBUG |
4747 ElementsKind elements_kind = object->GetElementsKind(); | 4716 ElementsKind elements_kind = object->GetElementsKind(); |
4748 ASSERT(IsFastElementsKind(elements_kind)); | 4717 #endif |
| 4718 ASSERT(elements_kind <= FAST_DOUBLE_ELEMENTS); |
4749 // Smis should never trigger transitions. | 4719 // Smis should never trigger transitions. |
4750 ASSERT(!value->IsSmi()); | 4720 ASSERT(!value->IsSmi()); |
4751 | 4721 |
4752 if (value->IsNumber()) { | 4722 if (value->IsNumber()) { |
4753 ASSERT(IsFastSmiElementsKind(elements_kind)); | 4723 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS); |
4754 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) | 4724 JSObject::TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS); |
4755 ? FAST_HOLEY_DOUBLE_ELEMENTS | 4725 if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(), |
4756 : FAST_DOUBLE_ELEMENTS; | 4726 FAST_DOUBLE_ELEMENTS)) { |
4757 if (IsMoreGeneralElementsKindTransition( | 4727 JSObject::TransitionElementsKind(boilerplate, FAST_DOUBLE_ELEMENTS); |
4758 boilerplate_object->GetElementsKind(), | |
4759 transitioned_kind)) { | |
4760 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); | |
4761 } | 4728 } |
4762 JSObject::TransitionElementsKind(object, transitioned_kind); | 4729 ASSERT(object->GetElementsKind() == FAST_DOUBLE_ELEMENTS); |
4763 ASSERT(IsFastDoubleElementsKind(object->GetElementsKind())); | |
4764 FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements()); | 4730 FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements()); |
4765 HeapNumber* number = HeapNumber::cast(*value); | 4731 HeapNumber* number = HeapNumber::cast(*value); |
4766 double_array->set(store_index, number->Number()); | 4732 double_array->set(store_index, number->Number()); |
4767 } else { | 4733 } else { |
4768 ASSERT(IsFastSmiElementsKind(elements_kind) || | 4734 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS || |
4769 IsFastDoubleElementsKind(elements_kind)); | 4735 elements_kind == FAST_DOUBLE_ELEMENTS); |
4770 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) | 4736 JSObject::TransitionElementsKind(object, FAST_ELEMENTS); |
4771 ? FAST_HOLEY_ELEMENTS | 4737 if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(), |
4772 : FAST_ELEMENTS; | 4738 FAST_ELEMENTS)) { |
4773 JSObject::TransitionElementsKind(object, transitioned_kind); | 4739 JSObject::TransitionElementsKind(boilerplate, FAST_ELEMENTS); |
4774 if (IsMoreGeneralElementsKindTransition( | |
4775 boilerplate_object->GetElementsKind(), | |
4776 transitioned_kind)) { | |
4777 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); | |
4778 } | 4740 } |
4779 FixedArray* object_array = FixedArray::cast(object->elements()); | 4741 FixedArray* object_array = FixedArray::cast(object->elements()); |
4780 object_array->set(store_index, *value); | 4742 object_array->set(store_index, *value); |
4781 } | 4743 } |
4782 return *object; | 4744 return *object; |
4783 } | 4745 } |
4784 | 4746 |
4785 | 4747 |
4786 // Check whether debugger and is about to step into the callback that is passed | 4748 // Check whether debugger and is about to step into the callback that is passed |
4787 // to a built-in function such as Array.forEach. | 4749 // to a built-in function such as Array.forEach. |
(...skipping 1192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5980 new_string, final_length); | 5942 new_string, final_length); |
5981 return new_string; | 5943 return new_string; |
5982 } | 5944 } |
5983 | 5945 |
5984 | 5946 |
5985 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) { | 5947 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) { |
5986 NoHandleAllocation ha; | 5948 NoHandleAllocation ha; |
5987 ASSERT(args.length() == 1); | 5949 ASSERT(args.length() == 1); |
5988 CONVERT_ARG_CHECKED(JSArray, array, 0); | 5950 CONVERT_ARG_CHECKED(JSArray, array, 0); |
5989 | 5951 |
5990 if (!array->HasFastObjectElements()) { | 5952 if (!array->HasFastElements()) return isolate->heap()->undefined_value(); |
5991 return isolate->heap()->undefined_value(); | |
5992 } | |
5993 FixedArray* elements = FixedArray::cast(array->elements()); | 5953 FixedArray* elements = FixedArray::cast(array->elements()); |
5994 int n = elements->length(); | 5954 int n = elements->length(); |
5995 bool ascii = true; | 5955 bool ascii = true; |
5996 int total_length = 0; | 5956 int total_length = 0; |
5997 | 5957 |
5998 for (int i = 0; i < n; i++) { | 5958 for (int i = 0; i < n; i++) { |
5999 Object* elt = elements->get(i); | 5959 Object* elt = elements->get(i); |
6000 if (!elt->IsString()) return isolate->heap()->undefined_value(); | 5960 if (!elt->IsString()) return isolate->heap()->undefined_value(); |
6001 String* element = String::cast(elt); | 5961 String* element = String::cast(elt); |
6002 if (!element->IsFlat()) return isolate->heap()->undefined_value(); | 5962 if (!element->IsFlat()) return isolate->heap()->undefined_value(); |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6425 // The list indices now contains the end of each part to create. | 6385 // The list indices now contains the end of each part to create. |
6426 | 6386 |
6427 // Create JSArray of substrings separated by separator. | 6387 // Create JSArray of substrings separated by separator. |
6428 int part_count = indices.length(); | 6388 int part_count = indices.length(); |
6429 | 6389 |
6430 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); | 6390 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); |
6431 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements(); | 6391 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements(); |
6432 if (maybe_result->IsFailure()) return maybe_result; | 6392 if (maybe_result->IsFailure()) return maybe_result; |
6433 result->set_length(Smi::FromInt(part_count)); | 6393 result->set_length(Smi::FromInt(part_count)); |
6434 | 6394 |
6435 ASSERT(result->HasFastObjectElements()); | 6395 ASSERT(result->HasFastElements()); |
6436 | 6396 |
6437 if (part_count == 1 && indices.at(0) == subject_length) { | 6397 if (part_count == 1 && indices.at(0) == subject_length) { |
6438 FixedArray::cast(result->elements())->set(0, *subject); | 6398 FixedArray::cast(result->elements())->set(0, *subject); |
6439 return *result; | 6399 return *result; |
6440 } | 6400 } |
6441 | 6401 |
6442 Handle<FixedArray> elements(FixedArray::cast(result->elements())); | 6402 Handle<FixedArray> elements(FixedArray::cast(result->elements())); |
6443 int part_start = 0; | 6403 int part_start = 0; |
6444 for (int i = 0; i < part_count; i++) { | 6404 for (int i = 0; i < part_count; i++) { |
6445 HandleScope local_loop_handle; | 6405 HandleScope local_loop_handle; |
6446 int part_end = indices.at(i); | 6406 int part_end = indices.at(i); |
6447 Handle<String> substring = | 6407 Handle<String> substring = |
6448 isolate->factory()->NewProperSubString(subject, part_start, part_end); | 6408 isolate->factory()->NewProperSubString(subject, part_start, part_end); |
6449 elements->set(i, *substring); | 6409 elements->set(i, *substring); |
6450 part_start = part_end + pattern_length; | 6410 part_start = part_end + pattern_length; |
6451 } | 6411 } |
6452 | 6412 |
6453 if (limit == 0xffffffffu) { | 6413 if (limit == 0xffffffffu) { |
6454 if (result->HasFastObjectElements()) { | 6414 if (result->HasFastElements()) { |
6455 StringSplitCache::Enter(isolate->heap(), | 6415 StringSplitCache::Enter(isolate->heap(), |
6456 isolate->heap()->string_split_cache(), | 6416 isolate->heap()->string_split_cache(), |
6457 *subject, | 6417 *subject, |
6458 *pattern, | 6418 *pattern, |
6459 *elements); | 6419 *elements); |
6460 } | 6420 } |
6461 } | 6421 } |
6462 | 6422 |
6463 return *result; | 6423 return *result; |
6464 } | 6424 } |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6801 int array_length = args.smi_at(1); | 6761 int array_length = args.smi_at(1); |
6802 CONVERT_ARG_CHECKED(String, special, 2); | 6762 CONVERT_ARG_CHECKED(String, special, 2); |
6803 | 6763 |
6804 // This assumption is used by the slice encoding in one or two smis. | 6764 // This assumption is used by the slice encoding in one or two smis. |
6805 ASSERT(Smi::kMaxValue >= String::kMaxLength); | 6765 ASSERT(Smi::kMaxValue >= String::kMaxLength); |
6806 | 6766 |
6807 MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements(); | 6767 MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements(); |
6808 if (maybe_result->IsFailure()) return maybe_result; | 6768 if (maybe_result->IsFailure()) return maybe_result; |
6809 | 6769 |
6810 int special_length = special->length(); | 6770 int special_length = special->length(); |
6811 if (!array->HasFastObjectElements()) { | 6771 if (!array->HasFastElements()) { |
6812 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); | 6772 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
6813 } | 6773 } |
6814 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6774 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
6815 if (fixed_array->length() < array_length) { | 6775 if (fixed_array->length() < array_length) { |
6816 array_length = fixed_array->length(); | 6776 array_length = fixed_array->length(); |
6817 } | 6777 } |
6818 | 6778 |
6819 if (array_length == 0) { | 6779 if (array_length == 0) { |
6820 return isolate->heap()->empty_string(); | 6780 return isolate->heap()->empty_string(); |
6821 } else if (array_length == 1) { | 6781 } else if (array_length == 1) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6911 NoHandleAllocation ha; | 6871 NoHandleAllocation ha; |
6912 ASSERT(args.length() == 3); | 6872 ASSERT(args.length() == 3); |
6913 CONVERT_ARG_CHECKED(JSArray, array, 0); | 6873 CONVERT_ARG_CHECKED(JSArray, array, 0); |
6914 if (!args[1]->IsSmi()) { | 6874 if (!args[1]->IsSmi()) { |
6915 isolate->context()->mark_out_of_memory(); | 6875 isolate->context()->mark_out_of_memory(); |
6916 return Failure::OutOfMemoryException(); | 6876 return Failure::OutOfMemoryException(); |
6917 } | 6877 } |
6918 int array_length = args.smi_at(1); | 6878 int array_length = args.smi_at(1); |
6919 CONVERT_ARG_CHECKED(String, separator, 2); | 6879 CONVERT_ARG_CHECKED(String, separator, 2); |
6920 | 6880 |
6921 if (!array->HasFastObjectElements()) { | 6881 if (!array->HasFastElements()) { |
6922 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); | 6882 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
6923 } | 6883 } |
6924 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6884 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
6925 if (fixed_array->length() < array_length) { | 6885 if (fixed_array->length() < array_length) { |
6926 array_length = fixed_array->length(); | 6886 array_length = fixed_array->length(); |
6927 } | 6887 } |
6928 | 6888 |
6929 if (array_length == 0) { | 6889 if (array_length == 0) { |
6930 return isolate->heap()->empty_string(); | 6890 return isolate->heap()->empty_string(); |
6931 } else if (array_length == 1) { | 6891 } else if (array_length == 1) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7028 } | 6988 } |
7029 } | 6989 } |
7030 ASSERT(cursor <= buffer.length()); | 6990 ASSERT(cursor <= buffer.length()); |
7031 } | 6991 } |
7032 | 6992 |
7033 | 6993 |
7034 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { | 6994 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { |
7035 NoHandleAllocation ha; | 6995 NoHandleAllocation ha; |
7036 ASSERT(args.length() == 3); | 6996 ASSERT(args.length() == 3); |
7037 CONVERT_ARG_CHECKED(JSArray, elements_array, 0); | 6997 CONVERT_ARG_CHECKED(JSArray, elements_array, 0); |
7038 RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements()); | 6998 RUNTIME_ASSERT(elements_array->HasFastElements() || |
| 6999 elements_array->HasFastSmiOnlyElements()); |
7039 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); | 7000 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); |
7040 CONVERT_ARG_CHECKED(String, separator, 2); | 7001 CONVERT_ARG_CHECKED(String, separator, 2); |
7041 // elements_array is fast-mode JSarray of alternating positions | 7002 // elements_array is fast-mode JSarray of alternating positions |
7042 // (increasing order) and strings. | 7003 // (increasing order) and strings. |
7043 // array_length is length of original array (used to add separators); | 7004 // array_length is length of original array (used to add separators); |
7044 // separator is string to put between elements. Assumed to be non-empty. | 7005 // separator is string to put between elements. Assumed to be non-empty. |
7045 | 7006 |
7046 // Find total length of join result. | 7007 // Find total length of join result. |
7047 int string_length = 0; | 7008 int string_length = 0; |
7048 bool is_ascii = separator->IsAsciiRepresentation(); | 7009 bool is_ascii = separator->IsAsciiRepresentation(); |
(...skipping 2140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9189 ASSERT(args.length() == 2); | 9150 ASSERT(args.length() == 2); |
9190 | 9151 |
9191 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); | 9152 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); |
9192 FlattenString(str); | 9153 FlattenString(str); |
9193 | 9154 |
9194 CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1); | 9155 CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1); |
9195 | 9156 |
9196 MaybeObject* maybe_result_array = | 9157 MaybeObject* maybe_result_array = |
9197 output->EnsureCanContainHeapObjectElements(); | 9158 output->EnsureCanContainHeapObjectElements(); |
9198 if (maybe_result_array->IsFailure()) return maybe_result_array; | 9159 if (maybe_result_array->IsFailure()) return maybe_result_array; |
9199 RUNTIME_ASSERT(output->HasFastObjectElements()); | 9160 RUNTIME_ASSERT(output->HasFastElements()); |
9200 | 9161 |
9201 AssertNoAllocation no_allocation; | 9162 AssertNoAllocation no_allocation; |
9202 | 9163 |
9203 FixedArray* output_array = FixedArray::cast(output->elements()); | 9164 FixedArray* output_array = FixedArray::cast(output->elements()); |
9204 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 9165 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
9205 bool result; | 9166 bool result; |
9206 String::FlatContent str_content = str->GetFlatContent(); | 9167 String::FlatContent str_content = str->GetFlatContent(); |
9207 if (str_content.IsAscii()) { | 9168 if (str_content.IsAscii()) { |
9208 result = DateParser::Parse(str_content.ToAsciiVector(), | 9169 result = DateParser::Parse(str_content.ToAsciiVector(), |
9209 output_array, | 9170 output_array, |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9421 } | 9382 } |
9422 | 9383 |
9423 | 9384 |
9424 // Push an object unto an array of objects if it is not already in the | 9385 // Push an object unto an array of objects if it is not already in the |
9425 // array. Returns true if the element was pushed on the stack and | 9386 // array. Returns true if the element was pushed on the stack and |
9426 // false otherwise. | 9387 // false otherwise. |
9427 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { | 9388 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { |
9428 ASSERT(args.length() == 2); | 9389 ASSERT(args.length() == 2); |
9429 CONVERT_ARG_CHECKED(JSArray, array, 0); | 9390 CONVERT_ARG_CHECKED(JSArray, array, 0); |
9430 CONVERT_ARG_CHECKED(JSObject, element, 1); | 9391 CONVERT_ARG_CHECKED(JSObject, element, 1); |
9431 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements()); | 9392 RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
9432 int length = Smi::cast(array->length())->value(); | 9393 int length = Smi::cast(array->length())->value(); |
9433 FixedArray* elements = FixedArray::cast(array->elements()); | 9394 FixedArray* elements = FixedArray::cast(array->elements()); |
9434 for (int i = 0; i < length; i++) { | 9395 for (int i = 0; i < length; i++) { |
9435 if (elements->get(i) == element) return isolate->heap()->false_value(); | 9396 if (elements->get(i) == element) return isolate->heap()->false_value(); |
9436 } | 9397 } |
9437 Object* obj; | 9398 Object* obj; |
9438 // Strict not needed. Used for cycle detection in Array join implementation. | 9399 // Strict not needed. Used for cycle detection in Array join implementation. |
9439 { MaybeObject* maybe_obj = | 9400 { MaybeObject* maybe_obj = |
9440 array->SetFastElement(length, element, kNonStrictMode, true); | 9401 array->SetFastElement(length, element, kNonStrictMode, true); |
9441 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9402 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9506 } | 9467 } |
9507 } | 9468 } |
9508 | 9469 |
9509 Handle<JSArray> ToArray() { | 9470 Handle<JSArray> ToArray() { |
9510 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); | 9471 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); |
9511 Handle<Object> length = | 9472 Handle<Object> length = |
9512 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); | 9473 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); |
9513 Handle<Map> map; | 9474 Handle<Map> map; |
9514 if (fast_elements_) { | 9475 if (fast_elements_) { |
9515 map = isolate_->factory()->GetElementsTransitionMap(array, | 9476 map = isolate_->factory()->GetElementsTransitionMap(array, |
9516 FAST_HOLEY_ELEMENTS); | 9477 FAST_ELEMENTS); |
9517 } else { | 9478 } else { |
9518 map = isolate_->factory()->GetElementsTransitionMap(array, | 9479 map = isolate_->factory()->GetElementsTransitionMap(array, |
9519 DICTIONARY_ELEMENTS); | 9480 DICTIONARY_ELEMENTS); |
9520 } | 9481 } |
9521 array->set_map(*map); | 9482 array->set_map(*map); |
9522 array->set_length(*length); | 9483 array->set_length(*length); |
9523 array->set_elements(*storage_); | 9484 array->set_elements(*storage_); |
9524 return array; | 9485 return array; |
9525 } | 9486 } |
9526 | 9487 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9565 // JSObject::kMaxElementCount. | 9526 // JSObject::kMaxElementCount. |
9566 uint32_t index_offset_; | 9527 uint32_t index_offset_; |
9567 bool fast_elements_; | 9528 bool fast_elements_; |
9568 }; | 9529 }; |
9569 | 9530 |
9570 | 9531 |
9571 static uint32_t EstimateElementCount(Handle<JSArray> array) { | 9532 static uint32_t EstimateElementCount(Handle<JSArray> array) { |
9572 uint32_t length = static_cast<uint32_t>(array->length()->Number()); | 9533 uint32_t length = static_cast<uint32_t>(array->length()->Number()); |
9573 int element_count = 0; | 9534 int element_count = 0; |
9574 switch (array->GetElementsKind()) { | 9535 switch (array->GetElementsKind()) { |
9575 case FAST_SMI_ELEMENTS: | 9536 case FAST_SMI_ONLY_ELEMENTS: |
9576 case FAST_HOLEY_SMI_ELEMENTS: | 9537 case FAST_ELEMENTS: { |
9577 case FAST_ELEMENTS: | |
9578 case FAST_HOLEY_ELEMENTS: { | |
9579 // Fast elements can't have lengths that are not representable by | 9538 // Fast elements can't have lengths that are not representable by |
9580 // a 32-bit signed integer. | 9539 // a 32-bit signed integer. |
9581 ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); | 9540 ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); |
9582 int fast_length = static_cast<int>(length); | 9541 int fast_length = static_cast<int>(length); |
9583 Handle<FixedArray> elements(FixedArray::cast(array->elements())); | 9542 Handle<FixedArray> elements(FixedArray::cast(array->elements())); |
9584 for (int i = 0; i < fast_length; i++) { | 9543 for (int i = 0; i < fast_length; i++) { |
9585 if (!elements->get(i)->IsTheHole()) element_count++; | 9544 if (!elements->get(i)->IsTheHole()) element_count++; |
9586 } | 9545 } |
9587 break; | 9546 break; |
9588 } | 9547 } |
9589 case FAST_DOUBLE_ELEMENTS: | 9548 case FAST_DOUBLE_ELEMENTS: |
9590 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
9591 // TODO(1810): Decide if it's worthwhile to implement this. | 9549 // TODO(1810): Decide if it's worthwhile to implement this. |
9592 UNREACHABLE(); | 9550 UNREACHABLE(); |
9593 break; | 9551 break; |
9594 case DICTIONARY_ELEMENTS: { | 9552 case DICTIONARY_ELEMENTS: { |
9595 Handle<SeededNumberDictionary> dictionary( | 9553 Handle<SeededNumberDictionary> dictionary( |
9596 SeededNumberDictionary::cast(array->elements())); | 9554 SeededNumberDictionary::cast(array->elements())); |
9597 int capacity = dictionary->Capacity(); | 9555 int capacity = dictionary->Capacity(); |
9598 for (int i = 0; i < capacity; i++) { | 9556 for (int i = 0; i < capacity; i++) { |
9599 Handle<Object> key(dictionary->KeyAt(i)); | 9557 Handle<Object> key(dictionary->KeyAt(i)); |
9600 if (dictionary->IsKey(*key)) { | 9558 if (dictionary->IsKey(*key)) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9671 uint32_t b = *bp; | 9629 uint32_t b = *bp; |
9672 return (a == b) ? 0 : (a < b) ? -1 : 1; | 9630 return (a == b) ? 0 : (a < b) ? -1 : 1; |
9673 } | 9631 } |
9674 | 9632 |
9675 | 9633 |
9676 static void CollectElementIndices(Handle<JSObject> object, | 9634 static void CollectElementIndices(Handle<JSObject> object, |
9677 uint32_t range, | 9635 uint32_t range, |
9678 List<uint32_t>* indices) { | 9636 List<uint32_t>* indices) { |
9679 ElementsKind kind = object->GetElementsKind(); | 9637 ElementsKind kind = object->GetElementsKind(); |
9680 switch (kind) { | 9638 switch (kind) { |
9681 case FAST_SMI_ELEMENTS: | 9639 case FAST_SMI_ONLY_ELEMENTS: |
9682 case FAST_ELEMENTS: | 9640 case FAST_ELEMENTS: { |
9683 case FAST_HOLEY_SMI_ELEMENTS: | |
9684 case FAST_HOLEY_ELEMENTS: { | |
9685 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 9641 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
9686 uint32_t length = static_cast<uint32_t>(elements->length()); | 9642 uint32_t length = static_cast<uint32_t>(elements->length()); |
9687 if (range < length) length = range; | 9643 if (range < length) length = range; |
9688 for (uint32_t i = 0; i < length; i++) { | 9644 for (uint32_t i = 0; i < length; i++) { |
9689 if (!elements->get(i)->IsTheHole()) { | 9645 if (!elements->get(i)->IsTheHole()) { |
9690 indices->Add(i); | 9646 indices->Add(i); |
9691 } | 9647 } |
9692 } | 9648 } |
9693 break; | 9649 break; |
9694 } | 9650 } |
9695 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
9696 case FAST_DOUBLE_ELEMENTS: { | 9651 case FAST_DOUBLE_ELEMENTS: { |
9697 // TODO(1810): Decide if it's worthwhile to implement this. | 9652 // TODO(1810): Decide if it's worthwhile to implement this. |
9698 UNREACHABLE(); | 9653 UNREACHABLE(); |
9699 break; | 9654 break; |
9700 } | 9655 } |
9701 case DICTIONARY_ELEMENTS: { | 9656 case DICTIONARY_ELEMENTS: { |
9702 Handle<SeededNumberDictionary> dict( | 9657 Handle<SeededNumberDictionary> dict( |
9703 SeededNumberDictionary::cast(object->elements())); | 9658 SeededNumberDictionary::cast(object->elements())); |
9704 uint32_t capacity = dict->Capacity(); | 9659 uint32_t capacity = dict->Capacity(); |
9705 for (uint32_t j = 0; j < capacity; j++) { | 9660 for (uint32_t j = 0; j < capacity; j++) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9800 * with the element index and the element's value. | 9755 * with the element index and the element's value. |
9801 * Afterwards it increments the base-index of the visitor by the array | 9756 * Afterwards it increments the base-index of the visitor by the array |
9802 * length. | 9757 * length. |
9803 * Returns false if any access threw an exception, otherwise true. | 9758 * Returns false if any access threw an exception, otherwise true. |
9804 */ | 9759 */ |
9805 static bool IterateElements(Isolate* isolate, | 9760 static bool IterateElements(Isolate* isolate, |
9806 Handle<JSArray> receiver, | 9761 Handle<JSArray> receiver, |
9807 ArrayConcatVisitor* visitor) { | 9762 ArrayConcatVisitor* visitor) { |
9808 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); | 9763 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); |
9809 switch (receiver->GetElementsKind()) { | 9764 switch (receiver->GetElementsKind()) { |
9810 case FAST_SMI_ELEMENTS: | 9765 case FAST_SMI_ONLY_ELEMENTS: |
9811 case FAST_ELEMENTS: | 9766 case FAST_ELEMENTS: { |
9812 case FAST_HOLEY_SMI_ELEMENTS: | |
9813 case FAST_HOLEY_ELEMENTS: { | |
9814 // Run through the elements FixedArray and use HasElement and GetElement | 9767 // Run through the elements FixedArray and use HasElement and GetElement |
9815 // to check the prototype for missing elements. | 9768 // to check the prototype for missing elements. |
9816 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); | 9769 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); |
9817 int fast_length = static_cast<int>(length); | 9770 int fast_length = static_cast<int>(length); |
9818 ASSERT(fast_length <= elements->length()); | 9771 ASSERT(fast_length <= elements->length()); |
9819 for (int j = 0; j < fast_length; j++) { | 9772 for (int j = 0; j < fast_length; j++) { |
9820 HandleScope loop_scope(isolate); | 9773 HandleScope loop_scope(isolate); |
9821 Handle<Object> element_value(elements->get(j), isolate); | 9774 Handle<Object> element_value(elements->get(j), isolate); |
9822 if (!element_value->IsTheHole()) { | 9775 if (!element_value->IsTheHole()) { |
9823 visitor->visit(j, element_value); | 9776 visitor->visit(j, element_value); |
9824 } else if (receiver->HasElement(j)) { | 9777 } else if (receiver->HasElement(j)) { |
9825 // Call GetElement on receiver, not its prototype, or getters won't | 9778 // Call GetElement on receiver, not its prototype, or getters won't |
9826 // have the correct receiver. | 9779 // have the correct receiver. |
9827 element_value = Object::GetElement(receiver, j); | 9780 element_value = Object::GetElement(receiver, j); |
9828 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); | 9781 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); |
9829 visitor->visit(j, element_value); | 9782 visitor->visit(j, element_value); |
9830 } | 9783 } |
9831 } | 9784 } |
9832 break; | 9785 break; |
9833 } | 9786 } |
9834 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
9835 case FAST_DOUBLE_ELEMENTS: { | 9787 case FAST_DOUBLE_ELEMENTS: { |
9836 // TODO(1810): Decide if it's worthwhile to implement this. | 9788 // TODO(1810): Decide if it's worthwhile to implement this. |
9837 UNREACHABLE(); | 9789 UNREACHABLE(); |
9838 break; | 9790 break; |
9839 } | 9791 } |
9840 case DICTIONARY_ELEMENTS: { | 9792 case DICTIONARY_ELEMENTS: { |
9841 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); | 9793 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); |
9842 List<uint32_t> indices(dict->Capacity() / 2); | 9794 List<uint32_t> indices(dict->Capacity() / 2); |
9843 // Collect all indices in the object and the prototypes less | 9795 // Collect all indices in the object and the prototypes less |
9844 // than length. This might introduce duplicates in the indices list. | 9796 // than length. This might introduce duplicates in the indices list. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9922 * See ECMAScript 262, 15.4.4.4. | 9874 * See ECMAScript 262, 15.4.4.4. |
9923 * TODO(581): Fix non-compliance for very large concatenations and update to | 9875 * TODO(581): Fix non-compliance for very large concatenations and update to |
9924 * following the ECMAScript 5 specification. | 9876 * following the ECMAScript 5 specification. |
9925 */ | 9877 */ |
9926 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) { | 9878 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) { |
9927 ASSERT(args.length() == 1); | 9879 ASSERT(args.length() == 1); |
9928 HandleScope handle_scope(isolate); | 9880 HandleScope handle_scope(isolate); |
9929 | 9881 |
9930 CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0); | 9882 CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0); |
9931 int argument_count = static_cast<int>(arguments->length()->Number()); | 9883 int argument_count = static_cast<int>(arguments->length()->Number()); |
9932 RUNTIME_ASSERT(arguments->HasFastObjectElements()); | 9884 RUNTIME_ASSERT(arguments->HasFastElements()); |
9933 Handle<FixedArray> elements(FixedArray::cast(arguments->elements())); | 9885 Handle<FixedArray> elements(FixedArray::cast(arguments->elements())); |
9934 | 9886 |
9935 // Pass 1: estimate the length and number of elements of the result. | 9887 // Pass 1: estimate the length and number of elements of the result. |
9936 // The actual length can be larger if any of the arguments have getters | 9888 // The actual length can be larger if any of the arguments have getters |
9937 // that mutate other arguments (but will otherwise be precise). | 9889 // that mutate other arguments (but will otherwise be precise). |
9938 // The number of elements is precise if there are no inherited elements. | 9890 // The number of elements is precise if there are no inherited elements. |
9939 | 9891 |
9940 uint32_t estimate_result_length = 0; | 9892 uint32_t estimate_result_length = 0; |
9941 uint32_t estimate_nof_elements = 0; | 9893 uint32_t estimate_nof_elements = 0; |
9942 { | 9894 { |
9943 for (int i = 0; i < argument_count; i++) { | 9895 for (int i = 0; i < argument_count; i++) { |
9944 HandleScope loop_scope; | 9896 HandleScope loop_scope; |
9945 Handle<Object> obj(elements->get(i)); | 9897 Handle<Object> obj(elements->get(i)); |
9946 uint32_t length_estimate; | 9898 uint32_t length_estimate; |
9947 uint32_t element_estimate; | 9899 uint32_t element_estimate; |
9948 if (obj->IsJSArray()) { | 9900 if (obj->IsJSArray()) { |
9949 Handle<JSArray> array(Handle<JSArray>::cast(obj)); | 9901 Handle<JSArray> array(Handle<JSArray>::cast(obj)); |
9950 // TODO(1810): Find out if it's worthwhile to properly support | 9902 // TODO(1810): Find out if it's worthwhile to properly support |
9951 // arbitrary ElementsKinds. For now, pessimistically transition to | 9903 // arbitrary ElementsKinds. For now, pessimistically transition to |
9952 // FAST_*_ELEMENTS. | 9904 // FAST_ELEMENTS. |
9953 if (array->HasFastDoubleElements()) { | 9905 if (array->HasFastDoubleElements()) { |
9954 ElementsKind to_kind = FAST_ELEMENTS; | |
9955 if (array->HasFastHoleyElements()) { | |
9956 to_kind = FAST_HOLEY_ELEMENTS; | |
9957 } | |
9958 array = Handle<JSArray>::cast( | 9906 array = Handle<JSArray>::cast( |
9959 JSObject::TransitionElementsKind(array, to_kind)); | 9907 JSObject::TransitionElementsKind(array, FAST_ELEMENTS)); |
9960 } | 9908 } |
9961 length_estimate = | 9909 length_estimate = |
9962 static_cast<uint32_t>(array->length()->Number()); | 9910 static_cast<uint32_t>(array->length()->Number()); |
9963 element_estimate = | 9911 element_estimate = |
9964 EstimateElementCount(array); | 9912 EstimateElementCount(array); |
9965 } else { | 9913 } else { |
9966 length_estimate = 1; | 9914 length_estimate = 1; |
9967 element_estimate = 1; | 9915 element_estimate = 1; |
9968 } | 9916 } |
9969 // Avoid overflows by capping at kMaxElementCount. | 9917 // Avoid overflows by capping at kMaxElementCount. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10046 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 9994 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
10047 return object->PrepareElementsForSort(limit); | 9995 return object->PrepareElementsForSort(limit); |
10048 } | 9996 } |
10049 | 9997 |
10050 | 9998 |
10051 // Move contents of argument 0 (an array) to argument 1 (an array) | 9999 // Move contents of argument 0 (an array) to argument 1 (an array) |
10052 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { | 10000 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { |
10053 ASSERT(args.length() == 2); | 10001 ASSERT(args.length() == 2); |
10054 CONVERT_ARG_CHECKED(JSArray, from, 0); | 10002 CONVERT_ARG_CHECKED(JSArray, from, 0); |
10055 CONVERT_ARG_CHECKED(JSArray, to, 1); | 10003 CONVERT_ARG_CHECKED(JSArray, to, 1); |
10056 from->ValidateElements(); | |
10057 to->ValidateElements(); | |
10058 FixedArrayBase* new_elements = from->elements(); | 10004 FixedArrayBase* new_elements = from->elements(); |
10059 ElementsKind from_kind = from->GetElementsKind(); | |
10060 MaybeObject* maybe_new_map; | 10005 MaybeObject* maybe_new_map; |
10061 maybe_new_map = to->GetElementsTransitionMap(isolate, from_kind); | 10006 ElementsKind elements_kind; |
| 10007 if (new_elements->map() == isolate->heap()->fixed_array_map() || |
| 10008 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { |
| 10009 elements_kind = FAST_ELEMENTS; |
| 10010 } else if (new_elements->map() == |
| 10011 isolate->heap()->fixed_double_array_map()) { |
| 10012 elements_kind = FAST_DOUBLE_ELEMENTS; |
| 10013 } else { |
| 10014 elements_kind = DICTIONARY_ELEMENTS; |
| 10015 } |
| 10016 maybe_new_map = to->GetElementsTransitionMap(isolate, elements_kind); |
10062 Object* new_map; | 10017 Object* new_map; |
10063 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 10018 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
10064 to->set_map_and_elements(Map::cast(new_map), new_elements); | 10019 to->set_map(Map::cast(new_map)); |
| 10020 to->set_elements(new_elements); |
10065 to->set_length(from->length()); | 10021 to->set_length(from->length()); |
10066 Object* obj; | 10022 Object* obj; |
10067 { MaybeObject* maybe_obj = from->ResetElements(); | 10023 { MaybeObject* maybe_obj = from->ResetElements(); |
10068 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 10024 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
10069 } | 10025 } |
10070 from->set_length(Smi::FromInt(0)); | 10026 from->set_length(Smi::FromInt(0)); |
10071 to->ValidateElements(); | |
10072 return to; | 10027 return to; |
10073 } | 10028 } |
10074 | 10029 |
10075 | 10030 |
10076 // How many elements does this object/array have? | 10031 // How many elements does this object/array have? |
10077 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) { | 10032 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) { |
10078 ASSERT(args.length() == 1); | 10033 ASSERT(args.length() == 1); |
10079 CONVERT_ARG_CHECKED(JSObject, object, 0); | 10034 CONVERT_ARG_CHECKED(JSObject, object, 0); |
10080 HeapObject* elements = object->elements(); | 10035 HeapObject* elements = object->elements(); |
10081 if (elements->IsDictionary()) { | 10036 if (elements->IsDictionary()) { |
(...skipping 29 matching lines...) Expand all Loading... |
10111 for (int i = 0; i < keys_length; i++) { | 10066 for (int i = 0; i < keys_length; i++) { |
10112 Object* key = keys->get(i); | 10067 Object* key = keys->get(i); |
10113 uint32_t index = 0; | 10068 uint32_t index = 0; |
10114 if (!key->ToArrayIndex(&index) || index >= length) { | 10069 if (!key->ToArrayIndex(&index) || index >= length) { |
10115 // Zap invalid keys. | 10070 // Zap invalid keys. |
10116 keys->set_undefined(i); | 10071 keys->set_undefined(i); |
10117 } | 10072 } |
10118 } | 10073 } |
10119 return *isolate->factory()->NewJSArrayWithElements(keys); | 10074 return *isolate->factory()->NewJSArrayWithElements(keys); |
10120 } else { | 10075 } else { |
10121 ASSERT(array->HasFastSmiOrObjectElements() || | 10076 ASSERT(array->HasFastElements() || |
| 10077 array->HasFastSmiOnlyElements() || |
10122 array->HasFastDoubleElements()); | 10078 array->HasFastDoubleElements()); |
10123 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); | 10079 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); |
10124 // -1 means start of array. | 10080 // -1 means start of array. |
10125 single_interval->set(0, Smi::FromInt(-1)); | 10081 single_interval->set(0, Smi::FromInt(-1)); |
10126 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); | 10082 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); |
10127 uint32_t actual_length = | 10083 uint32_t actual_length = |
10128 static_cast<uint32_t>(elements->length()); | 10084 static_cast<uint32_t>(elements->length()); |
10129 uint32_t min_length = actual_length < length ? actual_length : length; | 10085 uint32_t min_length = actual_length < length ? actual_length : length; |
10130 Handle<Object> length_object = | 10086 Handle<Object> length_object = |
10131 isolate->factory()->NewNumber(static_cast<double>(min_length)); | 10087 isolate->factory()->NewNumber(static_cast<double>(min_length)); |
(...skipping 3294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13426 return NULL; | 13382 return NULL; |
13427 } | 13383 } |
13428 | 13384 |
13429 | 13385 |
13430 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ | 13386 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ |
13431 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ | 13387 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ |
13432 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ | 13388 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ |
13433 return isolate->heap()->ToBoolean(obj->Has##Name()); \ | 13389 return isolate->heap()->ToBoolean(obj->Has##Name()); \ |
13434 } | 13390 } |
13435 | 13391 |
13436 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements) | 13392 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements) |
13437 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements) | 13393 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) |
13438 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements) | |
13439 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) | 13394 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) |
13440 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements) | |
13441 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) | 13395 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) |
13442 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) | 13396 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) |
13443 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) | 13397 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) |
13444 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) | 13398 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) |
13445 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) | 13399 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) |
13446 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) | 13400 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) |
13447 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) | 13401 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) |
13448 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) | 13402 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) |
13449 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements) | 13403 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements) |
13450 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements) | 13404 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements) |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13539 // Handle last resort GC and make sure to allow future allocations | 13493 // Handle last resort GC and make sure to allow future allocations |
13540 // to grow the heap without causing GCs (if possible). | 13494 // to grow the heap without causing GCs (if possible). |
13541 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13495 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13542 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13496 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13543 "Runtime::PerformGC"); | 13497 "Runtime::PerformGC"); |
13544 } | 13498 } |
13545 } | 13499 } |
13546 | 13500 |
13547 | 13501 |
13548 } } // namespace v8::internal | 13502 } } // namespace v8::internal |
OLD | NEW |