blob: c1041326b4b3b0aa73feecabd0fb91ff0aa0f63d [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"
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000032
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000033#include "arm/lithium-gap-resolver-arm.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "deoptimizer.h"
35#include "safepoint-table.h"
36#include "scopes.h"
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000037#include "v8utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000038
39namespace v8 {
40namespace internal {
41
42// Forward declarations.
43class LDeferredCode;
44class SafepointGenerator;
45
kasperl@chromium.orga5551262010-12-07 12:49:48 +000046class LCodeGen BASE_EMBEDDED {
47 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000048 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
49 : zone_(info->zone()),
jkummerow@chromium.org28583c92012-07-16 11:31:55 +000050 chunk_(static_cast<LPlatformChunk*>(chunk)),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000051 masm_(assembler),
52 info_(info),
53 current_block_(-1),
54 current_instruction_(-1),
55 instructions_(chunk->instructions()),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000056 deoptimizations_(4, info->zone()),
57 deopt_jump_table_(4, info->zone()),
58 deoptimization_literals_(8, info->zone()),
ulan@chromium.org2e04b582013-02-21 14:06:02 +000059 prototype_maps_(0, info->zone()),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000060 inlined_function_count_(0),
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000061 scope_(info->scope()),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000062 status_(UNUSED),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000063 translations_(info->zone()),
64 deferred_(8, info->zone()),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000065 osr_pc_offset_(-1),
ricow@chromium.org27bf2882011-11-17 08:34:43 +000066 last_lazy_deopt_pc_(0),
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000067 frame_is_built_(false),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000068 safepoints_(info->zone()),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000069 resolver_(this),
mmassi@chromium.org7028c052012-06-13 11:51:58 +000070 expected_safepoint_kind_(Safepoint::kSimple) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +000071 PopulateDeoptimizationLiteralsWithInlinedFunctions();
72 }
73
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000074
75 // Simple accessors.
76 MacroAssembler* masm() const { return masm_; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000077 CompilationInfo* info() const { return info_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000078 Isolate* isolate() const { return info_->isolate(); }
79 Factory* factory() const { return isolate()->factory(); }
80 Heap* heap() const { return isolate()->heap(); }
rossberg@chromium.org400388e2012-06-06 09:29:22 +000081 Zone* zone() const { return zone_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000082
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000083 bool NeedsEagerFrame() const {
84 return GetStackSlotCount() > 0 ||
85 info()->is_non_deferred_calling() ||
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000086 !info()->IsStub() ||
87 info()->requires_frame();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000088 }
89 bool NeedsDeferredFrame() const {
90 return !NeedsEagerFrame() && info()->is_deferred_calling();
91 }
92
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +000093 LinkRegisterStatus GetLinkRegisterState() const {
94 return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved;
95 }
96
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000097 // Support for converting LOperands to assembler types.
98 // LOperand must be a register.
99 Register ToRegister(LOperand* op) const;
100
101 // LOperand is loaded into scratch, unless already a register.
102 Register EmitLoadRegister(LOperand* op, Register scratch);
103
104 // LOperand must be a double register.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000105 DwVfpRegister ToDoubleRegister(LOperand* op) const;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000106
107 // LOperand is loaded into dbl_scratch, unless already a double register.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000108 DwVfpRegister EmitLoadDoubleRegister(LOperand* op,
109 SwVfpRegister flt_scratch,
110 DwVfpRegister dbl_scratch);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000111 int ToInteger32(LConstantOperand* op) const;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000112 double ToDouble(LConstantOperand* op) const;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000113 Operand ToOperand(LOperand* op);
114 MemOperand ToMemOperand(LOperand* op) const;
115 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
116 MemOperand ToHighMemOperand(LOperand* op) const;
117
danno@chromium.orgbf0c8202011-12-27 10:09:42 +0000118 bool IsInteger32(LConstantOperand* op) const;
119 Handle<Object> ToHandle(LConstantOperand* op) const;
120
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000121 // Try to generate code for the entire chunk, but it may fail if the
122 // chunk contains constructs we cannot handle. Returns true if the
123 // code generation attempt succeeded.
124 bool GenerateCode();
125
126 // Finish the code by setting stack height, safepoint, and bailout
127 // information on it.
128 void FinishCode(Handle<Code> code);
129
130 // Deferred code support.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000131 void DoDeferredBinaryOpStub(LPointerMap* pointer_map,
132 LOperand* left_argument,
133 LOperand* right_argument,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000134 Token::Value op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 void DoDeferredNumberTagD(LNumberTagD* instr);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000136
137 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
138 void DoDeferredNumberTagI(LInstruction* instr,
139 LOperand* value,
140 IntegerSignedness signedness);
141
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000142 void DoDeferredTaggedToI(LTaggedToI* instr);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000143 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
ager@chromium.org04921a82011-06-27 13:21:41 +0000144 void DoDeferredStackCheck(LStackCheck* instr);
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000145 void DoDeferredRandom(LRandom* instr);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000146 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000147 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
ulan@chromium.org967e2702012-02-28 09:49:15 +0000148 void DoDeferredAllocateObject(LAllocateObject* instr);
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000149 void DoDeferredAllocate(LAllocate* instr);
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000150 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
151 Label* map_check);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000152
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000153 void DoCheckMapCommon(Register map_reg, Handle<Map> map,
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000154 CompareMapMode mode, LEnvironment* env);
155
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 // Parallel move support.
157 void DoParallelMove(LParallelMove* move);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000158 void DoGap(LGap* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000159
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000160 MemOperand PrepareKeyedOperand(Register key,
161 Register base,
162 bool key_is_constant,
163 int constant_key,
164 int element_size,
165 int shift_size,
166 int additional_index,
167 int additional_offset);
168
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000169 // Emit frame translation commands for an environment.
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000170 void WriteTranslation(LEnvironment* environment,
171 Translation* translation,
172 int* arguments_index,
173 int* arguments_count);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000174
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000175 // Declare methods that deal with the individual node types.
176#define DECLARE_DO(type) void Do##type(L##type* node);
177 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
178#undef DECLARE_DO
179
180 private:
181 enum Status {
182 UNUSED,
183 GENERATING,
184 DONE,
185 ABORTED
186 };
187
188 bool is_unused() const { return status_ == UNUSED; }
189 bool is_generating() const { return status_ == GENERATING; }
190 bool is_done() const { return status_ == DONE; }
191 bool is_aborted() const { return status_ == ABORTED; }
192
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000193 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000194 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000195 }
196
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000197 LPlatformChunk* chunk() const { return chunk_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198 Scope* scope() const { return scope_; }
199 HGraph* graph() const { return chunk_->graph(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000200
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000201 Register scratch0() { return r9; }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000202 DwVfpRegister double_scratch0() { return kScratchDoubleReg; }
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000203
ulan@chromium.org77ca49a2013-04-22 09:43:56 +0000204 int GetNextEmittedBlock();
kasperl@chromium.orga5551262010-12-07 12:49:48 +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
danno@chromium.org160a7b02011-04-18 15:51:38 +0000214 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +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, ...);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000219 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000220
221 // Code generation passes. Returns true if code generation should
222 // continue.
223 bool GeneratePrologue();
224 bool GenerateBody();
225 bool GenerateDeferredCode();
danno@chromium.org40cb8782011-05-25 07:58:50 +0000226 bool GenerateDeoptJumpTable();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000227 bool GenerateSafepointTable();
228
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000229 enum SafepointMode {
230 RECORD_SIMPLE_SAFEPOINT,
231 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
232 };
233
rossberg@chromium.org89e18f52012-10-22 13:09:53 +0000234 void CallCode(
235 Handle<Code> code,
236 RelocInfo::Mode mode,
237 LInstruction* instr,
238 TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000239
rossberg@chromium.org89e18f52012-10-22 13:09:53 +0000240 void CallCodeGeneric(
241 Handle<Code> code,
242 RelocInfo::Mode mode,
243 LInstruction* instr,
244 SafepointMode safepoint_mode,
245 TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000246
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000247 void CallRuntime(const Runtime::Function* function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000248 int num_arguments,
249 LInstruction* instr);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000250
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000251 void CallRuntime(Runtime::FunctionId id,
252 int num_arguments,
253 LInstruction* instr) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000254 const Runtime::Function* function = Runtime::FunctionForId(id);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000255 CallRuntime(function, num_arguments, instr);
256 }
257
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000258 void CallRuntimeFromDeferred(Runtime::FunctionId id,
259 int argc,
260 LInstruction* instr);
261
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000262 enum R1State {
263 R1_UNINITIALIZED,
264 R1_CONTAINS_TARGET
265 };
266
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000267 // Generate a direct call to a known function. Expects the function
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000268 // to be in r1.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000269 void CallKnownFunction(Handle<JSFunction> function,
270 int arity,
danno@chromium.org40cb8782011-05-25 07:58:50 +0000271 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000272 CallKind call_kind,
273 R1State r1_state);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000274
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000275 void LoadHeapObject(Register result, Handle<HeapObject> object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000276
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000277 void RecordSafepointWithLazyDeopt(LInstruction* instr,
278 SafepointMode safepoint_mode);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000279
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000280 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
281 Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000282 void DeoptimizeIf(Condition cc, LEnvironment* environment);
283
284 void AddToTranslation(Translation* translation,
285 LOperand* op,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000286 bool is_tagged,
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000287 bool is_uint32,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000288 bool arguments_known,
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000289 int arguments_index,
290 int arguments_count);
ulan@chromium.org6ba1fd02013-02-14 14:56:11 +0000291 void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000292 void PopulateDeoptimizationData(Handle<Code> code);
293 int DefineDeoptimizationLiteral(Handle<Object> literal);
294
295 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
296
297 Register ToRegister(int index) const;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000298 DwVfpRegister ToDoubleRegister(int index) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000299
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000300 void EmitIntegerMathAbs(LMathAbs* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000301
302 // Support for recording safepoint and position information.
ager@chromium.org378b34e2011-01-28 08:04:38 +0000303 void RecordSafepoint(LPointerMap* pointers,
304 Safepoint::Kind kind,
305 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000306 Safepoint::DeoptMode mode);
307 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
308 void RecordSafepoint(Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000309 void RecordSafepointWithRegisters(LPointerMap* pointers,
310 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000311 Safepoint::DeoptMode mode);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000312 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
313 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000314 Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000315 void RecordPosition(int position);
316
317 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
ager@chromium.org04921a82011-06-27 13:21:41 +0000318 void EmitGoto(int block);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000319 void EmitBranch(int left_block, int right_block, Condition cc);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000320 void EmitNumberUntagD(Register input,
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000321 DwVfpRegister result,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000322 bool deoptimize_on_undefined,
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000323 bool deoptimize_on_minus_zero,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000324 LEnvironment* env,
325 NumberUntagDMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000326
327 // Emits optimized code for typeof x == "y". Modifies input register.
328 // Returns the condition on which a final split to
329 // true and false label should be made, to optimize fallthrough.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000330 Condition EmitTypeofIs(Label* true_label,
331 Label* false_label,
332 Register input,
333 Handle<String> type_name);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000334
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000335 // Emits optimized code for %_IsObject(x). Preserves input register.
336 // Returns the condition on which a final split to
337 // true and false label should be made, to optimize fallthrough.
338 Condition EmitIsObject(Register input,
339 Register temp1,
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000340 Label* is_not_object,
341 Label* is_object);
342
erikcorry0ad885c2011-11-21 13:51:57 +0000343 // Emits optimized code for %_IsString(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 EmitIsString(Register input,
347 Register temp1,
348 Label* is_not_string);
349
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000350 // Emits optimized code for %_IsConstructCall().
351 // Caller should branch on equal condition.
352 void EmitIsConstructCall(Register temp1, Register temp2);
353
lrn@chromium.org1c092762011-05-09 09:42:16 +0000354 void EmitLoadFieldOrConstantFunction(Register result,
355 Register object,
356 Handle<Map> type,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000357 Handle<String> name,
358 LEnvironment* env);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000359
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000360 // Emits optimized code to deep-copy the contents of statically known
361 // object graphs (e.g. object literal boilerplate).
362 void EmitDeepCopy(Handle<JSObject> object,
363 Register result,
364 Register source,
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000365 int* offset,
366 AllocationSiteMode mode);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000367
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +0000368 // Emit optimized code for integer division.
369 // Inputs are signed.
370 // All registers are clobbered.
371 // If 'remainder' is no_reg, it is not computed.
372 void EmitSignedIntegerDivisionByConstant(Register result,
373 Register dividend,
374 int32_t divisor,
375 Register remainder,
376 Register scratch,
377 LEnvironment* environment);
378
danno@chromium.org40cb8782011-05-25 07:58:50 +0000379 struct JumpTableEntry {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000380 inline JumpTableEntry(Address entry, bool frame, bool is_lazy)
danno@chromium.org40cb8782011-05-25 07:58:50 +0000381 : label(),
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000382 address(entry),
383 needs_frame(frame),
384 is_lazy_deopt(is_lazy) { }
danno@chromium.org40cb8782011-05-25 07:58:50 +0000385 Label label;
386 Address address;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000387 bool needs_frame;
388 bool is_lazy_deopt;
danno@chromium.org40cb8782011-05-25 07:58:50 +0000389 };
390
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000391 void EnsureSpaceForLazyDeopt();
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000392 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
393 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
394 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
395 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
396 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
397 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000398
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000399 Zone* zone_;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000400 LPlatformChunk* const chunk_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000401 MacroAssembler* const masm_;
402 CompilationInfo* const info_;
403
404 int current_block_;
405 int current_instruction_;
406 const ZoneList<LInstruction*>* instructions_;
407 ZoneList<LEnvironment*> deoptimizations_;
danno@chromium.org40cb8782011-05-25 07:58:50 +0000408 ZoneList<JumpTableEntry> deopt_jump_table_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000409 ZoneList<Handle<Object> > deoptimization_literals_;
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000410 ZoneList<Handle<Map> > prototype_maps_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000411 int inlined_function_count_;
412 Scope* const scope_;
413 Status status_;
414 TranslationBuffer translations_;
415 ZoneList<LDeferredCode*> deferred_;
416 int osr_pc_offset_;
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000417 int last_lazy_deopt_pc_;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000418 bool frame_is_built_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000419
420 // Builder that keeps track of safepoints in the code. The table
421 // itself is emitted at the end of the generated code.
422 SafepointTableBuilder safepoints_;
423
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000424 // Compiler from a set of parallel moves to a sequential list of moves.
425 LGapResolver resolver_;
426
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000427 Safepoint::Kind expected_safepoint_kind_;
428
429 class PushSafepointRegistersScope BASE_EMBEDDED {
430 public:
431 PushSafepointRegistersScope(LCodeGen* codegen,
432 Safepoint::Kind kind)
433 : codegen_(codegen) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000434 ASSERT(codegen_->info()->is_calling());
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000435 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
436 codegen_->expected_safepoint_kind_ = kind;
437
438 switch (codegen_->expected_safepoint_kind_) {
439 case Safepoint::kWithRegisters:
440 codegen_->masm_->PushSafepointRegisters();
441 break;
442 case Safepoint::kWithRegistersAndDoubles:
443 codegen_->masm_->PushSafepointRegistersAndDoubles();
444 break;
445 default:
446 UNREACHABLE();
447 }
448 }
449
450 ~PushSafepointRegistersScope() {
451 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
452 ASSERT((kind & Safepoint::kWithRegisters) != 0);
453 switch (kind) {
454 case Safepoint::kWithRegisters:
455 codegen_->masm_->PopSafepointRegisters();
456 break;
457 case Safepoint::kWithRegistersAndDoubles:
458 codegen_->masm_->PopSafepointRegistersAndDoubles();
459 break;
460 default:
461 UNREACHABLE();
462 }
463 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
464 }
465
466 private:
467 LCodeGen* codegen_;
468 };
469
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000470 friend class LDeferredCode;
471 friend class LEnvironment;
472 friend class SafepointGenerator;
473 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
474};
475
476
477class LDeferredCode: public ZoneObject {
478 public:
479 explicit LDeferredCode(LCodeGen* codegen)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000480 : codegen_(codegen),
481 external_exit_(NULL),
482 instruction_index_(codegen->current_instruction_) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000483 codegen->AddDeferredCode(this);
484 }
485
486 virtual ~LDeferredCode() { }
487 virtual void Generate() = 0;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000488 virtual LInstruction* instr() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000489
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000490 void SetExit(Label* exit) { external_exit_ = exit; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000491 Label* entry() { return &entry_; }
492 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000493 int instruction_index() const { return instruction_index_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000494
495 protected:
496 LCodeGen* codegen() const { return codegen_; }
497 MacroAssembler* masm() const { return codegen_->masm(); }
498
499 private:
500 LCodeGen* codegen_;
501 Label entry_;
502 Label exit_;
503 Label* external_exit_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000504 int instruction_index_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000505};
506
507} } // namespace v8::internal
508
509#endif // V8_ARM_LITHIUM_CODEGEN_ARM_H_