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 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 |