OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 __ bge(&done); \ | 560 __ bge(&done); \ |
561 Register value = i.InputRegister(3); \ | 561 Register value = i.InputRegister(3); \ |
562 __ asm_instr(value, operand); \ | 562 __ asm_instr(value, operand); \ |
563 __ bind(&done); \ | 563 __ bind(&done); \ |
564 } while (0) | 564 } while (0) |
565 | 565 |
566 void CodeGenerator::AssembleDeconstructFrame() { | 566 void CodeGenerator::AssembleDeconstructFrame() { |
567 __ LeaveFrame(StackFrame::MANUAL); | 567 __ LeaveFrame(StackFrame::MANUAL); |
568 } | 568 } |
569 | 569 |
570 void CodeGenerator::AssembleSetupStackPointer() {} | |
571 | |
572 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 570 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
573 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 571 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
574 if (sp_slot_delta > 0) { | 572 if (sp_slot_delta > 0) { |
575 __ AddP(sp, sp, Operand(sp_slot_delta * kPointerSize)); | 573 __ AddP(sp, sp, Operand(sp_slot_delta * kPointerSize)); |
576 } | 574 } |
577 frame_access_state()->SetFrameAccessToDefault(); | 575 frame_access_state()->SetFrameAccessToDefault(); |
578 } | 576 } |
579 | 577 |
580 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { | 578 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
581 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 579 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1802 void CodeGenerator::AssembleDeoptimizerCall( | 1800 void CodeGenerator::AssembleDeoptimizerCall( |
1803 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { | 1801 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { |
1804 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1802 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
1805 isolate(), deoptimization_id, bailout_type); | 1803 isolate(), deoptimization_id, bailout_type); |
1806 // TODO(turbofan): We should be able to generate better code by sharing the | 1804 // TODO(turbofan): We should be able to generate better code by sharing the |
1807 // actual final call site and just bl'ing to it here, similar to what we do | 1805 // actual final call site and just bl'ing to it here, similar to what we do |
1808 // in the lithium backend. | 1806 // in the lithium backend. |
1809 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1807 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
1810 } | 1808 } |
1811 | 1809 |
1812 void CodeGenerator::AssemblePrologue() { | 1810 void CodeGenerator::FinishFrame(Frame* frame) { |
| 1811 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1812 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); |
| 1813 |
| 1814 // Save callee-saved Double registers. |
| 1815 if (double_saves != 0) { |
| 1816 frame->AlignSavedCalleeRegisterSlots(); |
| 1817 DCHECK(kNumCalleeSavedDoubles == |
| 1818 base::bits::CountPopulation32(double_saves)); |
| 1819 frame->AllocateSavedCalleeRegisterSlots(kNumCalleeSavedDoubles * |
| 1820 (kDoubleSize / kPointerSize)); |
| 1821 } |
| 1822 // Save callee-saved registers. |
| 1823 const RegList saves = descriptor->CalleeSavedRegisters(); |
| 1824 if (saves != 0) { |
| 1825 // register save area does not include the fp or constant pool pointer. |
| 1826 const int num_saves = kNumCalleeSaved - 1; |
| 1827 DCHECK(num_saves == base::bits::CountPopulation32(saves)); |
| 1828 frame->AllocateSavedCalleeRegisterSlots(num_saves); |
| 1829 } |
| 1830 } |
| 1831 |
| 1832 void CodeGenerator::AssembleConstructFrame() { |
1813 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1833 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1814 | 1834 |
1815 if (frame_access_state()->has_frame()) { | 1835 if (frame_access_state()->has_frame()) { |
1816 if (descriptor->IsCFunctionCall()) { | 1836 if (descriptor->IsCFunctionCall()) { |
1817 __ Push(r14, fp); | 1837 __ Push(r14, fp); |
1818 __ LoadRR(fp, sp); | 1838 __ LoadRR(fp, sp); |
1819 } else if (descriptor->IsJSFunctionCall()) { | 1839 } else if (descriptor->IsJSFunctionCall()) { |
1820 __ Prologue(this->info()->GeneratePreagedPrologue(), ip); | 1840 __ Prologue(this->info()->GeneratePreagedPrologue(), ip); |
1821 } else { | 1841 } else { |
1822 StackFrame::Type type = info()->GetOutputStackFrameType(); | 1842 StackFrame::Type type = info()->GetOutputStackFrameType(); |
1823 // TODO(mbrandy): Detect cases where ip is the entrypoint (for | 1843 // TODO(mbrandy): Detect cases where ip is the entrypoint (for |
1824 // efficient intialization of the constant pool pointer register). | 1844 // efficient intialization of the constant pool pointer register). |
1825 __ StubPrologue(type); | 1845 __ StubPrologue(type); |
1826 } | 1846 } |
1827 } | 1847 } |
1828 | 1848 |
1829 int stack_shrink_slots = frame()->GetSpillSlotCount(); | 1849 int shrink_slots = frame()->GetSpillSlotCount(); |
1830 if (info()->is_osr()) { | 1850 if (info()->is_osr()) { |
1831 // TurboFan OSR-compiled functions cannot be entered directly. | 1851 // TurboFan OSR-compiled functions cannot be entered directly. |
1832 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1852 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
1833 | 1853 |
1834 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1854 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
1835 // frame is still on the stack. Optimized code uses OSR values directly from | 1855 // frame is still on the stack. Optimized code uses OSR values directly from |
1836 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1856 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
1837 // remaining stack slots. | 1857 // remaining stack slots. |
1838 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1858 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
1839 osr_pc_offset_ = __ pc_offset(); | 1859 osr_pc_offset_ = __ pc_offset(); |
1840 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); | 1860 shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); |
1841 } | 1861 } |
1842 | 1862 |
1843 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); | 1863 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); |
1844 if (double_saves != 0) { | 1864 if (shrink_slots > 0) { |
1845 stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots(); | 1865 __ lay(sp, MemOperand(sp, -shrink_slots * kPointerSize)); |
1846 } | |
1847 if (stack_shrink_slots > 0) { | |
1848 __ lay(sp, MemOperand(sp, -stack_shrink_slots * kPointerSize)); | |
1849 } | 1866 } |
1850 | 1867 |
1851 // Save callee-saved Double registers. | 1868 // Save callee-saved Double registers. |
1852 if (double_saves != 0) { | 1869 if (double_saves != 0) { |
1853 __ MultiPushDoubles(double_saves); | 1870 __ MultiPushDoubles(double_saves); |
1854 DCHECK(kNumCalleeSavedDoubles == | 1871 DCHECK(kNumCalleeSavedDoubles == |
1855 base::bits::CountPopulation32(double_saves)); | 1872 base::bits::CountPopulation32(double_saves)); |
1856 frame()->AllocateSavedCalleeRegisterSlots(kNumCalleeSavedDoubles * | |
1857 (kDoubleSize / kPointerSize)); | |
1858 } | 1873 } |
1859 | 1874 |
1860 // Save callee-saved registers. | 1875 // Save callee-saved registers. |
1861 const RegList saves = descriptor->CalleeSavedRegisters(); | 1876 const RegList saves = descriptor->CalleeSavedRegisters(); |
1862 if (saves != 0) { | 1877 if (saves != 0) { |
1863 __ MultiPush(saves); | 1878 __ MultiPush(saves); |
1864 // register save area does not include the fp or constant pool pointer. | 1879 // register save area does not include the fp or constant pool pointer. |
1865 const int num_saves = | |
1866 kNumCalleeSaved - 1 - (FLAG_enable_embedded_constant_pool ? 1 : 0); | |
1867 DCHECK(num_saves == base::bits::CountPopulation32(saves)); | |
1868 frame()->AllocateSavedCalleeRegisterSlots(num_saves); | |
1869 } | 1880 } |
1870 } | 1881 } |
1871 | 1882 |
1872 void CodeGenerator::AssembleReturn() { | 1883 void CodeGenerator::AssembleReturn() { |
1873 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1884 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1874 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 1885 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
1875 | 1886 |
1876 // Restore registers. | 1887 // Restore registers. |
1877 const RegList saves = descriptor->CalleeSavedRegisters(); | 1888 const RegList saves = descriptor->CalleeSavedRegisters(); |
1878 if (saves != 0) { | 1889 if (saves != 0) { |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2118 padding_size -= 2; | 2129 padding_size -= 2; |
2119 } | 2130 } |
2120 } | 2131 } |
2121 } | 2132 } |
2122 | 2133 |
2123 #undef __ | 2134 #undef __ |
2124 | 2135 |
2125 } // namespace compiler | 2136 } // namespace compiler |
2126 } // namespace internal | 2137 } // namespace internal |
2127 } // namespace v8 | 2138 } // namespace v8 |
OLD | NEW |