OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 | 770 |
771 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 771 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
772 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 772 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
773 isolate(), deoptimization_id, Deoptimizer::LAZY); | 773 isolate(), deoptimization_id, Deoptimizer::LAZY); |
774 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 774 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
775 } | 775 } |
776 | 776 |
777 | 777 |
778 void CodeGenerator::AssemblePrologue() { | 778 void CodeGenerator::AssemblePrologue() { |
779 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 779 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 780 int stack_slots = frame()->GetSpillSlotCount(); |
780 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 781 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
781 bool saved_pp; | 782 bool saved_pp; |
782 if (FLAG_enable_ool_constant_pool) { | 783 if (FLAG_enable_ool_constant_pool) { |
783 __ Push(lr, fp, pp); | 784 __ Push(lr, fp, pp); |
784 // Adjust FP to point to saved FP. | 785 // Adjust FP to point to saved FP. |
785 __ sub(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); | 786 __ sub(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); |
786 saved_pp = true; | 787 saved_pp = true; |
787 } else { | 788 } else { |
788 __ Push(lr, fp); | 789 __ Push(lr, fp); |
789 __ mov(fp, sp); | 790 __ mov(fp, sp); |
790 saved_pp = false; | 791 saved_pp = false; |
791 } | 792 } |
792 const RegList saves = descriptor->CalleeSavedRegisters(); | 793 const RegList saves = descriptor->CalleeSavedRegisters(); |
793 if (saves != 0 || saved_pp) { | 794 if (saves != 0 || saved_pp) { |
794 // Save callee-saved registers. | 795 // Save callee-saved registers. |
795 int register_save_area_size = saved_pp ? kPointerSize : 0; | 796 int register_save_area_size = saved_pp ? kPointerSize : 0; |
796 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { | 797 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { |
797 if (!((1 << i) & saves)) continue; | 798 if (!((1 << i) & saves)) continue; |
798 register_save_area_size += kPointerSize; | 799 register_save_area_size += kPointerSize; |
799 } | 800 } |
800 frame()->SetRegisterSaveAreaSize(register_save_area_size); | 801 frame()->SetRegisterSaveAreaSize(register_save_area_size); |
801 __ stm(db_w, sp, saves); | 802 __ stm(db_w, sp, saves); |
802 } | 803 } |
803 } else if (descriptor->IsJSFunctionCall()) { | 804 } else if (descriptor->IsJSFunctionCall()) { |
804 CompilationInfo* info = this->info(); | 805 CompilationInfo* info = this->info(); |
805 __ Prologue(info->IsCodePreAgingActive()); | 806 __ Prologue(info->IsCodePreAgingActive()); |
806 frame()->SetRegisterSaveAreaSize( | 807 frame()->SetRegisterSaveAreaSize( |
807 StandardFrameConstants::kFixedFrameSizeFromFp); | 808 StandardFrameConstants::kFixedFrameSizeFromFp); |
808 } else { | 809 } else if (stack_slots > 0) { |
809 __ StubPrologue(); | 810 __ StubPrologue(); |
810 frame()->SetRegisterSaveAreaSize( | 811 frame()->SetRegisterSaveAreaSize( |
811 StandardFrameConstants::kFixedFrameSizeFromFp); | 812 StandardFrameConstants::kFixedFrameSizeFromFp); |
812 } | 813 } |
813 int stack_slots = frame()->GetSpillSlotCount(); | |
814 | 814 |
815 if (info()->is_osr()) { | 815 if (info()->is_osr()) { |
816 // TurboFan OSR-compiled functions cannot be entered directly. | 816 // TurboFan OSR-compiled functions cannot be entered directly. |
817 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 817 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
818 | 818 |
819 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 819 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
820 // frame is still on the stack. Optimized code uses OSR values directly from | 820 // frame is still on the stack. Optimized code uses OSR values directly from |
821 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 821 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
822 // remaining stack slots. | 822 // remaining stack slots. |
823 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 823 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
824 osr_pc_offset_ = __ pc_offset(); | 824 osr_pc_offset_ = __ pc_offset(); |
825 DCHECK(stack_slots >= frame()->GetOsrStackSlotCount()); | 825 DCHECK(stack_slots >= frame()->GetOsrStackSlotCount()); |
826 stack_slots -= frame()->GetOsrStackSlotCount(); | 826 stack_slots -= frame()->GetOsrStackSlotCount(); |
827 } | 827 } |
828 | 828 |
829 if (stack_slots > 0) { | 829 if (stack_slots > 0) { |
830 __ sub(sp, sp, Operand(stack_slots * kPointerSize)); | 830 __ sub(sp, sp, Operand(stack_slots * kPointerSize)); |
831 } | 831 } |
832 } | 832 } |
833 | 833 |
834 | 834 |
835 void CodeGenerator::AssembleReturn() { | 835 void CodeGenerator::AssembleReturn() { |
836 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 836 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 837 int stack_slots = frame()->GetSpillSlotCount(); |
837 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 838 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
838 if (frame()->GetRegisterSaveAreaSize() > 0) { | 839 if (frame()->GetRegisterSaveAreaSize() > 0) { |
839 // Remove this frame's spill slots first. | 840 // Remove this frame's spill slots first. |
840 int stack_slots = frame()->GetSpillSlotCount(); | |
841 if (stack_slots > 0) { | 841 if (stack_slots > 0) { |
842 __ add(sp, sp, Operand(stack_slots * kPointerSize)); | 842 __ add(sp, sp, Operand(stack_slots * kPointerSize)); |
843 } | 843 } |
844 // Restore registers. | 844 // Restore registers. |
845 const RegList saves = descriptor->CalleeSavedRegisters(); | 845 const RegList saves = descriptor->CalleeSavedRegisters(); |
846 if (saves != 0) { | 846 if (saves != 0) { |
847 __ ldm(ia_w, sp, saves); | 847 __ ldm(ia_w, sp, saves); |
848 } | 848 } |
849 } | 849 } |
850 __ LeaveFrame(StackFrame::MANUAL); | 850 __ LeaveFrame(StackFrame::MANUAL); |
851 __ Ret(); | 851 __ Ret(); |
852 } else { | 852 } else if (descriptor->IsJSFunctionCall() || stack_slots > 0) { |
853 __ LeaveFrame(StackFrame::MANUAL); | 853 __ LeaveFrame(StackFrame::MANUAL); |
854 int pop_count = descriptor->IsJSFunctionCall() | 854 int pop_count = descriptor->IsJSFunctionCall() |
855 ? static_cast<int>(descriptor->JSParameterCount()) | 855 ? static_cast<int>(descriptor->JSParameterCount()) |
856 : 0; | 856 : 0; |
857 __ Drop(pop_count); | 857 __ Drop(pop_count); |
858 __ Ret(); | 858 __ Ret(); |
| 859 } else { |
| 860 __ Ret(); |
859 } | 861 } |
860 } | 862 } |
861 | 863 |
862 | 864 |
863 void CodeGenerator::AssembleMove(InstructionOperand* source, | 865 void CodeGenerator::AssembleMove(InstructionOperand* source, |
864 InstructionOperand* destination) { | 866 InstructionOperand* destination) { |
865 ArmOperandConverter g(this, NULL); | 867 ArmOperandConverter g(this, NULL); |
866 // Dispatch on the source and destination operand kinds. Not all | 868 // Dispatch on the source and destination operand kinds. Not all |
867 // combinations are possible. | 869 // combinations are possible. |
868 if (source->IsRegister()) { | 870 if (source->IsRegister()) { |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 } | 1056 } |
1055 } | 1057 } |
1056 MarkLazyDeoptSite(); | 1058 MarkLazyDeoptSite(); |
1057 } | 1059 } |
1058 | 1060 |
1059 #undef __ | 1061 #undef __ |
1060 | 1062 |
1061 } // namespace compiler | 1063 } // namespace compiler |
1062 } // namespace internal | 1064 } // namespace internal |
1063 } // namespace v8 | 1065 } // namespace v8 |
OLD | NEW |