| 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/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 2538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2549 | 2549 |
| 2550 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { | 2550 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { |
| 2551 __ ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 2551 __ ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2552 __ ldr(vector, FieldMemOperand(vector, | 2552 __ ldr(vector, FieldMemOperand(vector, |
| 2553 JSFunction::kSharedFunctionInfoOffset)); | 2553 JSFunction::kSharedFunctionInfoOffset)); |
| 2554 __ ldr(vector, FieldMemOperand(vector, | 2554 __ ldr(vector, FieldMemOperand(vector, |
| 2555 SharedFunctionInfo::kFeedbackVectorOffset)); | 2555 SharedFunctionInfo::kFeedbackVectorOffset)); |
| 2556 } | 2556 } |
| 2557 | 2557 |
| 2558 | 2558 |
| 2559 void CallIC_ArrayStub::Generate(MacroAssembler* masm) { | 2559 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { |
| 2560 // r1 - function | 2560 // r1 - function |
| 2561 // r3 - slot id | 2561 // r3 - slot id |
| 2562 // r2 - vector | 2562 // r2 - vector |
| 2563 Label miss; | 2563 // r4 - allocation site (loaded from vector[slot]) |
| 2564 int argc = arg_count(); | 2564 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r5); |
| 2565 ParameterCount actual(argc); | 2565 __ cmp(r1, r5); |
| 2566 | 2566 __ b(ne, miss); |
| 2567 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); | |
| 2568 __ cmp(r1, r4); | |
| 2569 __ b(ne, &miss); | |
| 2570 | 2567 |
| 2571 __ mov(r0, Operand(arg_count())); | 2568 __ mov(r0, Operand(arg_count())); |
| 2572 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | |
| 2573 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); | |
| 2574 | |
| 2575 // Verify that r4 contains an AllocationSite | |
| 2576 __ ldr(r5, FieldMemOperand(r4, HeapObject::kMapOffset)); | |
| 2577 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); | |
| 2578 __ b(ne, &miss); | |
| 2579 | 2569 |
| 2580 // Increment the call count for monomorphic function calls. | 2570 // Increment the call count for monomorphic function calls. |
| 2581 __ add(r2, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2571 __ add(r2, r2, Operand::PointerOffsetFromSmiKey(r3)); |
| 2582 __ add(r2, r2, Operand(FixedArray::kHeaderSize + kPointerSize)); | 2572 __ add(r2, r2, Operand(FixedArray::kHeaderSize + kPointerSize)); |
| 2583 __ ldr(r3, FieldMemOperand(r2, 0)); | 2573 __ ldr(r3, FieldMemOperand(r2, 0)); |
| 2584 __ add(r3, r3, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 2574 __ add(r3, r3, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
| 2585 __ str(r3, FieldMemOperand(r2, 0)); | 2575 __ str(r3, FieldMemOperand(r2, 0)); |
| 2586 | 2576 |
| 2587 __ mov(r2, r4); | 2577 __ mov(r2, r4); |
| 2588 __ mov(r3, r1); | 2578 __ mov(r3, r1); |
| 2589 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2579 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 2590 __ TailCallStub(&stub); | 2580 __ TailCallStub(&stub); |
| 2591 | |
| 2592 __ bind(&miss); | |
| 2593 GenerateMiss(masm); | |
| 2594 | |
| 2595 // The slow case, we need this no matter what to complete a call after a miss. | |
| 2596 __ mov(r0, Operand(arg_count())); | |
| 2597 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | |
| 2598 } | 2581 } |
| 2599 | 2582 |
| 2600 | 2583 |
| 2601 void CallICStub::Generate(MacroAssembler* masm) { | 2584 void CallICStub::Generate(MacroAssembler* masm) { |
| 2602 // r1 - function | 2585 // r1 - function |
| 2603 // r3 - slot id (Smi) | 2586 // r3 - slot id (Smi) |
| 2604 // r2 - vector | 2587 // r2 - vector |
| 2605 const int with_types_offset = | 2588 const int with_types_offset = |
| 2606 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 2589 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 2607 const int generic_offset = | 2590 const int generic_offset = |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2662 | 2645 |
| 2663 __ bind(&slow); | 2646 __ bind(&slow); |
| 2664 EmitSlowCase(masm, argc); | 2647 EmitSlowCase(masm, argc); |
| 2665 | 2648 |
| 2666 if (CallAsMethod()) { | 2649 if (CallAsMethod()) { |
| 2667 __ bind(&wrap); | 2650 __ bind(&wrap); |
| 2668 EmitWrapCase(masm, argc, &cont); | 2651 EmitWrapCase(masm, argc, &cont); |
| 2669 } | 2652 } |
| 2670 | 2653 |
| 2671 __ bind(&extra_checks_or_miss); | 2654 __ bind(&extra_checks_or_miss); |
| 2672 Label uninitialized, miss; | 2655 Label uninitialized, miss, not_allocation_site; |
| 2673 | 2656 |
| 2674 __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex); | 2657 __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex); |
| 2675 __ b(eq, &slow_start); | 2658 __ b(eq, &slow_start); |
| 2676 | 2659 |
| 2660 // Verify that r4 contains an AllocationSite |
| 2661 __ ldr(r5, FieldMemOperand(r4, HeapObject::kMapOffset)); |
| 2662 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); |
| 2663 __ b(ne, ¬_allocation_site); |
| 2664 |
| 2665 // We have an allocation site. |
| 2666 HandleArrayCase(masm, &miss); |
| 2667 |
| 2668 __ bind(¬_allocation_site); |
| 2669 |
| 2677 // The following cases attempt to handle MISS cases without going to the | 2670 // The following cases attempt to handle MISS cases without going to the |
| 2678 // runtime. | 2671 // runtime. |
| 2679 if (FLAG_trace_ic) { | 2672 if (FLAG_trace_ic) { |
| 2680 __ jmp(&miss); | 2673 __ jmp(&miss); |
| 2681 } | 2674 } |
| 2682 | 2675 |
| 2683 __ CompareRoot(r4, Heap::kuninitialized_symbolRootIndex); | 2676 __ CompareRoot(r4, Heap::kuninitialized_symbolRootIndex); |
| 2684 __ b(eq, &uninitialized); | 2677 __ b(eq, &uninitialized); |
| 2685 | 2678 |
| 2686 // We are going megamorphic. If the feedback is a JSFunction, it is fine | 2679 // We are going megamorphic. If the feedback is a JSFunction, it is fine |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2757 } | 2750 } |
| 2758 | 2751 |
| 2759 | 2752 |
| 2760 void CallICStub::GenerateMiss(MacroAssembler* masm) { | 2753 void CallICStub::GenerateMiss(MacroAssembler* masm) { |
| 2761 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2754 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 2762 | 2755 |
| 2763 // Push the receiver and the function and feedback info. | 2756 // Push the receiver and the function and feedback info. |
| 2764 __ Push(r1, r2, r3); | 2757 __ Push(r1, r2, r3); |
| 2765 | 2758 |
| 2766 // Call the entry. | 2759 // Call the entry. |
| 2767 Runtime::FunctionId id = GetICState() == DEFAULT | 2760 __ CallRuntime(Runtime::kCallIC_Miss, 3); |
| 2768 ? Runtime::kCallIC_Miss | |
| 2769 : Runtime::kCallIC_Customization_Miss; | |
| 2770 __ CallRuntime(id, 3); | |
| 2771 | 2761 |
| 2772 // Move result to edi and exit the internal frame. | 2762 // Move result to edi and exit the internal frame. |
| 2773 __ mov(r1, r0); | 2763 __ mov(r1, r0); |
| 2774 } | 2764 } |
| 2775 | 2765 |
| 2776 | 2766 |
| 2777 // StringCharCodeAtGenerator | 2767 // StringCharCodeAtGenerator |
| 2778 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 2768 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
| 2779 // If the receiver is a smi trigger the non-string case. | 2769 // If the receiver is a smi trigger the non-string case. |
| 2780 if (check_mode_ == RECEIVER_IS_UNKNOWN) { | 2770 if (check_mode_ == RECEIVER_IS_UNKNOWN) { |
| (...skipping 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4269 } | 4259 } |
| 4270 | 4260 |
| 4271 | 4261 |
| 4272 void CallICTrampolineStub::Generate(MacroAssembler* masm) { | 4262 void CallICTrampolineStub::Generate(MacroAssembler* masm) { |
| 4273 EmitLoadTypeFeedbackVector(masm, r2); | 4263 EmitLoadTypeFeedbackVector(masm, r2); |
| 4274 CallICStub stub(isolate(), state()); | 4264 CallICStub stub(isolate(), state()); |
| 4275 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 4265 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 4276 } | 4266 } |
| 4277 | 4267 |
| 4278 | 4268 |
| 4279 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) { | |
| 4280 EmitLoadTypeFeedbackVector(masm, r2); | |
| 4281 CallIC_ArrayStub stub(isolate(), state()); | |
| 4282 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | |
| 4283 } | |
| 4284 | |
| 4285 | |
| 4286 void LoadICStub::Generate(MacroAssembler* masm) { GenerateImpl(masm, false); } | 4269 void LoadICStub::Generate(MacroAssembler* masm) { GenerateImpl(masm, false); } |
| 4287 | 4270 |
| 4288 | 4271 |
| 4289 void LoadICStub::GenerateForTrampoline(MacroAssembler* masm) { | 4272 void LoadICStub::GenerateForTrampoline(MacroAssembler* masm) { |
| 4290 GenerateImpl(masm, true); | 4273 GenerateImpl(masm, true); |
| 4291 } | 4274 } |
| 4292 | 4275 |
| 4293 | 4276 |
| 4294 static void HandleArrayCases(MacroAssembler* masm, Register feedback, | 4277 static void HandleArrayCases(MacroAssembler* masm, Register feedback, |
| 4295 Register receiver_map, Register scratch1, | 4278 Register receiver_map, Register scratch1, |
| (...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5564 MemOperand(fp, 6 * kPointerSize), NULL); | 5547 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5565 } | 5548 } |
| 5566 | 5549 |
| 5567 | 5550 |
| 5568 #undef __ | 5551 #undef __ |
| 5569 | 5552 |
| 5570 } // namespace internal | 5553 } // namespace internal |
| 5571 } // namespace v8 | 5554 } // namespace v8 |
| 5572 | 5555 |
| 5573 #endif // V8_TARGET_ARCH_ARM | 5556 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |