| 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 |