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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 JSFunction* constructor = | 195 JSFunction* constructor = |
196 isolate->context()->global_context()->array_function(); | 196 isolate->context()->global_context()->array_function(); |
197 Object* obj; | 197 Object* obj; |
198 { MaybeObject* maybe_obj = heap->AllocateJSObject(constructor); | 198 { MaybeObject* maybe_obj = heap->AllocateJSObject(constructor); |
199 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 199 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
200 } | 200 } |
201 array = JSArray::cast(obj); | 201 array = JSArray::cast(obj); |
202 } | 202 } |
203 | 203 |
204 // 'array' now contains the JSArray we should initialize. | 204 // 'array' now contains the JSArray we should initialize. |
205 ASSERT(array->HasFastElements()); | 205 ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
206 | 206 |
207 // Optimize the case where there is one argument and the argument is a | 207 // Optimize the case where there is one argument and the argument is a |
208 // small smi. | 208 // small smi. |
209 if (args.length() == 2) { | 209 if (args.length() == 2) { |
210 Object* obj = args[1]; | 210 Object* obj = args[1]; |
211 if (obj->IsSmi()) { | 211 if (obj->IsSmi()) { |
212 int len = Smi::cast(obj)->value(); | 212 int len = Smi::cast(obj)->value(); |
213 if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) { | 213 if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) { |
214 Object* obj; | 214 Object* obj; |
215 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len); | 215 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len); |
216 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 216 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
217 } | 217 } |
218 array->SetContent(FixedArray::cast(obj)); | 218 MaybeObject* maybe_obj = array->SetContent(FixedArray::cast(obj)); |
219 if (maybe_obj->IsFailure()) return maybe_obj; | |
219 return array; | 220 return array; |
220 } | 221 } |
221 } | 222 } |
222 // Take the argument as the length. | 223 // Take the argument as the length. |
223 { MaybeObject* maybe_obj = array->Initialize(0); | 224 { MaybeObject* maybe_obj = array->Initialize(0); |
224 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 225 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
225 } | 226 } |
226 return array->SetElementsLength(args[1]); | 227 return array->SetElementsLength(args[1]); |
227 } | 228 } |
228 | 229 |
229 // Optimize the case where there are no parameters passed. | 230 // Optimize the case where there are no parameters passed. |
230 if (args.length() == 1) { | 231 if (args.length() == 1) { |
231 return array->Initialize(JSArray::kPreallocatedArrayElements); | 232 return array->Initialize(JSArray::kPreallocatedArrayElements); |
232 } | 233 } |
233 | 234 |
234 // Take the arguments as elements. | 235 // Take the arguments as elements. |
235 int number_of_elements = args.length() - 1; | 236 int number_of_elements = args.length() - 1; |
236 Smi* len = Smi::FromInt(number_of_elements); | 237 Smi* len = Smi::FromInt(number_of_elements); |
237 Object* obj; | 238 Object* obj; |
238 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len->value()); | 239 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len->value()); |
239 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 240 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
240 } | 241 } |
241 | 242 |
242 AssertNoAllocation no_gc; | 243 AssertNoAllocation no_gc; |
Jakob Kummerow
2011/09/16 16:30:34
Scope or move this, you're calling EnsureCanContai
danno
2011/09/21 14:32:04
Done.
| |
243 FixedArray* elms = FixedArray::cast(obj); | 244 FixedArray* elms = FixedArray::cast(obj); |
244 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); | 245 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
245 // Fill in the content | 246 // Fill in the content |
246 for (int index = 0; index < number_of_elements; index++) { | 247 for (int index = 0; index < number_of_elements; index++) { |
247 elms->set(index, args[index+1], mode); | 248 elms->set(index, args[index+1], mode); |
248 } | 249 } |
249 | 250 |
250 // Set length and elements on the array. | 251 // Set length and elements on the array. |
252 MaybeObject* maybe_object = | |
253 array->EnsureCanContainElements(FixedArray::cast(obj)); | |
254 if (maybe_object->IsFailure()) return maybe_object; | |
251 array->set_elements(FixedArray::cast(obj)); | 255 array->set_elements(FixedArray::cast(obj)); |
252 array->set_length(len); | 256 array->set_length(len); |
253 | 257 |
254 return array; | 258 return array; |
255 } | 259 } |
256 | 260 |
257 | 261 |
258 MUST_USE_RESULT static MaybeObject* AllocateJSArray(Heap* heap) { | 262 MUST_USE_RESULT static MaybeObject* AllocateJSArray(Heap* heap) { |
259 JSFunction* array_function = | 263 JSFunction* array_function = |
260 heap->isolate()->context()->global_context()->array_function(); | 264 heap->isolate()->context()->global_context()->array_function(); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
468 } | 472 } |
469 FixedArray* new_elms = FixedArray::cast(obj); | 473 FixedArray* new_elms = FixedArray::cast(obj); |
470 | 474 |
471 AssertNoAllocation no_gc; | 475 AssertNoAllocation no_gc; |
472 if (len > 0) { | 476 if (len > 0) { |
473 CopyElements(heap, &no_gc, new_elms, 0, elms, 0, len); | 477 CopyElements(heap, &no_gc, new_elms, 0, elms, 0, len); |
474 } | 478 } |
475 FillWithHoles(heap, new_elms, new_length, capacity); | 479 FillWithHoles(heap, new_elms, new_length, capacity); |
476 | 480 |
477 elms = new_elms; | 481 elms = new_elms; |
478 array->set_elements(elms); | |
479 } | 482 } |
480 | 483 |
484 MaybeObject* maybe = array->EnsureCanContainElements(&args, 1, to_add); | |
485 if (maybe->IsFailure()) return maybe; | |
486 | |
481 // Add the provided values. | 487 // Add the provided values. |
482 AssertNoAllocation no_gc; | 488 AssertNoAllocation no_gc; |
483 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); | 489 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
484 for (int index = 0; index < to_add; index++) { | 490 for (int index = 0; index < to_add; index++) { |
485 elms->set(index + len, args[index + 1], mode); | 491 elms->set(index + len, args[index + 1], mode); |
486 } | 492 } |
487 | 493 |
494 if (elms != array->elements()) { | |
495 array->set_elements(elms); | |
496 } | |
497 | |
488 // Set the length. | 498 // Set the length. |
489 array->set_length(Smi::FromInt(new_length)); | 499 array->set_length(Smi::FromInt(new_length)); |
490 return Smi::FromInt(new_length); | 500 return Smi::FromInt(new_length); |
491 } | 501 } |
492 | 502 |
493 | 503 |
494 BUILTIN(ArrayPop) { | 504 BUILTIN(ArrayPop) { |
495 Heap* heap = isolate->heap(); | 505 Heap* heap = isolate->heap(); |
496 Object* receiver = *args.receiver(); | 506 Object* receiver = *args.receiver(); |
497 Object* elms_obj; | 507 Object* elms_obj; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
532 EnsureJSArrayWithWritableFastElements(heap, receiver); | 542 EnsureJSArrayWithWritableFastElements(heap, receiver); |
533 if (maybe_elms_obj == NULL) | 543 if (maybe_elms_obj == NULL) |
534 return CallJsBuiltin(isolate, "ArrayShift", args); | 544 return CallJsBuiltin(isolate, "ArrayShift", args); |
535 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 545 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
536 } | 546 } |
537 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { | 547 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { |
538 return CallJsBuiltin(isolate, "ArrayShift", args); | 548 return CallJsBuiltin(isolate, "ArrayShift", args); |
539 } | 549 } |
540 FixedArray* elms = FixedArray::cast(elms_obj); | 550 FixedArray* elms = FixedArray::cast(elms_obj); |
541 JSArray* array = JSArray::cast(receiver); | 551 JSArray* array = JSArray::cast(receiver); |
542 ASSERT(array->HasFastElements()); | 552 ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
543 | 553 |
544 int len = Smi::cast(array->length())->value(); | 554 int len = Smi::cast(array->length())->value(); |
545 if (len == 0) return heap->undefined_value(); | 555 if (len == 0) return heap->undefined_value(); |
546 | 556 |
547 // Get first element | 557 // Get first element |
548 Object* first = elms->get(0); | 558 Object* first = elms->get(0); |
549 if (first->IsTheHole()) { | 559 if (first->IsTheHole()) { |
550 first = heap->undefined_value(); | 560 first = heap->undefined_value(); |
551 } | 561 } |
552 | 562 |
(...skipping 23 matching lines...) Expand all Loading... | |
576 EnsureJSArrayWithWritableFastElements(heap, receiver); | 586 EnsureJSArrayWithWritableFastElements(heap, receiver); |
577 if (maybe_elms_obj == NULL) | 587 if (maybe_elms_obj == NULL) |
578 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 588 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
579 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 589 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
580 } | 590 } |
581 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { | 591 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { |
582 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 592 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
583 } | 593 } |
584 FixedArray* elms = FixedArray::cast(elms_obj); | 594 FixedArray* elms = FixedArray::cast(elms_obj); |
585 JSArray* array = JSArray::cast(receiver); | 595 JSArray* array = JSArray::cast(receiver); |
586 ASSERT(array->HasFastElements()); | 596 ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
587 | 597 |
588 int len = Smi::cast(array->length())->value(); | 598 int len = Smi::cast(array->length())->value(); |
589 int to_add = args.length() - 1; | 599 int to_add = args.length() - 1; |
590 int new_length = len + to_add; | 600 int new_length = len + to_add; |
591 // Currently fixed arrays cannot grow too big, so | 601 // Currently fixed arrays cannot grow too big, so |
592 // we should never hit this case. | 602 // we should never hit this case. |
593 ASSERT(to_add <= (Smi::kMaxValue - len)); | 603 ASSERT(to_add <= (Smi::kMaxValue - len)); |
594 | 604 |
595 if (new_length > elms->length()) { | 605 if (new_length > elms->length()) { |
596 // New backing storage is needed. | 606 // New backing storage is needed. |
597 int capacity = new_length + (new_length >> 1) + 16; | 607 int capacity = new_length + (new_length >> 1) + 16; |
598 Object* obj; | 608 Object* obj; |
599 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); | 609 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); |
600 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 610 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
601 } | 611 } |
602 FixedArray* new_elms = FixedArray::cast(obj); | 612 FixedArray* new_elms = FixedArray::cast(obj); |
603 | 613 |
604 AssertNoAllocation no_gc; | 614 AssertNoAllocation no_gc; |
Jakob Kummerow
2011/09/16 16:30:34
Scope or move this, you're calling EnsureCanContai
danno
2011/09/21 14:32:04
Done.
| |
605 if (len > 0) { | 615 if (len > 0) { |
606 CopyElements(heap, &no_gc, new_elms, to_add, elms, 0, len); | 616 CopyElements(heap, &no_gc, new_elms, to_add, elms, 0, len); |
607 } | 617 } |
608 FillWithHoles(heap, new_elms, new_length, capacity); | 618 FillWithHoles(heap, new_elms, new_length, capacity); |
609 | 619 |
610 elms = new_elms; | 620 elms = new_elms; |
621 | |
622 MaybeObject* maybe_object = array->EnsureCanContainElements(elms); | |
623 if (maybe_object->IsFailure()) return maybe_object; | |
611 array->set_elements(elms); | 624 array->set_elements(elms); |
612 } else { | 625 } else { |
613 AssertNoAllocation no_gc; | 626 AssertNoAllocation no_gc; |
614 MoveElements(heap, &no_gc, elms, to_add, elms, 0, len); | 627 MoveElements(heap, &no_gc, elms, to_add, elms, 0, len); |
615 } | 628 } |
616 | 629 |
617 // Add the provided values. | 630 // Add the provided values. |
618 AssertNoAllocation no_gc; | 631 AssertNoAllocation no_gc; |
Jakob Kummerow
2011/09/16 16:30:34
Scope or move this, you're calling EnsureCanContai
danno
2011/09/21 14:32:04
Done.
| |
619 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); | 632 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
633 bool only_smis = array->HasFastSmiOnlyElements(); | |
620 for (int i = 0; i < to_add; i++) { | 634 for (int i = 0; i < to_add; i++) { |
635 if (only_smis && !args[i+1]->IsSmi() && | |
Jakob Kummerow
2011/09/16 16:30:34
nit: spaces around '+'
(also in the next line)
danno
2011/09/21 14:32:04
Done.
| |
636 args[i+1] != heap->the_hole_value()) { | |
637 MaybeObject* maybe_object = array->EnsureCanContainNonSmiElements(); | |
638 if (maybe_object->IsFailure()) return maybe_object; | |
639 only_smis = false; | |
640 } | |
621 elms->set(i, args[i + 1], mode); | 641 elms->set(i, args[i + 1], mode); |
622 } | 642 } |
623 | 643 |
624 // Set the length. | 644 // Set the length. |
625 array->set_length(Smi::FromInt(new_length)); | 645 array->set_length(Smi::FromInt(new_length)); |
626 return Smi::FromInt(new_length); | 646 return Smi::FromInt(new_length); |
627 } | 647 } |
628 | 648 |
629 | 649 |
630 BUILTIN(ArraySlice) { | 650 BUILTIN(ArraySlice) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
714 if (!maybe_result->ToObject(&result)) return maybe_result; | 734 if (!maybe_result->ToObject(&result)) return maybe_result; |
715 } | 735 } |
716 JSArray* result_array = JSArray::cast(result); | 736 JSArray* result_array = JSArray::cast(result); |
717 | 737 |
718 { MaybeObject* maybe_result = | 738 { MaybeObject* maybe_result = |
719 heap->AllocateUninitializedFixedArray(result_len); | 739 heap->AllocateUninitializedFixedArray(result_len); |
720 if (!maybe_result->ToObject(&result)) return maybe_result; | 740 if (!maybe_result->ToObject(&result)) return maybe_result; |
721 } | 741 } |
722 FixedArray* result_elms = FixedArray::cast(result); | 742 FixedArray* result_elms = FixedArray::cast(result); |
723 | 743 |
724 AssertNoAllocation no_gc; | 744 AssertNoAllocation no_gc; |
Jakob Kummerow
2011/09/16 16:30:34
Scope or move this, you're calling EnsureCanContai
danno
2011/09/21 14:32:04
Done.
| |
725 CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len); | 745 CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len); |
726 | 746 |
727 // Set elements. | 747 // Set elements. |
748 MaybeObject* maybe_object = | |
749 result_array->EnsureCanContainElements(result_elms); | |
750 if (maybe_object->IsFailure()) return maybe_object; | |
728 result_array->set_elements(result_elms); | 751 result_array->set_elements(result_elms); |
729 | 752 |
730 // Set the length. | 753 // Set the length. |
731 result_array->set_length(Smi::FromInt(result_len)); | 754 result_array->set_length(Smi::FromInt(result_len)); |
732 return result_array; | 755 return result_array; |
733 } | 756 } |
734 | 757 |
735 | 758 |
736 BUILTIN(ArraySplice) { | 759 BUILTIN(ArraySplice) { |
737 Heap* heap = isolate->heap(); | 760 Heap* heap = isolate->heap(); |
738 Object* receiver = *args.receiver(); | 761 Object* receiver = *args.receiver(); |
739 Object* elms_obj; | 762 Object* elms_obj; |
740 { MaybeObject* maybe_elms_obj = | 763 { MaybeObject* maybe_elms_obj = |
741 EnsureJSArrayWithWritableFastElements(heap, receiver); | 764 EnsureJSArrayWithWritableFastElements(heap, receiver); |
742 if (maybe_elms_obj == NULL) | 765 if (maybe_elms_obj == NULL) |
743 return CallJsBuiltin(isolate, "ArraySplice", args); | 766 return CallJsBuiltin(isolate, "ArraySplice", args); |
744 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 767 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
745 } | 768 } |
746 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { | 769 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { |
747 return CallJsBuiltin(isolate, "ArraySplice", args); | 770 return CallJsBuiltin(isolate, "ArraySplice", args); |
748 } | 771 } |
749 FixedArray* elms = FixedArray::cast(elms_obj); | 772 FixedArray* elms = FixedArray::cast(elms_obj); |
750 JSArray* array = JSArray::cast(receiver); | 773 JSArray* array = JSArray::cast(receiver); |
751 ASSERT(array->HasFastElements()); | 774 ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
752 | 775 |
753 int len = Smi::cast(array->length())->value(); | 776 int len = Smi::cast(array->length())->value(); |
754 | 777 |
755 int n_arguments = args.length() - 1; | 778 int n_arguments = args.length() - 1; |
756 | 779 |
757 int relative_start = 0; | 780 int relative_start = 0; |
758 if (n_arguments > 0) { | 781 if (n_arguments > 0) { |
759 Object* arg1 = args[1]; | 782 Object* arg1 = args[1]; |
760 if (arg1->IsSmi()) { | 783 if (arg1->IsSmi()) { |
761 relative_start = Smi::cast(arg1)->value(); | 784 relative_start = Smi::cast(arg1)->value(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
802 if (!maybe_result->ToObject(&result)) return maybe_result; | 825 if (!maybe_result->ToObject(&result)) return maybe_result; |
803 } | 826 } |
804 result_array = JSArray::cast(result); | 827 result_array = JSArray::cast(result); |
805 | 828 |
806 { MaybeObject* maybe_result = | 829 { MaybeObject* maybe_result = |
807 heap->AllocateUninitializedFixedArray(actual_delete_count); | 830 heap->AllocateUninitializedFixedArray(actual_delete_count); |
808 if (!maybe_result->ToObject(&result)) return maybe_result; | 831 if (!maybe_result->ToObject(&result)) return maybe_result; |
809 } | 832 } |
810 FixedArray* result_elms = FixedArray::cast(result); | 833 FixedArray* result_elms = FixedArray::cast(result); |
811 | 834 |
835 if (!array->HasFastSmiOnlyElements()) { | |
836 MaybeObject* maybe_result_array = | |
837 result_array->EnsureCanContainNonSmiElements(); | |
838 if (maybe_result_array->IsFailure()) return maybe_result_array; | |
839 } | |
840 | |
812 AssertNoAllocation no_gc; | 841 AssertNoAllocation no_gc; |
813 // Fill newly created array. | 842 // Fill newly created array. |
814 CopyElements(heap, | 843 CopyElements(heap, |
815 &no_gc, | 844 &no_gc, |
816 result_elms, 0, | 845 result_elms, 0, |
817 elms, actual_start, | 846 elms, actual_start, |
818 actual_delete_count); | 847 actual_delete_count); |
819 | 848 |
820 // Set elements. | 849 // Set elements. |
821 result_array->set_elements(result_elms); | 850 result_array->set_elements(result_elms); |
822 | 851 |
823 // Set the length. | 852 // Set the length. |
824 result_array->set_length(Smi::FromInt(actual_delete_count)); | 853 result_array->set_length(Smi::FromInt(actual_delete_count)); |
825 } | 854 } |
826 | 855 |
827 int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; | 856 int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; |
828 | 857 |
829 int new_length = len - actual_delete_count + item_count; | 858 int new_length = len - actual_delete_count + item_count; |
830 | 859 |
860 WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER; | |
861 bool elms_changed = false; | |
831 if (item_count < actual_delete_count) { | 862 if (item_count < actual_delete_count) { |
832 // Shrink the array. | 863 // Shrink the array. |
833 const bool trim_array = !heap->lo_space()->Contains(elms) && | 864 const bool trim_array = !heap->lo_space()->Contains(elms) && |
834 ((actual_start + item_count) < | 865 ((actual_start + item_count) < |
835 (len - actual_delete_count - actual_start)); | 866 (len - actual_delete_count - actual_start)); |
836 if (trim_array) { | 867 if (trim_array) { |
837 const int delta = actual_delete_count - item_count; | 868 const int delta = actual_delete_count - item_count; |
838 | 869 |
839 if (actual_start > 0) { | 870 if (actual_start > 0) { |
840 AssertNoAllocation no_gc; | 871 AssertNoAllocation no_gc; |
841 MoveElements(heap, &no_gc, elms, delta, elms, 0, actual_start); | 872 MoveElements(heap, &no_gc, elms, delta, elms, 0, actual_start); |
842 } | 873 } |
843 | 874 |
844 elms = LeftTrimFixedArray(heap, elms, delta); | 875 elms = LeftTrimFixedArray(heap, elms, delta); |
845 array->set_elements(elms, SKIP_WRITE_BARRIER); | 876 elms_changed = true; |
877 // elms in new space, can skip write barrier. | |
878 write_barrier_mode = SKIP_WRITE_BARRIER; | |
846 } else { | 879 } else { |
847 AssertNoAllocation no_gc; | 880 AssertNoAllocation no_gc; |
848 MoveElements(heap, &no_gc, | 881 MoveElements(heap, &no_gc, |
849 elms, actual_start + item_count, | 882 elms, actual_start + item_count, |
850 elms, actual_start + actual_delete_count, | 883 elms, actual_start + actual_delete_count, |
851 (len - actual_delete_count - actual_start)); | 884 (len - actual_delete_count - actual_start)); |
852 FillWithHoles(heap, elms, new_length, len); | 885 FillWithHoles(heap, elms, new_length, len); |
853 } | 886 } |
854 } else if (item_count > actual_delete_count) { | 887 } else if (item_count > actual_delete_count) { |
855 // Currently fixed arrays cannot grow too big, so | 888 // Currently fixed arrays cannot grow too big, so |
(...skipping 19 matching lines...) Expand all Loading... | |
875 const int to_copy = len - actual_delete_count - actual_start; | 908 const int to_copy = len - actual_delete_count - actual_start; |
876 if (to_copy > 0) { | 909 if (to_copy > 0) { |
877 CopyElements(heap, &no_gc, | 910 CopyElements(heap, &no_gc, |
878 new_elms, actual_start + item_count, | 911 new_elms, actual_start + item_count, |
879 elms, actual_start + actual_delete_count, | 912 elms, actual_start + actual_delete_count, |
880 to_copy); | 913 to_copy); |
881 } | 914 } |
882 FillWithHoles(heap, new_elms, new_length, capacity); | 915 FillWithHoles(heap, new_elms, new_length, capacity); |
883 | 916 |
884 elms = new_elms; | 917 elms = new_elms; |
885 array->set_elements(elms); | 918 elms_changed = true; |
886 } else { | 919 } else { |
887 AssertNoAllocation no_gc; | 920 AssertNoAllocation no_gc; |
888 MoveElements(heap, &no_gc, | 921 MoveElements(heap, &no_gc, |
889 elms, actual_start + item_count, | 922 elms, actual_start + item_count, |
890 elms, actual_start + actual_delete_count, | 923 elms, actual_start + actual_delete_count, |
891 (len - actual_delete_count - actual_start)); | 924 (len - actual_delete_count - actual_start)); |
892 } | 925 } |
893 } | 926 } |
894 | 927 |
928 MaybeObject* maybe = array->EnsureCanContainElements(&args, 3, item_count); | |
929 if (maybe->IsFailure()) return maybe; | |
930 | |
895 AssertNoAllocation no_gc; | 931 AssertNoAllocation no_gc; |
896 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); | 932 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
897 for (int k = actual_start; k < actual_start + item_count; k++) { | 933 for (int k = actual_start; k < actual_start + item_count; k++) { |
898 elms->set(k, args[3 + k - actual_start], mode); | 934 elms->set(k, args[3 + k - actual_start], mode); |
899 } | 935 } |
900 | 936 |
937 if (elms_changed) { | |
938 array->set_elements(elms, write_barrier_mode); | |
939 } | |
940 | |
901 // Set the length. | 941 // Set the length. |
902 array->set_length(Smi::FromInt(new_length)); | 942 array->set_length(Smi::FromInt(new_length)); |
903 | 943 |
904 return result_array; | 944 return result_array; |
905 } | 945 } |
906 | 946 |
907 | 947 |
908 BUILTIN(ArrayConcat) { | 948 BUILTIN(ArrayConcat) { |
909 Heap* heap = isolate->heap(); | 949 Heap* heap = isolate->heap(); |
910 Context* global_context = isolate->context()->global_context(); | 950 Context* global_context = isolate->context()->global_context(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
950 } | 990 } |
951 JSArray* result_array = JSArray::cast(result); | 991 JSArray* result_array = JSArray::cast(result); |
952 | 992 |
953 { MaybeObject* maybe_result = | 993 { MaybeObject* maybe_result = |
954 heap->AllocateUninitializedFixedArray(result_len); | 994 heap->AllocateUninitializedFixedArray(result_len); |
955 if (!maybe_result->ToObject(&result)) return maybe_result; | 995 if (!maybe_result->ToObject(&result)) return maybe_result; |
956 } | 996 } |
957 FixedArray* result_elms = FixedArray::cast(result); | 997 FixedArray* result_elms = FixedArray::cast(result); |
958 | 998 |
959 // Copy data. | 999 // Copy data. |
960 AssertNoAllocation no_gc; | 1000 AssertNoAllocation no_gc; |
Jakob Kummerow
2011/09/16 16:30:34
Scope or move this, you're calling EnsureCanContai
danno
2011/09/21 14:32:04
Done.
| |
961 int start_pos = 0; | 1001 int start_pos = 0; |
962 for (int i = 0; i < n_arguments; i++) { | 1002 for (int i = 0; i < n_arguments; i++) { |
963 JSArray* array = JSArray::cast(args[i]); | 1003 JSArray* array = JSArray::cast(args[i]); |
964 int len = Smi::cast(array->length())->value(); | 1004 int len = Smi::cast(array->length())->value(); |
965 if (len > 0) { | 1005 if (len > 0) { |
966 FixedArray* elms = FixedArray::cast(array->elements()); | 1006 FixedArray* elms = FixedArray::cast(array->elements()); |
967 CopyElements(heap, &no_gc, result_elms, start_pos, elms, 0, len); | 1007 CopyElements(heap, &no_gc, result_elms, start_pos, elms, 0, len); |
968 start_pos += len; | 1008 start_pos += len; |
969 } | 1009 } |
970 } | 1010 } |
971 ASSERT(start_pos == result_len); | 1011 ASSERT(start_pos == result_len); |
972 | 1012 |
973 // Set the length and elements. | 1013 // Set the length and elements. |
1014 MaybeObject* maybe_object = | |
1015 result_array->EnsureCanContainElements(result_elms); | |
1016 if (maybe_object->IsFailure()) return maybe_object; | |
974 result_array->set_length(Smi::FromInt(result_len)); | 1017 result_array->set_length(Smi::FromInt(result_len)); |
975 result_array->set_elements(result_elms); | 1018 result_array->set_elements(result_elms); |
976 | 1019 |
977 return result_array; | 1020 return result_array; |
978 } | 1021 } |
979 | 1022 |
980 | 1023 |
981 // ----------------------------------------------------------------------------- | 1024 // ----------------------------------------------------------------------------- |
982 // Strict mode poison pills | 1025 // Strict mode poison pills |
983 | 1026 |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1704 return Handle<Code>(code_address); \ | 1747 return Handle<Code>(code_address); \ |
1705 } | 1748 } |
1706 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1749 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
1707 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1750 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
1708 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1751 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
1709 #undef DEFINE_BUILTIN_ACCESSOR_C | 1752 #undef DEFINE_BUILTIN_ACCESSOR_C |
1710 #undef DEFINE_BUILTIN_ACCESSOR_A | 1753 #undef DEFINE_BUILTIN_ACCESSOR_A |
1711 | 1754 |
1712 | 1755 |
1713 } } // namespace v8::internal | 1756 } } // namespace v8::internal |
OLD | NEW |