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