OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 2989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3000 // If the name comparison succeeded, we know we have a fixed array with | 3000 // If the name comparison succeeded, we know we have a fixed array with |
3001 // at least one map/handler pair. | 3001 // at least one map/handler pair. |
3002 __ mov(feedback, FieldOperand(vector, slot, times_half_pointer_size, | 3002 __ mov(feedback, FieldOperand(vector, slot, times_half_pointer_size, |
3003 FixedArray::kHeaderSize + kPointerSize)); | 3003 FixedArray::kHeaderSize + kPointerSize)); |
3004 HandleArrayCases(masm, receiver, key, vector, slot, feedback, false, &miss); | 3004 HandleArrayCases(masm, receiver, key, vector, slot, feedback, false, &miss); |
3005 | 3005 |
3006 __ bind(&miss); | 3006 __ bind(&miss); |
3007 KeyedLoadIC::GenerateMiss(masm); | 3007 KeyedLoadIC::GenerateMiss(masm); |
3008 } | 3008 } |
3009 | 3009 |
3010 void StoreICTrampolineStub::Generate(MacroAssembler* masm) { | |
3011 __ EmitLoadTypeFeedbackVector(StoreWithVectorDescriptor::VectorRegister()); | |
3012 StoreICStub stub(isolate(), state()); | |
3013 stub.GenerateForTrampoline(masm); | |
3014 } | |
3015 | |
3016 void KeyedStoreICTrampolineStub::Generate(MacroAssembler* masm) { | 3010 void KeyedStoreICTrampolineStub::Generate(MacroAssembler* masm) { |
3017 __ EmitLoadTypeFeedbackVector(StoreWithVectorDescriptor::VectorRegister()); | 3011 __ EmitLoadTypeFeedbackVector(StoreWithVectorDescriptor::VectorRegister()); |
3018 KeyedStoreICStub stub(isolate(), state()); | 3012 KeyedStoreICStub stub(isolate(), state()); |
3019 stub.GenerateForTrampoline(masm); | 3013 stub.GenerateForTrampoline(masm); |
3020 } | 3014 } |
3021 | 3015 |
3022 void StoreICStub::Generate(MacroAssembler* masm) { GenerateImpl(masm, false); } | |
3023 | |
3024 void StoreICStub::GenerateForTrampoline(MacroAssembler* masm) { | |
3025 GenerateImpl(masm, true); | |
3026 } | |
3027 | |
3028 | |
3029 // value is on the stack already. | 3016 // value is on the stack already. |
3030 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, | 3017 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, |
3031 Register key, Register vector, | 3018 Register key, Register vector, |
3032 Register slot, Register feedback, | 3019 Register slot, Register feedback, |
3033 bool is_polymorphic, Label* miss) { | 3020 bool is_polymorphic, Label* miss) { |
3034 // feedback initially contains the feedback array | 3021 // feedback initially contains the feedback array |
3035 Label next, next_loop, prepare_next; | 3022 Label next, next_loop, prepare_next; |
3036 Label load_smi_map, compare_map; | 3023 Label load_smi_map, compare_map; |
3037 Label start_polymorphic; | 3024 Label start_polymorphic; |
3038 Label pop_and_miss; | 3025 Label pop_and_miss; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3135 __ bind(&compare_smi_map); | 3122 __ bind(&compare_smi_map); |
3136 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); | 3123 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); |
3137 __ j(not_equal, miss); | 3124 __ j(not_equal, miss); |
3138 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, | 3125 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, |
3139 FixedArray::kHeaderSize + kPointerSize)); | 3126 FixedArray::kHeaderSize + kPointerSize)); |
3140 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); | 3127 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); |
3141 // jump to the handler. | 3128 // jump to the handler. |
3142 __ jmp(weak_cell); | 3129 __ jmp(weak_cell); |
3143 } | 3130 } |
3144 | 3131 |
3145 void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | |
3146 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx | |
3147 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx | |
3148 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax | |
3149 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx | |
3150 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi | |
3151 Label miss; | |
3152 | |
3153 if (StoreWithVectorDescriptor::kPassLastArgsOnStack) { | |
3154 // Current stack layout: | |
3155 // - esp[8] -- value | |
3156 // - esp[4] -- slot | |
3157 // - esp[0] -- return address | |
3158 STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2); | |
3159 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); | |
3160 if (in_frame) { | |
3161 __ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor"); | |
3162 // If the vector is not on the stack, then insert the vector beneath | |
3163 // return address in order to prepare for calling handler with | |
3164 // StoreWithVector calling convention. | |
3165 __ push(Operand(esp, 0)); | |
3166 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister()); | |
3167 __ RecordComment("]"); | |
3168 } else { | |
3169 __ mov(vector, Operand(esp, 1 * kPointerSize)); | |
3170 } | |
3171 __ mov(slot, Operand(esp, 2 * kPointerSize)); | |
3172 } | |
3173 | |
3174 Register scratch = value; | |
3175 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, | |
3176 FixedArray::kHeaderSize)); | |
3177 | |
3178 // Is it a weak cell? | |
3179 Label try_array; | |
3180 Label not_array, smi_key, key_okay; | |
3181 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); | |
3182 __ j(not_equal, &try_array); | |
3183 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss); | |
3184 | |
3185 // Is it a fixed array? | |
3186 __ bind(&try_array); | |
3187 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex); | |
3188 __ j(not_equal, ¬_array); | |
3189 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, true, | |
3190 &miss); | |
3191 | |
3192 __ bind(¬_array); | |
3193 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex); | |
3194 __ j(not_equal, &miss); | |
3195 | |
3196 masm->isolate()->store_stub_cache()->GenerateProbe(masm, receiver, key, slot, | |
3197 no_reg); | |
3198 __ bind(&miss); | |
3199 StoreIC::GenerateMiss(masm); | |
3200 } | |
3201 | |
3202 void KeyedStoreICStub::Generate(MacroAssembler* masm) { | 3132 void KeyedStoreICStub::Generate(MacroAssembler* masm) { |
3203 GenerateImpl(masm, false); | 3133 GenerateImpl(masm, false); |
3204 } | 3134 } |
3205 | 3135 |
3206 void KeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { | 3136 void KeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { |
3207 GenerateImpl(masm, true); | 3137 GenerateImpl(masm, true); |
3208 } | 3138 } |
3209 | 3139 |
3210 | 3140 |
3211 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, | 3141 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, |
(...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4942 kStackUnwindSpace, nullptr, return_value_operand, | 4872 kStackUnwindSpace, nullptr, return_value_operand, |
4943 NULL); | 4873 NULL); |
4944 } | 4874 } |
4945 | 4875 |
4946 #undef __ | 4876 #undef __ |
4947 | 4877 |
4948 } // namespace internal | 4878 } // namespace internal |
4949 } // namespace v8 | 4879 } // namespace v8 |
4950 | 4880 |
4951 #endif // V8_TARGET_ARCH_X87 | 4881 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |