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 |