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 4008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4019 MacroAssembler* masm, | 4019 MacroAssembler* masm, |
4020 bool is_js_array, | 4020 bool is_js_array, |
4021 KeyedAccessGrowMode grow_mode) { | 4021 KeyedAccessGrowMode grow_mode) { |
4022 // ----------- S t a t e ------------- | 4022 // ----------- S t a t e ------------- |
4023 // -- rax : value | 4023 // -- rax : value |
4024 // -- rcx : key | 4024 // -- rcx : key |
4025 // -- rdx : receiver | 4025 // -- rdx : receiver |
4026 // -- rsp[0] : return address | 4026 // -- rsp[0] : return address |
4027 // ----------------------------------- | 4027 // ----------------------------------- |
4028 Label miss_force_generic, transition_elements_kind, finish_store; | 4028 Label miss_force_generic, transition_elements_kind, finish_store; |
4029 Label grow, slow, check_capacity; | 4029 Label grow, slow, check_capacity, restore_key_transition_elements_kind; |
4030 | 4030 |
4031 // This stub is meant to be tail-jumped to, the receiver must already | 4031 // This stub is meant to be tail-jumped to, the receiver must already |
4032 // have been verified by the caller to not be a smi. | 4032 // have been verified by the caller to not be a smi. |
4033 | 4033 |
4034 // Check that the key is a smi or a heap number convertible to a smi. | 4034 // Check that the key is a smi or a heap number convertible to a smi. |
4035 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); | 4035 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); |
4036 | 4036 |
4037 // Get the elements array. | 4037 // Get the elements array. |
4038 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); | 4038 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); |
4039 __ AssertFastElements(rdi); | 4039 __ AssertFastElements(rdi); |
4040 | 4040 |
4041 // Check that the key is within bounds. | 4041 // Check that the key is within bounds. |
4042 if (is_js_array) { | 4042 if (is_js_array) { |
4043 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); | 4043 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); |
4044 if (grow_mode == ALLOW_JSARRAY_GROWTH) { | 4044 if (grow_mode == ALLOW_JSARRAY_GROWTH) { |
4045 __ j(above_equal, &grow); | 4045 __ j(above_equal, &grow); |
4046 } else { | 4046 } else { |
4047 __ j(above_equal, &miss_force_generic); | 4047 __ j(above_equal, &miss_force_generic); |
4048 } | 4048 } |
4049 } else { | 4049 } else { |
4050 __ SmiCompare(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset)); | 4050 __ SmiCompare(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset)); |
4051 __ j(above_equal, &miss_force_generic); | 4051 __ j(above_equal, &miss_force_generic); |
4052 } | 4052 } |
4053 | 4053 |
4054 // Handle smi values specially | 4054 // Handle smi values specially |
4055 __ bind(&finish_store); | 4055 __ bind(&finish_store); |
4056 __ SmiToInteger32(rcx, rcx); | 4056 __ SmiToInteger32(rcx, rcx); |
4057 __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0, | 4057 __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0, |
4058 &transition_elements_kind); | 4058 &restore_key_transition_elements_kind); |
4059 __ ret(0); | 4059 __ ret(0); |
4060 | 4060 |
4061 // Handle store cache miss, replacing the ic with the generic stub. | 4061 // Handle store cache miss, replacing the ic with the generic stub. |
4062 __ bind(&miss_force_generic); | 4062 __ bind(&miss_force_generic); |
4063 Handle<Code> ic_force_generic = | 4063 Handle<Code> ic_force_generic = |
4064 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4064 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
4065 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 4065 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
4066 | 4066 |
4067 __ bind(&transition_elements_kind); | 4067 __ bind(&restore_key_transition_elements_kind); |
4068 // Restore smi-tagging of rcx. | 4068 // Restore smi-tagging of rcx. |
4069 __ Integer32ToSmi(rcx, rcx); | 4069 __ Integer32ToSmi(rcx, rcx); |
| 4070 __ bind(&transition_elements_kind); |
4070 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4071 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
4071 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 4072 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
4072 | 4073 |
4073 if (is_js_array && grow_mode == ALLOW_JSARRAY_GROWTH) { | 4074 if (is_js_array && grow_mode == ALLOW_JSARRAY_GROWTH) { |
4074 // Grow the array by a single element if possible. | 4075 // Grow the array by a single element if possible. |
4075 __ bind(&grow); | 4076 __ bind(&grow); |
4076 | 4077 |
4077 // Make sure the array is only growing by a single element, anything else | 4078 // Make sure the array is only growing by a single element, anything else |
4078 // must be handled by the runtime. Flags are already set by previous | 4079 // must be handled by the runtime. Flags are already set by previous |
4079 // compare. | 4080 // compare. |
(...skipping 20 matching lines...) Expand all Loading... |
4100 // rcx: key | 4101 // rcx: key |
4101 // rdx: receiver | 4102 // rdx: receiver |
4102 // rdi: elements | 4103 // rdi: elements |
4103 // Initialize the new FixedDoubleArray. Leave elements unitialized for | 4104 // Initialize the new FixedDoubleArray. Leave elements unitialized for |
4104 // efficiency, they are guaranteed to be initialized before use. | 4105 // efficiency, they are guaranteed to be initialized before use. |
4105 __ Move(FieldOperand(rdi, JSObject::kMapOffset), | 4106 __ Move(FieldOperand(rdi, JSObject::kMapOffset), |
4106 masm->isolate()->factory()->fixed_double_array_map()); | 4107 masm->isolate()->factory()->fixed_double_array_map()); |
4107 __ Move(FieldOperand(rdi, FixedDoubleArray::kLengthOffset), | 4108 __ Move(FieldOperand(rdi, FixedDoubleArray::kLengthOffset), |
4108 Smi::FromInt(JSArray::kPreallocatedArrayElements)); | 4109 Smi::FromInt(JSArray::kPreallocatedArrayElements)); |
4109 | 4110 |
| 4111 __ movq(r8, BitCast<int64_t, uint64_t>(kHoleNanInt64), RelocInfo::NONE); |
| 4112 for (int i = 1; i < JSArray::kPreallocatedArrayElements; i++) { |
| 4113 __ movq(FieldOperand(rdi, FixedDoubleArray::OffsetOfElementAt(i)), r8); |
| 4114 } |
| 4115 |
| 4116 // Increment the length of the array. |
| 4117 __ SmiToInteger32(rcx, rcx); |
| 4118 __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0, |
| 4119 &restore_key_transition_elements_kind); |
| 4120 |
4110 // Install the new backing store in the JSArray. | 4121 // Install the new backing store in the JSArray. |
4111 __ movq(FieldOperand(rdx, JSObject::kElementsOffset), rdi); | 4122 __ movq(FieldOperand(rdx, JSObject::kElementsOffset), rdi); |
4112 __ RecordWriteField(rdx, JSObject::kElementsOffset, rdi, rbx, | 4123 __ RecordWriteField(rdx, JSObject::kElementsOffset, rdi, rbx, |
4113 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 4124 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
4114 | 4125 |
4115 // Increment the length of the array. | 4126 // Increment the length of the array. |
4116 __ Move(FieldOperand(rdx, JSArray::kLengthOffset), Smi::FromInt(1)); | 4127 __ Move(FieldOperand(rdx, JSArray::kLengthOffset), Smi::FromInt(1)); |
4117 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); | 4128 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); |
4118 __ jmp(&finish_store); | 4129 __ ret(0); |
4119 | 4130 |
4120 __ bind(&check_capacity); | 4131 __ bind(&check_capacity); |
4121 // rax: value | 4132 // rax: value |
4122 // rcx: key | 4133 // rcx: key |
4123 // rdx: receiver | 4134 // rdx: receiver |
4124 // rdi: elements | 4135 // rdi: elements |
4125 // Make sure that the backing store can hold additional elements. | 4136 // Make sure that the backing store can hold additional elements. |
4126 __ cmpq(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset)); | 4137 __ cmpq(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset)); |
4127 __ j(above_equal, &slow); | 4138 __ j(above_equal, &slow); |
4128 | 4139 |
4129 // Grow the array and finish the store. | 4140 // Grow the array and finish the store. |
4130 __ SmiAddConstant(FieldOperand(rdx, JSArray::kLengthOffset), | 4141 __ SmiAddConstant(FieldOperand(rdx, JSArray::kLengthOffset), |
4131 Smi::FromInt(1)); | 4142 Smi::FromInt(1)); |
4132 __ jmp(&finish_store); | 4143 __ jmp(&finish_store); |
4133 | 4144 |
4134 __ bind(&slow); | 4145 __ bind(&slow); |
4135 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); | 4146 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); |
4136 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 4147 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
4137 } | 4148 } |
4138 } | 4149 } |
4139 | 4150 |
4140 | 4151 |
4141 #undef __ | 4152 #undef __ |
4142 | 4153 |
4143 } } // namespace v8::internal | 4154 } } // namespace v8::internal |
4144 | 4155 |
4145 #endif // V8_TARGET_ARCH_X64 | 4156 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |