blob: 09182523271b78aabd037c2315686d467b86f214 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Ben Murdochb0fe1622011-05-05 13:52:32 +01004
5#ifndef V8_IA32_LITHIUM_CODEGEN_IA32_H_
6#define V8_IA32_LITHIUM_CODEGEN_IA32_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/ia32/lithium-ia32.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +01009
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/base/logging.h"
11#include "src/deoptimizer.h"
12#include "src/ia32/lithium-gap-resolver-ia32.h"
13#include "src/lithium-codegen.h"
14#include "src/safepoint-table.h"
15#include "src/scopes.h"
16#include "src/utils.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010017
18namespace v8 {
19namespace internal {
20
21// Forward declarations.
22class LDeferredCode;
Ben Murdochb8e0da22011-05-16 14:20:40 +010023class LGapNode;
Ben Murdochb0fe1622011-05-05 13:52:32 +010024class SafepointGenerator;
25
Ben Murdochb8a8cc12014-11-26 15:28:44 +000026class LCodeGen: public LCodeGenBase {
Ben Murdochb0fe1622011-05-05 13:52:32 +010027 public:
28 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029 : LCodeGenBase(chunk, assembler, info),
30 deoptimizations_(4, info->zone()),
31 jump_table_(4, info->zone()),
32 deoptimization_literals_(8, info->zone()),
Ben Murdochb0fe1622011-05-05 13:52:32 +010033 inlined_function_count_(0),
Ben Murdoche0cee9b2011-05-25 10:26:03 +010034 scope_(info->scope()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035 translations_(info->zone()),
36 deferred_(8, info->zone()),
37 dynamic_frame_alignment_(false),
38 support_aligned_spilled_doubles_(false),
Ben Murdochb8e0da22011-05-16 14:20:40 +010039 osr_pc_offset_(-1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040 frame_is_built_(false),
41 safepoints_(info->zone()),
Ben Murdoch8b112d22011-06-08 16:22:53 +010042 resolver_(this),
43 expected_safepoint_kind_(Safepoint::kSimple) {
Ben Murdochb0fe1622011-05-05 13:52:32 +010044 PopulateDeoptimizationLiteralsWithInlinedFunctions();
45 }
46
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047 int LookupDestination(int block_id) const {
48 return chunk()->LookupDestination(block_id);
49 }
50
51 bool IsNextEmittedBlock(int block_id) const {
52 return LookupDestination(block_id) == GetNextEmittedBlock();
53 }
54
55 bool NeedsEagerFrame() const {
56 return GetStackSlotCount() > 0 ||
57 info()->is_non_deferred_calling() ||
58 !info()->IsStub() ||
59 info()->requires_frame();
60 }
61 bool NeedsDeferredFrame() const {
62 return !NeedsEagerFrame() && info()->is_deferred_calling();
63 }
Ben Murdochb8e0da22011-05-16 14:20:40 +010064
65 // Support for converting LOperands to assembler types.
66 Operand ToOperand(LOperand* op) const;
67 Register ToRegister(LOperand* op) const;
68 XMMRegister ToDoubleRegister(LOperand* op) const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010069
70 bool IsInteger32(LConstantOperand* op) const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071 bool IsSmi(LConstantOperand* op) const;
72 Immediate ToImmediate(LOperand* op, const Representation& r) const {
73 return Immediate(ToRepresentation(LConstantOperand::cast(op), r));
Ben Murdoch3ef787d2012-04-12 10:51:47 +010074 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075 double ToDouble(LConstantOperand* op) const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010076
77 Handle<Object> ToHandle(LConstantOperand* op) const;
Ben Murdochb8e0da22011-05-16 14:20:40 +010078
79 // The operand denoting the second word (the one with a higher address) of
80 // a double stack slot.
81 Operand HighOperand(LOperand* op);
82
Ben Murdochb0fe1622011-05-05 13:52:32 +010083 // Try to generate code for the entire chunk, but it may fail if the
84 // chunk contains constructs we cannot handle. Returns true if the
85 // code generation attempt succeeded.
86 bool GenerateCode();
87
88 // Finish the code by setting stack height, safepoint, and bailout
89 // information on it.
90 void FinishCode(Handle<Code> code);
91
92 // Deferred code support.
93 void DoDeferredNumberTagD(LNumberTagD* instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094
95 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
96 void DoDeferredNumberTagIU(LInstruction* instr,
97 LOperand* value,
98 LOperand* temp,
99 IntegerSignedness signedness);
100
101 void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
102 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000103 void DoDeferredStackCheck(LStackCheck* instr);
Steve Block1e0659c2011-05-24 12:43:12 +0100104 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
Steve Block44f0eee2011-05-26 01:26:41 +0100105 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106 void DoDeferredAllocate(LAllocate* instr);
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000107 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
108 Label* map_check);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109 void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
110 void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
111 Register object,
112 Register index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100113
Ben Murdochb0fe1622011-05-05 13:52:32 +0100114 // Parallel move support.
115 void DoParallelMove(LParallelMove* move);
Ben Murdoch257744e2011-11-30 15:57:28 +0000116 void DoGap(LGap* instr);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100117
Ben Murdochb8e0da22011-05-16 14:20:40 +0100118 // Emit frame translation commands for an environment.
119 void WriteTranslation(LEnvironment* environment, Translation* translation);
120
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100121 void EnsureRelocSpaceForDeoptimization();
122
Ben Murdochb0fe1622011-05-05 13:52:32 +0100123 // Declare methods that deal with the individual node types.
124#define DECLARE_DO(type) void Do##type(L##type* node);
125 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
126#undef DECLARE_DO
127
128 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129 StrictMode strict_mode() const { return info()->strict_mode(); }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100130
Ben Murdochb0fe1622011-05-05 13:52:32 +0100131 Scope* scope() const { return scope_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100132
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000133 XMMRegister double_scratch0() const { return xmm0; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100134
135 void EmitClassOfTest(Label* if_true,
136 Label* if_false,
137 Handle<String> class_name,
138 Register input,
139 Register temporary,
140 Register temporary2);
141
Ben Murdoch257744e2011-11-30 15:57:28 +0000142 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100143
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000144 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100145
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000146 void SaveCallerDoubles();
147 void RestoreCallerDoubles();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100148
149 // Code generation passes. Returns true if code generation should
150 // continue.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000151 void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE;
152 void GenerateBodyInstructionPost(LInstruction* instr) OVERRIDE;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100153 bool GeneratePrologue();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100154 bool GenerateDeferredCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000155 bool GenerateJumpTable();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100156 bool GenerateSafepointTable();
157
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158 // Generates the custom OSR entrypoint and sets the osr_pc_offset.
159 void GenerateOsrPrologue();
160
Ben Murdoch8b112d22011-06-08 16:22:53 +0100161 enum SafepointMode {
162 RECORD_SIMPLE_SAFEPOINT,
163 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
164 };
165
166 void CallCode(Handle<Code> code,
167 RelocInfo::Mode mode,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000168 LInstruction* instr);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100169
170 void CallCodeGeneric(Handle<Code> code,
171 RelocInfo::Mode mode,
172 LInstruction* instr,
Ben Murdoch8b112d22011-06-08 16:22:53 +0100173 SafepointMode safepoint_mode);
174
175 void CallRuntime(const Runtime::Function* fun,
176 int argc,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000177 LInstruction* instr,
178 SaveFPRegsMode save_doubles = kDontSaveFPRegs);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100179
180 void CallRuntime(Runtime::FunctionId id,
181 int argc,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000182 LInstruction* instr) {
Steve Block44f0eee2011-05-26 01:26:41 +0100183 const Runtime::Function* function = Runtime::FunctionForId(id);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000184 CallRuntime(function, argc, instr);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100185 }
186
Ben Murdoch8b112d22011-06-08 16:22:53 +0100187 void CallRuntimeFromDeferred(Runtime::FunctionId id,
188 int argc,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000189 LInstruction* instr,
190 LOperand* context);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100191
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192 void LoadContextFromDeferred(LOperand* context);
193
194 enum EDIState {
195 EDI_UNINITIALIZED,
196 EDI_CONTAINS_TARGET
197 };
198
Ben Murdochb0fe1622011-05-05 13:52:32 +0100199 // Generate a direct call to a known function. Expects the function
200 // to be in edi.
201 void CallKnownFunction(Handle<JSFunction> function,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000202 int formal_parameter_count,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100203 int arity,
Ben Murdoch257744e2011-11-30 15:57:28 +0000204 LInstruction* instr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000205 EDIState edi_state);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100206
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000207 void RecordSafepointWithLazyDeopt(LInstruction* instr,
208 SafepointMode safepoint_mode);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100209
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000210 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
211 Safepoint::DeoptMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000212 void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail,
213 Deoptimizer::BailoutType bailout_type);
214 void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100215
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000216 bool DeoptEveryNTimes() {
217 return FLAG_deopt_every_n_times != 0 && !info()->IsStub();
218 }
219
220 void AddToTranslation(LEnvironment* environment,
221 Translation* translation,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100222 LOperand* op,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000223 bool is_tagged,
224 bool is_uint32,
225 int* object_index_pointer,
226 int* dematerialized_index_pointer);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100227 void PopulateDeoptimizationData(Handle<Code> code);
228 int DefineDeoptimizationLiteral(Handle<Object> literal);
229
230 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
231
232 Register ToRegister(int index) const;
233 XMMRegister ToDoubleRegister(int index) const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234 int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const;
235 int32_t ToInteger32(LConstantOperand* op) const;
236 ExternalReference ToExternalReference(LConstantOperand* op) const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100237
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000238 Operand BuildFastArrayOperand(LOperand* elements_pointer,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000239 LOperand* key,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000240 Representation key_representation,
Ben Murdoch589d6972011-11-30 16:04:58 +0000241 ElementsKind elements_kind,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000242 uint32_t base_offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100243
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000244 Operand BuildSeqStringOperand(Register string,
245 LOperand* index,
246 String::Encoding encoding);
247
248 void EmitIntegerMathAbs(LMathAbs* instr);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100249
250 // Support for recording safepoint and position information.
Steve Block1e0659c2011-05-24 12:43:12 +0100251 void RecordSafepoint(LPointerMap* pointers,
252 Safepoint::Kind kind,
253 int arguments,
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000254 Safepoint::DeoptMode mode);
255 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
256 void RecordSafepoint(Safepoint::DeoptMode mode);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100257 void RecordSafepointWithRegisters(LPointerMap* pointers,
258 int arguments,
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000259 Safepoint::DeoptMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000260
261 void RecordAndWritePosition(int position) OVERRIDE;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100262
263 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000264 void EmitGoto(int block);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000265
266 // EmitBranch expects to be the last instruction of a block.
267 template<class InstrType>
268 void EmitBranch(InstrType instr, Condition cc);
269 template<class InstrType>
270 void EmitFalseBranch(InstrType instr, Condition cc);
271 void EmitNumberUntagD(LNumberUntagD* instr, Register input, Register temp,
272 XMMRegister result, NumberUntagDMode mode);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100273
274 // Emits optimized code for typeof x == "y". Modifies input register.
275 // Returns the condition on which a final split to
276 // true and false label should be made, to optimize fallthrough.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000277 Condition EmitTypeofIs(LTypeofIsAndBranch* instr, Register input);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100278
279 // Emits optimized code for %_IsObject(x). Preserves input register.
280 // Returns the condition on which a final split to
281 // true and false label should be made, to optimize fallthrough.
282 Condition EmitIsObject(Register input,
283 Register temp1,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100284 Label* is_not_object,
285 Label* is_object);
286
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100287 // Emits optimized code for %_IsString(x). Preserves input register.
288 // Returns the condition on which a final split to
289 // true and false label should be made, to optimize fallthrough.
290 Condition EmitIsString(Register input,
291 Register temp1,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000292 Label* is_not_string,
293 SmiCheck check_needed);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100294
Steve Block1e0659c2011-05-24 12:43:12 +0100295 // Emits optimized code for %_IsConstructCall().
296 // Caller should branch on equal condition.
297 void EmitIsConstructCall(Register temp);
298
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100299 // Emits optimized code to deep-copy the contents of statically known
300 // object graphs (e.g. object literal boilerplate).
301 void EmitDeepCopy(Handle<JSObject> object,
302 Register result,
303 Register source,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000304 int* offset,
305 AllocationSiteMode mode);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100306
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000307 void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE;
308 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
309 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
310 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
311 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
312 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
313 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
314
315 template <class T>
316 void EmitVectorLoadICRegisters(T* instr);
317
318 void EmitReturn(LReturn* instr, bool dynamic_frame_alignment);
Steve Block1e0659c2011-05-24 12:43:12 +0100319
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100320 // Emits code for pushing either a tagged constant, a (non-double)
321 // register, or a stack slot operand.
322 void EmitPushTaggedOperand(LOperand* operand);
323
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000324 friend class LGapResolver;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100325
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000326#ifdef _MSC_VER
327 // On windows, you may not access the stack more than one page below
328 // the most recently mapped page. To make the allocated area randomly
329 // accessible, we write an arbitrary value to each page in range
330 // esp + offset - page_size .. esp in turn.
331 void MakeSureStackPagesMapped(int offset);
332#endif
333
Ben Murdochb0fe1622011-05-05 13:52:32 +0100334 ZoneList<LEnvironment*> deoptimizations_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000335 ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100336 ZoneList<Handle<Object> > deoptimization_literals_;
337 int inlined_function_count_;
338 Scope* const scope_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100339 TranslationBuffer translations_;
340 ZoneList<LDeferredCode*> deferred_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341 bool dynamic_frame_alignment_;
342 bool support_aligned_spilled_doubles_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100343 int osr_pc_offset_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000344 bool frame_is_built_;
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100345
Ben Murdochb0fe1622011-05-05 13:52:32 +0100346 // Builder that keeps track of safepoints in the code. The table
347 // itself is emitted at the end of the generated code.
348 SafepointTableBuilder safepoints_;
349
Ben Murdochb8e0da22011-05-16 14:20:40 +0100350 // Compiler from a set of parallel moves to a sequential list of moves.
351 LGapResolver resolver_;
352
Ben Murdoch8b112d22011-06-08 16:22:53 +0100353 Safepoint::Kind expected_safepoint_kind_;
354
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000355 class PushSafepointRegistersScope FINAL BASE_EMBEDDED {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100356 public:
357 explicit PushSafepointRegistersScope(LCodeGen* codegen)
358 : codegen_(codegen) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100360 codegen_->masm_->PushSafepointRegisters();
361 codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000362 DCHECK(codegen_->info()->is_calling());
Ben Murdoch8b112d22011-06-08 16:22:53 +0100363 }
364
365 ~PushSafepointRegistersScope() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000366 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100367 codegen_->masm_->PopSafepointRegisters();
368 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
369 }
370
371 private:
372 LCodeGen* codegen_;
373 };
374
Ben Murdochb0fe1622011-05-05 13:52:32 +0100375 friend class LDeferredCode;
376 friend class LEnvironment;
377 friend class SafepointGenerator;
378 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
379};
380
381
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000382class LDeferredCode : public ZoneObject {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100383 public:
384 explicit LDeferredCode(LCodeGen* codegen)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100385 : codegen_(codegen),
386 external_exit_(NULL),
387 instruction_index_(codegen->current_instruction_) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100388 codegen->AddDeferredCode(this);
389 }
390
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000391 virtual ~LDeferredCode() {}
Ben Murdochb0fe1622011-05-05 13:52:32 +0100392 virtual void Generate() = 0;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100393 virtual LInstruction* instr() = 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100394
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100395 void SetExit(Label* exit) { external_exit_ = exit; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100396 Label* entry() { return &entry_; }
397 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000398 Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100399 int instruction_index() const { return instruction_index_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100400
401 protected:
402 LCodeGen* codegen() const { return codegen_; }
403 MacroAssembler* masm() const { return codegen_->masm(); }
404
405 private:
406 LCodeGen* codegen_;
407 Label entry_;
408 Label exit_;
409 Label* external_exit_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000410 Label done_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100411 int instruction_index_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100412};
413
414} } // namespace v8::internal
415
416#endif // V8_IA32_LITHIUM_CODEGEN_IA32_H_