blob: 8d1c5c4ed25ec0307396313619a91b5d3ecc56eb [file] [log] [blame]
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_X64_LITHIUM_CODEGEN_X64_H_
29#define V8_X64_LITHIUM_CODEGEN_X64_H_
30
31#include "x64/lithium-x64.h"
32
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000033#include "checks.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "deoptimizer.h"
35#include "safepoint-table.h"
36#include "scopes.h"
37
38namespace v8 {
39namespace internal {
40
41// Forward declarations.
42class LDeferredCode;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000043class LGapNode;
44class SafepointGenerator;
45
46class LGapResolver BASE_EMBEDDED {
47 public:
48 LGapResolver();
49 const ZoneList<LMoveOperands>* Resolve(const ZoneList<LMoveOperands>* moves,
50 LOperand* marker_operand);
51
52 private:
53 LGapNode* LookupNode(LOperand* operand);
54 bool CanReach(LGapNode* a, LGapNode* b, int visited_id);
55 bool CanReach(LGapNode* a, LGapNode* b);
56 void RegisterMove(LMoveOperands move);
57 void AddResultMove(LOperand* from, LOperand* to);
58 void AddResultMove(LGapNode* from, LGapNode* to);
59 void ResolveCycle(LGapNode* start, LOperand* marker_operand);
60
61 ZoneList<LGapNode*> nodes_;
62 ZoneList<LGapNode*> identified_cycles_;
63 ZoneList<LMoveOperands> result_;
64 int next_visited_id_;
65};
66
kasperl@chromium.orga5551262010-12-07 12:49:48 +000067
68class LCodeGen BASE_EMBEDDED {
69 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000070 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
71 : chunk_(chunk),
72 masm_(assembler),
73 info_(info),
74 current_block_(-1),
75 current_instruction_(-1),
76 instructions_(chunk->instructions()),
77 deoptimizations_(4),
78 deoptimization_literals_(8),
79 inlined_function_count_(0),
80 scope_(chunk->graph()->info()->scope()),
81 status_(UNUSED),
82 deferred_(8),
83 osr_pc_offset_(-1) {
84 PopulateDeoptimizationLiteralsWithInlinedFunctions();
85 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +000086
87 // Try to generate code for the entire chunk, but it may fail if the
88 // chunk contains constructs we cannot handle. Returns true if the
89 // code generation attempt succeeded.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000090 bool GenerateCode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +000091
92 // Finish the code by setting stack height, safepoint, and bailout
93 // information on it.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000094 void FinishCode(Handle<Code> code);
95
96 // Deferred code support.
97 void DoDeferredNumberTagD(LNumberTagD* instr);
98 void DoDeferredNumberTagI(LNumberTagI* instr);
99 void DoDeferredTaggedToI(LTaggedToI* instr);
100 void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
101 void DoDeferredStackCheck(LGoto* instr);
102 void DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
103 Label* map_check);
104
105 // Parallel move support.
106 void DoParallelMove(LParallelMove* move);
107
108 // Emit frame translation commands for an environment.
109 void WriteTranslation(LEnvironment* environment, Translation* translation);
110
111 // Declare methods that deal with the individual node types.
112#define DECLARE_DO(type) void Do##type(L##type* node);
113 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
114#undef DECLARE_DO
115
116 private:
117 enum Status {
118 UNUSED,
119 GENERATING,
120 DONE,
121 ABORTED
122 };
123
124 bool is_unused() const { return status_ == UNUSED; }
125 bool is_generating() const { return status_ == GENERATING; }
126 bool is_done() const { return status_ == DONE; }
127 bool is_aborted() const { return status_ == ABORTED; }
128
129 LChunk* chunk() const { return chunk_; }
130 Scope* scope() const { return scope_; }
131 HGraph* graph() const { return chunk_->graph(); }
132 MacroAssembler* masm() const { return masm_; }
133
134 int GetNextEmittedBlock(int block);
135 LInstruction* GetNextInstruction();
136
137 void EmitClassOfTest(Label* if_true,
138 Label* if_false,
139 Handle<String> class_name,
140 Register input,
141 Register temporary,
142 Register temporary2);
143
144 int StackSlotCount() const { return chunk()->spill_slot_count(); }
145 int ParameterCount() const { return scope()->num_parameters(); }
146
147 void Abort(const char* format, ...);
148 void Comment(const char* format, ...);
149
150 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code); }
151
152 // Code generation passes. Returns true if code generation should
153 // continue.
154 bool GeneratePrologue();
155 bool GenerateBody();
156 bool GenerateDeferredCode();
157 bool GenerateSafepointTable();
158
159 void CallCode(Handle<Code> code,
160 RelocInfo::Mode mode,
161 LInstruction* instr);
162 void CallRuntime(Runtime::Function* function,
163 int num_arguments,
164 LInstruction* instr);
165 void CallRuntime(Runtime::FunctionId id,
166 int num_arguments,
167 LInstruction* instr) {
168 Runtime::Function* function = Runtime::FunctionForId(id);
169 CallRuntime(function, num_arguments, instr);
170 }
171
172 // Generate a direct call to a known function. Expects the function
173 // to be in edi.
174 void CallKnownFunction(Handle<JSFunction> function,
175 int arity,
176 LInstruction* instr);
177
178 void LoadHeapObject(Register result, Handle<HeapObject> object);
179
180 void RegisterLazyDeoptimization(LInstruction* instr);
181 void RegisterEnvironmentForDeoptimization(LEnvironment* environment);
182 void DeoptimizeIf(Condition cc, LEnvironment* environment);
183
184 void AddToTranslation(Translation* translation,
185 LOperand* op,
186 bool is_tagged);
187 void PopulateDeoptimizationData(Handle<Code> code);
188 int DefineDeoptimizationLiteral(Handle<Object> literal);
189
190 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
191
192 Register ToRegister(int index) const;
193 XMMRegister ToDoubleRegister(int index) const;
194 Register ToRegister(LOperand* op) const;
195 XMMRegister ToDoubleRegister(LOperand* op) const;
196 bool IsInteger32Constant(LConstantOperand* op) const;
197 int ToInteger32(LConstantOperand* op) const;
198 bool IsTaggedConstant(LConstantOperand* op) const;
199 Handle<Object> ToHandle(LConstantOperand* op) const;
200 Operand ToOperand(LOperand* op) const;
201
202 // Specific math operations - used from DoUnaryMathOperation.
203 void DoMathAbs(LUnaryMathOperation* instr);
204 void DoMathFloor(LUnaryMathOperation* instr);
205 void DoMathRound(LUnaryMathOperation* instr);
206 void DoMathSqrt(LUnaryMathOperation* instr);
207 void DoMathPowHalf(LUnaryMathOperation* instr);
208 void DoMathLog(LUnaryMathOperation* instr);
209 void DoMathCos(LUnaryMathOperation* instr);
210 void DoMathSin(LUnaryMathOperation* instr);
211
212 // Support for recording safepoint and position information.
213 void RecordSafepoint(LPointerMap* pointers, int deoptimization_index);
214 void RecordSafepointWithRegisters(LPointerMap* pointers,
215 int arguments,
216 int deoptimization_index);
217 void RecordPosition(int position);
218
219 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
220 void EmitGoto(int block, LDeferredCode* deferred_stack_check = NULL);
221 void EmitBranch(int left_block, int right_block, Condition cc);
222 void EmitCmpI(LOperand* left, LOperand* right);
223 void EmitNumberUntagD(Register input, XMMRegister result, LEnvironment* env);
224
225 // Emits optimized code for typeof x == "y". Modifies input register.
226 // Returns the condition on which a final split to
227 // true and false label should be made, to optimize fallthrough.
228 Condition EmitTypeofIs(Label* true_label, Label* false_label,
229 Register input, Handle<String> type_name);
230
231 // Emits optimized code for %_IsObject(x). Preserves input register.
232 // Returns the condition on which a final split to
233 // true and false label should be made, to optimize fallthrough.
234 Condition EmitIsObject(Register input,
235 Register temp1,
236 Register temp2,
237 Label* is_not_object,
238 Label* is_object);
239
240 LChunk* const chunk_;
241 MacroAssembler* const masm_;
242 CompilationInfo* const info_;
243
244 int current_block_;
245 int current_instruction_;
246 const ZoneList<LInstruction*>* instructions_;
247 ZoneList<LEnvironment*> deoptimizations_;
248 ZoneList<Handle<Object> > deoptimization_literals_;
249 int inlined_function_count_;
250 Scope* const scope_;
251 Status status_;
252 TranslationBuffer translations_;
253 ZoneList<LDeferredCode*> deferred_;
254 int osr_pc_offset_;
255
256 // Builder that keeps track of safepoints in the code. The table
257 // itself is emitted at the end of the generated code.
258 SafepointTableBuilder safepoints_;
259
260 // Compiler from a set of parallel moves to a sequential list of moves.
261 LGapResolver resolver_;
262
263 friend class LDeferredCode;
264 friend class LEnvironment;
265 friend class SafepointGenerator;
266 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
267};
268
269
270class LDeferredCode: public ZoneObject {
271 public:
272 explicit LDeferredCode(LCodeGen* codegen)
273 : codegen_(codegen), external_exit_(NULL) {
274 codegen->AddDeferredCode(this);
275 }
276
277 virtual ~LDeferredCode() { }
278 virtual void Generate() = 0;
279
280 void SetExit(Label *exit) { external_exit_ = exit; }
281 Label* entry() { return &entry_; }
282 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
283
284 protected:
285 LCodeGen* codegen() const { return codegen_; }
286 MacroAssembler* masm() const { return codegen_->masm(); }
287
288 private:
289 LCodeGen* codegen_;
290 Label entry_;
291 Label exit_;
292 Label* external_exit_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000293};
294
295} } // namespace v8::internal
296
297#endif // V8_X64_LITHIUM_CODEGEN_X64_H_