blob: 598a847539e45958353c7c22a9464b6823e4a68d [file] [log] [blame]
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001// Copyright 2012 the V8 project authors. All rights reserved.
ager@chromium.org5c838252010-02-19 08:53:10 +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
lrn@chromium.org7516f052011-03-30 08:52:27 +000028#ifndef V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
29#define V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
ager@chromium.org5c838252010-02-19 08:53:10 +000030
lrn@chromium.org7516f052011-03-30 08:52:27 +000031#include "mips/lithium-mips.h"
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000032#include "mips/lithium-gap-resolver-mips.h"
lrn@chromium.org7516f052011-03-30 08:52:27 +000033#include "deoptimizer.h"
34#include "safepoint-table.h"
35#include "scopes.h"
36
ager@chromium.org5c838252010-02-19 08:53:10 +000037namespace v8 {
38namespace internal {
39
lrn@chromium.org7516f052011-03-30 08:52:27 +000040// Forward declarations.
41class LDeferredCode;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000042class SafepointGenerator;
ager@chromium.org5c838252010-02-19 08:53:10 +000043
lrn@chromium.org7516f052011-03-30 08:52:27 +000044class LCodeGen BASE_EMBEDDED {
45 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000046 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
47 : zone_(info->zone()),
jkummerow@chromium.org28583c92012-07-16 11:31:55 +000048 chunk_(static_cast<LPlatformChunk*>(chunk)),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000049 masm_(assembler),
50 info_(info),
51 current_block_(-1),
52 current_instruction_(-1),
53 instructions_(chunk->instructions()),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000054 deoptimizations_(4, info->zone()),
55 deopt_jump_table_(4, info->zone()),
56 deoptimization_literals_(8, info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000057 inlined_function_count_(0),
58 scope_(info->scope()),
59 status_(UNUSED),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000060 translations_(info->zone()),
61 deferred_(8, info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000062 osr_pc_offset_(-1),
erikcorry0ad885c2011-11-21 13:51:57 +000063 last_lazy_deopt_pc_(0),
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000064 frame_is_built_(false),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000065 safepoints_(info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000066 resolver_(this),
67 expected_safepoint_kind_(Safepoint::kSimple) {
68 PopulateDeoptimizationLiteralsWithInlinedFunctions();
69 }
70
71
72 // Simple accessors.
73 MacroAssembler* masm() const { return masm_; }
74 CompilationInfo* info() const { return info_; }
75 Isolate* isolate() const { return info_->isolate(); }
76 Factory* factory() const { return isolate()->factory(); }
77 Heap* heap() const { return isolate()->heap(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +000078 Zone* zone() const { return zone_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000079
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000080 bool NeedsEagerFrame() const {
81 return GetStackSlotCount() > 0 ||
82 info()->is_non_deferred_calling() ||
83 !info()->IsStub();
84 }
85 bool NeedsDeferredFrame() const {
86 return !NeedsEagerFrame() && info()->is_deferred_calling();
87 }
88
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000089 // Support for converting LOperands to assembler types.
90 // LOperand must be a register.
91 Register ToRegister(LOperand* op) const;
92
93 // LOperand is loaded into scratch, unless already a register.
94 Register EmitLoadRegister(LOperand* op, Register scratch);
95
96 // LOperand must be a double register.
97 DoubleRegister ToDoubleRegister(LOperand* op) const;
98
99 // LOperand is loaded into dbl_scratch, unless already a double register.
100 DoubleRegister EmitLoadDoubleRegister(LOperand* op,
101 FloatRegister flt_scratch,
102 DoubleRegister dbl_scratch);
103 int ToInteger32(LConstantOperand* op) const;
104 double ToDouble(LConstantOperand* op) const;
105 Operand ToOperand(LOperand* op);
106 MemOperand ToMemOperand(LOperand* op) const;
107 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
108 MemOperand ToHighMemOperand(LOperand* op) const;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000109
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000110 bool IsInteger32(LConstantOperand* op) const;
111 Handle<Object> ToHandle(LConstantOperand* op) const;
112
lrn@chromium.org7516f052011-03-30 08:52:27 +0000113 // Try to generate code for the entire chunk, but it may fail if the
114 // chunk contains constructs we cannot handle. Returns true if the
115 // code generation attempt succeeded.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000116 bool GenerateCode();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000117
lrn@chromium.org7516f052011-03-30 08:52:27 +0000118 // Finish the code by setting stack height, safepoint, and bailout
119 // information on it.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000120 void FinishCode(Handle<Code> code);
121
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000122 void DoDeferredNumberTagD(LNumberTagD* instr);
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000123
124 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
125 void DoDeferredNumberTagI(LInstruction* instr,
126 LOperand* value,
127 IntegerSignedness signedness);
128
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000129 void DoDeferredTaggedToI(LTaggedToI* instr);
130 void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
131 void DoDeferredStackCheck(LStackCheck* instr);
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000132 void DoDeferredRandom(LRandom* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000133 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
134 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
ulan@chromium.org967e2702012-02-28 09:49:15 +0000135 void DoDeferredAllocateObject(LAllocateObject* instr);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000136 void DoDeferredAllocate(LAllocate* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000137 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
138 Label* map_check);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000139
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000140 void DoCheckMapCommon(Register map_reg, Handle<Map> map,
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000141 CompareMapMode mode, LEnvironment* env);
142
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000143 // Parallel move support.
144 void DoParallelMove(LParallelMove* move);
145 void DoGap(LGap* instr);
146
danno@chromium.org129d3982012-07-25 15:01:47 +0000147 MemOperand PrepareKeyedOperand(Register key,
148 Register base,
149 bool key_is_constant,
150 int constant_key,
151 int element_size,
152 int shift_size,
153 int additional_index,
154 int additional_offset);
155
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000156 // Emit frame translation commands for an environment.
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000157 void WriteTranslation(LEnvironment* environment,
158 Translation* translation,
159 int* arguments_index,
160 int* arguments_count);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000161
162 // Declare methods that deal with the individual node types.
163#define DECLARE_DO(type) void Do##type(L##type* node);
164 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
165#undef DECLARE_DO
166
167 private:
168 enum Status {
169 UNUSED,
170 GENERATING,
171 DONE,
172 ABORTED
173 };
174
175 bool is_unused() const { return status_ == UNUSED; }
176 bool is_generating() const { return status_ == GENERATING; }
177 bool is_done() const { return status_ == DONE; }
178 bool is_aborted() const { return status_ == ABORTED; }
179
180 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000181 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000182 }
183
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000184 LPlatformChunk* chunk() const { return chunk_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000185 Scope* scope() const { return scope_; }
186 HGraph* graph() const { return chunk_->graph(); }
187
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000188 Register scratch0() { return kLithiumScratchReg; }
189 Register scratch1() { return kLithiumScratchReg2; }
190 DoubleRegister double_scratch0() { return kLithiumScratchDouble; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000191
192 int GetNextEmittedBlock(int block);
193 LInstruction* GetNextInstruction();
194
195 void EmitClassOfTest(Label* if_true,
196 Label* if_false,
197 Handle<String> class_name,
198 Register input,
199 Register temporary,
200 Register temporary2);
201
202 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000203 int GetParameterCount() const { return info()->num_parameters(); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000204
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000205 void Abort(const char* reason);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000206 void Comment(const char* format, ...);
207
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000208 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000209
210 // Code generation passes. Returns true if code generation should
211 // continue.
212 bool GeneratePrologue();
213 bool GenerateBody();
214 bool GenerateDeferredCode();
215 bool GenerateDeoptJumpTable();
216 bool GenerateSafepointTable();
217
218 enum SafepointMode {
219 RECORD_SIMPLE_SAFEPOINT,
220 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
221 };
222
223 void CallCode(Handle<Code> code,
224 RelocInfo::Mode mode,
225 LInstruction* instr);
226
227 void CallCodeGeneric(Handle<Code> code,
228 RelocInfo::Mode mode,
229 LInstruction* instr,
230 SafepointMode safepoint_mode);
231
232 void CallRuntime(const Runtime::Function* function,
233 int num_arguments,
234 LInstruction* instr);
235
236 void CallRuntime(Runtime::FunctionId id,
237 int num_arguments,
238 LInstruction* instr) {
239 const Runtime::Function* function = Runtime::FunctionForId(id);
240 CallRuntime(function, num_arguments, instr);
241 }
242
243 void CallRuntimeFromDeferred(Runtime::FunctionId id,
244 int argc,
245 LInstruction* instr);
246
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000247 enum A1State {
248 A1_UNINITIALIZED,
249 A1_CONTAINS_TARGET
250 };
251
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000252 // Generate a direct call to a known function. Expects the function
253 // to be in a1.
254 void CallKnownFunction(Handle<JSFunction> function,
255 int arity,
256 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000257 CallKind call_kind,
258 A1State a1_state);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000259
260 void LoadHeapObject(Register result, Handle<HeapObject> object);
261
erikcorry0ad885c2011-11-21 13:51:57 +0000262 void RecordSafepointWithLazyDeopt(LInstruction* instr,
263 SafepointMode safepoint_mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000264
erikcorry0ad885c2011-11-21 13:51:57 +0000265 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
266 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000267 void DeoptimizeIf(Condition cc,
268 LEnvironment* environment,
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000269 Register src1 = zero_reg,
270 const Operand& src2 = Operand(zero_reg));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000271
272 void AddToTranslation(Translation* translation,
273 LOperand* op,
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000274 bool is_tagged,
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000275 bool is_uint32,
276 int arguments_index,
277 int arguments_count);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000278 void PopulateDeoptimizationData(Handle<Code> code);
279 int DefineDeoptimizationLiteral(Handle<Object> literal);
280
281 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
282
283 Register ToRegister(int index) const;
284 DoubleRegister ToDoubleRegister(int index) const;
285
286 // Specific math operations - used from DoUnaryMathOperation.
287 void EmitIntegerMathAbs(LUnaryMathOperation* instr);
288 void DoMathAbs(LUnaryMathOperation* instr);
289 void DoMathFloor(LUnaryMathOperation* instr);
290 void DoMathRound(LUnaryMathOperation* instr);
291 void DoMathSqrt(LUnaryMathOperation* instr);
292 void DoMathPowHalf(LUnaryMathOperation* instr);
293 void DoMathLog(LUnaryMathOperation* instr);
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +0000294 void DoMathTan(LUnaryMathOperation* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000295 void DoMathCos(LUnaryMathOperation* instr);
296 void DoMathSin(LUnaryMathOperation* instr);
297
298 // Support for recording safepoint and position information.
299 void RecordSafepoint(LPointerMap* pointers,
300 Safepoint::Kind kind,
301 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000302 Safepoint::DeoptMode mode);
303 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
304 void RecordSafepoint(Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000305 void RecordSafepointWithRegisters(LPointerMap* pointers,
306 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000307 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000308 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
309 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000310 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000311 void RecordPosition(int position);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000312
313 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
314 void EmitGoto(int block);
315 void EmitBranch(int left_block,
316 int right_block,
317 Condition cc,
318 Register src1,
319 const Operand& src2);
320 void EmitBranchF(int left_block,
321 int right_block,
322 Condition cc,
323 FPURegister src1,
324 FPURegister src2);
325 void EmitCmpI(LOperand* left, LOperand* right);
326 void EmitNumberUntagD(Register input,
327 DoubleRegister result,
328 bool deoptimize_on_undefined,
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000329 bool deoptimize_on_minus_zero,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000330 LEnvironment* env,
331 NumberUntagDMode mode);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000332
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000333 // Emits optimized code for typeof x == "y". Modifies input register.
334 // Returns the condition on which a final split to
335 // true and false label should be made, to optimize fallthrough.
336 // Returns two registers in cmp1 and cmp2 that can be used in the
337 // Branch instruction after EmitTypeofIs.
338 Condition EmitTypeofIs(Label* true_label,
339 Label* false_label,
340 Register input,
341 Handle<String> type_name,
342 Register& cmp1,
343 Operand& cmp2);
344
345 // Emits optimized code for %_IsObject(x). Preserves input register.
346 // Returns the condition on which a final split to
347 // true and false label should be made, to optimize fallthrough.
348 Condition EmitIsObject(Register input,
349 Register temp1,
erikcorry0ad885c2011-11-21 13:51:57 +0000350 Register temp2,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000351 Label* is_not_object,
352 Label* is_object);
353
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +0000354 // Emits optimized code for %_IsString(x). Preserves input register.
355 // Returns the condition on which a final split to
356 // true and false label should be made, to optimize fallthrough.
357 Condition EmitIsString(Register input,
358 Register temp1,
359 Label* is_not_string);
360
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000361 // Emits optimized code for %_IsConstructCall().
362 // Caller should branch on equal condition.
363 void EmitIsConstructCall(Register temp1, Register temp2);
364
365 void EmitLoadFieldOrConstantFunction(Register result,
366 Register object,
367 Handle<Map> type,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000368 Handle<String> name,
369 LEnvironment* env);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000370
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000371 // Emits optimized code to deep-copy the contents of statically known
372 // object graphs (e.g. object literal boilerplate).
373 void EmitDeepCopy(Handle<JSObject> object,
374 Register result,
375 Register source,
yangguo@chromium.org28381b42013-01-21 14:39:38 +0000376 int* offset,
377 AllocationSiteMode mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000378
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000379 struct JumpTableEntry {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000380 inline JumpTableEntry(Address entry, bool frame, bool is_lazy)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000381 : label(),
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000382 address(entry),
383 needs_frame(frame),
384 is_lazy_deopt(is_lazy) { }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000385 Label label;
386 Address address;
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000387 bool needs_frame;
388 bool is_lazy_deopt;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000389 };
390
erikcorry0ad885c2011-11-21 13:51:57 +0000391 void EnsureSpaceForLazyDeopt();
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000392 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
393 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
394 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
395 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
396 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
397 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000398
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000399 Zone* zone_;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000400 LPlatformChunk* const chunk_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000401 MacroAssembler* const masm_;
402 CompilationInfo* const info_;
403
404 int current_block_;
405 int current_instruction_;
406 const ZoneList<LInstruction*>* instructions_;
407 ZoneList<LEnvironment*> deoptimizations_;
408 ZoneList<JumpTableEntry> deopt_jump_table_;
409 ZoneList<Handle<Object> > deoptimization_literals_;
410 int inlined_function_count_;
411 Scope* const scope_;
412 Status status_;
413 TranslationBuffer translations_;
414 ZoneList<LDeferredCode*> deferred_;
415 int osr_pc_offset_;
erikcorry0ad885c2011-11-21 13:51:57 +0000416 int last_lazy_deopt_pc_;
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000417 bool frame_is_built_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000418
419 // Builder that keeps track of safepoints in the code. The table
420 // itself is emitted at the end of the generated code.
421 SafepointTableBuilder safepoints_;
422
423 // Compiler from a set of parallel moves to a sequential list of moves.
424 LGapResolver resolver_;
425
426 Safepoint::Kind expected_safepoint_kind_;
427
428 class PushSafepointRegistersScope BASE_EMBEDDED {
429 public:
430 PushSafepointRegistersScope(LCodeGen* codegen,
431 Safepoint::Kind kind)
432 : codegen_(codegen) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000433 ASSERT(codegen_->info()->is_calling());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000434 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
435 codegen_->expected_safepoint_kind_ = kind;
436
437 switch (codegen_->expected_safepoint_kind_) {
438 case Safepoint::kWithRegisters:
439 codegen_->masm_->PushSafepointRegisters();
440 break;
441 case Safepoint::kWithRegistersAndDoubles:
442 codegen_->masm_->PushSafepointRegistersAndDoubles();
443 break;
444 default:
445 UNREACHABLE();
446 }
447 }
448
449 ~PushSafepointRegistersScope() {
450 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
451 ASSERT((kind & Safepoint::kWithRegisters) != 0);
452 switch (kind) {
453 case Safepoint::kWithRegisters:
454 codegen_->masm_->PopSafepointRegisters();
455 break;
456 case Safepoint::kWithRegistersAndDoubles:
457 codegen_->masm_->PopSafepointRegistersAndDoubles();
458 break;
459 default:
460 UNREACHABLE();
461 }
462 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
463 }
464
465 private:
466 LCodeGen* codegen_;
467 };
468
469 friend class LDeferredCode;
470 friend class LEnvironment;
471 friend class SafepointGenerator;
472 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
473};
474
475
476class LDeferredCode: public ZoneObject {
477 public:
478 explicit LDeferredCode(LCodeGen* codegen)
479 : codegen_(codegen),
480 external_exit_(NULL),
481 instruction_index_(codegen->current_instruction_) {
482 codegen->AddDeferredCode(this);
483 }
484
485 virtual ~LDeferredCode() { }
486 virtual void Generate() = 0;
487 virtual LInstruction* instr() = 0;
488
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000489 void SetExit(Label* exit) { external_exit_ = exit; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000490 Label* entry() { return &entry_; }
491 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
492 int instruction_index() const { return instruction_index_; }
493
494 protected:
495 LCodeGen* codegen() const { return codegen_; }
496 MacroAssembler* masm() const { return codegen_->masm(); }
497
498 private:
499 LCodeGen* codegen_;
500 Label entry_;
501 Label exit_;
502 Label* external_exit_;
503 int instruction_index_;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000504};
ager@chromium.org5c838252010-02-19 08:53:10 +0000505
506} } // namespace v8::internal
507
lrn@chromium.org7516f052011-03-30 08:52:27 +0000508#endif // V8_MIPS_LITHIUM_CODEGEN_MIPS_H_