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 2865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2876 // -- eax : value | 2876 // -- eax : value |
2877 // -- ecx : key | 2877 // -- ecx : key |
2878 // -- edx : receiver | 2878 // -- edx : receiver |
2879 // -- esp[0] : return address | 2879 // -- esp[0] : return address |
2880 // ----------------------------------- | 2880 // ----------------------------------- |
2881 ElementsKind elements_kind = receiver_map->elements_kind(); | 2881 ElementsKind elements_kind = receiver_map->elements_kind(); |
2882 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; | 2882 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; |
2883 Handle<Code> stub = | 2883 Handle<Code> stub = |
2884 KeyedStoreElementStub(is_jsarray, | 2884 KeyedStoreElementStub(is_jsarray, |
2885 elements_kind, | 2885 elements_kind, |
2886 grow_mode_).GetCode(isolate()); | 2886 store_mode_).GetCode(isolate()); |
2887 | 2887 |
2888 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); | 2888 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); |
2889 | 2889 |
2890 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2890 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
2891 __ jmp(ic, RelocInfo::CODE_TARGET); | 2891 __ jmp(ic, RelocInfo::CODE_TARGET); |
2892 | 2892 |
2893 // Return the generated code. | 2893 // Return the generated code. |
2894 return GetCode(Code::NORMAL, factory()->empty_string()); | 2894 return GetCode(Code::NORMAL, factory()->empty_string()); |
2895 } | 2895 } |
2896 | 2896 |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3531 Handle<Code> miss_ic = | 3531 Handle<Code> miss_ic = |
3532 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3532 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
3533 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3533 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
3534 } | 3534 } |
3535 | 3535 |
3536 | 3536 |
3537 void KeyedStoreStubCompiler::GenerateStoreFastElement( | 3537 void KeyedStoreStubCompiler::GenerateStoreFastElement( |
3538 MacroAssembler* masm, | 3538 MacroAssembler* masm, |
3539 bool is_js_array, | 3539 bool is_js_array, |
3540 ElementsKind elements_kind, | 3540 ElementsKind elements_kind, |
3541 KeyedAccessGrowMode grow_mode) { | 3541 KeyedAccessStoreMode store_mode) { |
3542 // ----------- S t a t e ------------- | 3542 // ----------- S t a t e ------------- |
3543 // -- eax : value | 3543 // -- eax : value |
3544 // -- ecx : key | 3544 // -- ecx : key |
3545 // -- edx : receiver | 3545 // -- edx : receiver |
3546 // -- esp[0] : return address | 3546 // -- esp[0] : return address |
3547 // ----------------------------------- | 3547 // ----------------------------------- |
3548 Label miss_force_generic, grow, slow, transition_elements_kind; | 3548 Label miss_force_generic, grow, slow, transition_elements_kind; |
3549 Label check_capacity, prepare_slow, finish_store, commit_backing_store; | 3549 Label check_capacity, prepare_slow, finish_store, commit_backing_store; |
3550 | 3550 |
3551 // This stub is meant to be tail-jumped to, the receiver must already | 3551 // This stub is meant to be tail-jumped to, the receiver must already |
3552 // have been verified by the caller to not be a smi. | 3552 // have been verified by the caller to not be a smi. |
3553 | 3553 |
3554 // Check that the key is a smi or a heap number convertible to a smi. | 3554 // Check that the key is a smi or a heap number convertible to a smi. |
3555 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic); | 3555 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic); |
3556 | 3556 |
3557 if (IsFastSmiElementsKind(elements_kind)) { | 3557 if (IsFastSmiElementsKind(elements_kind)) { |
3558 __ JumpIfNotSmi(eax, &transition_elements_kind); | 3558 __ JumpIfNotSmi(eax, &transition_elements_kind); |
3559 } | 3559 } |
3560 | 3560 |
3561 // Get the elements array and make sure it is a fast element array, not 'cow'. | 3561 // Get the elements array and make sure it is a fast element array, not 'cow'. |
3562 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 3562 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
3563 if (is_js_array) { | 3563 if (is_js_array) { |
3564 // Check that the key is within bounds. | 3564 // Check that the key is within bounds. |
3565 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. | 3565 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. |
3566 if (grow_mode == ALLOW_JSARRAY_GROWTH) { | 3566 if (IsGrowStoreMode(store_mode)) { |
3567 __ j(above_equal, &grow); | 3567 __ j(above_equal, &grow); |
3568 } else { | 3568 } else { |
3569 __ j(above_equal, &miss_force_generic); | 3569 __ j(above_equal, &miss_force_generic); |
3570 } | 3570 } |
3571 } else { | 3571 } else { |
3572 // Check that the key is within bounds. | 3572 // Check that the key is within bounds. |
3573 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. | 3573 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. |
3574 __ j(above_equal, &miss_force_generic); | 3574 __ j(above_equal, &miss_force_generic); |
3575 } | 3575 } |
3576 | 3576 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3608 __ bind(&miss_force_generic); | 3608 __ bind(&miss_force_generic); |
3609 Handle<Code> ic_force_generic = | 3609 Handle<Code> ic_force_generic = |
3610 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3610 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
3611 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 3611 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
3612 | 3612 |
3613 // Handle transition to other elements kinds without using the generic stub. | 3613 // Handle transition to other elements kinds without using the generic stub. |
3614 __ bind(&transition_elements_kind); | 3614 __ bind(&transition_elements_kind); |
3615 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 3615 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
3616 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 3616 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
3617 | 3617 |
3618 if (is_js_array && grow_mode == ALLOW_JSARRAY_GROWTH) { | 3618 if (is_js_array && IsGrowStoreMode(store_mode)) { |
3619 // Handle transition requiring the array to grow. | 3619 // Handle transition requiring the array to grow. |
3620 __ bind(&grow); | 3620 __ bind(&grow); |
3621 | 3621 |
3622 // Make sure the array is only growing by a single element, anything else | 3622 // Make sure the array is only growing by a single element, anything else |
3623 // must be handled by the runtime. Flags are already set by previous | 3623 // must be handled by the runtime. Flags are already set by previous |
3624 // compare. | 3624 // compare. |
3625 __ j(not_equal, &miss_force_generic); | 3625 __ j(not_equal, &miss_force_generic); |
3626 | 3626 |
3627 // Check for the empty array, and preallocate a small backing store if | 3627 // Check for the empty array, and preallocate a small backing store if |
3628 // possible. | 3628 // possible. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3686 __ bind(&slow); | 3686 __ bind(&slow); |
3687 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); | 3687 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); |
3688 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3688 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
3689 } | 3689 } |
3690 } | 3690 } |
3691 | 3691 |
3692 | 3692 |
3693 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( | 3693 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( |
3694 MacroAssembler* masm, | 3694 MacroAssembler* masm, |
3695 bool is_js_array, | 3695 bool is_js_array, |
3696 KeyedAccessGrowMode grow_mode) { | 3696 KeyedAccessStoreMode store_mode) { |
3697 // ----------- S t a t e ------------- | 3697 // ----------- S t a t e ------------- |
3698 // -- eax : value | 3698 // -- eax : value |
3699 // -- ecx : key | 3699 // -- ecx : key |
3700 // -- edx : receiver | 3700 // -- edx : receiver |
3701 // -- esp[0] : return address | 3701 // -- esp[0] : return address |
3702 // ----------------------------------- | 3702 // ----------------------------------- |
3703 Label miss_force_generic, transition_elements_kind, grow, slow; | 3703 Label miss_force_generic, transition_elements_kind, grow, slow; |
3704 Label check_capacity, prepare_slow, finish_store, commit_backing_store; | 3704 Label check_capacity, prepare_slow, finish_store, commit_backing_store; |
3705 | 3705 |
3706 // This stub is meant to be tail-jumped to, the receiver must already | 3706 // This stub is meant to be tail-jumped to, the receiver must already |
3707 // have been verified by the caller to not be a smi. | 3707 // have been verified by the caller to not be a smi. |
3708 | 3708 |
3709 // Check that the key is a smi or a heap number convertible to a smi. | 3709 // Check that the key is a smi or a heap number convertible to a smi. |
3710 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic); | 3710 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic); |
3711 | 3711 |
3712 // Get the elements array. | 3712 // Get the elements array. |
3713 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 3713 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
3714 __ AssertFastElements(edi); | 3714 __ AssertFastElements(edi); |
3715 | 3715 |
3716 if (is_js_array) { | 3716 if (is_js_array) { |
3717 // Check that the key is within bounds. | 3717 // Check that the key is within bounds. |
3718 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. | 3718 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. |
3719 if (grow_mode == ALLOW_JSARRAY_GROWTH) { | 3719 if (IsGrowStoreMode(store_mode)) { |
3720 __ j(above_equal, &grow); | 3720 __ j(above_equal, &grow); |
3721 } else { | 3721 } else { |
3722 __ j(above_equal, &miss_force_generic); | 3722 __ j(above_equal, &miss_force_generic); |
3723 } | 3723 } |
3724 } else { | 3724 } else { |
3725 // Check that the key is within bounds. | 3725 // Check that the key is within bounds. |
3726 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. | 3726 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. |
3727 __ j(above_equal, &miss_force_generic); | 3727 __ j(above_equal, &miss_force_generic); |
3728 } | 3728 } |
3729 | 3729 |
3730 __ bind(&finish_store); | 3730 __ bind(&finish_store); |
3731 __ StoreNumberToDoubleElements(eax, edi, ecx, edx, xmm0, | 3731 __ StoreNumberToDoubleElements(eax, edi, ecx, edx, xmm0, |
3732 &transition_elements_kind, true); | 3732 &transition_elements_kind, true); |
3733 __ ret(0); | 3733 __ ret(0); |
3734 | 3734 |
3735 // Handle store cache miss, replacing the ic with the generic stub. | 3735 // Handle store cache miss, replacing the ic with the generic stub. |
3736 __ bind(&miss_force_generic); | 3736 __ bind(&miss_force_generic); |
3737 Handle<Code> ic_force_generic = | 3737 Handle<Code> ic_force_generic = |
3738 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3738 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
3739 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 3739 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
3740 | 3740 |
3741 // Handle transition to other elements kinds without using the generic stub. | 3741 // Handle transition to other elements kinds without using the generic stub. |
3742 __ bind(&transition_elements_kind); | 3742 __ bind(&transition_elements_kind); |
3743 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 3743 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
3744 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 3744 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
3745 | 3745 |
3746 if (is_js_array && grow_mode == ALLOW_JSARRAY_GROWTH) { | 3746 if (is_js_array && IsGrowStoreMode(store_mode)) { |
3747 // Handle transition requiring the array to grow. | 3747 // Handle transition requiring the array to grow. |
3748 __ bind(&grow); | 3748 __ bind(&grow); |
3749 | 3749 |
3750 // Make sure the array is only growing by a single element, anything else | 3750 // Make sure the array is only growing by a single element, anything else |
3751 // must be handled by the runtime. Flags are already set by previous | 3751 // must be handled by the runtime. Flags are already set by previous |
3752 // compare. | 3752 // compare. |
3753 __ j(not_equal, &miss_force_generic); | 3753 __ j(not_equal, &miss_force_generic); |
3754 | 3754 |
3755 // Transition on values that can't be stored in a FixedDoubleArray. | 3755 // Transition on values that can't be stored in a FixedDoubleArray. |
3756 Label value_is_smi; | 3756 Label value_is_smi; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3826 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3826 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
3827 } | 3827 } |
3828 } | 3828 } |
3829 | 3829 |
3830 | 3830 |
3831 #undef __ | 3831 #undef __ |
3832 | 3832 |
3833 } } // namespace v8::internal | 3833 } } // namespace v8::internal |
3834 | 3834 |
3835 #endif // V8_TARGET_ARCH_IA32 | 3835 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |