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_ONLY_ELEMENTS: | 211 case FAST_SMI_ELEMENTS: |
212 case FAST_ELEMENTS: { | 212 case FAST_ELEMENTS: |
213 case FAST_HOLEY_SMI_ELEMENTS: | |
214 case FAST_HOLEY_ELEMENTS: { | |
213 FixedArray* elements = FixedArray::cast(copy->elements()); | 215 FixedArray* elements = FixedArray::cast(copy->elements()); |
214 if (elements->map() == heap->fixed_cow_array_map()) { | 216 if (elements->map() == heap->fixed_cow_array_map()) { |
215 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 217 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
216 #ifdef DEBUG | 218 #ifdef DEBUG |
217 for (int i = 0; i < elements->length(); i++) { | 219 for (int i = 0; i < elements->length(); i++) { |
218 ASSERT(!elements->get(i)->IsJSObject()); | 220 ASSERT(!elements->get(i)->IsJSObject()); |
219 } | 221 } |
220 #endif | 222 #endif |
221 } else { | 223 } else { |
222 for (int i = 0; i < elements->length(); i++) { | 224 for (int i = 0; i < elements->length(); i++) { |
223 Object* value = elements->get(i); | 225 Object* value = elements->get(i); |
224 ASSERT(value->IsSmi() || | 226 ASSERT(value->IsSmi() || |
225 value->IsTheHole() || | 227 value->IsTheHole() || |
226 (copy->GetElementsKind() == FAST_ELEMENTS)); | 228 (IsFastObjectElementsKind(copy->GetElementsKind()))); |
227 if (value->IsJSObject()) { | 229 if (value->IsJSObject()) { |
228 JSObject* js_object = JSObject::cast(value); | 230 JSObject* js_object = JSObject::cast(value); |
229 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, | 231 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, |
230 js_object); | 232 js_object); |
231 if (!maybe_result->ToObject(&result)) return maybe_result; | 233 if (!maybe_result->ToObject(&result)) return maybe_result; |
232 } | 234 } |
233 elements->set(i, result); | 235 elements->set(i, result); |
234 } | 236 } |
235 } | 237 } |
236 } | 238 } |
(...skipping 24 matching lines...) Expand all Loading... | |
261 case EXTERNAL_PIXEL_ELEMENTS: | 263 case EXTERNAL_PIXEL_ELEMENTS: |
262 case EXTERNAL_BYTE_ELEMENTS: | 264 case EXTERNAL_BYTE_ELEMENTS: |
263 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 265 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
264 case EXTERNAL_SHORT_ELEMENTS: | 266 case EXTERNAL_SHORT_ELEMENTS: |
265 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 267 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
266 case EXTERNAL_INT_ELEMENTS: | 268 case EXTERNAL_INT_ELEMENTS: |
267 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 269 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
268 case EXTERNAL_FLOAT_ELEMENTS: | 270 case EXTERNAL_FLOAT_ELEMENTS: |
269 case EXTERNAL_DOUBLE_ELEMENTS: | 271 case EXTERNAL_DOUBLE_ELEMENTS: |
270 case FAST_DOUBLE_ELEMENTS: | 272 case FAST_DOUBLE_ELEMENTS: |
273 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
271 // No contained objects, nothing to do. | 274 // No contained objects, nothing to do. |
272 break; | 275 break; |
273 } | 276 } |
274 return copy; | 277 return copy; |
275 } | 278 } |
276 | 279 |
277 | 280 |
278 static Handle<Map> ComputeObjectLiteralMap( | 281 static Handle<Map> ComputeObjectLiteralMap( |
279 Handle<Context> context, | 282 Handle<Context> context, |
280 Handle<FixedArray> constant_properties, | 283 Handle<FixedArray> constant_properties, |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
445 if (Map::IsValidElementsTransition(from_kind, to_kind)) { | 448 if (Map::IsValidElementsTransition(from_kind, to_kind)) { |
446 Handle<Object> result = JSObject::TransitionElementsKind( | 449 Handle<Object> result = JSObject::TransitionElementsKind( |
447 Handle<JSObject>::cast(object), to_kind); | 450 Handle<JSObject>::cast(object), to_kind); |
448 if (result.is_null()) return isolate->ThrowIllegalOperation(); | 451 if (result.is_null()) return isolate->ThrowIllegalOperation(); |
449 return *result; | 452 return *result; |
450 } | 453 } |
451 return isolate->ThrowIllegalOperation(); | 454 return isolate->ThrowIllegalOperation(); |
452 } | 455 } |
453 | 456 |
454 | 457 |
455 static const int kSmiOnlyLiteralMinimumLength = 1024; | 458 static const int kSmiLiteralMinimumLength = 1024; |
456 | 459 |
457 | 460 |
458 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( | 461 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( |
459 Isolate* isolate, | 462 Isolate* isolate, |
460 Handle<FixedArray> literals, | 463 Handle<FixedArray> literals, |
461 Handle<FixedArray> elements) { | 464 Handle<FixedArray> elements) { |
462 // Create the JSArray. | 465 // Create the JSArray. |
463 Handle<JSFunction> constructor( | 466 Handle<JSFunction> constructor( |
464 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); | 467 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
465 Handle<JSArray> object = | 468 Handle<JSArray> object = |
466 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); | 469 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); |
467 | 470 |
468 ElementsKind constant_elements_kind = | 471 ElementsKind constant_elements_kind = |
469 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); | 472 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); |
470 Handle<FixedArrayBase> constant_elements_values( | 473 Handle<FixedArrayBase> constant_elements_values( |
471 FixedArrayBase::cast(elements->get(1))); | 474 FixedArrayBase::cast(elements->get(1))); |
472 | 475 |
476 ASSERT(IsFastElementsKind(constant_elements_kind)); | |
473 Context* global_context = isolate->context()->global_context(); | 477 Context* global_context = isolate->context()->global_context(); |
474 if (constant_elements_kind == FAST_SMI_ONLY_ELEMENTS) { | 478 Object* maybe_maps_array = global_context->js_array_maps(); |
475 object->set_map(Map::cast(global_context->smi_js_array_map())); | 479 ASSERT(!maybe_maps_array->IsUndefined()); |
476 } else if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { | 480 Object* maybe_map = FixedArray::cast(maybe_maps_array)->get( |
477 object->set_map(Map::cast(global_context->double_js_array_map())); | 481 constant_elements_kind); |
478 } else { | 482 ASSERT(maybe_map->IsMap()); |
479 object->set_map(Map::cast(global_context->object_js_array_map())); | 483 object->set_map(Map::cast(maybe_map)); |
480 } | |
481 | 484 |
482 Handle<FixedArrayBase> copied_elements_values; | 485 Handle<FixedArrayBase> copied_elements_values; |
483 if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { | 486 if (IsFastDoubleElementsKind(constant_elements_kind)) { |
484 ASSERT(FLAG_smi_only_arrays); | 487 ASSERT(FLAG_smi_only_arrays); |
485 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( | 488 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( |
486 Handle<FixedDoubleArray>::cast(constant_elements_values)); | 489 Handle<FixedDoubleArray>::cast(constant_elements_values)); |
487 } else { | 490 } else { |
488 ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS || | 491 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind)); |
489 constant_elements_kind == FAST_ELEMENTS); | |
490 const bool is_cow = | 492 const bool is_cow = |
491 (constant_elements_values->map() == | 493 (constant_elements_values->map() == |
492 isolate->heap()->fixed_cow_array_map()); | 494 isolate->heap()->fixed_cow_array_map()); |
493 if (is_cow) { | 495 if (is_cow) { |
494 copied_elements_values = constant_elements_values; | 496 copied_elements_values = constant_elements_values; |
495 #if DEBUG | 497 #if DEBUG |
496 Handle<FixedArray> fixed_array_values = | 498 Handle<FixedArray> fixed_array_values = |
497 Handle<FixedArray>::cast(copied_elements_values); | 499 Handle<FixedArray>::cast(copied_elements_values); |
498 for (int i = 0; i < fixed_array_values->length(); i++) { | 500 for (int i = 0; i < fixed_array_values->length(); i++) { |
499 ASSERT(!fixed_array_values->get(i)->IsFixedArray()); | 501 ASSERT(!fixed_array_values->get(i)->IsFixedArray()); |
(...skipping 15 matching lines...) Expand all Loading... | |
515 CreateLiteralBoilerplate(isolate, literals, fa); | 517 CreateLiteralBoilerplate(isolate, literals, fa); |
516 if (result.is_null()) return result; | 518 if (result.is_null()) return result; |
517 fixed_array_values_copy->set(i, *result); | 519 fixed_array_values_copy->set(i, *result); |
518 } | 520 } |
519 } | 521 } |
520 } | 522 } |
521 } | 523 } |
522 object->set_elements(*copied_elements_values); | 524 object->set_elements(*copied_elements_values); |
523 object->set_length(Smi::FromInt(copied_elements_values->length())); | 525 object->set_length(Smi::FromInt(copied_elements_values->length())); |
524 | 526 |
525 // Ensure that the boilerplate object has FAST_ELEMENTS, unless the flag is | 527 // Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is |
526 // on or the object is larger than the threshold. | 528 // on or the object is larger than the threshold. |
527 if (!FLAG_smi_only_arrays && | 529 if (!FLAG_smi_only_arrays && |
528 constant_elements_values->length() < kSmiOnlyLiteralMinimumLength) { | 530 constant_elements_values->length() < kSmiLiteralMinimumLength) { |
529 if (object->GetElementsKind() != FAST_ELEMENTS) { | 531 ElementsKind elements_kind = object->GetElementsKind(); |
530 CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure()); | 532 if (!IsFastObjectElementsKind(elements_kind)) { |
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 } | |
531 } | 539 } |
532 } | 540 } |
533 | 541 |
534 return object; | 542 return object; |
535 } | 543 } |
536 | 544 |
537 | 545 |
538 static Handle<Object> CreateLiteralBoilerplate( | 546 static Handle<Object> CreateLiteralBoilerplate( |
539 Isolate* isolate, | 547 Isolate* isolate, |
540 Handle<FixedArray> literals, | 548 Handle<FixedArray> literals, |
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1723 | 1731 |
1724 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { | 1732 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { |
1725 HandleScope scope(isolate); | 1733 HandleScope scope(isolate); |
1726 ASSERT(args.length() == 4); | 1734 ASSERT(args.length() == 4); |
1727 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); | 1735 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
1728 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); | 1736 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); |
1729 // Due to the way the JS calls are constructed this must be less than the | 1737 // Due to the way the JS calls are constructed this must be less than the |
1730 // length of a string, i.e. it is always a Smi. We check anyway for security. | 1738 // length of a string, i.e. it is always a Smi. We check anyway for security. |
1731 CONVERT_SMI_ARG_CHECKED(index, 2); | 1739 CONVERT_SMI_ARG_CHECKED(index, 2); |
1732 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); | 1740 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); |
1733 RUNTIME_ASSERT(last_match_info->HasFastElements()); | 1741 RUNTIME_ASSERT(last_match_info->HasFastObjectElements()); |
1734 RUNTIME_ASSERT(index >= 0); | 1742 RUNTIME_ASSERT(index >= 0); |
1735 RUNTIME_ASSERT(index <= subject->length()); | 1743 RUNTIME_ASSERT(index <= subject->length()); |
1736 isolate->counters()->regexp_entry_runtime()->Increment(); | 1744 isolate->counters()->regexp_entry_runtime()->Increment(); |
1737 Handle<Object> result = RegExpImpl::Exec(regexp, | 1745 Handle<Object> result = RegExpImpl::Exec(regexp, |
1738 subject, | 1746 subject, |
1739 index, | 1747 index, |
1740 last_match_info); | 1748 last_match_info); |
1741 if (result.is_null()) return Failure::Exception(); | 1749 if (result.is_null()) return Failure::Exception(); |
1742 return *result; | 1750 return *result; |
1743 } | 1751 } |
(...skipping 1353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3097 | 3105 |
3098 // Index of end of last match. | 3106 // Index of end of last match. |
3099 int prev = 0; | 3107 int prev = 0; |
3100 | 3108 |
3101 // Number of parts added by compiled replacement plus preceeding | 3109 // Number of parts added by compiled replacement plus preceeding |
3102 // string and possibly suffix after last match. It is possible for | 3110 // string and possibly suffix after last match. It is possible for |
3103 // all components to use two elements when encoded as two smis. | 3111 // all components to use two elements when encoded as two smis. |
3104 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2); | 3112 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2); |
3105 bool matched = true; | 3113 bool matched = true; |
3106 do { | 3114 do { |
3107 ASSERT(last_match_info_handle->HasFastElements()); | 3115 ASSERT(last_match_info_handle->HasFastObjectElements()); |
3108 // Increase the capacity of the builder before entering local handle-scope, | 3116 // Increase the capacity of the builder before entering local handle-scope, |
3109 // so its internal buffer can safely allocate a new handle if it grows. | 3117 // so its internal buffer can safely allocate a new handle if it grows. |
3110 builder.EnsureCapacity(parts_added_per_loop); | 3118 builder.EnsureCapacity(parts_added_per_loop); |
3111 | 3119 |
3112 HandleScope loop_scope(isolate); | 3120 HandleScope loop_scope(isolate); |
3113 int start, end; | 3121 int start, end; |
3114 { | 3122 { |
3115 AssertNoAllocation match_info_array_is_not_in_a_handle; | 3123 AssertNoAllocation match_info_array_is_not_in_a_handle; |
3116 FixedArray* match_info_array = | 3124 FixedArray* match_info_array = |
3117 FixedArray::cast(last_match_info_handle->elements()); | 3125 FixedArray::cast(last_match_info_handle->elements()); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3194 } | 3202 } |
3195 } | 3203 } |
3196 | 3204 |
3197 Handle<Object> match = RegExpImpl::Exec(regexp_handle, | 3205 Handle<Object> match = RegExpImpl::Exec(regexp_handle, |
3198 subject_handle, | 3206 subject_handle, |
3199 0, | 3207 0, |
3200 last_match_info_handle); | 3208 last_match_info_handle); |
3201 if (match.is_null()) return Failure::Exception(); | 3209 if (match.is_null()) return Failure::Exception(); |
3202 if (match->IsNull()) return *subject_handle; | 3210 if (match->IsNull()) return *subject_handle; |
3203 | 3211 |
3204 ASSERT(last_match_info_handle->HasFastElements()); | 3212 ASSERT(last_match_info_handle->HasFastObjectElements()); |
3205 | 3213 |
3206 int start, end; | 3214 int start, end; |
3207 { | 3215 { |
3208 AssertNoAllocation match_info_array_is_not_in_a_handle; | 3216 AssertNoAllocation match_info_array_is_not_in_a_handle; |
3209 FixedArray* match_info_array = | 3217 FixedArray* match_info_array = |
3210 FixedArray::cast(last_match_info_handle->elements()); | 3218 FixedArray::cast(last_match_info_handle->elements()); |
3211 | 3219 |
3212 start = RegExpImpl::GetCapture(match_info_array, 0); | 3220 start = RegExpImpl::GetCapture(match_info_array, 0); |
3213 end = RegExpImpl::GetCapture(match_info_array, 1); | 3221 end = RegExpImpl::GetCapture(match_info_array, 1); |
3214 } | 3222 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3268 next++; | 3276 next++; |
3269 if (next > length) break; | 3277 if (next > length) break; |
3270 } | 3278 } |
3271 match = RegExpImpl::Exec(regexp_handle, | 3279 match = RegExpImpl::Exec(regexp_handle, |
3272 subject_handle, | 3280 subject_handle, |
3273 next, | 3281 next, |
3274 last_match_info_handle); | 3282 last_match_info_handle); |
3275 if (match.is_null()) return Failure::Exception(); | 3283 if (match.is_null()) return Failure::Exception(); |
3276 if (match->IsNull()) break; | 3284 if (match->IsNull()) break; |
3277 | 3285 |
3278 ASSERT(last_match_info_handle->HasFastElements()); | 3286 ASSERT(last_match_info_handle->HasFastObjectElements()); |
3279 HandleScope loop_scope(isolate); | 3287 HandleScope loop_scope(isolate); |
3280 { | 3288 { |
3281 AssertNoAllocation match_info_array_is_not_in_a_handle; | 3289 AssertNoAllocation match_info_array_is_not_in_a_handle; |
3282 FixedArray* match_info_array = | 3290 FixedArray* match_info_array = |
3283 FixedArray::cast(last_match_info_handle->elements()); | 3291 FixedArray::cast(last_match_info_handle->elements()); |
3284 start = RegExpImpl::GetCapture(match_info_array, 0); | 3292 start = RegExpImpl::GetCapture(match_info_array, 0); |
3285 end = RegExpImpl::GetCapture(match_info_array, 1); | 3293 end = RegExpImpl::GetCapture(match_info_array, 1); |
3286 } | 3294 } |
3287 } while (true); | 3295 } while (true); |
3288 | 3296 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3338 if (!maybe_flat_replacement->ToObject(&flat_replacement)) { | 3346 if (!maybe_flat_replacement->ToObject(&flat_replacement)) { |
3339 return maybe_flat_replacement; | 3347 return maybe_flat_replacement; |
3340 } | 3348 } |
3341 } | 3349 } |
3342 replacement = String::cast(flat_replacement); | 3350 replacement = String::cast(flat_replacement); |
3343 } | 3351 } |
3344 | 3352 |
3345 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); | 3353 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); |
3346 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); | 3354 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); |
3347 | 3355 |
3348 ASSERT(last_match_info->HasFastElements()); | 3356 ASSERT(last_match_info->HasFastObjectElements()); |
3349 | 3357 |
3350 if (replacement->length() == 0) { | 3358 if (replacement->length() == 0) { |
3351 if (subject->HasOnlyAsciiChars()) { | 3359 if (subject->HasOnlyAsciiChars()) { |
3352 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( | 3360 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( |
3353 isolate, subject, regexp, last_match_info); | 3361 isolate, subject, regexp, last_match_info); |
3354 } else { | 3362 } else { |
3355 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( | 3363 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( |
3356 isolate, subject, regexp, last_match_info); | 3364 isolate, subject, regexp, last_match_info); |
3357 } | 3365 } |
3358 } | 3366 } |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4003 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) { | 4011 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) { |
4004 ASSERT(args.length() == 4); | 4012 ASSERT(args.length() == 4); |
4005 HandleScope handles(isolate); | 4013 HandleScope handles(isolate); |
4006 | 4014 |
4007 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); | 4015 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); |
4008 if (!subject->IsFlat()) FlattenString(subject); | 4016 if (!subject->IsFlat()) FlattenString(subject); |
4009 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); | 4017 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
4010 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); | 4018 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); |
4011 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); | 4019 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); |
4012 | 4020 |
4013 ASSERT(last_match_info->HasFastElements()); | 4021 ASSERT(last_match_info->HasFastObjectElements()); |
4014 ASSERT(regexp->GetFlags().is_global()); | 4022 ASSERT(regexp->GetFlags().is_global()); |
4015 Handle<FixedArray> result_elements; | 4023 Handle<FixedArray> result_elements; |
4016 if (result_array->HasFastElements()) { | 4024 if (result_array->HasFastObjectElements()) { |
4017 result_elements = | 4025 result_elements = |
4018 Handle<FixedArray>(FixedArray::cast(result_array->elements())); | 4026 Handle<FixedArray>(FixedArray::cast(result_array->elements())); |
4019 } | 4027 } |
4020 if (result_elements.is_null() || result_elements->length() < 16) { | 4028 if (result_elements.is_null() || result_elements->length() < 16) { |
4021 result_elements = isolate->factory()->NewFixedArrayWithHoles(16); | 4029 result_elements = isolate->factory()->NewFixedArrayWithHoles(16); |
4022 } | 4030 } |
4023 FixedArrayBuilder builder(result_elements); | 4031 FixedArrayBuilder builder(result_elements); |
4024 | 4032 |
4025 if (regexp->TypeTag() == JSRegExp::ATOM) { | 4033 if (regexp->TypeTag() == JSRegExp::ATOM) { |
4026 Handle<String> pattern( | 4034 Handle<String> pattern( |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4308 if (!receiver->IsGlobalObject()) return value; | 4316 if (!receiver->IsGlobalObject()) return value; |
4309 value = JSGlobalPropertyCell::cast(value)->value(); | 4317 value = JSGlobalPropertyCell::cast(value)->value(); |
4310 if (!value->IsTheHole()) return value; | 4318 if (!value->IsTheHole()) return value; |
4311 // If value is the hole do the general lookup. | 4319 // If value is the hole do the general lookup. |
4312 } | 4320 } |
4313 } | 4321 } |
4314 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { | 4322 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { |
4315 // JSObject without a string key. If the key is a Smi, check for a | 4323 // JSObject without a string key. If the key is a Smi, check for a |
4316 // definite out-of-bounds access to elements, which is a strong indicator | 4324 // definite out-of-bounds access to elements, which is a strong indicator |
4317 // that subsequent accesses will also call the runtime. Proactively | 4325 // that subsequent accesses will also call the runtime. Proactively |
4318 // transition elements to FAST_ELEMENTS to avoid excessive boxing of | 4326 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of |
4319 // doubles for those future calls in the case that the elements would | 4327 // doubles for those future calls in the case that the elements would |
4320 // become FAST_DOUBLE_ELEMENTS. | 4328 // become FAST_DOUBLE_ELEMENTS. |
4321 Handle<JSObject> js_object(args.at<JSObject>(0)); | 4329 Handle<JSObject> js_object(args.at<JSObject>(0)); |
4322 ElementsKind elements_kind = js_object->GetElementsKind(); | 4330 ElementsKind elements_kind = js_object->GetElementsKind(); |
4323 if (elements_kind == FAST_SMI_ONLY_ELEMENTS || | 4331 if (IsFastElementsKind(elements_kind) && |
4324 elements_kind == FAST_DOUBLE_ELEMENTS) { | 4332 !IsFastObjectElementsKind(elements_kind)) { |
4325 FixedArrayBase* elements = js_object->elements(); | 4333 FixedArrayBase* elements = js_object->elements(); |
4326 if (args.at<Smi>(1)->value() >= elements->length()) { | 4334 if (args.at<Smi>(1)->value() >= elements->length()) { |
4335 if (IsFastHoleyElementsKind(elements_kind)) { | |
4336 elements_kind = FAST_HOLEY_ELEMENTS; | |
4337 } else { | |
4338 elements_kind = FAST_ELEMENTS; | |
4339 } | |
4327 MaybeObject* maybe_object = TransitionElements(js_object, | 4340 MaybeObject* maybe_object = TransitionElements(js_object, |
4328 FAST_ELEMENTS, | 4341 elements_kind, |
4329 isolate); | 4342 isolate); |
4330 if (maybe_object->IsFailure()) return maybe_object; | 4343 if (maybe_object->IsFailure()) return maybe_object; |
4331 } | 4344 } |
4332 } | 4345 } |
4333 } | 4346 } |
4334 } else if (args[0]->IsString() && args[1]->IsSmi()) { | 4347 } else if (args[0]->IsString() && args[1]->IsSmi()) { |
4335 // Fast case for string indexing using [] with a smi index. | 4348 // Fast case for string indexing using [] with a smi index. |
4336 HandleScope scope(isolate); | 4349 HandleScope scope(isolate); |
4337 Handle<String> str = args.at<String>(0); | 4350 Handle<String> str = args.at<String>(0); |
4338 int index = args.smi_at(1); | 4351 int index = args.smi_at(1); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4488 // of a string using [] notation. We need to support this too in | 4501 // of a string using [] notation. We need to support this too in |
4489 // JavaScript. | 4502 // JavaScript. |
4490 // In the case of a String object we just need to redirect the assignment to | 4503 // In the case of a String object we just need to redirect the assignment to |
4491 // the underlying string if the index is in range. Since the underlying | 4504 // the underlying string if the index is in range. Since the underlying |
4492 // string does nothing with the assignment then we can ignore such | 4505 // string does nothing with the assignment then we can ignore such |
4493 // assignments. | 4506 // assignments. |
4494 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4507 if (js_object->IsStringObjectWithCharacterAt(index)) { |
4495 return *value; | 4508 return *value; |
4496 } | 4509 } |
4497 | 4510 |
4511 js_object->ValidateElements(); | |
4498 Handle<Object> result = JSObject::SetElement( | 4512 Handle<Object> result = JSObject::SetElement( |
4499 js_object, index, value, attr, strict_mode, set_mode); | 4513 js_object, index, value, attr, strict_mode, set_mode); |
4514 js_object->ValidateElements(); | |
4500 if (result.is_null()) return Failure::Exception(); | 4515 if (result.is_null()) return Failure::Exception(); |
4501 return *value; | 4516 return *value; |
4502 } | 4517 } |
4503 | 4518 |
4504 if (key->IsString()) { | 4519 if (key->IsString()) { |
4505 Handle<Object> result; | 4520 Handle<Object> result; |
4506 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 4521 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
4507 result = JSObject::SetElement( | 4522 result = JSObject::SetElement( |
4508 js_object, index, value, attr, strict_mode, set_mode); | 4523 js_object, index, value, attr, strict_mode, set_mode); |
4509 } else { | 4524 } else { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4647 value, | 4662 value, |
4648 attributes, | 4663 attributes, |
4649 strict_mode); | 4664 strict_mode); |
4650 } | 4665 } |
4651 | 4666 |
4652 | 4667 |
4653 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) { | 4668 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) { |
4654 NoHandleAllocation ha; | 4669 NoHandleAllocation ha; |
4655 RUNTIME_ASSERT(args.length() == 1); | 4670 RUNTIME_ASSERT(args.length() == 1); |
4656 Handle<Object> object = args.at<Object>(0); | 4671 Handle<Object> object = args.at<Object>(0); |
4657 return TransitionElements(object, FAST_DOUBLE_ELEMENTS, isolate); | 4672 if (object->IsJSObject()) { |
4673 Handle<JSObject> js_object(Handle<JSObject>::cast(object)); | |
4674 ElementsKind new_kind = js_object->HasFastHoleyElements() | |
4675 ? FAST_HOLEY_DOUBLE_ELEMENTS | |
4676 : FAST_DOUBLE_ELEMENTS; | |
4677 return TransitionElements(object, new_kind, isolate); | |
4678 } else { | |
4679 return *object; | |
4680 } | |
4658 } | 4681 } |
4659 | 4682 |
4660 | 4683 |
4661 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) { | 4684 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) { |
4662 NoHandleAllocation ha; | 4685 NoHandleAllocation ha; |
4663 RUNTIME_ASSERT(args.length() == 1); | 4686 RUNTIME_ASSERT(args.length() == 1); |
4664 Handle<Object> object = args.at<Object>(0); | 4687 Handle<Object> object = args.at<Object>(0); |
4665 return TransitionElements(object, FAST_ELEMENTS, isolate); | 4688 if (object->IsJSObject()) { |
4689 Handle<JSObject> js_object(Handle<JSObject>::cast(object)); | |
4690 ElementsKind new_kind = js_object->HasFastHoleyElements() | |
4691 ? FAST_HOLEY_ELEMENTS | |
4692 : FAST_ELEMENTS; | |
4693 return TransitionElements(object, new_kind, isolate); | |
4694 } else { | |
4695 return *object; | |
4696 } | |
4666 } | 4697 } |
4667 | 4698 |
4668 | 4699 |
4669 // Set the native flag on the function. | 4700 // Set the native flag on the function. |
4670 // This is used to decide if we should transform null and undefined | 4701 // This is used to decide if we should transform null and undefined |
4671 // into the global object when doing call and apply. | 4702 // into the global object when doing call and apply. |
4672 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { | 4703 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { |
4673 NoHandleAllocation ha; | 4704 NoHandleAllocation ha; |
4674 RUNTIME_ASSERT(args.length() == 1); | 4705 RUNTIME_ASSERT(args.length() == 1); |
4675 | 4706 |
(...skipping 10 matching lines...) Expand all Loading... | |
4686 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { | 4717 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { |
4687 RUNTIME_ASSERT(args.length() == 5); | 4718 RUNTIME_ASSERT(args.length() == 5); |
4688 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 4719 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
4689 CONVERT_SMI_ARG_CHECKED(store_index, 1); | 4720 CONVERT_SMI_ARG_CHECKED(store_index, 1); |
4690 Handle<Object> value = args.at<Object>(2); | 4721 Handle<Object> value = args.at<Object>(2); |
4691 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); | 4722 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); |
4692 CONVERT_SMI_ARG_CHECKED(literal_index, 4); | 4723 CONVERT_SMI_ARG_CHECKED(literal_index, 4); |
4693 HandleScope scope; | 4724 HandleScope scope; |
4694 | 4725 |
4695 Object* raw_boilerplate_object = literals->get(literal_index); | 4726 Object* raw_boilerplate_object = literals->get(literal_index); |
4696 Handle<JSArray> boilerplate(JSArray::cast(raw_boilerplate_object)); | 4727 Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object)); |
4697 #if DEBUG | |
4698 ElementsKind elements_kind = object->GetElementsKind(); | 4728 ElementsKind elements_kind = object->GetElementsKind(); |
4699 #endif | 4729 ASSERT(IsFastElementsKind(elements_kind)); |
4700 ASSERT(elements_kind <= FAST_DOUBLE_ELEMENTS); | |
4701 // Smis should never trigger transitions. | 4730 // Smis should never trigger transitions. |
4702 ASSERT(!value->IsSmi()); | 4731 ASSERT(!value->IsSmi()); |
4703 | 4732 |
4704 if (value->IsNumber()) { | 4733 if (value->IsNumber()) { |
4705 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS); | 4734 ASSERT(IsFastSmiElementsKind(elements_kind)); |
4706 JSObject::TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS); | 4735 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) |
4707 if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(), | 4736 ? FAST_HOLEY_DOUBLE_ELEMENTS |
4708 FAST_DOUBLE_ELEMENTS)) { | 4737 : FAST_DOUBLE_ELEMENTS; |
4709 JSObject::TransitionElementsKind(boilerplate, FAST_DOUBLE_ELEMENTS); | 4738 if (IsMoreGeneralElementsKindTransition( |
4739 boilerplate_object->GetElementsKind(), | |
4740 transitioned_kind)) { | |
4741 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); | |
4710 } | 4742 } |
4711 ASSERT(object->GetElementsKind() == FAST_DOUBLE_ELEMENTS); | 4743 JSObject::TransitionElementsKind(object, transitioned_kind); |
4712 FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements()); | 4744 ASSERT(IsFastDoubleElementsKind(object->GetElementsKind())); |
4745 FixedDoubleArray* double_array = | |
Jakob Kummerow
2012/05/13 21:55:27
Why the line break?
danno
2012/05/22 11:05:21
Done.
| |
4746 FixedDoubleArray::cast(object->elements()); | |
4713 HeapNumber* number = HeapNumber::cast(*value); | 4747 HeapNumber* number = HeapNumber::cast(*value); |
4714 double_array->set(store_index, number->Number()); | 4748 double_array->set(store_index, number->Number()); |
4715 } else { | 4749 } else { |
4716 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS || | 4750 ASSERT(IsFastSmiElementsKind(elements_kind) || |
4717 elements_kind == FAST_DOUBLE_ELEMENTS); | 4751 IsFastDoubleElementsKind(elements_kind)); |
4718 JSObject::TransitionElementsKind(object, FAST_ELEMENTS); | 4752 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) |
4719 if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(), | 4753 ? FAST_HOLEY_ELEMENTS |
4720 FAST_ELEMENTS)) { | 4754 : FAST_ELEMENTS; |
4721 JSObject::TransitionElementsKind(boilerplate, FAST_ELEMENTS); | 4755 JSObject::TransitionElementsKind(object, transitioned_kind); |
4756 if (IsMoreGeneralElementsKindTransition( | |
4757 boilerplate_object->GetElementsKind(), | |
4758 transitioned_kind)) { | |
4759 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); | |
4722 } | 4760 } |
4723 FixedArray* object_array = FixedArray::cast(object->elements()); | 4761 FixedArray* object_array = |
Jakob Kummerow
2012/05/13 21:55:27
Why the line break?
danno
2012/05/22 11:05:21
Done.
| |
4762 FixedArray::cast(object->elements()); | |
4724 object_array->set(store_index, *value); | 4763 object_array->set(store_index, *value); |
4725 } | 4764 } |
4726 return *object; | 4765 return *object; |
4727 } | 4766 } |
4728 | 4767 |
4729 | 4768 |
4730 // Check whether debugger and is about to step into the callback that is passed | 4769 // Check whether debugger and is about to step into the callback that is passed |
4731 // to a built-in function such as Array.forEach. | 4770 // to a built-in function such as Array.forEach. |
4732 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) { | 4771 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) { |
4733 if (!isolate->IsDebuggerActive()) return isolate->heap()->false_value(); | 4772 if (!isolate->IsDebuggerActive()) return isolate->heap()->false_value(); |
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5924 new_string, final_length); | 5963 new_string, final_length); |
5925 return new_string; | 5964 return new_string; |
5926 } | 5965 } |
5927 | 5966 |
5928 | 5967 |
5929 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) { | 5968 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) { |
5930 NoHandleAllocation ha; | 5969 NoHandleAllocation ha; |
5931 ASSERT(args.length() == 1); | 5970 ASSERT(args.length() == 1); |
5932 CONVERT_ARG_CHECKED(JSArray, array, 0); | 5971 CONVERT_ARG_CHECKED(JSArray, array, 0); |
5933 | 5972 |
5934 if (!array->HasFastElements()) return isolate->heap()->undefined_value(); | 5973 if (!array->HasFastObjectElements()) { |
5974 return isolate->heap()->undefined_value(); | |
5975 } | |
5935 FixedArray* elements = FixedArray::cast(array->elements()); | 5976 FixedArray* elements = FixedArray::cast(array->elements()); |
5936 int n = elements->length(); | 5977 int n = elements->length(); |
5937 bool ascii = true; | 5978 bool ascii = true; |
5938 int total_length = 0; | 5979 int total_length = 0; |
5939 | 5980 |
5940 for (int i = 0; i < n; i++) { | 5981 for (int i = 0; i < n; i++) { |
5941 Object* elt = elements->get(i); | 5982 Object* elt = elements->get(i); |
5942 if (!elt->IsString()) return isolate->heap()->undefined_value(); | 5983 if (!elt->IsString()) return isolate->heap()->undefined_value(); |
5943 String* element = String::cast(elt); | 5984 String* element = String::cast(elt); |
5944 if (!element->IsFlat()) return isolate->heap()->undefined_value(); | 5985 if (!element->IsFlat()) return isolate->heap()->undefined_value(); |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6367 // The list indices now contains the end of each part to create. | 6408 // The list indices now contains the end of each part to create. |
6368 | 6409 |
6369 // Create JSArray of substrings separated by separator. | 6410 // Create JSArray of substrings separated by separator. |
6370 int part_count = indices.length(); | 6411 int part_count = indices.length(); |
6371 | 6412 |
6372 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); | 6413 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); |
6373 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements(); | 6414 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements(); |
6374 if (maybe_result->IsFailure()) return maybe_result; | 6415 if (maybe_result->IsFailure()) return maybe_result; |
6375 result->set_length(Smi::FromInt(part_count)); | 6416 result->set_length(Smi::FromInt(part_count)); |
6376 | 6417 |
6377 ASSERT(result->HasFastElements()); | 6418 ASSERT(result->HasFastObjectElements()); |
6378 | 6419 |
6379 if (part_count == 1 && indices.at(0) == subject_length) { | 6420 if (part_count == 1 && indices.at(0) == subject_length) { |
6380 FixedArray::cast(result->elements())->set(0, *subject); | 6421 FixedArray::cast(result->elements())->set(0, *subject); |
6381 return *result; | 6422 return *result; |
6382 } | 6423 } |
6383 | 6424 |
6384 Handle<FixedArray> elements(FixedArray::cast(result->elements())); | 6425 Handle<FixedArray> elements(FixedArray::cast(result->elements())); |
6385 int part_start = 0; | 6426 int part_start = 0; |
6386 for (int i = 0; i < part_count; i++) { | 6427 for (int i = 0; i < part_count; i++) { |
6387 HandleScope local_loop_handle; | 6428 HandleScope local_loop_handle; |
6388 int part_end = indices.at(i); | 6429 int part_end = indices.at(i); |
6389 Handle<String> substring = | 6430 Handle<String> substring = |
6390 isolate->factory()->NewProperSubString(subject, part_start, part_end); | 6431 isolate->factory()->NewProperSubString(subject, part_start, part_end); |
6391 elements->set(i, *substring); | 6432 elements->set(i, *substring); |
6392 part_start = part_end + pattern_length; | 6433 part_start = part_end + pattern_length; |
6393 } | 6434 } |
6394 | 6435 |
6395 if (limit == 0xffffffffu) { | 6436 if (limit == 0xffffffffu) { |
6396 if (result->HasFastElements()) { | 6437 if (result->HasFastObjectElements()) { |
6397 StringSplitCache::Enter(isolate->heap(), | 6438 StringSplitCache::Enter(isolate->heap(), |
6398 isolate->heap()->string_split_cache(), | 6439 isolate->heap()->string_split_cache(), |
6399 *subject, | 6440 *subject, |
6400 *pattern, | 6441 *pattern, |
6401 *elements); | 6442 *elements); |
6402 } | 6443 } |
6403 } | 6444 } |
6404 | 6445 |
6405 return *result; | 6446 return *result; |
6406 } | 6447 } |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6743 int array_length = args.smi_at(1); | 6784 int array_length = args.smi_at(1); |
6744 CONVERT_ARG_CHECKED(String, special, 2); | 6785 CONVERT_ARG_CHECKED(String, special, 2); |
6745 | 6786 |
6746 // This assumption is used by the slice encoding in one or two smis. | 6787 // This assumption is used by the slice encoding in one or two smis. |
6747 ASSERT(Smi::kMaxValue >= String::kMaxLength); | 6788 ASSERT(Smi::kMaxValue >= String::kMaxLength); |
6748 | 6789 |
6749 MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements(); | 6790 MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements(); |
6750 if (maybe_result->IsFailure()) return maybe_result; | 6791 if (maybe_result->IsFailure()) return maybe_result; |
6751 | 6792 |
6752 int special_length = special->length(); | 6793 int special_length = special->length(); |
6753 if (!array->HasFastElements()) { | 6794 if (!array->HasFastObjectElements()) { |
6754 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); | 6795 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
6755 } | 6796 } |
6756 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6797 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
6757 if (fixed_array->length() < array_length) { | 6798 if (fixed_array->length() < array_length) { |
6758 array_length = fixed_array->length(); | 6799 array_length = fixed_array->length(); |
6759 } | 6800 } |
6760 | 6801 |
6761 if (array_length == 0) { | 6802 if (array_length == 0) { |
6762 return isolate->heap()->empty_string(); | 6803 return isolate->heap()->empty_string(); |
6763 } else if (array_length == 1) { | 6804 } else if (array_length == 1) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6853 NoHandleAllocation ha; | 6894 NoHandleAllocation ha; |
6854 ASSERT(args.length() == 3); | 6895 ASSERT(args.length() == 3); |
6855 CONVERT_ARG_CHECKED(JSArray, array, 0); | 6896 CONVERT_ARG_CHECKED(JSArray, array, 0); |
6856 if (!args[1]->IsSmi()) { | 6897 if (!args[1]->IsSmi()) { |
6857 isolate->context()->mark_out_of_memory(); | 6898 isolate->context()->mark_out_of_memory(); |
6858 return Failure::OutOfMemoryException(); | 6899 return Failure::OutOfMemoryException(); |
6859 } | 6900 } |
6860 int array_length = args.smi_at(1); | 6901 int array_length = args.smi_at(1); |
6861 CONVERT_ARG_CHECKED(String, separator, 2); | 6902 CONVERT_ARG_CHECKED(String, separator, 2); |
6862 | 6903 |
6863 if (!array->HasFastElements()) { | 6904 if (!array->HasFastObjectElements()) { |
6864 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); | 6905 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
6865 } | 6906 } |
6866 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6907 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
6867 if (fixed_array->length() < array_length) { | 6908 if (fixed_array->length() < array_length) { |
6868 array_length = fixed_array->length(); | 6909 array_length = fixed_array->length(); |
6869 } | 6910 } |
6870 | 6911 |
6871 if (array_length == 0) { | 6912 if (array_length == 0) { |
6872 return isolate->heap()->empty_string(); | 6913 return isolate->heap()->empty_string(); |
6873 } else if (array_length == 1) { | 6914 } else if (array_length == 1) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6970 } | 7011 } |
6971 } | 7012 } |
6972 ASSERT(cursor <= buffer.length()); | 7013 ASSERT(cursor <= buffer.length()); |
6973 } | 7014 } |
6974 | 7015 |
6975 | 7016 |
6976 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { | 7017 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { |
6977 NoHandleAllocation ha; | 7018 NoHandleAllocation ha; |
6978 ASSERT(args.length() == 3); | 7019 ASSERT(args.length() == 3); |
6979 CONVERT_ARG_CHECKED(JSArray, elements_array, 0); | 7020 CONVERT_ARG_CHECKED(JSArray, elements_array, 0); |
6980 RUNTIME_ASSERT(elements_array->HasFastElements() || | 7021 RUNTIME_ASSERT(elements_array->HasFastObjectElements() || |
Jakob Kummerow
2012/05/13 21:55:27
HasFastSmiOrObjectElements()?
danno
2012/05/22 11:05:21
Done.
| |
6981 elements_array->HasFastSmiOnlyElements()); | 7022 elements_array->HasFastSmiElements()); |
6982 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); | 7023 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); |
6983 CONVERT_ARG_CHECKED(String, separator, 2); | 7024 CONVERT_ARG_CHECKED(String, separator, 2); |
6984 // elements_array is fast-mode JSarray of alternating positions | 7025 // elements_array is fast-mode JSarray of alternating positions |
6985 // (increasing order) and strings. | 7026 // (increasing order) and strings. |
6986 // array_length is length of original array (used to add separators); | 7027 // array_length is length of original array (used to add separators); |
6987 // separator is string to put between elements. Assumed to be non-empty. | 7028 // separator is string to put between elements. Assumed to be non-empty. |
6988 | 7029 |
6989 // Find total length of join result. | 7030 // Find total length of join result. |
6990 int string_length = 0; | 7031 int string_length = 0; |
6991 bool is_ascii = separator->IsAsciiRepresentation(); | 7032 bool is_ascii = separator->IsAsciiRepresentation(); |
(...skipping 2140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9132 ASSERT(args.length() == 2); | 9173 ASSERT(args.length() == 2); |
9133 | 9174 |
9134 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); | 9175 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); |
9135 FlattenString(str); | 9176 FlattenString(str); |
9136 | 9177 |
9137 CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1); | 9178 CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1); |
9138 | 9179 |
9139 MaybeObject* maybe_result_array = | 9180 MaybeObject* maybe_result_array = |
9140 output->EnsureCanContainHeapObjectElements(); | 9181 output->EnsureCanContainHeapObjectElements(); |
9141 if (maybe_result_array->IsFailure()) return maybe_result_array; | 9182 if (maybe_result_array->IsFailure()) return maybe_result_array; |
9142 RUNTIME_ASSERT(output->HasFastElements()); | 9183 RUNTIME_ASSERT(output->HasFastObjectElements()); |
9143 | 9184 |
9144 AssertNoAllocation no_allocation; | 9185 AssertNoAllocation no_allocation; |
9145 | 9186 |
9146 FixedArray* output_array = FixedArray::cast(output->elements()); | 9187 FixedArray* output_array = FixedArray::cast(output->elements()); |
9147 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 9188 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
9148 bool result; | 9189 bool result; |
9149 String::FlatContent str_content = str->GetFlatContent(); | 9190 String::FlatContent str_content = str->GetFlatContent(); |
9150 if (str_content.IsAscii()) { | 9191 if (str_content.IsAscii()) { |
9151 result = DateParser::Parse(str_content.ToAsciiVector(), | 9192 result = DateParser::Parse(str_content.ToAsciiVector(), |
9152 output_array, | 9193 output_array, |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9364 } | 9405 } |
9365 | 9406 |
9366 | 9407 |
9367 // Push an object unto an array of objects if it is not already in the | 9408 // Push an object unto an array of objects if it is not already in the |
9368 // array. Returns true if the element was pushed on the stack and | 9409 // array. Returns true if the element was pushed on the stack and |
9369 // false otherwise. | 9410 // false otherwise. |
9370 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { | 9411 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { |
9371 ASSERT(args.length() == 2); | 9412 ASSERT(args.length() == 2); |
9372 CONVERT_ARG_CHECKED(JSArray, array, 0); | 9413 CONVERT_ARG_CHECKED(JSArray, array, 0); |
9373 CONVERT_ARG_CHECKED(JSObject, element, 1); | 9414 CONVERT_ARG_CHECKED(JSObject, element, 1); |
9374 RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); | 9415 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements()); |
9375 int length = Smi::cast(array->length())->value(); | 9416 int length = Smi::cast(array->length())->value(); |
9376 FixedArray* elements = FixedArray::cast(array->elements()); | 9417 FixedArray* elements = FixedArray::cast(array->elements()); |
9377 for (int i = 0; i < length; i++) { | 9418 for (int i = 0; i < length; i++) { |
9378 if (elements->get(i) == element) return isolate->heap()->false_value(); | 9419 if (elements->get(i) == element) return isolate->heap()->false_value(); |
9379 } | 9420 } |
9380 Object* obj; | 9421 Object* obj; |
9381 // Strict not needed. Used for cycle detection in Array join implementation. | 9422 // Strict not needed. Used for cycle detection in Array join implementation. |
9382 { MaybeObject* maybe_obj = | 9423 { MaybeObject* maybe_obj = |
9383 array->SetFastElement(length, element, kNonStrictMode, true); | 9424 array->SetFastElement(length, element, kNonStrictMode, true); |
9384 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9425 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9449 } | 9490 } |
9450 } | 9491 } |
9451 | 9492 |
9452 Handle<JSArray> ToArray() { | 9493 Handle<JSArray> ToArray() { |
9453 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); | 9494 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); |
9454 Handle<Object> length = | 9495 Handle<Object> length = |
9455 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); | 9496 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); |
9456 Handle<Map> map; | 9497 Handle<Map> map; |
9457 if (fast_elements_) { | 9498 if (fast_elements_) { |
9458 map = isolate_->factory()->GetElementsTransitionMap(array, | 9499 map = isolate_->factory()->GetElementsTransitionMap(array, |
9459 FAST_ELEMENTS); | 9500 FAST_HOLEY_ELEMENTS); |
9460 } else { | 9501 } else { |
9461 map = isolate_->factory()->GetElementsTransitionMap(array, | 9502 map = isolate_->factory()->GetElementsTransitionMap(array, |
9462 DICTIONARY_ELEMENTS); | 9503 DICTIONARY_ELEMENTS); |
9463 } | 9504 } |
9464 array->set_map(*map); | 9505 array->set_map(*map); |
9465 array->set_length(*length); | 9506 array->set_length(*length); |
9466 array->set_elements(*storage_); | 9507 array->set_elements(*storage_); |
9467 return array; | 9508 return array; |
9468 } | 9509 } |
9469 | 9510 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9508 // JSObject::kMaxElementCount. | 9549 // JSObject::kMaxElementCount. |
9509 uint32_t index_offset_; | 9550 uint32_t index_offset_; |
9510 bool fast_elements_; | 9551 bool fast_elements_; |
9511 }; | 9552 }; |
9512 | 9553 |
9513 | 9554 |
9514 static uint32_t EstimateElementCount(Handle<JSArray> array) { | 9555 static uint32_t EstimateElementCount(Handle<JSArray> array) { |
9515 uint32_t length = static_cast<uint32_t>(array->length()->Number()); | 9556 uint32_t length = static_cast<uint32_t>(array->length()->Number()); |
9516 int element_count = 0; | 9557 int element_count = 0; |
9517 switch (array->GetElementsKind()) { | 9558 switch (array->GetElementsKind()) { |
9518 case FAST_SMI_ONLY_ELEMENTS: | 9559 case FAST_SMI_ELEMENTS: |
9519 case FAST_ELEMENTS: { | 9560 case FAST_HOLEY_SMI_ELEMENTS: |
9561 case FAST_ELEMENTS: | |
9562 case FAST_HOLEY_ELEMENTS: { | |
9520 // Fast elements can't have lengths that are not representable by | 9563 // Fast elements can't have lengths that are not representable by |
9521 // a 32-bit signed integer. | 9564 // a 32-bit signed integer. |
9522 ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); | 9565 ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); |
9523 int fast_length = static_cast<int>(length); | 9566 int fast_length = static_cast<int>(length); |
9524 Handle<FixedArray> elements(FixedArray::cast(array->elements())); | 9567 Handle<FixedArray> elements(FixedArray::cast(array->elements())); |
9525 for (int i = 0; i < fast_length; i++) { | 9568 for (int i = 0; i < fast_length; i++) { |
9526 if (!elements->get(i)->IsTheHole()) element_count++; | 9569 if (!elements->get(i)->IsTheHole()) element_count++; |
9527 } | 9570 } |
9528 break; | 9571 break; |
9529 } | 9572 } |
9530 case FAST_DOUBLE_ELEMENTS: | 9573 case FAST_DOUBLE_ELEMENTS: |
9574 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
9531 // TODO(1810): Decide if it's worthwhile to implement this. | 9575 // TODO(1810): Decide if it's worthwhile to implement this. |
9532 UNREACHABLE(); | 9576 UNREACHABLE(); |
9533 break; | 9577 break; |
9534 case DICTIONARY_ELEMENTS: { | 9578 case DICTIONARY_ELEMENTS: { |
9535 Handle<SeededNumberDictionary> dictionary( | 9579 Handle<SeededNumberDictionary> dictionary( |
9536 SeededNumberDictionary::cast(array->elements())); | 9580 SeededNumberDictionary::cast(array->elements())); |
9537 int capacity = dictionary->Capacity(); | 9581 int capacity = dictionary->Capacity(); |
9538 for (int i = 0; i < capacity; i++) { | 9582 for (int i = 0; i < capacity; i++) { |
9539 Handle<Object> key(dictionary->KeyAt(i)); | 9583 Handle<Object> key(dictionary->KeyAt(i)); |
9540 if (dictionary->IsKey(*key)) { | 9584 if (dictionary->IsKey(*key)) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9611 uint32_t b = *bp; | 9655 uint32_t b = *bp; |
9612 return (a == b) ? 0 : (a < b) ? -1 : 1; | 9656 return (a == b) ? 0 : (a < b) ? -1 : 1; |
9613 } | 9657 } |
9614 | 9658 |
9615 | 9659 |
9616 static void CollectElementIndices(Handle<JSObject> object, | 9660 static void CollectElementIndices(Handle<JSObject> object, |
9617 uint32_t range, | 9661 uint32_t range, |
9618 List<uint32_t>* indices) { | 9662 List<uint32_t>* indices) { |
9619 ElementsKind kind = object->GetElementsKind(); | 9663 ElementsKind kind = object->GetElementsKind(); |
9620 switch (kind) { | 9664 switch (kind) { |
9621 case FAST_SMI_ONLY_ELEMENTS: | 9665 case FAST_SMI_ELEMENTS: |
9622 case FAST_ELEMENTS: { | 9666 case FAST_ELEMENTS: |
9667 case FAST_HOLEY_SMI_ELEMENTS: | |
9668 case FAST_HOLEY_ELEMENTS: { | |
9623 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 9669 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
9624 uint32_t length = static_cast<uint32_t>(elements->length()); | 9670 uint32_t length = static_cast<uint32_t>(elements->length()); |
9625 if (range < length) length = range; | 9671 if (range < length) length = range; |
9626 for (uint32_t i = 0; i < length; i++) { | 9672 for (uint32_t i = 0; i < length; i++) { |
9627 if (!elements->get(i)->IsTheHole()) { | 9673 if (!elements->get(i)->IsTheHole()) { |
9628 indices->Add(i); | 9674 indices->Add(i); |
9629 } | 9675 } |
9630 } | 9676 } |
9631 break; | 9677 break; |
9632 } | 9678 } |
9679 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
9633 case FAST_DOUBLE_ELEMENTS: { | 9680 case FAST_DOUBLE_ELEMENTS: { |
9634 // TODO(1810): Decide if it's worthwhile to implement this. | 9681 // TODO(1810): Decide if it's worthwhile to implement this. |
9635 UNREACHABLE(); | 9682 UNREACHABLE(); |
9636 break; | 9683 break; |
9637 } | 9684 } |
9638 case DICTIONARY_ELEMENTS: { | 9685 case DICTIONARY_ELEMENTS: { |
9639 Handle<SeededNumberDictionary> dict( | 9686 Handle<SeededNumberDictionary> dict( |
9640 SeededNumberDictionary::cast(object->elements())); | 9687 SeededNumberDictionary::cast(object->elements())); |
9641 uint32_t capacity = dict->Capacity(); | 9688 uint32_t capacity = dict->Capacity(); |
9642 for (uint32_t j = 0; j < capacity; j++) { | 9689 for (uint32_t j = 0; j < capacity; j++) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9737 * with the element index and the element's value. | 9784 * with the element index and the element's value. |
9738 * Afterwards it increments the base-index of the visitor by the array | 9785 * Afterwards it increments the base-index of the visitor by the array |
9739 * length. | 9786 * length. |
9740 * Returns false if any access threw an exception, otherwise true. | 9787 * Returns false if any access threw an exception, otherwise true. |
9741 */ | 9788 */ |
9742 static bool IterateElements(Isolate* isolate, | 9789 static bool IterateElements(Isolate* isolate, |
9743 Handle<JSArray> receiver, | 9790 Handle<JSArray> receiver, |
9744 ArrayConcatVisitor* visitor) { | 9791 ArrayConcatVisitor* visitor) { |
9745 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); | 9792 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); |
9746 switch (receiver->GetElementsKind()) { | 9793 switch (receiver->GetElementsKind()) { |
9747 case FAST_SMI_ONLY_ELEMENTS: | 9794 case FAST_SMI_ELEMENTS: |
9748 case FAST_ELEMENTS: { | 9795 case FAST_ELEMENTS: |
9796 case FAST_HOLEY_SMI_ELEMENTS: | |
9797 case FAST_HOLEY_ELEMENTS: { | |
9749 // Run through the elements FixedArray and use HasElement and GetElement | 9798 // Run through the elements FixedArray and use HasElement and GetElement |
9750 // to check the prototype for missing elements. | 9799 // to check the prototype for missing elements. |
9751 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); | 9800 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); |
9752 int fast_length = static_cast<int>(length); | 9801 int fast_length = static_cast<int>(length); |
9753 ASSERT(fast_length <= elements->length()); | 9802 ASSERT(fast_length <= elements->length()); |
9754 for (int j = 0; j < fast_length; j++) { | 9803 for (int j = 0; j < fast_length; j++) { |
9755 HandleScope loop_scope(isolate); | 9804 HandleScope loop_scope(isolate); |
9756 Handle<Object> element_value(elements->get(j), isolate); | 9805 Handle<Object> element_value(elements->get(j), isolate); |
9757 if (!element_value->IsTheHole()) { | 9806 if (!element_value->IsTheHole()) { |
9758 visitor->visit(j, element_value); | 9807 visitor->visit(j, element_value); |
9759 } else if (receiver->HasElement(j)) { | 9808 } else if (receiver->HasElement(j)) { |
9760 // Call GetElement on receiver, not its prototype, or getters won't | 9809 // Call GetElement on receiver, not its prototype, or getters won't |
9761 // have the correct receiver. | 9810 // have the correct receiver. |
9762 element_value = Object::GetElement(receiver, j); | 9811 element_value = Object::GetElement(receiver, j); |
9763 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); | 9812 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); |
9764 visitor->visit(j, element_value); | 9813 visitor->visit(j, element_value); |
9765 } | 9814 } |
9766 } | 9815 } |
9767 break; | 9816 break; |
9768 } | 9817 } |
9818 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
9769 case FAST_DOUBLE_ELEMENTS: { | 9819 case FAST_DOUBLE_ELEMENTS: { |
9770 // TODO(1810): Decide if it's worthwhile to implement this. | 9820 // TODO(1810): Decide if it's worthwhile to implement this. |
9771 UNREACHABLE(); | 9821 UNREACHABLE(); |
9772 break; | 9822 break; |
9773 } | 9823 } |
9774 case DICTIONARY_ELEMENTS: { | 9824 case DICTIONARY_ELEMENTS: { |
9775 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); | 9825 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); |
9776 List<uint32_t> indices(dict->Capacity() / 2); | 9826 List<uint32_t> indices(dict->Capacity() / 2); |
9777 // Collect all indices in the object and the prototypes less | 9827 // Collect all indices in the object and the prototypes less |
9778 // than length. This might introduce duplicates in the indices list. | 9828 // than length. This might introduce duplicates in the indices list. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9856 * See ECMAScript 262, 15.4.4.4. | 9906 * See ECMAScript 262, 15.4.4.4. |
9857 * TODO(581): Fix non-compliance for very large concatenations and update to | 9907 * TODO(581): Fix non-compliance for very large concatenations and update to |
9858 * following the ECMAScript 5 specification. | 9908 * following the ECMAScript 5 specification. |
9859 */ | 9909 */ |
9860 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) { | 9910 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) { |
9861 ASSERT(args.length() == 1); | 9911 ASSERT(args.length() == 1); |
9862 HandleScope handle_scope(isolate); | 9912 HandleScope handle_scope(isolate); |
9863 | 9913 |
9864 CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0); | 9914 CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0); |
9865 int argument_count = static_cast<int>(arguments->length()->Number()); | 9915 int argument_count = static_cast<int>(arguments->length()->Number()); |
9866 RUNTIME_ASSERT(arguments->HasFastElements()); | 9916 RUNTIME_ASSERT(arguments->HasFastObjectElements()); |
9867 Handle<FixedArray> elements(FixedArray::cast(arguments->elements())); | 9917 Handle<FixedArray> elements(FixedArray::cast(arguments->elements())); |
9868 | 9918 |
9869 // Pass 1: estimate the length and number of elements of the result. | 9919 // Pass 1: estimate the length and number of elements of the result. |
9870 // The actual length can be larger if any of the arguments have getters | 9920 // The actual length can be larger if any of the arguments have getters |
9871 // that mutate other arguments (but will otherwise be precise). | 9921 // that mutate other arguments (but will otherwise be precise). |
9872 // The number of elements is precise if there are no inherited elements. | 9922 // The number of elements is precise if there are no inherited elements. |
9873 | 9923 |
9874 uint32_t estimate_result_length = 0; | 9924 uint32_t estimate_result_length = 0; |
9875 uint32_t estimate_nof_elements = 0; | 9925 uint32_t estimate_nof_elements = 0; |
9876 { | 9926 { |
9877 for (int i = 0; i < argument_count; i++) { | 9927 for (int i = 0; i < argument_count; i++) { |
9878 HandleScope loop_scope; | 9928 HandleScope loop_scope; |
9879 Handle<Object> obj(elements->get(i)); | 9929 Handle<Object> obj(elements->get(i)); |
9880 uint32_t length_estimate; | 9930 uint32_t length_estimate; |
9881 uint32_t element_estimate; | 9931 uint32_t element_estimate; |
9882 if (obj->IsJSArray()) { | 9932 if (obj->IsJSArray()) { |
9883 Handle<JSArray> array(Handle<JSArray>::cast(obj)); | 9933 Handle<JSArray> array(Handle<JSArray>::cast(obj)); |
9884 // TODO(1810): Find out if it's worthwhile to properly support | 9934 // TODO(1810): Find out if it's worthwhile to properly support |
9885 // arbitrary ElementsKinds. For now, pessimistically transition to | 9935 // arbitrary ElementsKinds. For now, pessimistically transition to |
9886 // FAST_ELEMENTS. | 9936 // FAST_*_ELEMENTS. |
9887 if (array->HasFastDoubleElements()) { | 9937 if (array->HasFastDoubleElements()) { |
9938 ElementsKind to_kind = FAST_ELEMENTS; | |
9939 if (array->HasFastHoleyElements()) { | |
9940 to_kind = FAST_HOLEY_ELEMENTS; | |
9941 } | |
9888 array = Handle<JSArray>::cast( | 9942 array = Handle<JSArray>::cast( |
9889 JSObject::TransitionElementsKind(array, FAST_ELEMENTS)); | 9943 JSObject::TransitionElementsKind(array, FAST_ELEMENTS)); |
Jakob Kummerow
2012/05/13 21:55:27
s/FAST_ELEMENTS/to_kind/ !
danno
2012/05/22 11:05:21
Done.
| |
9890 } | 9944 } |
9891 length_estimate = | 9945 length_estimate = |
9892 static_cast<uint32_t>(array->length()->Number()); | 9946 static_cast<uint32_t>(array->length()->Number()); |
9893 element_estimate = | 9947 element_estimate = |
9894 EstimateElementCount(array); | 9948 EstimateElementCount(array); |
9895 } else { | 9949 } else { |
9896 length_estimate = 1; | 9950 length_estimate = 1; |
9897 element_estimate = 1; | 9951 element_estimate = 1; |
9898 } | 9952 } |
9899 // Avoid overflows by capping at kMaxElementCount. | 9953 // Avoid overflows by capping at kMaxElementCount. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9976 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 10030 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
9977 return object->PrepareElementsForSort(limit); | 10031 return object->PrepareElementsForSort(limit); |
9978 } | 10032 } |
9979 | 10033 |
9980 | 10034 |
9981 // Move contents of argument 0 (an array) to argument 1 (an array) | 10035 // Move contents of argument 0 (an array) to argument 1 (an array) |
9982 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { | 10036 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { |
9983 ASSERT(args.length() == 2); | 10037 ASSERT(args.length() == 2); |
9984 CONVERT_ARG_CHECKED(JSArray, from, 0); | 10038 CONVERT_ARG_CHECKED(JSArray, from, 0); |
9985 CONVERT_ARG_CHECKED(JSArray, to, 1); | 10039 CONVERT_ARG_CHECKED(JSArray, to, 1); |
10040 from->ValidateElements(); | |
10041 to->ValidateElements(); | |
9986 FixedArrayBase* new_elements = from->elements(); | 10042 FixedArrayBase* new_elements = from->elements(); |
10043 ElementsKind from_kind = from->GetElementsKind(); | |
9987 MaybeObject* maybe_new_map; | 10044 MaybeObject* maybe_new_map; |
9988 ElementsKind elements_kind; | 10045 maybe_new_map = to->GetElementsTransitionMap(isolate, from_kind); |
9989 if (new_elements->map() == isolate->heap()->fixed_array_map() || | |
9990 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { | |
9991 elements_kind = FAST_ELEMENTS; | |
9992 } else if (new_elements->map() == | |
9993 isolate->heap()->fixed_double_array_map()) { | |
9994 elements_kind = FAST_DOUBLE_ELEMENTS; | |
9995 } else { | |
9996 elements_kind = DICTIONARY_ELEMENTS; | |
9997 } | |
9998 maybe_new_map = to->GetElementsTransitionMap(isolate, elements_kind); | |
9999 Object* new_map; | 10046 Object* new_map; |
10000 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 10047 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
10001 to->set_map(Map::cast(new_map)); | 10048 to->set_map_and_elements(Map::cast(new_map), new_elements); |
10002 to->set_elements(new_elements); | |
10003 to->set_length(from->length()); | 10049 to->set_length(from->length()); |
10004 Object* obj; | 10050 Object* obj; |
10005 { MaybeObject* maybe_obj = from->ResetElements(); | 10051 { MaybeObject* maybe_obj = from->ResetElements(); |
10006 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 10052 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
10007 } | 10053 } |
10008 from->set_length(Smi::FromInt(0)); | 10054 from->set_length(Smi::FromInt(0)); |
10055 to->ValidateElements(); | |
10009 return to; | 10056 return to; |
10010 } | 10057 } |
10011 | 10058 |
10012 | 10059 |
10013 // How many elements does this object/array have? | 10060 // How many elements does this object/array have? |
10014 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) { | 10061 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) { |
10015 ASSERT(args.length() == 1); | 10062 ASSERT(args.length() == 1); |
10016 CONVERT_ARG_CHECKED(JSObject, object, 0); | 10063 CONVERT_ARG_CHECKED(JSObject, object, 0); |
10017 HeapObject* elements = object->elements(); | 10064 HeapObject* elements = object->elements(); |
10018 if (elements->IsDictionary()) { | 10065 if (elements->IsDictionary()) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10078 for (int i = 0; i < keys_length; i++) { | 10125 for (int i = 0; i < keys_length; i++) { |
10079 Object* key = keys->get(i); | 10126 Object* key = keys->get(i); |
10080 uint32_t index = 0; | 10127 uint32_t index = 0; |
10081 if (!key->ToArrayIndex(&index) || index >= length) { | 10128 if (!key->ToArrayIndex(&index) || index >= length) { |
10082 // Zap invalid keys. | 10129 // Zap invalid keys. |
10083 keys->set_undefined(i); | 10130 keys->set_undefined(i); |
10084 } | 10131 } |
10085 } | 10132 } |
10086 return *isolate->factory()->NewJSArrayWithElements(keys); | 10133 return *isolate->factory()->NewJSArrayWithElements(keys); |
10087 } else { | 10134 } else { |
10088 ASSERT(array->HasFastElements() || | 10135 ASSERT(array->HasFastSmiOrObjectElements() || |
10089 array->HasFastSmiOnlyElements() || | |
10090 array->HasFastDoubleElements()); | 10136 array->HasFastDoubleElements()); |
10091 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); | 10137 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); |
10092 // -1 means start of array. | 10138 // -1 means start of array. |
10093 single_interval->set(0, Smi::FromInt(-1)); | 10139 single_interval->set(0, Smi::FromInt(-1)); |
10094 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); | 10140 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); |
10095 uint32_t actual_length = | 10141 uint32_t actual_length = |
10096 static_cast<uint32_t>(elements->length()); | 10142 static_cast<uint32_t>(elements->length()); |
10097 uint32_t min_length = actual_length < length ? actual_length : length; | 10143 uint32_t min_length = actual_length < length ? actual_length : length; |
10098 Handle<Object> length_object = | 10144 Handle<Object> length_object = |
10099 isolate->factory()->NewNumber(static_cast<double>(min_length)); | 10145 isolate->factory()->NewNumber(static_cast<double>(min_length)); |
(...skipping 3294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13394 return NULL; | 13440 return NULL; |
13395 } | 13441 } |
13396 | 13442 |
13397 | 13443 |
13398 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ | 13444 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ |
13399 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ | 13445 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ |
13400 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ | 13446 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ |
13401 return isolate->heap()->ToBoolean(obj->Has##Name()); \ | 13447 return isolate->heap()->ToBoolean(obj->Has##Name()); \ |
13402 } | 13448 } |
13403 | 13449 |
13404 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements) | 13450 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements) |
13405 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) | 13451 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements) |
13452 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements) | |
13406 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) | 13453 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) |
13454 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements) | |
13407 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) | 13455 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) |
13408 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) | 13456 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) |
13409 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) | 13457 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) |
13410 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) | 13458 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) |
13411 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) | 13459 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) |
13412 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) | 13460 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) |
13413 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) | 13461 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) |
13414 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) | 13462 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) |
13415 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements) | 13463 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements) |
13416 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements) | 13464 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements) |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13505 // Handle last resort GC and make sure to allow future allocations | 13553 // Handle last resort GC and make sure to allow future allocations |
13506 // to grow the heap without causing GCs (if possible). | 13554 // to grow the heap without causing GCs (if possible). |
13507 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13555 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13508 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13556 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13509 "Runtime::PerformGC"); | 13557 "Runtime::PerformGC"); |
13510 } | 13558 } |
13511 } | 13559 } |
13512 | 13560 |
13513 | 13561 |
13514 } } // namespace v8::internal | 13562 } } // namespace v8::internal |
OLD | NEW |