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/ast/scopes.h" | 7 #include "src/ast/scopes.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 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 __ bind(&done); \ | 687 __ bind(&done); \ |
688 __ cmp(result, result); \ | 688 __ cmp(result, result); \ |
689 __ bne(&done); \ | 689 __ bne(&done); \ |
690 __ isync(); \ | 690 __ isync(); \ |
691 } while (0) | 691 } while (0) |
692 | 692 |
693 void CodeGenerator::AssembleDeconstructFrame() { | 693 void CodeGenerator::AssembleDeconstructFrame() { |
694 __ LeaveFrame(StackFrame::MANUAL); | 694 __ LeaveFrame(StackFrame::MANUAL); |
695 } | 695 } |
696 | 696 |
697 void CodeGenerator::AssembleSetupStackPointer() {} | |
698 | |
699 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 697 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
700 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 698 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
701 if (sp_slot_delta > 0) { | 699 if (sp_slot_delta > 0) { |
702 __ Add(sp, sp, sp_slot_delta * kPointerSize, r0); | 700 __ Add(sp, sp, sp_slot_delta * kPointerSize, r0); |
703 } | 701 } |
704 frame_access_state()->SetFrameAccessToDefault(); | 702 frame_access_state()->SetFrameAccessToDefault(); |
705 } | 703 } |
706 | 704 |
707 | 705 |
708 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { | 706 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 void CodeGenerator::AssembleDeoptimizerCall( | 1745 void CodeGenerator::AssembleDeoptimizerCall( |
1748 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { | 1746 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { |
1749 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1747 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
1750 isolate(), deoptimization_id, bailout_type); | 1748 isolate(), deoptimization_id, bailout_type); |
1751 // TODO(turbofan): We should be able to generate better code by sharing the | 1749 // TODO(turbofan): We should be able to generate better code by sharing the |
1752 // actual final call site and just bl'ing to it here, similar to what we do | 1750 // actual final call site and just bl'ing to it here, similar to what we do |
1753 // in the lithium backend. | 1751 // in the lithium backend. |
1754 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1752 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
1755 } | 1753 } |
1756 | 1754 |
| 1755 void CodeGenerator::FinishFrame(Frame* frame) { |
| 1756 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1757 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); |
1757 | 1758 |
1758 void CodeGenerator::AssemblePrologue() { | 1759 // Save callee-saved Double registers. |
| 1760 if (double_saves != 0) { |
| 1761 frame->AlignSavedCalleeRegisterSlots(); |
| 1762 DCHECK(kNumCalleeSavedDoubles == |
| 1763 base::bits::CountPopulation32(double_saves)); |
| 1764 frame->AllocateSavedCalleeRegisterSlots(kNumCalleeSavedDoubles * |
| 1765 (kDoubleSize / kPointerSize)); |
| 1766 } |
| 1767 // Save callee-saved registers. |
| 1768 const RegList saves = |
| 1769 FLAG_enable_embedded_constant_pool |
| 1770 ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() |
| 1771 : descriptor->CalleeSavedRegisters(); |
| 1772 if (saves != 0) { |
| 1773 // register save area does not include the fp or constant pool pointer. |
| 1774 const int num_saves = |
| 1775 kNumCalleeSaved - 1 - (FLAG_enable_embedded_constant_pool ? 1 : 0); |
| 1776 DCHECK(num_saves == base::bits::CountPopulation32(saves)); |
| 1777 frame->AllocateSavedCalleeRegisterSlots(num_saves); |
| 1778 } |
| 1779 } |
| 1780 |
| 1781 void CodeGenerator::AssembleConstructFrame() { |
1759 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1782 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1760 if (frame_access_state()->has_frame()) { | 1783 if (frame_access_state()->has_frame()) { |
1761 if (descriptor->IsCFunctionCall()) { | 1784 if (descriptor->IsCFunctionCall()) { |
1762 __ function_descriptor(); | 1785 __ function_descriptor(); |
1763 __ mflr(r0); | 1786 __ mflr(r0); |
1764 if (FLAG_enable_embedded_constant_pool) { | 1787 if (FLAG_enable_embedded_constant_pool) { |
1765 __ Push(r0, fp, kConstantPoolRegister); | 1788 __ Push(r0, fp, kConstantPoolRegister); |
1766 // Adjust FP to point to saved FP. | 1789 // Adjust FP to point to saved FP. |
1767 __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); | 1790 __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); |
1768 } else { | 1791 } else { |
1769 __ Push(r0, fp); | 1792 __ Push(r0, fp); |
1770 __ mr(fp, sp); | 1793 __ mr(fp, sp); |
1771 } | 1794 } |
1772 } else if (descriptor->IsJSFunctionCall()) { | 1795 } else if (descriptor->IsJSFunctionCall()) { |
1773 __ Prologue(this->info()->GeneratePreagedPrologue(), ip); | 1796 __ Prologue(this->info()->GeneratePreagedPrologue(), ip); |
1774 } else { | 1797 } else { |
1775 StackFrame::Type type = info()->GetOutputStackFrameType(); | 1798 StackFrame::Type type = info()->GetOutputStackFrameType(); |
1776 // TODO(mbrandy): Detect cases where ip is the entrypoint (for | 1799 // TODO(mbrandy): Detect cases where ip is the entrypoint (for |
1777 // efficient intialization of the constant pool pointer register). | 1800 // efficient intialization of the constant pool pointer register). |
1778 __ StubPrologue(type); | 1801 __ StubPrologue(type); |
1779 } | 1802 } |
1780 } | 1803 } |
1781 | 1804 |
1782 int stack_shrink_slots = frame()->GetSpillSlotCount(); | 1805 int shrink_slots = frame()->GetSpillSlotCount(); |
1783 if (info()->is_osr()) { | 1806 if (info()->is_osr()) { |
1784 // TurboFan OSR-compiled functions cannot be entered directly. | 1807 // TurboFan OSR-compiled functions cannot be entered directly. |
1785 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1808 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
1786 | 1809 |
1787 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1810 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
1788 // frame is still on the stack. Optimized code uses OSR values directly from | 1811 // frame is still on the stack. Optimized code uses OSR values directly from |
1789 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1812 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
1790 // remaining stack slots. | 1813 // remaining stack slots. |
1791 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1814 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
1792 osr_pc_offset_ = __ pc_offset(); | 1815 osr_pc_offset_ = __ pc_offset(); |
1793 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); | 1816 shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); |
1794 } | 1817 } |
1795 | 1818 |
1796 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); | 1819 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); |
1797 if (double_saves != 0) { | 1820 if (shrink_slots > 0) { |
1798 stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots(); | 1821 __ Add(sp, sp, -shrink_slots * kPointerSize, r0); |
1799 } | |
1800 if (stack_shrink_slots > 0) { | |
1801 __ Add(sp, sp, -stack_shrink_slots * kPointerSize, r0); | |
1802 } | 1822 } |
1803 | 1823 |
1804 // Save callee-saved Double registers. | 1824 // Save callee-saved Double registers. |
1805 if (double_saves != 0) { | 1825 if (double_saves != 0) { |
1806 __ MultiPushDoubles(double_saves); | 1826 __ MultiPushDoubles(double_saves); |
1807 DCHECK(kNumCalleeSavedDoubles == | 1827 DCHECK(kNumCalleeSavedDoubles == |
1808 base::bits::CountPopulation32(double_saves)); | 1828 base::bits::CountPopulation32(double_saves)); |
1809 frame()->AllocateSavedCalleeRegisterSlots(kNumCalleeSavedDoubles * | |
1810 (kDoubleSize / kPointerSize)); | |
1811 } | 1829 } |
1812 | 1830 |
1813 // Save callee-saved registers. | 1831 // Save callee-saved registers. |
1814 const RegList saves = | 1832 const RegList saves = |
1815 FLAG_enable_embedded_constant_pool | 1833 FLAG_enable_embedded_constant_pool |
1816 ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() | 1834 ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() |
1817 : descriptor->CalleeSavedRegisters(); | 1835 : descriptor->CalleeSavedRegisters(); |
1818 if (saves != 0) { | 1836 if (saves != 0) { |
1819 __ MultiPush(saves); | 1837 __ MultiPush(saves); |
1820 // register save area does not include the fp or constant pool pointer. | 1838 // register save area does not include the fp or constant pool pointer. |
1821 const int num_saves = | |
1822 kNumCalleeSaved - 1 - (FLAG_enable_embedded_constant_pool ? 1 : 0); | |
1823 DCHECK(num_saves == base::bits::CountPopulation32(saves)); | |
1824 frame()->AllocateSavedCalleeRegisterSlots(num_saves); | |
1825 } | 1839 } |
1826 } | 1840 } |
1827 | 1841 |
1828 | 1842 |
1829 void CodeGenerator::AssembleReturn() { | 1843 void CodeGenerator::AssembleReturn() { |
1830 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1844 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1831 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 1845 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
1832 | 1846 |
1833 // Restore registers. | 1847 // Restore registers. |
1834 const RegList saves = | 1848 const RegList saves = |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2080 padding_size -= v8::internal::Assembler::kInstrSize; | 2094 padding_size -= v8::internal::Assembler::kInstrSize; |
2081 } | 2095 } |
2082 } | 2096 } |
2083 } | 2097 } |
2084 | 2098 |
2085 #undef __ | 2099 #undef __ |
2086 | 2100 |
2087 } // namespace compiler | 2101 } // namespace compiler |
2088 } // namespace internal | 2102 } // namespace internal |
2089 } // namespace v8 | 2103 } // namespace v8 |
OLD | NEW |