Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 | 235 |
| 236 // Take the arguments as elements. | 236 // Take the arguments as elements. |
| 237 int number_of_elements = args.length() - 1; | 237 int number_of_elements = args.length() - 1; |
| 238 Smi* len = Smi::FromInt(number_of_elements); | 238 Smi* len = Smi::FromInt(number_of_elements); |
| 239 Object* obj; | 239 Object* obj; |
| 240 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len->value()); | 240 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len->value()); |
| 241 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 241 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 242 } | 242 } |
| 243 | 243 |
| 244 // Set length and elements on the array. | 244 // Set length and elements on the array. |
| 245 if (FLAG_smi_only_arrays) { | 245 MaybeObject* maybe_object = |
| 246 MaybeObject* maybe_object = | 246 array->EnsureCanContainElements(FixedArray::cast(obj)); |
| 247 array->EnsureCanContainElements(FixedArray::cast(obj)); | 247 if (maybe_object->IsFailure()) return maybe_object; |
| 248 if (maybe_object->IsFailure()) return maybe_object; | |
| 249 } | |
| 250 | 248 |
| 251 AssertNoAllocation no_gc; | 249 AssertNoAllocation no_gc; |
| 252 FixedArray* elms = FixedArray::cast(obj); | 250 FixedArray* elms = FixedArray::cast(obj); |
| 253 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); | 251 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
| 254 // Fill in the content | 252 // Fill in the content |
| 255 for (int index = 0; index < number_of_elements; index++) { | 253 for (int index = 0; index < number_of_elements; index++) { |
| 256 elms->set(index, args[index+1], mode); | 254 elms->set(index, args[index+1], mode); |
| 257 } | 255 } |
| 258 | 256 |
| 259 array->set_elements(FixedArray::cast(obj)); | 257 array->set_elements(FixedArray::cast(obj)); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 if (proto == heap->null_value()) return false; | 393 if (proto == heap->null_value()) return false; |
| 396 array_proto = JSObject::cast(proto); | 394 array_proto = JSObject::cast(proto); |
| 397 if (array_proto != global_context->initial_object_prototype()) return false; | 395 if (array_proto != global_context->initial_object_prototype()) return false; |
| 398 if (array_proto->elements() != heap->empty_fixed_array()) return false; | 396 if (array_proto->elements() != heap->empty_fixed_array()) return false; |
| 399 return array_proto->GetPrototype()->IsNull(); | 397 return array_proto->GetPrototype()->IsNull(); |
| 400 } | 398 } |
| 401 | 399 |
| 402 | 400 |
| 403 MUST_USE_RESULT | 401 MUST_USE_RESULT |
| 404 static inline MaybeObject* EnsureJSArrayWithWritableFastElements( | 402 static inline MaybeObject* EnsureJSArrayWithWritableFastElements( |
| 405 Heap* heap, Object* receiver) { | 403 Heap* heap, Object* receiver, Arguments* args, int first_added_arg) { |
| 406 if (!receiver->IsJSArray()) return NULL; | 404 if (!receiver->IsJSArray()) return NULL; |
| 407 JSArray* array = JSArray::cast(receiver); | 405 JSArray* array = JSArray::cast(receiver); |
| 408 HeapObject* elms = array->elements(); | 406 HeapObject* elms = array->elements(); |
| 409 if (elms->map() == heap->fixed_array_map()) return elms; | 407 Map* map = elms->map(); |
| 410 if (elms->map() == heap->fixed_cow_array_map()) { | 408 if (map == heap->fixed_array_map()) { |
| 411 return array->EnsureWritableFastElements(); | 409 if (args == NULL || !array->HasFastSmiOnlyElements()) { |
| 410 return elms; | |
| 411 } | |
| 412 } else if (map == heap->fixed_cow_array_map()) { | |
| 413 MaybeObject* maybe_writable_result = array->EnsureWritableFastElements(); | |
|
Jakob Kummerow
2011/10/07 17:58:13
nit: excess space after =
danno
2011/10/10 11:26:33
Done.
| |
| 414 if (maybe_writable_result->IsFailure()) return maybe_writable_result; | |
|
Jakob Kummerow
2011/10/07 17:58:13
You don't need this line (it's included in the nex
danno
2011/10/10 11:26:33
Done.
| |
| 415 if (args == NULL || !array->HasFastSmiOnlyElements() || | |
| 416 maybe_writable_result->IsFailure()) { | |
| 417 return maybe_writable_result; | |
| 418 } | |
| 419 } else { | |
| 420 return NULL; | |
| 412 } | 421 } |
| 413 return NULL; | 422 |
| 423 // Need to ensure that the arguments passed in args can be contained in | |
| 424 // the array. | |
| 425 int args_length = args->length(); | |
| 426 if (first_added_arg >= args_length) return array->elements(); | |
| 427 | |
| 428 MaybeObject* maybe_array = array->EnsureCanContainElements( | |
| 429 args, | |
| 430 first_added_arg, | |
| 431 args_length - first_added_arg); | |
| 432 if (maybe_array->IsFailure()) return maybe_array; | |
| 433 return array->elements(); | |
| 414 } | 434 } |
| 415 | 435 |
| 416 | 436 |
| 417 static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap, | 437 static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap, |
| 418 JSArray* receiver) { | 438 JSArray* receiver) { |
| 419 Context* global_context = heap->isolate()->context()->global_context(); | 439 Context* global_context = heap->isolate()->context()->global_context(); |
| 420 JSObject* array_proto = | 440 JSObject* array_proto = |
| 421 JSObject::cast(global_context->array_function()->prototype()); | 441 JSObject::cast(global_context->array_function()->prototype()); |
| 422 return receiver->GetPrototype() == array_proto && | 442 return receiver->GetPrototype() == array_proto && |
| 423 ArrayPrototypeHasNoElements(heap, global_context, array_proto); | 443 ArrayPrototypeHasNoElements(heap, global_context, array_proto); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 450 if (pending_exception) return Failure::Exception(); | 470 if (pending_exception) return Failure::Exception(); |
| 451 return *result; | 471 return *result; |
| 452 } | 472 } |
| 453 | 473 |
| 454 | 474 |
| 455 BUILTIN(ArrayPush) { | 475 BUILTIN(ArrayPush) { |
| 456 Heap* heap = isolate->heap(); | 476 Heap* heap = isolate->heap(); |
| 457 Object* receiver = *args.receiver(); | 477 Object* receiver = *args.receiver(); |
| 458 Object* elms_obj; | 478 Object* elms_obj; |
| 459 { MaybeObject* maybe_elms_obj = | 479 { MaybeObject* maybe_elms_obj = |
| 460 EnsureJSArrayWithWritableFastElements(heap, receiver); | 480 EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 1); |
| 461 if (maybe_elms_obj == NULL) { | 481 if (maybe_elms_obj == NULL) { |
| 462 return CallJsBuiltin(isolate, "ArrayPush", args); | 482 return CallJsBuiltin(isolate, "ArrayPush", args); |
| 463 } | 483 } |
| 464 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 484 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 465 } | 485 } |
| 466 FixedArray* elms = FixedArray::cast(elms_obj); | 486 FixedArray* elms = FixedArray::cast(elms_obj); |
| 467 JSArray* array = JSArray::cast(receiver); | 487 JSArray* array = JSArray::cast(receiver); |
| 468 | 488 |
| 489 int to_add = args.length() - 1; | |
| 469 int len = Smi::cast(array->length())->value(); | 490 int len = Smi::cast(array->length())->value(); |
| 470 int to_add = args.length() - 1; | |
| 471 if (to_add == 0) { | 491 if (to_add == 0) { |
| 472 return Smi::FromInt(len); | 492 return Smi::FromInt(len); |
| 473 } | 493 } |
| 494 | |
| 474 // Currently fixed arrays cannot grow too big, so | 495 // Currently fixed arrays cannot grow too big, so |
| 475 // we should never hit this case. | 496 // we should never hit this case. |
| 476 ASSERT(to_add <= (Smi::kMaxValue - len)); | 497 ASSERT(to_add <= (Smi::kMaxValue - len)); |
| 477 | 498 |
| 478 int new_length = len + to_add; | 499 int new_length = len + to_add; |
| 479 | 500 |
| 480 if (new_length > elms->length()) { | 501 if (new_length > elms->length()) { |
| 481 // New backing storage is needed. | 502 // New backing storage is needed. |
| 482 int capacity = new_length + (new_length >> 1) + 16; | 503 int capacity = new_length + (new_length >> 1) + 16; |
| 483 Object* obj; | 504 Object* obj; |
| 484 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); | 505 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); |
| 485 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 506 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 486 } | 507 } |
| 487 FixedArray* new_elms = FixedArray::cast(obj); | 508 FixedArray* new_elms = FixedArray::cast(obj); |
| 488 | 509 |
| 489 AssertNoAllocation no_gc; | 510 AssertNoAllocation no_gc; |
| 490 if (len > 0) { | 511 if (len > 0) { |
| 491 CopyElements(heap, &no_gc, new_elms, 0, elms, 0, len); | 512 CopyElements(heap, &no_gc, new_elms, 0, elms, 0, len); |
| 492 } | 513 } |
| 493 FillWithHoles(heap, new_elms, new_length, capacity); | 514 FillWithHoles(heap, new_elms, new_length, capacity); |
| 494 | 515 |
| 495 elms = new_elms; | 516 elms = new_elms; |
| 496 } | 517 } |
| 497 | 518 |
| 498 MaybeObject* maybe = array->EnsureCanContainElements(&args, 1, to_add); | |
| 499 if (maybe->IsFailure()) return maybe; | |
| 500 | |
| 501 // Add the provided values. | 519 // Add the provided values. |
| 502 AssertNoAllocation no_gc; | 520 AssertNoAllocation no_gc; |
| 503 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); | 521 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
| 504 for (int index = 0; index < to_add; index++) { | 522 for (int index = 0; index < to_add; index++) { |
| 505 elms->set(index + len, args[index + 1], mode); | 523 elms->set(index + len, args[index + 1], mode); |
| 506 } | 524 } |
| 507 | 525 |
| 508 if (elms != array->elements()) { | 526 if (elms != array->elements()) { |
| 509 array->set_elements(elms); | 527 array->set_elements(elms); |
| 510 } | 528 } |
| 511 | 529 |
| 512 // Set the length. | 530 // Set the length. |
| 513 array->set_length(Smi::FromInt(new_length)); | 531 array->set_length(Smi::FromInt(new_length)); |
| 514 return Smi::FromInt(new_length); | 532 return Smi::FromInt(new_length); |
| 515 } | 533 } |
| 516 | 534 |
| 517 | 535 |
| 518 BUILTIN(ArrayPop) { | 536 BUILTIN(ArrayPop) { |
| 519 Heap* heap = isolate->heap(); | 537 Heap* heap = isolate->heap(); |
| 520 Object* receiver = *args.receiver(); | 538 Object* receiver = *args.receiver(); |
| 521 Object* elms_obj; | 539 Object* elms_obj; |
| 522 { MaybeObject* maybe_elms_obj = | 540 { MaybeObject* maybe_elms_obj = |
| 523 EnsureJSArrayWithWritableFastElements(heap, receiver); | 541 EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0); |
| 524 if (maybe_elms_obj == NULL) return CallJsBuiltin(isolate, "ArrayPop", args); | 542 if (maybe_elms_obj == NULL) return CallJsBuiltin(isolate, "ArrayPop", args); |
| 525 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 543 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 526 } | 544 } |
| 527 FixedArray* elms = FixedArray::cast(elms_obj); | 545 FixedArray* elms = FixedArray::cast(elms_obj); |
| 528 JSArray* array = JSArray::cast(receiver); | 546 JSArray* array = JSArray::cast(receiver); |
| 529 | 547 |
| 530 int len = Smi::cast(array->length())->value(); | 548 int len = Smi::cast(array->length())->value(); |
| 531 if (len == 0) return heap->undefined_value(); | 549 if (len == 0) return heap->undefined_value(); |
| 532 | 550 |
| 533 // Get top element | 551 // Get top element |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 546 | 564 |
| 547 return top; | 565 return top; |
| 548 } | 566 } |
| 549 | 567 |
| 550 | 568 |
| 551 BUILTIN(ArrayShift) { | 569 BUILTIN(ArrayShift) { |
| 552 Heap* heap = isolate->heap(); | 570 Heap* heap = isolate->heap(); |
| 553 Object* receiver = *args.receiver(); | 571 Object* receiver = *args.receiver(); |
| 554 Object* elms_obj; | 572 Object* elms_obj; |
| 555 { MaybeObject* maybe_elms_obj = | 573 { MaybeObject* maybe_elms_obj = |
| 556 EnsureJSArrayWithWritableFastElements(heap, receiver); | 574 EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0); |
| 557 if (maybe_elms_obj == NULL) | 575 if (maybe_elms_obj == NULL) |
| 558 return CallJsBuiltin(isolate, "ArrayShift", args); | 576 return CallJsBuiltin(isolate, "ArrayShift", args); |
| 559 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 577 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 560 } | 578 } |
| 561 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { | 579 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { |
| 562 return CallJsBuiltin(isolate, "ArrayShift", args); | 580 return CallJsBuiltin(isolate, "ArrayShift", args); |
| 563 } | 581 } |
| 564 FixedArray* elms = FixedArray::cast(elms_obj); | 582 FixedArray* elms = FixedArray::cast(elms_obj); |
| 565 JSArray* array = JSArray::cast(receiver); | 583 JSArray* array = JSArray::cast(receiver); |
| 566 ASSERT(array->HasFastTypeElements()); | 584 ASSERT(array->HasFastTypeElements()); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 588 | 606 |
| 589 return first; | 607 return first; |
| 590 } | 608 } |
| 591 | 609 |
| 592 | 610 |
| 593 BUILTIN(ArrayUnshift) { | 611 BUILTIN(ArrayUnshift) { |
| 594 Heap* heap = isolate->heap(); | 612 Heap* heap = isolate->heap(); |
| 595 Object* receiver = *args.receiver(); | 613 Object* receiver = *args.receiver(); |
| 596 Object* elms_obj; | 614 Object* elms_obj; |
| 597 { MaybeObject* maybe_elms_obj = | 615 { MaybeObject* maybe_elms_obj = |
| 598 EnsureJSArrayWithWritableFastElements(heap, receiver); | 616 EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0); |
| 599 if (maybe_elms_obj == NULL) | 617 if (maybe_elms_obj == NULL) |
| 600 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 618 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
| 601 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 619 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 602 } | 620 } |
| 603 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { | 621 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { |
| 604 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 622 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
| 605 } | 623 } |
| 606 FixedArray* elms = FixedArray::cast(elms_obj); | 624 FixedArray* elms = FixedArray::cast(elms_obj); |
| 607 JSArray* array = JSArray::cast(receiver); | 625 JSArray* array = JSArray::cast(receiver); |
| 608 ASSERT(array->HasFastTypeElements()); | 626 ASSERT(array->HasFastTypeElements()); |
| 609 | 627 |
| 610 int len = Smi::cast(array->length())->value(); | 628 int len = Smi::cast(array->length())->value(); |
| 611 int to_add = args.length() - 1; | 629 int to_add = args.length() - 1; |
| 612 int new_length = len + to_add; | 630 int new_length = len + to_add; |
| 613 // Currently fixed arrays cannot grow too big, so | 631 // Currently fixed arrays cannot grow too big, so |
| 614 // we should never hit this case. | 632 // we should never hit this case. |
| 615 ASSERT(to_add <= (Smi::kMaxValue - len)); | 633 ASSERT(to_add <= (Smi::kMaxValue - len)); |
| 616 | 634 |
| 617 if (FLAG_smi_only_arrays) { | 635 MaybeObject* maybe_object = |
| 618 MaybeObject* maybe_object = | 636 array->EnsureCanContainElements(&args, 1, to_add); |
| 619 array->EnsureCanContainElements(&args, 1, to_add); | 637 if (maybe_object->IsFailure()) return maybe_object; |
| 620 if (maybe_object->IsFailure()) return maybe_object; | |
| 621 } | |
| 622 | 638 |
| 623 if (new_length > elms->length()) { | 639 if (new_length > elms->length()) { |
| 624 // New backing storage is needed. | 640 // New backing storage is needed. |
| 625 int capacity = new_length + (new_length >> 1) + 16; | 641 int capacity = new_length + (new_length >> 1) + 16; |
| 626 Object* obj; | 642 Object* obj; |
| 627 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); | 643 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); |
| 628 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 644 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 629 } | 645 } |
| 630 FixedArray* new_elms = FixedArray::cast(obj); | 646 FixedArray* new_elms = FixedArray::cast(obj); |
| 631 AssertNoAllocation no_gc; | 647 AssertNoAllocation no_gc; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 if (!maybe_result->ToObject(&result)) return maybe_result; | 756 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 741 } | 757 } |
| 742 JSArray* result_array = JSArray::cast(result); | 758 JSArray* result_array = JSArray::cast(result); |
| 743 | 759 |
| 744 { MaybeObject* maybe_result = | 760 { MaybeObject* maybe_result = |
| 745 heap->AllocateUninitializedFixedArray(result_len); | 761 heap->AllocateUninitializedFixedArray(result_len); |
| 746 if (!maybe_result->ToObject(&result)) return maybe_result; | 762 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 747 } | 763 } |
| 748 FixedArray* result_elms = FixedArray::cast(result); | 764 FixedArray* result_elms = FixedArray::cast(result); |
| 749 | 765 |
| 750 if (FLAG_smi_only_arrays) { | 766 MaybeObject* maybe_object = |
| 751 MaybeObject* maybe_object = | 767 result_array->EnsureCanContainElements(result_elms); |
| 752 result_array->EnsureCanContainElements(result_elms); | 768 if (maybe_object->IsFailure()) return maybe_object; |
| 753 if (maybe_object->IsFailure()) return maybe_object; | |
| 754 } | |
| 755 | 769 |
| 756 AssertNoAllocation no_gc; | 770 AssertNoAllocation no_gc; |
| 757 CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len); | 771 CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len); |
| 758 | 772 |
| 759 // Set elements. | 773 // Set elements. |
| 760 result_array->set_elements(result_elms); | 774 result_array->set_elements(result_elms); |
| 761 | 775 |
| 762 // Set the length. | 776 // Set the length. |
| 763 result_array->set_length(Smi::FromInt(result_len)); | 777 result_array->set_length(Smi::FromInt(result_len)); |
| 764 return result_array; | 778 return result_array; |
| 765 } | 779 } |
| 766 | 780 |
| 767 | 781 |
| 768 BUILTIN(ArraySplice) { | 782 BUILTIN(ArraySplice) { |
| 769 Heap* heap = isolate->heap(); | 783 Heap* heap = isolate->heap(); |
| 770 Object* receiver = *args.receiver(); | 784 Object* receiver = *args.receiver(); |
| 771 Object* elms_obj; | 785 Object* elms_obj; |
| 772 { MaybeObject* maybe_elms_obj = | 786 { MaybeObject* maybe_elms_obj = |
| 773 EnsureJSArrayWithWritableFastElements(heap, receiver); | 787 EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 3); |
| 774 if (maybe_elms_obj == NULL) | 788 if (maybe_elms_obj == NULL) |
| 775 return CallJsBuiltin(isolate, "ArraySplice", args); | 789 return CallJsBuiltin(isolate, "ArraySplice", args); |
| 776 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 790 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 777 } | 791 } |
| 778 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { | 792 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { |
| 779 return CallJsBuiltin(isolate, "ArraySplice", args); | 793 return CallJsBuiltin(isolate, "ArraySplice", args); |
| 780 } | 794 } |
| 781 FixedArray* elms = FixedArray::cast(elms_obj); | 795 FixedArray* elms = FixedArray::cast(elms_obj); |
| 782 JSArray* array = JSArray::cast(receiver); | 796 JSArray* array = JSArray::cast(receiver); |
| 783 ASSERT(array->HasFastTypeElements()); | 797 ASSERT(array->HasFastTypeElements()); |
| 784 | 798 |
| 785 int len = Smi::cast(array->length())->value(); | 799 int len = Smi::cast(array->length())->value(); |
| 786 | |
| 787 int n_arguments = args.length() - 1; | 800 int n_arguments = args.length() - 1; |
| 801 int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; | |
| 788 | 802 |
| 789 int relative_start = 0; | 803 int relative_start = 0; |
| 790 if (n_arguments > 0) { | 804 if (n_arguments > 0) { |
| 791 Object* arg1 = args[1]; | 805 Object* arg1 = args[1]; |
| 792 if (arg1->IsSmi()) { | 806 if (arg1->IsSmi()) { |
| 793 relative_start = Smi::cast(arg1)->value(); | 807 relative_start = Smi::cast(arg1)->value(); |
| 794 } else if (!arg1->IsUndefined()) { | 808 } else if (!arg1->IsUndefined()) { |
| 795 return CallJsBuiltin(isolate, "ArraySplice", args); | 809 return CallJsBuiltin(isolate, "ArraySplice", args); |
| 796 } | 810 } |
| 797 } | 811 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 849 elms, actual_start, | 863 elms, actual_start, |
| 850 actual_delete_count); | 864 actual_delete_count); |
| 851 | 865 |
| 852 // Set elements. | 866 // Set elements. |
| 853 result_array->set_elements(result_elms); | 867 result_array->set_elements(result_elms); |
| 854 | 868 |
| 855 // Set the length. | 869 // Set the length. |
| 856 result_array->set_length(Smi::FromInt(actual_delete_count)); | 870 result_array->set_length(Smi::FromInt(actual_delete_count)); |
| 857 } | 871 } |
| 858 | 872 |
| 859 int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; | |
| 860 | |
| 861 if (FLAG_smi_only_arrays) { | |
| 862 MaybeObject* maybe = array->EnsureCanContainElements(&args, 3, item_count); | |
| 863 if (maybe->IsFailure()) return maybe; | |
| 864 } | |
| 865 | |
| 866 int new_length = len - actual_delete_count + item_count; | 873 int new_length = len - actual_delete_count + item_count; |
| 867 | 874 |
| 868 bool elms_changed = false; | 875 bool elms_changed = false; |
| 869 if (item_count < actual_delete_count) { | 876 if (item_count < actual_delete_count) { |
| 870 // Shrink the array. | 877 // Shrink the array. |
| 871 const bool trim_array = !heap->lo_space()->Contains(elms) && | 878 const bool trim_array = !heap->lo_space()->Contains(elms) && |
| 872 ((actual_start + item_count) < | 879 ((actual_start + item_count) < |
| 873 (len - actual_delete_count - actual_start)); | 880 (len - actual_delete_count - actual_start)); |
| 874 if (trim_array) { | 881 if (trim_array) { |
| 875 const int delta = actual_delete_count - item_count; | 882 const int delta = actual_delete_count - item_count; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 992 if (!maybe_result->ToObject(&result)) return maybe_result; | 999 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 993 } | 1000 } |
| 994 JSArray* result_array = JSArray::cast(result); | 1001 JSArray* result_array = JSArray::cast(result); |
| 995 | 1002 |
| 996 { MaybeObject* maybe_result = | 1003 { MaybeObject* maybe_result = |
| 997 heap->AllocateUninitializedFixedArray(result_len); | 1004 heap->AllocateUninitializedFixedArray(result_len); |
| 998 if (!maybe_result->ToObject(&result)) return maybe_result; | 1005 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 999 } | 1006 } |
| 1000 FixedArray* result_elms = FixedArray::cast(result); | 1007 FixedArray* result_elms = FixedArray::cast(result); |
| 1001 | 1008 |
| 1002 if (FLAG_smi_only_arrays) { | 1009 // Ensure element type transitions happen before copying elements in. |
| 1010 if (result_array->HasFastSmiOnlyElements()) { | |
| 1003 for (int i = 0; i < n_arguments; i++) { | 1011 for (int i = 0; i < n_arguments; i++) { |
| 1004 JSArray* array = JSArray::cast(args[i]); | 1012 JSArray* array = JSArray::cast(args[i]); |
| 1005 int len = Smi::cast(array->length())->value(); | 1013 if (!array->HasFastSmiOnlyElements()) { |
| 1006 if (len > 0) { | 1014 result_array->EnsureCanContainNonSmiElements(); |
| 1007 FixedArray* elms = FixedArray::cast(array->elements()); | 1015 break; |
| 1008 MaybeObject* maybe_object = | |
| 1009 result_array->EnsureCanContainElements(elms); | |
| 1010 if (maybe_object->IsFailure()) return maybe_object; | |
| 1011 } | 1016 } |
| 1012 } | 1017 } |
| 1013 } | 1018 } |
| 1014 | 1019 |
| 1015 // Copy data. | 1020 // Copy data. |
| 1016 AssertNoAllocation no_gc; | 1021 AssertNoAllocation no_gc; |
| 1017 int start_pos = 0; | 1022 int start_pos = 0; |
| 1018 for (int i = 0; i < n_arguments; i++) { | 1023 for (int i = 0; i < n_arguments; i++) { |
| 1019 JSArray* array = JSArray::cast(args[i]); | 1024 JSArray* array = JSArray::cast(args[i]); |
| 1020 int len = Smi::cast(array->length())->value(); | 1025 int len = Smi::cast(array->length())->value(); |
| (...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1761 return Handle<Code>(code_address); \ | 1766 return Handle<Code>(code_address); \ |
| 1762 } | 1767 } |
| 1763 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1768 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
| 1764 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1769 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 1765 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1770 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 1766 #undef DEFINE_BUILTIN_ACCESSOR_C | 1771 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 1767 #undef DEFINE_BUILTIN_ACCESSOR_A | 1772 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 1768 | 1773 |
| 1769 | 1774 |
| 1770 } } // namespace v8::internal | 1775 } } // namespace v8::internal |
| OLD | NEW |