| 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_ARM | 5 #if V8_TARGET_ARCH_ARM |
| 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 3044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3055 if (function_mode() == JS_FUNCTION_STUB_MODE) { | 3055 if (function_mode() == JS_FUNCTION_STUB_MODE) { |
| 3056 __ add(r1, r1, Operand(1)); | 3056 __ add(r1, r1, Operand(1)); |
| 3057 } | 3057 } |
| 3058 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 3058 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 3059 __ mov(r1, Operand(r1, LSL, kPointerSizeLog2)); | 3059 __ mov(r1, Operand(r1, LSL, kPointerSizeLog2)); |
| 3060 __ add(sp, sp, r1); | 3060 __ add(sp, sp, r1); |
| 3061 __ Ret(); | 3061 __ Ret(); |
| 3062 } | 3062 } |
| 3063 | 3063 |
| 3064 | 3064 |
| 3065 void LoadICTrampolineStub::Generate(MacroAssembler* masm) { | |
| 3066 __ EmitLoadTypeFeedbackVector(LoadWithVectorDescriptor::VectorRegister()); | |
| 3067 LoadICStub stub(isolate()); | |
| 3068 stub.GenerateForTrampoline(masm); | |
| 3069 } | |
| 3070 | |
| 3071 | |
| 3072 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { | 3065 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { |
| 3073 __ EmitLoadTypeFeedbackVector(LoadWithVectorDescriptor::VectorRegister()); | 3066 __ EmitLoadTypeFeedbackVector(LoadWithVectorDescriptor::VectorRegister()); |
| 3074 KeyedLoadICStub stub(isolate()); | 3067 KeyedLoadICStub stub(isolate()); |
| 3075 stub.GenerateForTrampoline(masm); | 3068 stub.GenerateForTrampoline(masm); |
| 3076 } | 3069 } |
| 3077 | 3070 |
| 3078 | 3071 |
| 3079 void CallICTrampolineStub::Generate(MacroAssembler* masm) { | 3072 void CallICTrampolineStub::Generate(MacroAssembler* masm) { |
| 3080 __ EmitLoadTypeFeedbackVector(r2); | 3073 __ EmitLoadTypeFeedbackVector(r2); |
| 3081 CallICStub stub(isolate(), state()); | 3074 CallICStub stub(isolate(), state()); |
| 3082 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 3075 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 3083 } | 3076 } |
| 3084 | 3077 |
| 3085 | 3078 |
| 3086 void LoadICStub::Generate(MacroAssembler* masm) { GenerateImpl(masm, false); } | |
| 3087 | |
| 3088 | |
| 3089 void LoadICStub::GenerateForTrampoline(MacroAssembler* masm) { | |
| 3090 GenerateImpl(masm, true); | |
| 3091 } | |
| 3092 | |
| 3093 | |
| 3094 static void HandleArrayCases(MacroAssembler* masm, Register feedback, | 3079 static void HandleArrayCases(MacroAssembler* masm, Register feedback, |
| 3095 Register receiver_map, Register scratch1, | 3080 Register receiver_map, Register scratch1, |
| 3096 Register scratch2, bool is_polymorphic, | 3081 Register scratch2, bool is_polymorphic, |
| 3097 Label* miss) { | 3082 Label* miss) { |
| 3098 // feedback initially contains the feedback array | 3083 // feedback initially contains the feedback array |
| 3099 Label next_loop, prepare_next; | 3084 Label next_loop, prepare_next; |
| 3100 Label start_polymorphic; | 3085 Label start_polymorphic; |
| 3101 | 3086 |
| 3102 Register cached_map = scratch1; | 3087 Register cached_map = scratch1; |
| 3103 | 3088 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3172 __ cmp(cached_map, receiver_map); | 3157 __ cmp(cached_map, receiver_map); |
| 3173 __ b(ne, try_array); | 3158 __ b(ne, try_array); |
| 3174 Register handler = feedback; | 3159 Register handler = feedback; |
| 3175 __ add(handler, vector, Operand::PointerOffsetFromSmiKey(slot)); | 3160 __ add(handler, vector, Operand::PointerOffsetFromSmiKey(slot)); |
| 3176 __ ldr(handler, | 3161 __ ldr(handler, |
| 3177 FieldMemOperand(handler, FixedArray::kHeaderSize + kPointerSize)); | 3162 FieldMemOperand(handler, FixedArray::kHeaderSize + kPointerSize)); |
| 3178 __ add(pc, handler, Operand(Code::kHeaderSize - kHeapObjectTag)); | 3163 __ add(pc, handler, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 3179 } | 3164 } |
| 3180 | 3165 |
| 3181 | 3166 |
| 3182 void LoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | |
| 3183 Register receiver = LoadWithVectorDescriptor::ReceiverRegister(); // r1 | |
| 3184 Register name = LoadWithVectorDescriptor::NameRegister(); // r2 | |
| 3185 Register vector = LoadWithVectorDescriptor::VectorRegister(); // r3 | |
| 3186 Register slot = LoadWithVectorDescriptor::SlotRegister(); // r0 | |
| 3187 Register feedback = r4; | |
| 3188 Register receiver_map = r5; | |
| 3189 Register scratch1 = r6; | |
| 3190 | |
| 3191 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot)); | |
| 3192 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); | |
| 3193 | |
| 3194 // Try to quickly handle the monomorphic case without knowing for sure | |
| 3195 // if we have a weak cell in feedback. We do know it's safe to look | |
| 3196 // at WeakCell::kValueOffset. | |
| 3197 Label try_array, load_smi_map, compare_map; | |
| 3198 Label not_array, miss; | |
| 3199 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, slot, | |
| 3200 scratch1, &compare_map, &load_smi_map, &try_array); | |
| 3201 | |
| 3202 // Is it a fixed array? | |
| 3203 __ bind(&try_array); | |
| 3204 __ ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset)); | |
| 3205 __ CompareRoot(scratch1, Heap::kFixedArrayMapRootIndex); | |
| 3206 __ b(ne, ¬_array); | |
| 3207 HandleArrayCases(masm, feedback, receiver_map, scratch1, r9, true, &miss); | |
| 3208 | |
| 3209 __ bind(¬_array); | |
| 3210 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); | |
| 3211 __ b(ne, &miss); | |
| 3212 masm->isolate()->load_stub_cache()->GenerateProbe( | |
| 3213 masm, receiver, name, feedback, receiver_map, scratch1, r9); | |
| 3214 | |
| 3215 __ bind(&miss); | |
| 3216 LoadIC::GenerateMiss(masm); | |
| 3217 | |
| 3218 __ bind(&load_smi_map); | |
| 3219 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); | |
| 3220 __ jmp(&compare_map); | |
| 3221 } | |
| 3222 | |
| 3223 | |
| 3224 void KeyedLoadICStub::Generate(MacroAssembler* masm) { | 3167 void KeyedLoadICStub::Generate(MacroAssembler* masm) { |
| 3225 GenerateImpl(masm, false); | 3168 GenerateImpl(masm, false); |
| 3226 } | 3169 } |
| 3227 | 3170 |
| 3228 | 3171 |
| 3229 void KeyedLoadICStub::GenerateForTrampoline(MacroAssembler* masm) { | 3172 void KeyedLoadICStub::GenerateForTrampoline(MacroAssembler* masm) { |
| 3230 GenerateImpl(masm, true); | 3173 GenerateImpl(masm, true); |
| 3231 } | 3174 } |
| 3232 | 3175 |
| 3233 | 3176 |
| (...skipping 1679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4913 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 4856 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |
| 4914 kStackUnwindSpace, NULL, return_value_operand, NULL); | 4857 kStackUnwindSpace, NULL, return_value_operand, NULL); |
| 4915 } | 4858 } |
| 4916 | 4859 |
| 4917 #undef __ | 4860 #undef __ |
| 4918 | 4861 |
| 4919 } // namespace internal | 4862 } // namespace internal |
| 4920 } // namespace v8 | 4863 } // namespace v8 |
| 4921 | 4864 |
| 4922 #endif // V8_TARGET_ARCH_ARM | 4865 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |