blob: fd4a2a5ca7e07f80e8b756c27ce2d04059b3bedf [file] [log] [blame]
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001// Copyright 2012 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_ARM_LITHIUM_CODEGEN_ARM_H_
29#define V8_ARM_LITHIUM_CODEGEN_ARM_H_
30
31#include "arm/lithium-arm.h"
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000032#include "arm/lithium-gap-resolver-arm.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033#include "deoptimizer.h"
34#include "safepoint-table.h"
35#include "scopes.h"
36
37namespace v8 {
38namespace internal {
39
40// Forward declarations.
41class LDeferredCode;
42class SafepointGenerator;
43
kasperl@chromium.orga5551262010-12-07 12:49:48 +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)),
kasperl@chromium.orga5551262010-12-07 12:49:48 +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()),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000057 inlined_function_count_(0),
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000058 scope_(info->scope()),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059 status_(UNUSED),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000060 translations_(info->zone()),
61 deferred_(8, info->zone()),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000062 osr_pc_offset_(-1),
ricow@chromium.org27bf2882011-11-17 08:34:43 +000063 last_lazy_deopt_pc_(0),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000064 safepoints_(info->zone()),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000065 resolver_(this),
mmassi@chromium.org7028c052012-06-13 11:51:58 +000066 expected_safepoint_kind_(Safepoint::kSimple) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +000067 PopulateDeoptimizationLiteralsWithInlinedFunctions();
68 }
69
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000070
71 // Simple accessors.
72 MacroAssembler* masm() const { return masm_; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000073 CompilationInfo* info() const { return info_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000074 Isolate* isolate() const { return info_->isolate(); }
75 Factory* factory() const { return isolate()->factory(); }
76 Heap* heap() const { return isolate()->heap(); }
rossberg@chromium.org400388e2012-06-06 09:29:22 +000077 Zone* zone() const { return zone_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000078
79 // Support for converting LOperands to assembler types.
80 // LOperand must be a register.
81 Register ToRegister(LOperand* op) const;
82
83 // LOperand is loaded into scratch, unless already a register.
84 Register EmitLoadRegister(LOperand* op, Register scratch);
85
86 // LOperand must be a double register.
87 DoubleRegister ToDoubleRegister(LOperand* op) const;
88
89 // LOperand is loaded into dbl_scratch, unless already a double register.
90 DoubleRegister EmitLoadDoubleRegister(LOperand* op,
91 SwVfpRegister flt_scratch,
92 DoubleRegister dbl_scratch);
93 int ToInteger32(LConstantOperand* op) const;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000094 double ToDouble(LConstantOperand* op) const;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000095 Operand ToOperand(LOperand* op);
96 MemOperand ToMemOperand(LOperand* op) const;
97 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
98 MemOperand ToHighMemOperand(LOperand* op) const;
99
danno@chromium.orgbf0c8202011-12-27 10:09:42 +0000100 bool IsInteger32(LConstantOperand* op) const;
101 Handle<Object> ToHandle(LConstantOperand* op) const;
102
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000103 // Try to generate code for the entire chunk, but it may fail if the
104 // chunk contains constructs we cannot handle. Returns true if the
105 // code generation attempt succeeded.
106 bool GenerateCode();
107
108 // Finish the code by setting stack height, safepoint, and bailout
109 // information on it.
110 void FinishCode(Handle<Code> code);
111
112 // Deferred code support.
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000113 template<int T>
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000114 void DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
115 Token::Value op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000116 void DoDeferredNumberTagD(LNumberTagD* instr);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000117
118 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
119 void DoDeferredNumberTagI(LInstruction* instr,
120 LOperand* value,
121 IntegerSignedness signedness);
122
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000123 void DoDeferredTaggedToI(LTaggedToI* instr);
124 void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
ager@chromium.org04921a82011-06-27 13:21:41 +0000125 void DoDeferredStackCheck(LStackCheck* instr);
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000126 void DoDeferredRandom(LRandom* instr);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000127 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000128 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
ulan@chromium.org967e2702012-02-28 09:49:15 +0000129 void DoDeferredAllocateObject(LAllocateObject* instr);
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000130 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
131 Label* map_check);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000132
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000133 void DoCheckMapCommon(Register reg, Register scratch, Handle<Map> map,
134 CompareMapMode mode, LEnvironment* env);
135
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 // Parallel move support.
137 void DoParallelMove(LParallelMove* move);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000138 void DoGap(LGap* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000139
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000140 MemOperand PrepareKeyedOperand(Register key,
141 Register base,
142 bool key_is_constant,
143 int constant_key,
144 int element_size,
145 int shift_size,
146 int additional_index,
147 int additional_offset);
148
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000149 // Emit frame translation commands for an environment.
150 void WriteTranslation(LEnvironment* environment, Translation* translation);
151
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000152 // Declare methods that deal with the individual node types.
153#define DECLARE_DO(type) void Do##type(L##type* node);
154 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
155#undef DECLARE_DO
156
157 private:
158 enum Status {
159 UNUSED,
160 GENERATING,
161 DONE,
162 ABORTED
163 };
164
165 bool is_unused() const { return status_ == UNUSED; }
166 bool is_generating() const { return status_ == GENERATING; }
167 bool is_done() const { return status_ == DONE; }
168 bool is_aborted() const { return status_ == ABORTED; }
169
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000170 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000171 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000172 }
173
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000174 LPlatformChunk* chunk() const { return chunk_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000175 Scope* scope() const { return scope_; }
176 HGraph* graph() const { return chunk_->graph(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000177
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000178 Register scratch0() { return r9; }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000179 DwVfpRegister double_scratch0() { return kScratchDoubleReg; }
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000180
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000181 int GetNextEmittedBlock(int block);
182 LInstruction* GetNextInstruction();
183
184 void EmitClassOfTest(Label* if_true,
185 Label* if_false,
186 Handle<String> class_name,
187 Register input,
188 Register temporary,
189 Register temporary2);
190
danno@chromium.org160a7b02011-04-18 15:51:38 +0000191 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
192 int GetParameterCount() const { return scope()->num_parameters(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000193
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000194 void Abort(const char* reason);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195 void Comment(const char* format, ...);
196
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000197 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198
199 // Code generation passes. Returns true if code generation should
200 // continue.
201 bool GeneratePrologue();
202 bool GenerateBody();
203 bool GenerateDeferredCode();
danno@chromium.org40cb8782011-05-25 07:58:50 +0000204 bool GenerateDeoptJumpTable();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000205 bool GenerateSafepointTable();
206
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000207 enum SafepointMode {
208 RECORD_SIMPLE_SAFEPOINT,
209 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
210 };
211
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212 void CallCode(Handle<Code> code,
213 RelocInfo::Mode mode,
214 LInstruction* instr);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000215
216 void CallCodeGeneric(Handle<Code> code,
217 RelocInfo::Mode mode,
218 LInstruction* instr,
219 SafepointMode safepoint_mode);
220
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000221 void CallRuntime(const Runtime::Function* function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000222 int num_arguments,
223 LInstruction* instr);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000224
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225 void CallRuntime(Runtime::FunctionId id,
226 int num_arguments,
227 LInstruction* instr) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000228 const Runtime::Function* function = Runtime::FunctionForId(id);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000229 CallRuntime(function, num_arguments, instr);
230 }
231
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000232 void CallRuntimeFromDeferred(Runtime::FunctionId id,
233 int argc,
234 LInstruction* instr);
235
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000236 enum R1State {
237 R1_UNINITIALIZED,
238 R1_CONTAINS_TARGET
239 };
240
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000241 // Generate a direct call to a known function. Expects the function
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000242 // to be in r1.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000243 void CallKnownFunction(Handle<JSFunction> function,
244 int arity,
danno@chromium.org40cb8782011-05-25 07:58:50 +0000245 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000246 CallKind call_kind,
247 R1State r1_state);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000248
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000249 void LoadHeapObject(Register result, Handle<HeapObject> object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000250
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000251 void RecordSafepointWithLazyDeopt(LInstruction* instr,
252 SafepointMode safepoint_mode);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000253
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000254 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
255 Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000256 void DeoptimizeIf(Condition cc, LEnvironment* environment);
257
258 void AddToTranslation(Translation* translation,
259 LOperand* op,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000260 bool is_tagged,
261 bool is_uint32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000262 void PopulateDeoptimizationData(Handle<Code> code);
263 int DefineDeoptimizationLiteral(Handle<Object> literal);
264
265 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
266
267 Register ToRegister(int index) const;
268 DoubleRegister ToDoubleRegister(int index) const;
269
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000270 // Specific math operations - used from DoUnaryMathOperation.
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000271 void EmitIntegerMathAbs(LUnaryMathOperation* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000272 void DoMathAbs(LUnaryMathOperation* instr);
273 void DoMathFloor(LUnaryMathOperation* instr);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000274 void DoMathRound(LUnaryMathOperation* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000275 void DoMathSqrt(LUnaryMathOperation* instr);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000276 void DoMathPowHalf(LUnaryMathOperation* instr);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000277 void DoMathLog(LUnaryMathOperation* instr);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000278 void DoMathTan(LUnaryMathOperation* instr);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000279 void DoMathCos(LUnaryMathOperation* instr);
280 void DoMathSin(LUnaryMathOperation* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000281
282 // Support for recording safepoint and position information.
ager@chromium.org378b34e2011-01-28 08:04:38 +0000283 void RecordSafepoint(LPointerMap* pointers,
284 Safepoint::Kind kind,
285 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000286 Safepoint::DeoptMode mode);
287 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
288 void RecordSafepoint(Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000289 void RecordSafepointWithRegisters(LPointerMap* pointers,
290 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000291 Safepoint::DeoptMode mode);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000292 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
293 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000294 Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000295 void RecordPosition(int position);
296
297 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
ager@chromium.org04921a82011-06-27 13:21:41 +0000298 void EmitGoto(int block);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000299 void EmitBranch(int left_block, int right_block, Condition cc);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000300 void EmitNumberUntagD(Register input,
301 DoubleRegister result,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000302 bool deoptimize_on_undefined,
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000303 bool deoptimize_on_minus_zero,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000304 LEnvironment* env);
305
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000306 void DeoptIfTaggedButNotSmi(LEnvironment* environment,
307 HValue* value,
308 LOperand* operand);
309
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000310 // Emits optimized code for typeof x == "y". Modifies input register.
311 // Returns the condition on which a final split to
312 // true and false label should be made, to optimize fallthrough.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000313 Condition EmitTypeofIs(Label* true_label,
314 Label* false_label,
315 Register input,
316 Handle<String> type_name);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000317
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000318 // Emits optimized code for %_IsObject(x). Preserves input register.
319 // Returns the condition on which a final split to
320 // true and false label should be made, to optimize fallthrough.
321 Condition EmitIsObject(Register input,
322 Register temp1,
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000323 Label* is_not_object,
324 Label* is_object);
325
erikcorry0ad885c2011-11-21 13:51:57 +0000326 // Emits optimized code for %_IsString(x). Preserves input register.
327 // Returns the condition on which a final split to
328 // true and false label should be made, to optimize fallthrough.
329 Condition EmitIsString(Register input,
330 Register temp1,
331 Label* is_not_string);
332
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000333 // Emits optimized code for %_IsConstructCall().
334 // Caller should branch on equal condition.
335 void EmitIsConstructCall(Register temp1, Register temp2);
336
lrn@chromium.org1c092762011-05-09 09:42:16 +0000337 void EmitLoadFieldOrConstantFunction(Register result,
338 Register object,
339 Handle<Map> type,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000340 Handle<String> name,
341 LEnvironment* env);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000342
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000343 // Emits optimized code to deep-copy the contents of statically known
344 // object graphs (e.g. object literal boilerplate).
345 void EmitDeepCopy(Handle<JSObject> object,
346 Register result,
347 Register source,
348 int* offset);
349
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +0000350 // Emit optimized code for integer division.
351 // Inputs are signed.
352 // All registers are clobbered.
353 // If 'remainder' is no_reg, it is not computed.
354 void EmitSignedIntegerDivisionByConstant(Register result,
355 Register dividend,
356 int32_t divisor,
357 Register remainder,
358 Register scratch,
359 LEnvironment* environment);
360
danno@chromium.org40cb8782011-05-25 07:58:50 +0000361 struct JumpTableEntry {
362 explicit inline JumpTableEntry(Address entry)
363 : label(),
364 address(entry) { }
365 Label label;
366 Address address;
367 };
368
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000369 void EnsureSpaceForLazyDeopt();
370
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000371 Zone* zone_;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000372 LPlatformChunk* const chunk_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000373 MacroAssembler* const masm_;
374 CompilationInfo* const info_;
375
376 int current_block_;
377 int current_instruction_;
378 const ZoneList<LInstruction*>* instructions_;
379 ZoneList<LEnvironment*> deoptimizations_;
danno@chromium.org40cb8782011-05-25 07:58:50 +0000380 ZoneList<JumpTableEntry> deopt_jump_table_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000381 ZoneList<Handle<Object> > deoptimization_literals_;
382 int inlined_function_count_;
383 Scope* const scope_;
384 Status status_;
385 TranslationBuffer translations_;
386 ZoneList<LDeferredCode*> deferred_;
387 int osr_pc_offset_;
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000388 int last_lazy_deopt_pc_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000389
390 // Builder that keeps track of safepoints in the code. The table
391 // itself is emitted at the end of the generated code.
392 SafepointTableBuilder safepoints_;
393
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000394 // Compiler from a set of parallel moves to a sequential list of moves.
395 LGapResolver resolver_;
396
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000397 Safepoint::Kind expected_safepoint_kind_;
398
399 class PushSafepointRegistersScope BASE_EMBEDDED {
400 public:
401 PushSafepointRegistersScope(LCodeGen* codegen,
402 Safepoint::Kind kind)
403 : codegen_(codegen) {
404 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
405 codegen_->expected_safepoint_kind_ = kind;
406
407 switch (codegen_->expected_safepoint_kind_) {
408 case Safepoint::kWithRegisters:
409 codegen_->masm_->PushSafepointRegisters();
410 break;
411 case Safepoint::kWithRegistersAndDoubles:
412 codegen_->masm_->PushSafepointRegistersAndDoubles();
413 break;
414 default:
415 UNREACHABLE();
416 }
417 }
418
419 ~PushSafepointRegistersScope() {
420 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
421 ASSERT((kind & Safepoint::kWithRegisters) != 0);
422 switch (kind) {
423 case Safepoint::kWithRegisters:
424 codegen_->masm_->PopSafepointRegisters();
425 break;
426 case Safepoint::kWithRegistersAndDoubles:
427 codegen_->masm_->PopSafepointRegistersAndDoubles();
428 break;
429 default:
430 UNREACHABLE();
431 }
432 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
433 }
434
435 private:
436 LCodeGen* codegen_;
437 };
438
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000439 friend class LDeferredCode;
440 friend class LEnvironment;
441 friend class SafepointGenerator;
442 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
443};
444
445
446class LDeferredCode: public ZoneObject {
447 public:
448 explicit LDeferredCode(LCodeGen* codegen)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000449 : codegen_(codegen),
450 external_exit_(NULL),
451 instruction_index_(codegen->current_instruction_) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000452 codegen->AddDeferredCode(this);
453 }
454
455 virtual ~LDeferredCode() { }
456 virtual void Generate() = 0;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000457 virtual LInstruction* instr() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000458
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000459 void SetExit(Label* exit) { external_exit_ = exit; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000460 Label* entry() { return &entry_; }
461 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000462 int instruction_index() const { return instruction_index_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000463
464 protected:
465 LCodeGen* codegen() const { return codegen_; }
466 MacroAssembler* masm() const { return codegen_->masm(); }
467
468 private:
469 LCodeGen* codegen_;
470 Label entry_;
471 Label exit_;
472 Label* external_exit_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000473 int instruction_index_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000474};
475
476} } // namespace v8::internal
477
478#endif // V8_ARM_LITHIUM_CODEGEN_ARM_H_