blob: b82181c3314d12f1845f33eb180182eec336fc64 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_CODE_GENERATOR_H_
6#define V8_COMPILER_CODE_GENERATOR_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/compiler/gap-resolver.h"
9#include "src/compiler/instruction.h"
10#include "src/deoptimizer.h"
11#include "src/macro-assembler.h"
12#include "src/safepoint-table.h"
13
14namespace v8 {
15namespace internal {
16namespace compiler {
17
Emily Bernierd0a1eb72015-03-24 16:35:39 -040018// Forward declarations.
Ben Murdochda12d292016-06-02 14:46:10 +010019class DeoptimizationExit;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020class FrameAccessState;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040021class Linkage;
22class OutOfLineCode;
23
24struct BranchInfo {
25 FlagsCondition condition;
26 Label* true_label;
27 Label* false_label;
28 bool fallthru;
29};
30
31
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032class InstructionOperandIterator {
33 public:
34 InstructionOperandIterator(Instruction* instr, size_t pos)
35 : instr_(instr), pos_(pos) {}
36
37 Instruction* instruction() const { return instr_; }
38 InstructionOperand* Advance() { return instr_->InputAt(pos_++); }
39
40 private:
41 Instruction* instr_;
42 size_t pos_;
43};
44
45
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046// Generates native code for a sequence of instructions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047class CodeGenerator final : public GapResolver::Assembler {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040049 explicit CodeGenerator(Frame* frame, Linkage* linkage,
50 InstructionSequence* code, CompilationInfo* info);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051
52 // Generate native code.
53 Handle<Code> GenerateCode();
54
55 InstructionSequence* code() const { return code_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000056 FrameAccessState* frame_access_state() const { return frame_access_state_; }
57 Frame* frame() const { return frame_access_state_->frame(); }
58 Isolate* isolate() const { return info_->isolate(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040059 Linkage* linkage() const { return linkage_; }
60
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000061 Label* GetLabel(RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062
63 private:
64 MacroAssembler* masm() { return &masm_; }
65 GapResolver* resolver() { return &resolver_; }
66 SafepointTableBuilder* safepoints() { return &safepoints_; }
67 Zone* zone() const { return code()->zone(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040068 CompilationInfo* info() const { return info_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069
70 // Checks if {block} will appear directly after {current_block_} when
71 // assembling code, in which case, a fall-through can be used.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000072 bool IsNextInAssemblyOrder(RpoNumber block) const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073
74 // Record a safepoint with the given pointer map.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075 void RecordSafepoint(ReferenceMap* references, Safepoint::Kind kind,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076 int arguments, Safepoint::DeoptMode deopt_mode);
77
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078 // Check if a heap object can be materialized by loading from the frame, which
79 // is usually way cheaper than materializing the actual heap object constant.
Ben Murdochda12d292016-06-02 14:46:10 +010080 bool IsMaterializableFromFrame(Handle<HeapObject> object, int* slot_return);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000081 // Check if a heap object can be materialized by loading from a heap root,
82 // which is cheaper on some platforms than materializing the actual heap
83 // object constant.
84 bool IsMaterializableFromRoot(Handle<HeapObject> object,
85 Heap::RootListIndex* index_return);
86
Ben Murdochda12d292016-06-02 14:46:10 +010087 // Assemble instructions for the specified block.
88 void AssembleBlock(const InstructionBlock* block);
89
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090 // Assemble code for the specified instruction.
Ben Murdochda12d292016-06-02 14:46:10 +010091 void AssembleInstruction(Instruction* instr, const InstructionBlock* block);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092 void AssembleSourcePosition(Instruction* instr);
93 void AssembleGaps(Instruction* instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094
95 // ===========================================================================
96 // ============= Architecture-specific code generation methods. ==============
97 // ===========================================================================
98
99 void AssembleArchInstruction(Instruction* instr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000100 void AssembleArchJump(RpoNumber target);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400101 void AssembleArchBranch(Instruction* instr, BranchInfo* branch);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102 void AssembleArchBoolean(Instruction* instr, FlagsCondition condition);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000103 void AssembleArchLookupSwitch(Instruction* instr);
104 void AssembleArchTableSwitch(Instruction* instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106 void AssembleDeoptimizerCall(int deoptimization_id,
107 Deoptimizer::BailoutType bailout_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000108
109 // Generates an architecture-specific, descriptor-specific prologue
110 // to set up a stack frame.
111 void AssemblePrologue();
Ben Murdochda12d292016-06-02 14:46:10 +0100112
113 void AssembleSetupStackPointer();
114
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115 // Generates an architecture-specific, descriptor-specific return sequence
116 // to tear down a stack frame.
117 void AssembleReturn();
118
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119 // Generates code to deconstruct a the caller's frame, including arguments.
120 void AssembleDeconstructActivationRecord(int stack_param_delta);
121
Ben Murdochda12d292016-06-02 14:46:10 +0100122 void AssembleDeconstructFrame();
123
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124 // Generates code to manipulate the stack in preparation for a tail call.
125 void AssemblePrepareTailCall(int stack_param_delta);
126
Ben Murdochda12d292016-06-02 14:46:10 +0100127 // Generates code to pop current frame if it is an arguments adaptor frame.
128 void AssemblePopArgumentsAdaptorFrame(Register args_reg, Register scratch1,
129 Register scratch2, Register scratch3);
130
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000131 // ===========================================================================
132 // ============== Architecture-specific gap resolver methods. ================
133 // ===========================================================================
134
135 // Interface used by the gap resolver to emit moves and swaps.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400136 void AssembleMove(InstructionOperand* source,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000137 InstructionOperand* destination) final;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400138 void AssembleSwap(InstructionOperand* source,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000139 InstructionOperand* destination) final;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140
141 // ===========================================================================
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000142 // =================== Jump table construction methods. ======================
143 // ===========================================================================
144
145 class JumpTable;
146 // Adds a jump table that is emitted after the actual code. Returns label
147 // pointing to the beginning of the table. {targets} is assumed to be static
148 // or zone allocated.
149 Label* AddJumpTable(Label** targets, size_t target_count);
150 // Emits a jump table.
151 void AssembleJumpTable(Label** targets, size_t target_count);
152
153 // ===========================================================================
154 // ================== Deoptimization table construction. =====================
155 // ===========================================================================
156
157 void RecordCallPosition(Instruction* instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158 void PopulateDeoptimizationData(Handle<Code> code);
159 int DefineDeoptimizationLiteral(Handle<Object> literal);
Ben Murdochda12d292016-06-02 14:46:10 +0100160 FrameStateDescriptor* GetFrameStateDescriptor(Instruction* instr,
161 size_t frame_state_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000162 int BuildTranslation(Instruction* instr, int pc_offset,
Ben Murdochda12d292016-06-02 14:46:10 +0100163 size_t frame_state_offset,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000164 OutputFrameStateCombine state_combine);
165 void BuildTranslationForFrameStateDescriptor(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000166 FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
167 Translation* translation, OutputFrameStateCombine state_combine);
168 void TranslateStateValueDescriptor(StateValueDescriptor* desc,
169 Translation* translation,
170 InstructionOperandIterator* iter);
171 void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc,
172 InstructionOperandIterator* iter,
173 OutputFrameStateCombine combine,
174 Translation* translation);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175 void AddTranslationForOperand(Translation* translation, Instruction* instr,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400176 InstructionOperand* op, MachineType type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000177 void AddNopForSmiCodeInlining();
178 void EnsureSpaceForLazyDeopt();
179 void MarkLazyDeoptSite();
180
Ben Murdochda12d292016-06-02 14:46:10 +0100181 DeoptimizationExit* AddDeoptimizationExit(Instruction* instr,
182 size_t frame_state_offset);
183
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000184 // Converts the delta in the number of stack parameter passed from a tail
185 // caller to the callee into the distance (in pointers) the SP must be
186 // adjusted, taking frame elision and other relevant factors into
187 // consideration.
188 int TailCallFrameStackSlotDelta(int stack_param_delta);
189
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 // ===========================================================================
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000191
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192 struct DeoptimizationState : ZoneObject {
193 public:
194 BailoutId bailout_id() const { return bailout_id_; }
195 int translation_id() const { return translation_id_; }
196 int pc_offset() const { return pc_offset_; }
197
198 DeoptimizationState(BailoutId bailout_id, int translation_id, int pc_offset)
199 : bailout_id_(bailout_id),
200 translation_id_(translation_id),
201 pc_offset_(pc_offset) {}
202
203 private:
204 BailoutId bailout_id_;
205 int translation_id_;
206 int pc_offset_;
207 };
208
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209 struct HandlerInfo {
210 bool caught_locally;
211 Label* handler;
212 int pc_offset;
213 };
214
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400215 friend class OutOfLineCode;
216
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000217 FrameAccessState* frame_access_state_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400218 Linkage* const linkage_;
219 InstructionSequence* const code_;
220 CompilationInfo* const info_;
221 Label* const labels_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000222 Label return_label_;
223 RpoNumber current_block_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000224 SourcePosition current_source_position_;
225 MacroAssembler masm_;
226 GapResolver resolver_;
227 SafepointTableBuilder safepoints_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000228 ZoneVector<HandlerInfo> handlers_;
Ben Murdochda12d292016-06-02 14:46:10 +0100229 ZoneDeque<DeoptimizationExit*> deoptimization_exits_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000230 ZoneDeque<DeoptimizationState*> deoptimization_states_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000231 ZoneDeque<Handle<Object>> deoptimization_literals_;
232 size_t inlined_function_count_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000233 TranslationBuffer translations_;
234 int last_lazy_deopt_pc_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000235 JumpTable* jump_tables_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400236 OutOfLineCode* ools_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000237 int osr_pc_offset_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000238};
239
240} // namespace compiler
241} // namespace internal
242} // namespace v8
243
244#endif // V8_COMPILER_CODE_GENERATOR_H