blob: 0dbfe65a40dbe85827d5ffbb7ffc822902942e1e [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 "deoptimizer.h"
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000032#include "mips/lithium-gap-resolver-mips.h"
33#include "mips/lithium-mips.h"
lrn@chromium.org7516f052011-03-30 08:52:27 +000034#include "safepoint-table.h"
35#include "scopes.h"
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000036#include "v8utils.h"
lrn@chromium.org7516f052011-03-30 08:52:27 +000037
ager@chromium.org5c838252010-02-19 08:53:10 +000038namespace v8 {
39namespace internal {
40
lrn@chromium.org7516f052011-03-30 08:52:27 +000041// Forward declarations.
42class LDeferredCode;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000043class SafepointGenerator;
ager@chromium.org5c838252010-02-19 08:53:10 +000044
lrn@chromium.org7516f052011-03-30 08:52:27 +000045class LCodeGen BASE_EMBEDDED {
46 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000047 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
48 : zone_(info->zone()),
jkummerow@chromium.org28583c92012-07-16 11:31:55 +000049 chunk_(static_cast<LPlatformChunk*>(chunk)),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000050 masm_(assembler),
51 info_(info),
52 current_block_(-1),
53 current_instruction_(-1),
54 instructions_(chunk->instructions()),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000055 deoptimizations_(4, info->zone()),
56 deopt_jump_table_(4, info->zone()),
57 deoptimization_literals_(8, info->zone()),
ulan@chromium.org2e04b582013-02-21 14:06:02 +000058 prototype_maps_(0, info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000059 inlined_function_count_(0),
60 scope_(info->scope()),
61 status_(UNUSED),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000062 translations_(info->zone()),
63 deferred_(8, info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000064 osr_pc_offset_(-1),
erikcorry0ad885c2011-11-21 13:51:57 +000065 last_lazy_deopt_pc_(0),
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000066 frame_is_built_(false),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000067 safepoints_(info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000068 resolver_(this),
69 expected_safepoint_kind_(Safepoint::kSimple) {
70 PopulateDeoptimizationLiteralsWithInlinedFunctions();
71 }
72
73
74 // Simple accessors.
75 MacroAssembler* masm() const { return masm_; }
76 CompilationInfo* info() const { return info_; }
77 Isolate* isolate() const { return info_->isolate(); }
78 Factory* factory() const { return isolate()->factory(); }
79 Heap* heap() const { return isolate()->heap(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +000080 Zone* zone() const { return zone_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000081
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000082 bool NeedsEagerFrame() const {
83 return GetStackSlotCount() > 0 ||
84 info()->is_non_deferred_calling() ||
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000085 !info()->IsStub() ||
86 info()->requires_frame();
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000087 }
88 bool NeedsDeferredFrame() const {
89 return !NeedsEagerFrame() && info()->is_deferred_calling();
90 }
91
danno@chromium.orgc99cd482013-03-21 15:26:42 +000092 RAStatus GetRAState() const {
93 return frame_is_built_ ? kRAHasBeenSaved : kRAHasNotBeenSaved;
94 }
95
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000096 // Support for converting LOperands to assembler types.
97 // LOperand must be a register.
98 Register ToRegister(LOperand* op) const;
99
100 // LOperand is loaded into scratch, unless already a register.
101 Register EmitLoadRegister(LOperand* op, Register scratch);
102
103 // LOperand must be a double register.
104 DoubleRegister ToDoubleRegister(LOperand* op) const;
105
106 // LOperand is loaded into dbl_scratch, unless already a double register.
107 DoubleRegister EmitLoadDoubleRegister(LOperand* op,
108 FloatRegister flt_scratch,
109 DoubleRegister dbl_scratch);
110 int ToInteger32(LConstantOperand* op) const;
111 double ToDouble(LConstantOperand* op) const;
112 Operand ToOperand(LOperand* op);
113 MemOperand ToMemOperand(LOperand* op) const;
114 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
115 MemOperand ToHighMemOperand(LOperand* op) const;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000116
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000117 bool IsInteger32(LConstantOperand* op) const;
118 Handle<Object> ToHandle(LConstantOperand* op) const;
119
lrn@chromium.org7516f052011-03-30 08:52:27 +0000120 // Try to generate code for the entire chunk, but it may fail if the
121 // chunk contains constructs we cannot handle. Returns true if the
122 // code generation attempt succeeded.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000123 bool GenerateCode();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000124
lrn@chromium.org7516f052011-03-30 08:52:27 +0000125 // Finish the code by setting stack height, safepoint, and bailout
126 // information on it.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000127 void FinishCode(Handle<Code> code);
128
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000129 void DoDeferredNumberTagD(LNumberTagD* instr);
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000130
131 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
132 void DoDeferredNumberTagI(LInstruction* instr,
133 LOperand* value,
134 IntegerSignedness signedness);
135
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000136 void DoDeferredTaggedToI(LTaggedToI* instr);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000137 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000138 void DoDeferredStackCheck(LStackCheck* instr);
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000139 void DoDeferredRandom(LRandom* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000140 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
141 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
ulan@chromium.org967e2702012-02-28 09:49:15 +0000142 void DoDeferredAllocateObject(LAllocateObject* instr);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000143 void DoDeferredAllocate(LAllocate* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000144 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
145 Label* map_check);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000146
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000147 void DoCheckMapCommon(Register map_reg, Handle<Map> map,
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000148 CompareMapMode mode, LEnvironment* env);
149
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000150 // Parallel move support.
151 void DoParallelMove(LParallelMove* move);
152 void DoGap(LGap* instr);
153
danno@chromium.org129d3982012-07-25 15:01:47 +0000154 MemOperand PrepareKeyedOperand(Register key,
155 Register base,
156 bool key_is_constant,
157 int constant_key,
158 int element_size,
159 int shift_size,
160 int additional_index,
161 int additional_offset);
162
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000163 // Emit frame translation commands for an environment.
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000164 void WriteTranslation(LEnvironment* environment,
165 Translation* translation,
166 int* arguments_index,
167 int* arguments_count);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000168
169 // Declare methods that deal with the individual node types.
170#define DECLARE_DO(type) void Do##type(L##type* node);
171 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
172#undef DECLARE_DO
173
174 private:
175 enum Status {
176 UNUSED,
177 GENERATING,
178 DONE,
179 ABORTED
180 };
181
182 bool is_unused() const { return status_ == UNUSED; }
183 bool is_generating() const { return status_ == GENERATING; }
184 bool is_done() const { return status_ == DONE; }
185 bool is_aborted() const { return status_ == ABORTED; }
186
187 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000188 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000189 }
190
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000191 LPlatformChunk* chunk() const { return chunk_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000192 Scope* scope() const { return scope_; }
193 HGraph* graph() const { return chunk_->graph(); }
194
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000195 Register scratch0() { return kLithiumScratchReg; }
196 Register scratch1() { return kLithiumScratchReg2; }
197 DoubleRegister double_scratch0() { return kLithiumScratchDouble; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000198
ulan@chromium.org77ca49a2013-04-22 09:43:56 +0000199 int GetNextEmittedBlock();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000200 LInstruction* GetNextInstruction();
201
202 void EmitClassOfTest(Label* if_true,
203 Label* if_false,
204 Handle<String> class_name,
205 Register input,
206 Register temporary,
207 Register temporary2);
208
209 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000210
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000211 void Abort(const char* reason);
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000212 void FPRINTF_CHECKING Comment(const char* format, ...);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000213
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000214 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000215
216 // Code generation passes. Returns true if code generation should
217 // continue.
218 bool GeneratePrologue();
219 bool GenerateBody();
220 bool GenerateDeferredCode();
221 bool GenerateDeoptJumpTable();
222 bool GenerateSafepointTable();
223
224 enum SafepointMode {
225 RECORD_SIMPLE_SAFEPOINT,
226 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
227 };
228
229 void CallCode(Handle<Code> code,
230 RelocInfo::Mode mode,
231 LInstruction* instr);
232
233 void CallCodeGeneric(Handle<Code> code,
234 RelocInfo::Mode mode,
235 LInstruction* instr,
236 SafepointMode safepoint_mode);
237
238 void CallRuntime(const Runtime::Function* function,
239 int num_arguments,
240 LInstruction* instr);
241
242 void CallRuntime(Runtime::FunctionId id,
243 int num_arguments,
244 LInstruction* instr) {
245 const Runtime::Function* function = Runtime::FunctionForId(id);
246 CallRuntime(function, num_arguments, instr);
247 }
248
249 void CallRuntimeFromDeferred(Runtime::FunctionId id,
250 int argc,
251 LInstruction* instr);
252
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000253 enum A1State {
254 A1_UNINITIALIZED,
255 A1_CONTAINS_TARGET
256 };
257
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000258 // Generate a direct call to a known function. Expects the function
259 // to be in a1.
260 void CallKnownFunction(Handle<JSFunction> function,
261 int arity,
262 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000263 CallKind call_kind,
264 A1State a1_state);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000265
266 void LoadHeapObject(Register result, Handle<HeapObject> object);
267
erikcorry0ad885c2011-11-21 13:51:57 +0000268 void RecordSafepointWithLazyDeopt(LInstruction* instr,
269 SafepointMode safepoint_mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000270
erikcorry0ad885c2011-11-21 13:51:57 +0000271 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
272 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000273 void DeoptimizeIf(Condition cc,
274 LEnvironment* environment,
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000275 Register src1 = zero_reg,
276 const Operand& src2 = Operand(zero_reg));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000277
278 void AddToTranslation(Translation* translation,
279 LOperand* op,
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000280 bool is_tagged,
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000281 bool is_uint32,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000282 bool arguments_known,
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000283 int arguments_index,
284 int arguments_count);
ulan@chromium.org6ba1fd02013-02-14 14:56:11 +0000285 void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000286 void PopulateDeoptimizationData(Handle<Code> code);
287 int DefineDeoptimizationLiteral(Handle<Object> literal);
288
289 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
290
291 Register ToRegister(int index) const;
292 DoubleRegister ToDoubleRegister(int index) const;
293
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000294 void EmitIntegerMathAbs(LMathAbs* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000295
296 // Support for recording safepoint and position information.
297 void RecordSafepoint(LPointerMap* pointers,
298 Safepoint::Kind kind,
299 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000300 Safepoint::DeoptMode mode);
301 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
302 void RecordSafepoint(Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000303 void RecordSafepointWithRegisters(LPointerMap* pointers,
304 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000305 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000306 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
307 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000308 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000309 void RecordPosition(int position);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000310
311 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
312 void EmitGoto(int block);
313 void EmitBranch(int left_block,
314 int right_block,
315 Condition cc,
316 Register src1,
317 const Operand& src2);
318 void EmitBranchF(int left_block,
319 int right_block,
320 Condition cc,
321 FPURegister src1,
322 FPURegister src2);
323 void EmitCmpI(LOperand* left, LOperand* right);
324 void EmitNumberUntagD(Register input,
325 DoubleRegister result,
326 bool deoptimize_on_undefined,
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000327 bool deoptimize_on_minus_zero,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000328 LEnvironment* env,
329 NumberUntagDMode mode);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000330
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000331 // Emits optimized code for typeof x == "y". Modifies input register.
332 // Returns the condition on which a final split to
333 // true and false label should be made, to optimize fallthrough.
334 // Returns two registers in cmp1 and cmp2 that can be used in the
335 // Branch instruction after EmitTypeofIs.
336 Condition EmitTypeofIs(Label* true_label,
337 Label* false_label,
338 Register input,
339 Handle<String> type_name,
340 Register& cmp1,
341 Operand& cmp2);
342
343 // Emits optimized code for %_IsObject(x). Preserves input register.
344 // Returns the condition on which a final split to
345 // true and false label should be made, to optimize fallthrough.
346 Condition EmitIsObject(Register input,
347 Register temp1,
erikcorry0ad885c2011-11-21 13:51:57 +0000348 Register temp2,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000349 Label* is_not_object,
350 Label* is_object);
351
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +0000352 // Emits optimized code for %_IsString(x). Preserves input register.
353 // Returns the condition on which a final split to
354 // true and false label should be made, to optimize fallthrough.
355 Condition EmitIsString(Register input,
356 Register temp1,
357 Label* is_not_string);
358
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000359 // Emits optimized code for %_IsConstructCall().
360 // Caller should branch on equal condition.
361 void EmitIsConstructCall(Register temp1, Register temp2);
362
363 void EmitLoadFieldOrConstantFunction(Register result,
364 Register object,
365 Handle<Map> type,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000366 Handle<String> name,
367 LEnvironment* env);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000368
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000369 // Emits optimized code to deep-copy the contents of statically known
370 // object graphs (e.g. object literal boilerplate).
371 void EmitDeepCopy(Handle<JSObject> object,
372 Register result,
373 Register source,
yangguo@chromium.org28381b42013-01-21 14:39:38 +0000374 int* offset,
375 AllocationSiteMode mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000376
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000377 struct JumpTableEntry {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000378 inline JumpTableEntry(Address entry, bool frame, bool is_lazy)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000379 : label(),
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000380 address(entry),
381 needs_frame(frame),
382 is_lazy_deopt(is_lazy) { }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000383 Label label;
384 Address address;
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000385 bool needs_frame;
386 bool is_lazy_deopt;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000387 };
388
erikcorry0ad885c2011-11-21 13:51:57 +0000389 void EnsureSpaceForLazyDeopt();
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000390 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
391 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
392 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
393 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
394 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
395 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000396
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000397 Zone* zone_;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000398 LPlatformChunk* const chunk_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000399 MacroAssembler* const masm_;
400 CompilationInfo* const info_;
401
402 int current_block_;
403 int current_instruction_;
404 const ZoneList<LInstruction*>* instructions_;
405 ZoneList<LEnvironment*> deoptimizations_;
406 ZoneList<JumpTableEntry> deopt_jump_table_;
407 ZoneList<Handle<Object> > deoptimization_literals_;
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000408 ZoneList<Handle<Map> > prototype_maps_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000409 int inlined_function_count_;
410 Scope* const scope_;
411 Status status_;
412 TranslationBuffer translations_;
413 ZoneList<LDeferredCode*> deferred_;
414 int osr_pc_offset_;
erikcorry0ad885c2011-11-21 13:51:57 +0000415 int last_lazy_deopt_pc_;
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000416 bool frame_is_built_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000417
418 // Builder that keeps track of safepoints in the code. The table
419 // itself is emitted at the end of the generated code.
420 SafepointTableBuilder safepoints_;
421
422 // Compiler from a set of parallel moves to a sequential list of moves.
423 LGapResolver resolver_;
424
425 Safepoint::Kind expected_safepoint_kind_;
426
427 class PushSafepointRegistersScope BASE_EMBEDDED {
428 public:
429 PushSafepointRegistersScope(LCodeGen* codegen,
430 Safepoint::Kind kind)
431 : codegen_(codegen) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000432 ASSERT(codegen_->info()->is_calling());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000433 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
434 codegen_->expected_safepoint_kind_ = kind;
435
436 switch (codegen_->expected_safepoint_kind_) {
437 case Safepoint::kWithRegisters:
438 codegen_->masm_->PushSafepointRegisters();
439 break;
440 case Safepoint::kWithRegistersAndDoubles:
441 codegen_->masm_->PushSafepointRegistersAndDoubles();
442 break;
443 default:
444 UNREACHABLE();
445 }
446 }
447
448 ~PushSafepointRegistersScope() {
449 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
450 ASSERT((kind & Safepoint::kWithRegisters) != 0);
451 switch (kind) {
452 case Safepoint::kWithRegisters:
453 codegen_->masm_->PopSafepointRegisters();
454 break;
455 case Safepoint::kWithRegistersAndDoubles:
456 codegen_->masm_->PopSafepointRegistersAndDoubles();
457 break;
458 default:
459 UNREACHABLE();
460 }
461 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
462 }
463
464 private:
465 LCodeGen* codegen_;
466 };
467
468 friend class LDeferredCode;
469 friend class LEnvironment;
470 friend class SafepointGenerator;
471 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
472};
473
474
475class LDeferredCode: public ZoneObject {
476 public:
477 explicit LDeferredCode(LCodeGen* codegen)
478 : codegen_(codegen),
479 external_exit_(NULL),
480 instruction_index_(codegen->current_instruction_) {
481 codegen->AddDeferredCode(this);
482 }
483
484 virtual ~LDeferredCode() { }
485 virtual void Generate() = 0;
486 virtual LInstruction* instr() = 0;
487
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000488 void SetExit(Label* exit) { external_exit_ = exit; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000489 Label* entry() { return &entry_; }
490 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
491 int instruction_index() const { return instruction_index_; }
492
493 protected:
494 LCodeGen* codegen() const { return codegen_; }
495 MacroAssembler* masm() const { return codegen_->masm(); }
496
497 private:
498 LCodeGen* codegen_;
499 Label entry_;
500 Label exit_;
501 Label* external_exit_;
502 int instruction_index_;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000503};
ager@chromium.org5c838252010-02-19 08:53:10 +0000504
505} } // namespace v8::internal
506
lrn@chromium.org7516f052011-03-30 08:52:27 +0000507#endif // V8_MIPS_LITHIUM_CODEGEN_MIPS_H_