Chromium Code Reviews| 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 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2561 Handle<Map> receiver_map) { | 2561 Handle<Map> receiver_map) { |
| 2562 // ----------- S t a t e ------------- | 2562 // ----------- S t a t e ------------- |
| 2563 // -- eax : value | 2563 // -- eax : value |
| 2564 // -- ecx : key | 2564 // -- ecx : key |
| 2565 // -- edx : receiver | 2565 // -- edx : receiver |
| 2566 // -- esp[0] : return address | 2566 // -- esp[0] : return address |
| 2567 // ----------------------------------- | 2567 // ----------------------------------- |
| 2568 ElementsKind elements_kind = receiver_map->elements_kind(); | 2568 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 2569 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; | 2569 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; |
| 2570 Handle<Code> stub = | 2570 Handle<Code> stub = |
| 2571 KeyedStoreElementStub(is_jsarray, elements_kind).GetCode(); | 2571 KeyedStoreElementStub(is_jsarray, elements_kind, grow_mode_).GetCode(); |
| 2572 | 2572 |
| 2573 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); | 2573 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); |
| 2574 | 2574 |
| 2575 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2575 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| 2576 __ jmp(ic, RelocInfo::CODE_TARGET); | 2576 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2577 | 2577 |
| 2578 // Return the generated code. | 2578 // Return the generated code. |
| 2579 return GetCode(NORMAL, factory()->empty_string()); | 2579 return GetCode(NORMAL, factory()->empty_string()); |
| 2580 } | 2580 } |
| 2581 | 2581 |
| (...skipping 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3688 __ bind(&miss_force_generic); | 3688 __ bind(&miss_force_generic); |
| 3689 Handle<Code> miss_ic = | 3689 Handle<Code> miss_ic = |
| 3690 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | 3690 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
| 3691 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3691 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
| 3692 } | 3692 } |
| 3693 | 3693 |
| 3694 | 3694 |
| 3695 void KeyedStoreStubCompiler::GenerateStoreFastElement( | 3695 void KeyedStoreStubCompiler::GenerateStoreFastElement( |
| 3696 MacroAssembler* masm, | 3696 MacroAssembler* masm, |
| 3697 bool is_js_array, | 3697 bool is_js_array, |
| 3698 ElementsKind elements_kind) { | 3698 ElementsKind elements_kind, |
| 3699 KeyedAccessGrowMode grow_mode) { | |
| 3699 // ----------- S t a t e ------------- | 3700 // ----------- S t a t e ------------- |
| 3700 // -- eax : value | 3701 // -- eax : value |
| 3701 // -- ecx : key | 3702 // -- ecx : key |
| 3702 // -- edx : receiver | 3703 // -- edx : receiver |
| 3703 // -- esp[0] : return address | 3704 // -- esp[0] : return address |
| 3704 // ----------------------------------- | 3705 // ----------------------------------- |
| 3705 Label miss_force_generic, transition_elements_kind; | 3706 Label miss_force_generic, grow, slow, transition_elements_kind; |
| 3707 Label check_capacity, prepare_slow, finish_store, commit_backing_store; | |
| 3706 | 3708 |
| 3707 // This stub is meant to be tail-jumped to, the receiver must already | 3709 // This stub is meant to be tail-jumped to, the receiver must already |
| 3708 // have been verified by the caller to not be a smi. | 3710 // have been verified by the caller to not be a smi. |
| 3709 | 3711 |
| 3710 // Check that the key is a smi. | 3712 // Check that the key is a smi. |
| 3711 __ JumpIfNotSmi(ecx, &miss_force_generic); | 3713 __ JumpIfNotSmi(ecx, &miss_force_generic); |
| 3712 | 3714 |
| 3715 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { | |
| 3716 __ JumpIfNotSmi(eax, &transition_elements_kind); | |
| 3717 } | |
| 3718 | |
| 3713 // Get the elements array and make sure it is a fast element array, not 'cow'. | 3719 // Get the elements array and make sure it is a fast element array, not 'cow'. |
| 3714 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 3720 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
| 3715 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), | |
| 3716 Immediate(masm->isolate()->factory()->fixed_array_map())); | |
| 3717 __ j(not_equal, &miss_force_generic); | |
| 3718 | |
| 3719 if (is_js_array) { | 3721 if (is_js_array) { |
| 3720 // Check that the key is within bounds. | 3722 // Check that the key is within bounds. |
| 3721 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. | 3723 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. |
| 3722 __ j(above_equal, &miss_force_generic); | 3724 if (grow_mode == ALLOW_JSARRAY_GROWTH) { |
| 3725 __ j(above_equal, &grow); | |
| 3726 } else { | |
| 3727 __ j(above_equal, &miss_force_generic); | |
| 3728 } | |
| 3723 } else { | 3729 } else { |
| 3724 // Check that the key is within bounds. | 3730 // Check that the key is within bounds. |
| 3725 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. | 3731 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. |
| 3726 __ j(above_equal, &miss_force_generic); | 3732 __ j(above_equal, &miss_force_generic); |
| 3727 } | 3733 } |
| 3728 | 3734 |
| 3735 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), | |
| 3736 Immediate(masm->isolate()->factory()->fixed_array_map())); | |
| 3737 __ j(not_equal, &miss_force_generic); | |
| 3738 | |
| 3739 __ bind(&finish_store); | |
| 3729 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { | 3740 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
| 3730 __ JumpIfNotSmi(eax, &transition_elements_kind); | |
| 3731 // ecx is a smi, use times_half_pointer_size instead of | 3741 // ecx is a smi, use times_half_pointer_size instead of |
| 3732 // times_pointer_size | 3742 // times_pointer_size |
| 3733 __ mov(FieldOperand(edi, | 3743 __ mov(FieldOperand(edi, |
| 3734 ecx, | 3744 ecx, |
| 3735 times_half_pointer_size, | 3745 times_half_pointer_size, |
| 3736 FixedArray::kHeaderSize), eax); | 3746 FixedArray::kHeaderSize), eax); |
| 3737 } else { | 3747 } else { |
| 3738 ASSERT(elements_kind == FAST_ELEMENTS); | 3748 ASSERT(elements_kind == FAST_ELEMENTS); |
| 3739 // Do the store and update the write barrier. | 3749 // Do the store and update the write barrier. |
| 3740 // ecx is a smi, use times_half_pointer_size instead of | 3750 // ecx is a smi, use times_half_pointer_size instead of |
| 3741 // times_pointer_size | 3751 // times_pointer_size |
| 3742 __ lea(ecx, FieldOperand(edi, | 3752 __ lea(ecx, FieldOperand(edi, |
| 3743 ecx, | 3753 ecx, |
| 3744 times_half_pointer_size, | 3754 times_half_pointer_size, |
| 3745 FixedArray::kHeaderSize)); | 3755 FixedArray::kHeaderSize)); |
| 3746 __ mov(Operand(ecx, 0), eax); | 3756 __ mov(Operand(ecx, 0), eax); |
| 3747 // Make sure to preserve the value in register eax. | 3757 // Make sure to preserve the value in register eax. |
| 3748 __ mov(edx, eax); | 3758 __ mov(ebx, eax); |
| 3749 __ RecordWrite(edi, ecx, edx, kDontSaveFPRegs); | 3759 __ RecordWrite(edi, ecx, ebx, kDontSaveFPRegs); |
| 3750 } | 3760 } |
| 3751 | 3761 |
| 3752 // Done. | 3762 // Done. |
| 3753 __ ret(0); | 3763 __ ret(0); |
| 3754 | 3764 |
| 3755 // Handle store cache miss, replacing the ic with the generic stub. | 3765 // Handle store cache miss, replacing the ic with the generic stub. |
| 3756 __ bind(&miss_force_generic); | 3766 __ bind(&miss_force_generic); |
| 3757 Handle<Code> ic_force_generic = | 3767 Handle<Code> ic_force_generic = |
| 3758 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3768 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| 3759 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 3769 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
| 3760 | 3770 |
| 3761 // Handle transition to other elements kinds without using the generic stub. | 3771 // Handle transition to other elements kinds without using the generic stub. |
| 3762 __ bind(&transition_elements_kind); | 3772 __ bind(&transition_elements_kind); |
| 3763 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 3773 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
| 3764 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 3774 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
| 3775 | |
| 3776 if (is_js_array && grow_mode == ALLOW_JSARRAY_GROWTH) { | |
|
Vyacheslav Egorov (Chromium)
2012/02/09 16:29:19
We might have setters on the prototype:
function
danno
2012/02/10 12:25:34
It turns out the existing elements ICs are very br
| |
| 3777 // Handle transition requiring the array to grow. | |
| 3778 __ bind(&grow); | |
| 3779 | |
| 3780 // Make sure the array is only growing by a single element, anything else | |
| 3781 // must be handled by the runtime. Flags are already set by previous | |
| 3782 // compare. | |
| 3783 __ j(not_equal, &miss_force_generic); | |
| 3784 | |
| 3785 // Check for the empty array, and preallocate a small backing store if | |
| 3786 // possible. | |
| 3787 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | |
| 3788 __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array())); | |
| 3789 __ j(not_equal, &check_capacity); | |
| 3790 | |
| 3791 int size = FixedArray::SizeFor(JSArray::kPreallocatedArrayElements); | |
| 3792 __ AllocateInNewSpace(size, | |
| 3793 edi, | |
| 3794 ebx, | |
| 3795 ecx, | |
| 3796 &prepare_slow, | |
| 3797 TAG_OBJECT); | |
| 3798 // Restore the key, which is known to be the array length. | |
| 3799 | |
| 3800 // eax: value | |
| 3801 // ecx: key | |
| 3802 // edx: receiver | |
| 3803 // edi: elements | |
| 3804 // Make sure that the backing store can hold additional elements. | |
| 3805 __ mov(FieldOperand(edi, JSObject::kMapOffset), | |
| 3806 Immediate(masm->isolate()->factory()->fixed_array_map())); | |
| 3807 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), | |
| 3808 Immediate(Smi::FromInt(JSArray::kPreallocatedArrayElements))); | |
| 3809 __ mov(ebx, Immediate(masm->isolate()->factory()->the_hole_value())); | |
| 3810 for (int i = 1; i < JSArray::kPreallocatedArrayElements; ++i) { | |
| 3811 __ mov(FieldOperand(edi, FixedArray::SizeFor(i)), ebx); | |
| 3812 } | |
| 3813 | |
| 3814 // Store the element at index zero. | |
| 3815 __ mov(FieldOperand(edi, FixedArray::SizeFor(0)), eax); | |
| 3816 | |
| 3817 // Install the new backing store in the JSArray. | |
| 3818 __ mov(FieldOperand(edx, JSObject::kElementsOffset), edi); | |
| 3819 __ RecordWriteField(edx, JSObject::kElementsOffset, edi, ebx, | |
| 3820 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
| 3821 | |
| 3822 // Increment the length of the array. | |
| 3823 __ add(FieldOperand(edx, JSArray::kLengthOffset), | |
|
Vyacheslav Egorov (Chromium)
2012/02/09 16:29:19
can be actually move of smi 1 instead of addition
danno
2012/02/10 12:25:34
Done.
| |
| 3824 Immediate(Smi::FromInt(1))); | |
| 3825 __ ret(0); | |
| 3826 | |
| 3827 __ bind(&check_capacity); | |
| 3828 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), | |
| 3829 Immediate(masm->isolate()->factory()->fixed_cow_array_map())); | |
| 3830 __ j(equal, &miss_force_generic); | |
| 3831 | |
| 3832 // eax: value | |
| 3833 // ecx: key | |
| 3834 // edx: receiver | |
| 3835 // edi: elements | |
| 3836 // Make sure that the backing store can hold additional elements. | |
| 3837 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); | |
| 3838 __ j(above_equal, &slow); | |
| 3839 | |
| 3840 // Grow the array and finish the store. | |
| 3841 __ add(FieldOperand(edx, JSArray::kLengthOffset), | |
| 3842 Immediate(Smi::FromInt(1))); | |
| 3843 __ jmp(&finish_store); | |
| 3844 | |
| 3845 __ bind(&prepare_slow); | |
| 3846 // Restore the key, which is known to be the array length. | |
| 3847 __ mov(ecx, Immediate(0)); | |
| 3848 | |
| 3849 __ bind(&slow); | |
| 3850 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); | |
| 3851 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | |
| 3852 } | |
| 3765 } | 3853 } |
| 3766 | 3854 |
| 3767 | 3855 |
| 3768 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( | 3856 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( |
| 3769 MacroAssembler* masm, | 3857 MacroAssembler* masm, |
| 3770 bool is_js_array) { | 3858 bool is_js_array, |
| 3859 KeyedAccessGrowMode grow_mode) { | |
| 3771 // ----------- S t a t e ------------- | 3860 // ----------- S t a t e ------------- |
| 3772 // -- eax : value | 3861 // -- eax : value |
| 3773 // -- ecx : key | 3862 // -- ecx : key |
| 3774 // -- edx : receiver | 3863 // -- edx : receiver |
| 3775 // -- esp[0] : return address | 3864 // -- esp[0] : return address |
| 3776 // ----------------------------------- | 3865 // ----------------------------------- |
| 3777 Label miss_force_generic, transition_elements_kind; | 3866 Label miss_force_generic, transition_elements_kind, grow, slow; |
| 3867 Label check_capacity, prepare_slow, finish_store, commit_backing_store; | |
| 3778 | 3868 |
| 3779 // This stub is meant to be tail-jumped to, the receiver must already | 3869 // This stub is meant to be tail-jumped to, the receiver must already |
| 3780 // have been verified by the caller to not be a smi. | 3870 // have been verified by the caller to not be a smi. |
| 3781 | 3871 |
| 3782 // Check that the key is a smi. | 3872 // Check that the key is a smi. |
| 3783 __ JumpIfNotSmi(ecx, &miss_force_generic); | 3873 __ JumpIfNotSmi(ecx, &miss_force_generic); |
| 3784 | 3874 |
| 3785 // Get the elements array. | 3875 // Get the elements array. |
| 3786 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 3876 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
| 3787 __ AssertFastElements(edi); | 3877 __ AssertFastElements(edi); |
| 3788 | 3878 |
| 3789 if (is_js_array) { | 3879 if (is_js_array) { |
| 3790 // Check that the key is within bounds. | 3880 // Check that the key is within bounds. |
| 3791 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. | 3881 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. |
| 3882 if (grow_mode == ALLOW_JSARRAY_GROWTH) { | |
| 3883 __ j(above_equal, &grow); | |
| 3884 } else { | |
| 3885 __ j(above_equal, &miss_force_generic); | |
| 3886 } | |
| 3792 } else { | 3887 } else { |
| 3793 // Check that the key is within bounds. | 3888 // Check that the key is within bounds. |
| 3794 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. | 3889 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. |
| 3795 } | 3890 } |
| 3796 __ j(above_equal, &miss_force_generic); | |
| 3797 | 3891 |
| 3892 __ bind(&finish_store); | |
| 3798 __ StoreNumberToDoubleElements(eax, | 3893 __ StoreNumberToDoubleElements(eax, |
| 3799 edi, | 3894 edi, |
| 3800 ecx, | 3895 ecx, |
| 3801 edx, | 3896 edx, |
| 3802 xmm0, | 3897 xmm0, |
| 3803 &transition_elements_kind, | 3898 &transition_elements_kind, |
| 3804 true); | 3899 true); |
| 3805 __ ret(0); | 3900 __ ret(0); |
| 3806 | 3901 |
| 3807 // Handle store cache miss, replacing the ic with the generic stub. | 3902 // Handle store cache miss, replacing the ic with the generic stub. |
| 3808 __ bind(&miss_force_generic); | 3903 __ bind(&miss_force_generic); |
| 3809 Handle<Code> ic_force_generic = | 3904 Handle<Code> ic_force_generic = |
| 3810 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3905 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| 3811 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 3906 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
| 3812 | 3907 |
| 3813 // Handle transition to other elements kinds without using the generic stub. | 3908 // Handle transition to other elements kinds without using the generic stub. |
| 3814 __ bind(&transition_elements_kind); | 3909 __ bind(&transition_elements_kind); |
| 3815 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 3910 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
| 3816 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 3911 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
| 3912 | |
| 3913 if (is_js_array && grow_mode == ALLOW_JSARRAY_GROWTH) { | |
| 3914 // Handle transition requiring the array to grow. | |
| 3915 __ bind(&grow); | |
| 3916 | |
| 3917 // Make sure the array is only growing by a single element, anything else | |
| 3918 // must be handled by the runtime. Flags are already set by previous | |
| 3919 // compare. | |
| 3920 __ j(not_equal, &miss_force_generic); | |
| 3921 | |
| 3922 // Transition on values that can't be stored in a FixedDoubleArray. | |
| 3923 Label value_is_smi; | |
| 3924 __ JumpIfSmi(eax, &value_is_smi); | |
| 3925 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), | |
| 3926 Immediate(Handle<Map>(masm->isolate()->heap()->heap_number_map()))); | |
| 3927 __ j(not_equal, &transition_elements_kind); | |
| 3928 __ bind(&value_is_smi); | |
| 3929 | |
| 3930 // Check for the empty array, and preallocate a small backing store if | |
| 3931 // possible. | |
| 3932 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | |
| 3933 __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array())); | |
| 3934 __ j(not_equal, &check_capacity); | |
| 3935 | |
| 3936 int size = FixedDoubleArray::SizeFor(JSArray::kPreallocatedArrayElements); | |
| 3937 __ AllocateInNewSpace(size, | |
| 3938 edi, | |
| 3939 ebx, | |
| 3940 ecx, | |
| 3941 &prepare_slow, | |
| 3942 TAG_OBJECT); | |
| 3943 // Restore the key, which is known to be the array length. | |
| 3944 __ mov(ecx, Immediate(0)); | |
| 3945 | |
| 3946 // eax: value | |
| 3947 // ecx: key | |
| 3948 // edx: receiver | |
| 3949 // edi: elements | |
| 3950 // Make sure that the backing store can hold additional elements. | |
| 3951 __ mov(FieldOperand(edi, JSObject::kMapOffset), | |
| 3952 Immediate(masm->isolate()->factory()->fixed_double_array_map())); | |
| 3953 __ mov(FieldOperand(edi, FixedDoubleArray::kLengthOffset), | |
| 3954 Immediate(Smi::FromInt(JSArray::kPreallocatedArrayElements))); | |
| 3955 | |
| 3956 // Install the new backing store in the JSArray. | |
| 3957 __ mov(FieldOperand(edx, JSObject::kElementsOffset), edi); | |
|
Vyacheslav Egorov (Chromium)
2012/02/10 00:19:18
elements of the backing store are completely unini
danno
2012/02/10 12:25:34
Done.
| |
| 3958 __ RecordWriteField(edx, JSObject::kElementsOffset, edi, ebx, | |
| 3959 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
| 3960 | |
| 3961 // Increment the length of the array. | |
| 3962 __ add(FieldOperand(edx, JSArray::kLengthOffset), | |
| 3963 Immediate(Smi::FromInt(1))); | |
| 3964 __ jmp(&finish_store); | |
| 3965 | |
| 3966 __ bind(&check_capacity); | |
| 3967 // eax: value | |
| 3968 // ecx: key | |
| 3969 // edx: receiver | |
| 3970 // edi: elements | |
| 3971 // Make sure that the backing store can hold additional elements. | |
| 3972 __ cmp(ecx, FieldOperand(edi, FixedDoubleArray::kLengthOffset)); | |
| 3973 __ j(above_equal, &slow); | |
| 3974 | |
| 3975 // Grow the array and finish the store. | |
| 3976 __ add(FieldOperand(edx, JSArray::kLengthOffset), | |
| 3977 Immediate(Smi::FromInt(1))); | |
| 3978 __ jmp(&finish_store); | |
| 3979 | |
| 3980 __ bind(&prepare_slow); | |
| 3981 // Restore the key, which is known to be the array length. | |
| 3982 __ mov(ecx, Immediate(0)); | |
| 3983 | |
| 3984 __ bind(&slow); | |
| 3985 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); | |
| 3986 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | |
| 3987 } | |
| 3817 } | 3988 } |
| 3818 | 3989 |
| 3819 | 3990 |
| 3820 #undef __ | 3991 #undef __ |
| 3821 | 3992 |
| 3822 } } // namespace v8::internal | 3993 } } // namespace v8::internal |
| 3823 | 3994 |
| 3824 #endif // V8_TARGET_ARCH_IA32 | 3995 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |