blob: 1c99cf99f1b685ae6d191c244bce18c46da9287f [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()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000058 inlined_function_count_(0),
59 scope_(info->scope()),
60 status_(UNUSED),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000061 translations_(info->zone()),
62 deferred_(8, info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000063 osr_pc_offset_(-1),
erikcorry0ad885c2011-11-21 13:51:57 +000064 last_lazy_deopt_pc_(0),
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000065 frame_is_built_(false),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000066 safepoints_(info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000067 resolver_(this),
68 expected_safepoint_kind_(Safepoint::kSimple) {
69 PopulateDeoptimizationLiteralsWithInlinedFunctions();
70 }
71
72
73 // Simple accessors.
74 MacroAssembler* masm() const { return masm_; }
75 CompilationInfo* info() const { return info_; }
76 Isolate* isolate() const { return info_->isolate(); }
77 Factory* factory() const { return isolate()->factory(); }
78 Heap* heap() const { return isolate()->heap(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +000079 Zone* zone() const { return zone_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000080
ulan@chromium.org32d7dba2013-04-24 10:59:06 +000081 // TODO(svenpanne) Use this consistently.
82 int LookupDestination(int block_id) const {
83 return chunk()->LookupDestination(block_id);
84 }
85
86 bool IsNextEmittedBlock(int block_id) const {
87 return LookupDestination(block_id) == GetNextEmittedBlock();
88 }
89
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000090 bool NeedsEagerFrame() const {
91 return GetStackSlotCount() > 0 ||
92 info()->is_non_deferred_calling() ||
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000093 !info()->IsStub() ||
94 info()->requires_frame();
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000095 }
96 bool NeedsDeferredFrame() const {
97 return !NeedsEagerFrame() && info()->is_deferred_calling();
98 }
99
danno@chromium.orgc99cd482013-03-21 15:26:42 +0000100 RAStatus GetRAState() const {
101 return frame_is_built_ ? kRAHasBeenSaved : kRAHasNotBeenSaved;
102 }
103
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000104 // Support for converting LOperands to assembler types.
105 // LOperand must be a register.
106 Register ToRegister(LOperand* op) const;
107
108 // LOperand is loaded into scratch, unless already a register.
109 Register EmitLoadRegister(LOperand* op, Register scratch);
110
111 // LOperand must be a double register.
112 DoubleRegister ToDoubleRegister(LOperand* op) const;
113
114 // LOperand is loaded into dbl_scratch, unless already a double register.
115 DoubleRegister EmitLoadDoubleRegister(LOperand* op,
116 FloatRegister flt_scratch,
117 DoubleRegister dbl_scratch);
118 int ToInteger32(LConstantOperand* op) const;
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000119 Smi* ToSmi(LConstantOperand* op) const;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000120 double ToDouble(LConstantOperand* op) const;
121 Operand ToOperand(LOperand* op);
122 MemOperand ToMemOperand(LOperand* op) const;
123 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
124 MemOperand ToHighMemOperand(LOperand* op) const;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000125
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000126 bool IsInteger32(LConstantOperand* op) const;
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000127 bool IsSmi(LConstantOperand* op) const;
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000128 Handle<Object> ToHandle(LConstantOperand* op) const;
129
lrn@chromium.org7516f052011-03-30 08:52:27 +0000130 // Try to generate code for the entire chunk, but it may fail if the
131 // chunk contains constructs we cannot handle. Returns true if the
132 // code generation attempt succeeded.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000133 bool GenerateCode();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000134
lrn@chromium.org7516f052011-03-30 08:52:27 +0000135 // Finish the code by setting stack height, safepoint, and bailout
136 // information on it.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000137 void FinishCode(Handle<Code> code);
138
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000139 void DoDeferredNumberTagD(LNumberTagD* instr);
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000140
141 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
142 void DoDeferredNumberTagI(LInstruction* instr,
143 LOperand* value,
144 IntegerSignedness signedness);
145
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000146 void DoDeferredTaggedToI(LTaggedToI* instr);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000147 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000148 void DoDeferredStackCheck(LStackCheck* instr);
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000149 void DoDeferredRandom(LRandom* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000150 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
151 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000152 void DoDeferredAllocate(LAllocate* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000153 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
154 Label* map_check);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000155
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000156 void DoCheckMapCommon(Register map_reg, Handle<Map> map, LEnvironment* env);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000157
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000158 // Parallel move support.
159 void DoParallelMove(LParallelMove* move);
160 void DoGap(LGap* instr);
161
danno@chromium.org129d3982012-07-25 15:01:47 +0000162 MemOperand PrepareKeyedOperand(Register key,
163 Register base,
164 bool key_is_constant,
165 int constant_key,
166 int element_size,
167 int shift_size,
168 int additional_index,
169 int additional_offset);
170
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000171 // Emit frame translation commands for an environment.
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000172 void WriteTranslation(LEnvironment* environment, Translation* translation);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000173
174 // Declare methods that deal with the individual node types.
175#define DECLARE_DO(type) void Do##type(L##type* node);
176 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
177#undef DECLARE_DO
178
179 private:
180 enum Status {
181 UNUSED,
182 GENERATING,
183 DONE,
184 ABORTED
185 };
186
187 bool is_unused() const { return status_ == UNUSED; }
188 bool is_generating() const { return status_ == GENERATING; }
189 bool is_done() const { return status_ == DONE; }
190 bool is_aborted() const { return status_ == ABORTED; }
191
192 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000193 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000194 }
195
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000196 LPlatformChunk* chunk() const { return chunk_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000197 Scope* scope() const { return scope_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000198 HGraph* graph() const { return chunk()->graph(); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000199
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000200 Register scratch0() { return kLithiumScratchReg; }
201 Register scratch1() { return kLithiumScratchReg2; }
202 DoubleRegister double_scratch0() { return kLithiumScratchDouble; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000203
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000204 int GetNextEmittedBlock() const;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000205 LInstruction* GetNextInstruction();
206
207 void EmitClassOfTest(Label* if_true,
208 Label* if_false,
209 Handle<String> class_name,
210 Register input,
211 Register temporary,
212 Register temporary2);
213
214 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000215
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000216 void Abort(const char* reason);
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000217 void FPRINTF_CHECKING Comment(const char* format, ...);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000218
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000219 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000220
221 // Code generation passes. Returns true if code generation should
222 // continue.
223 bool GeneratePrologue();
224 bool GenerateBody();
225 bool GenerateDeferredCode();
226 bool GenerateDeoptJumpTable();
227 bool GenerateSafepointTable();
228
229 enum SafepointMode {
230 RECORD_SIMPLE_SAFEPOINT,
231 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
232 };
233
234 void CallCode(Handle<Code> code,
235 RelocInfo::Mode mode,
236 LInstruction* instr);
237
238 void CallCodeGeneric(Handle<Code> code,
239 RelocInfo::Mode mode,
240 LInstruction* instr,
241 SafepointMode safepoint_mode);
242
243 void CallRuntime(const Runtime::Function* function,
244 int num_arguments,
245 LInstruction* instr);
246
247 void CallRuntime(Runtime::FunctionId id,
248 int num_arguments,
249 LInstruction* instr) {
250 const Runtime::Function* function = Runtime::FunctionForId(id);
251 CallRuntime(function, num_arguments, instr);
252 }
253
254 void CallRuntimeFromDeferred(Runtime::FunctionId id,
255 int argc,
256 LInstruction* instr);
257
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000258 enum A1State {
259 A1_UNINITIALIZED,
260 A1_CONTAINS_TARGET
261 };
262
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000263 // Generate a direct call to a known function. Expects the function
264 // to be in a1.
265 void CallKnownFunction(Handle<JSFunction> function,
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000266 int formal_parameter_count,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000267 int arity,
268 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000269 CallKind call_kind,
270 A1State a1_state);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000271
272 void LoadHeapObject(Register result, Handle<HeapObject> object);
273
erikcorry0ad885c2011-11-21 13:51:57 +0000274 void RecordSafepointWithLazyDeopt(LInstruction* instr,
275 SafepointMode safepoint_mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000276
erikcorry0ad885c2011-11-21 13:51:57 +0000277 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
278 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000279 void DeoptimizeIf(Condition cc,
280 LEnvironment* environment,
palfia@homejinni.com04109732013-05-15 09:50:32 +0000281 Deoptimizer::BailoutType bailout_type,
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000282 Register src1 = zero_reg,
283 const Operand& src2 = Operand(zero_reg));
palfia@homejinni.com04109732013-05-15 09:50:32 +0000284 void DeoptimizeIf(Condition cc,
285 LEnvironment* environment,
286 Register src1 = zero_reg,
287 const Operand& src2 = Operand(zero_reg));
288 void SoftDeoptimize(LEnvironment* environment,
289 Register src1 = zero_reg,
290 const Operand& src2 = Operand(zero_reg));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000291
292 void AddToTranslation(Translation* translation,
293 LOperand* op,
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000294 bool is_tagged,
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000295 bool is_uint32);
ulan@chromium.org6ba1fd02013-02-14 14:56:11 +0000296 void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000297 void PopulateDeoptimizationData(Handle<Code> code);
298 int DefineDeoptimizationLiteral(Handle<Object> literal);
299
300 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
301
302 Register ToRegister(int index) const;
303 DoubleRegister ToDoubleRegister(int index) const;
304
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000305 void EmitIntegerMathAbs(LMathAbs* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000306
307 // Support for recording safepoint and position information.
308 void RecordSafepoint(LPointerMap* pointers,
309 Safepoint::Kind kind,
310 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000311 Safepoint::DeoptMode mode);
312 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
313 void RecordSafepoint(Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000314 void RecordSafepointWithRegisters(LPointerMap* pointers,
315 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000316 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000317 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
318 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000319 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000320 void RecordPosition(int position);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000321
322 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
323 void EmitGoto(int block);
324 void EmitBranch(int left_block,
325 int right_block,
326 Condition cc,
327 Register src1,
328 const Operand& src2);
329 void EmitBranchF(int left_block,
330 int right_block,
331 Condition cc,
332 FPURegister src1,
333 FPURegister src2);
334 void EmitCmpI(LOperand* left, LOperand* right);
335 void EmitNumberUntagD(Register input,
336 DoubleRegister result,
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000337 bool allow_undefined_as_nan,
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000338 bool deoptimize_on_minus_zero,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000339 LEnvironment* env,
340 NumberUntagDMode mode);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000341
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000342 // Emits optimized code for typeof x == "y". Modifies input register.
343 // Returns the condition on which a final split to
344 // true and false label should be made, to optimize fallthrough.
345 // Returns two registers in cmp1 and cmp2 that can be used in the
346 // Branch instruction after EmitTypeofIs.
347 Condition EmitTypeofIs(Label* true_label,
348 Label* false_label,
349 Register input,
350 Handle<String> type_name,
351 Register& cmp1,
352 Operand& cmp2);
353
354 // Emits optimized code for %_IsObject(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 EmitIsObject(Register input,
358 Register temp1,
erikcorry0ad885c2011-11-21 13:51:57 +0000359 Register temp2,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000360 Label* is_not_object,
361 Label* is_object);
362
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +0000363 // Emits optimized code for %_IsString(x). Preserves input register.
364 // Returns the condition on which a final split to
365 // true and false label should be made, to optimize fallthrough.
366 Condition EmitIsString(Register input,
367 Register temp1,
368 Label* is_not_string);
369
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000370 // Emits optimized code for %_IsConstructCall().
371 // Caller should branch on equal condition.
372 void EmitIsConstructCall(Register temp1, Register temp2);
373
374 void EmitLoadFieldOrConstantFunction(Register result,
375 Register object,
376 Handle<Map> type,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000377 Handle<String> name,
378 LEnvironment* env);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000379
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000380 // Emits optimized code to deep-copy the contents of statically known
381 // object graphs (e.g. object literal boilerplate).
382 void EmitDeepCopy(Handle<JSObject> object,
383 Register result,
384 Register source,
yangguo@chromium.org28381b42013-01-21 14:39:38 +0000385 int* offset,
386 AllocationSiteMode mode);
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000387 // Emit optimized code for integer division.
388 // Inputs are signed.
389 // All registers are clobbered.
390 // If 'remainder' is no_reg, it is not computed.
391 void EmitSignedIntegerDivisionByConstant(Register result,
392 Register dividend,
393 int32_t divisor,
394 Register remainder,
395 Register scratch,
396 LEnvironment* environment);
397
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000398
erikcorry0ad885c2011-11-21 13:51:57 +0000399 void EnsureSpaceForLazyDeopt();
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000400 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
401 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
402 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
403 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
404 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
405 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000406
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000407 Zone* zone_;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000408 LPlatformChunk* const chunk_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000409 MacroAssembler* const masm_;
410 CompilationInfo* const info_;
411
412 int current_block_;
413 int current_instruction_;
414 const ZoneList<LInstruction*>* instructions_;
415 ZoneList<LEnvironment*> deoptimizations_;
palfia@homejinni.com04109732013-05-15 09:50:32 +0000416 ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000417 ZoneList<Handle<Object> > deoptimization_literals_;
418 int inlined_function_count_;
419 Scope* const scope_;
420 Status status_;
421 TranslationBuffer translations_;
422 ZoneList<LDeferredCode*> deferred_;
423 int osr_pc_offset_;
erikcorry0ad885c2011-11-21 13:51:57 +0000424 int last_lazy_deopt_pc_;
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000425 bool frame_is_built_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000426
427 // Builder that keeps track of safepoints in the code. The table
428 // itself is emitted at the end of the generated code.
429 SafepointTableBuilder safepoints_;
430
431 // Compiler from a set of parallel moves to a sequential list of moves.
432 LGapResolver resolver_;
433
434 Safepoint::Kind expected_safepoint_kind_;
435
436 class PushSafepointRegistersScope BASE_EMBEDDED {
437 public:
438 PushSafepointRegistersScope(LCodeGen* codegen,
439 Safepoint::Kind kind)
440 : codegen_(codegen) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000441 ASSERT(codegen_->info()->is_calling());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000442 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
443 codegen_->expected_safepoint_kind_ = kind;
444
445 switch (codegen_->expected_safepoint_kind_) {
446 case Safepoint::kWithRegisters:
447 codegen_->masm_->PushSafepointRegisters();
448 break;
449 case Safepoint::kWithRegistersAndDoubles:
450 codegen_->masm_->PushSafepointRegistersAndDoubles();
451 break;
452 default:
453 UNREACHABLE();
454 }
455 }
456
457 ~PushSafepointRegistersScope() {
458 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
459 ASSERT((kind & Safepoint::kWithRegisters) != 0);
460 switch (kind) {
461 case Safepoint::kWithRegisters:
462 codegen_->masm_->PopSafepointRegisters();
463 break;
464 case Safepoint::kWithRegistersAndDoubles:
465 codegen_->masm_->PopSafepointRegistersAndDoubles();
466 break;
467 default:
468 UNREACHABLE();
469 }
470 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
471 }
472
473 private:
474 LCodeGen* codegen_;
475 };
476
477 friend class LDeferredCode;
478 friend class LEnvironment;
479 friend class SafepointGenerator;
480 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
481};
482
483
484class LDeferredCode: public ZoneObject {
485 public:
486 explicit LDeferredCode(LCodeGen* codegen)
487 : codegen_(codegen),
488 external_exit_(NULL),
489 instruction_index_(codegen->current_instruction_) {
490 codegen->AddDeferredCode(this);
491 }
492
493 virtual ~LDeferredCode() { }
494 virtual void Generate() = 0;
495 virtual LInstruction* instr() = 0;
496
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000497 void SetExit(Label* exit) { external_exit_ = exit; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000498 Label* entry() { return &entry_; }
499 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
500 int instruction_index() const { return instruction_index_; }
501
502 protected:
503 LCodeGen* codegen() const { return codegen_; }
504 MacroAssembler* masm() const { return codegen_->masm(); }
505
506 private:
507 LCodeGen* codegen_;
508 Label entry_;
509 Label exit_;
510 Label* external_exit_;
511 int instruction_index_;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000512};
ager@chromium.org5c838252010-02-19 08:53:10 +0000513
514} } // namespace v8::internal
515
lrn@chromium.org7516f052011-03-30 08:52:27 +0000516#endif // V8_MIPS_LITHIUM_CODEGEN_MIPS_H_