blob: 51cfe08fc134ec9cc7a37d849e53facffafbdca4 [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_X64_LITHIUM_CODEGEN_X64_H_
29#define V8_X64_LITHIUM_CODEGEN_X64_H_
30
31#include "x64/lithium-x64.h"
32
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000033#include "checks.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "deoptimizer.h"
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +000035#include "lithium-codegen.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000036#include "safepoint-table.h"
37#include "scopes.h"
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000038#include "v8utils.h"
ager@chromium.org0ee099b2011-01-25 14:06:47 +000039#include "x64/lithium-gap-resolver-x64.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000040
41namespace v8 {
42namespace internal {
43
44// Forward declarations.
45class LDeferredCode;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000046class SafepointGenerator;
47
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +000048class LCodeGen: public LCodeGenBase {
kasperl@chromium.orga5551262010-12-07 12:49:48 +000049 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000050 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +000051 : LCodeGenBase(chunk, assembler, info),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000052 deoptimizations_(4, info->zone()),
53 jump_table_(4, info->zone()),
54 deoptimization_literals_(8, info->zone()),
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000055 inlined_function_count_(0),
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000056 scope_(info->scope()),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000057 translations_(info->zone()),
58 deferred_(8, info->zone()),
ager@chromium.org0ee099b2011-01-25 14:06:47 +000059 osr_pc_offset_(-1),
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000060 frame_is_built_(false),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000061 safepoints_(info->zone()),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000062 resolver_(this),
bmeurer@chromium.org71f9fca2013-10-22 08:00:09 +000063 expected_safepoint_kind_(Safepoint::kSimple) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000064 PopulateDeoptimizationLiteralsWithInlinedFunctions();
65 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +000066
ulan@chromium.org32d7dba2013-04-24 10:59:06 +000067 int LookupDestination(int block_id) const {
68 return chunk()->LookupDestination(block_id);
69 }
70
71 bool IsNextEmittedBlock(int block_id) const {
72 return LookupDestination(block_id) == GetNextEmittedBlock();
73 }
74
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000075 bool NeedsEagerFrame() const {
76 return GetStackSlotCount() > 0 ||
77 info()->is_non_deferred_calling() ||
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000078 !info()->IsStub() ||
79 info()->requires_frame();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000080 }
81 bool NeedsDeferredFrame() const {
82 return !NeedsEagerFrame() && info()->is_deferred_calling();
83 }
84
ager@chromium.org0ee099b2011-01-25 14:06:47 +000085 // Support for converting LOperands to assembler types.
86 Register ToRegister(LOperand* op) const;
87 XMMRegister ToDoubleRegister(LOperand* op) const;
88 bool IsInteger32Constant(LConstantOperand* op) const;
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +000089 bool IsSmiConstant(LConstantOperand* op) const;
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +000090 int32_t ToInteger32(LConstantOperand* op) const;
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +000091 Smi* ToSmi(LConstantOperand* op) const;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000092 double ToDouble(LConstantOperand* op) const;
danno@chromium.orgd3c42102013-08-01 16:58:23 +000093 ExternalReference ToExternalReference(LConstantOperand* op) const;
ager@chromium.org0ee099b2011-01-25 14:06:47 +000094 bool IsTaggedConstant(LConstantOperand* op) const;
95 Handle<Object> ToHandle(LConstantOperand* op) const;
96 Operand ToOperand(LOperand* op) const;
97
kasperl@chromium.orga5551262010-12-07 12:49:48 +000098 // Try to generate code for the entire chunk, but it may fail if the
99 // chunk contains constructs we cannot handle. Returns true if the
100 // code generation attempt succeeded.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000101 bool GenerateCode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102
103 // Finish the code by setting stack height, safepoint, and bailout
104 // information on it.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000105 void FinishCode(Handle<Code> code);
106
107 // Deferred code support.
108 void DoDeferredNumberTagD(LNumberTagD* instr);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000109 void DoDeferredNumberTagU(LNumberTagU* instr);
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000110 void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000111 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
ager@chromium.org04921a82011-06-27 13:21:41 +0000112 void DoDeferredStackCheck(LStackCheck* instr);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000113 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000114 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000115 void DoDeferredAllocate(LAllocate* instr);
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000116 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
117 Label* map_check);
danno@chromium.org59400602013-08-13 17:09:37 +0000118 void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000119
120// Parallel move support.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000121 void DoParallelMove(LParallelMove* move);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000122 void DoGap(LGap* instr);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000123
124 // Emit frame translation commands for an environment.
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000125 void WriteTranslation(LEnvironment* environment, Translation* translation);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000126
127 // Declare methods that deal with the individual node types.
128#define DECLARE_DO(type) void Do##type(L##type* node);
129 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
130#undef DECLARE_DO
131
132 private:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000133 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000134 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000135 }
136
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000137 LPlatformChunk* chunk() const { return chunk_; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000138 Scope* scope() const { return scope_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000139 HGraph* graph() const { return chunk()->graph(); }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000140
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000141 XMMRegister double_scratch0() const { return xmm0; }
142
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000143 void EmitClassOfTest(Label* if_true,
144 Label* if_false,
145 Handle<String> class_name,
146 Register input,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000147 Register temporary,
148 Register scratch);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000149
danno@chromium.org160a7b02011-04-18 15:51:38 +0000150 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000151
danno@chromium.org59400602013-08-13 17:09:37 +0000152 void Abort(BailoutReason reason);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000153
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000154 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000155
156 // Code generation passes. Returns true if code generation should
157 // continue.
158 bool GeneratePrologue();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000159 bool GenerateDeferredCode();
ager@chromium.org9ee27ae2011-03-02 13:43:26 +0000160 bool GenerateJumpTable();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000161 bool GenerateSafepointTable();
162
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000163 // Generates the custom OSR entrypoint and sets the osr_pc_offset.
164 void GenerateOsrPrologue();
165
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000166 enum SafepointMode {
167 RECORD_SIMPLE_SAFEPOINT,
168 RECORD_SAFEPOINT_WITH_REGISTERS
169 };
170
171 void CallCodeGeneric(Handle<Code> code,
172 RelocInfo::Mode mode,
173 LInstruction* instr,
174 SafepointMode safepoint_mode,
175 int argc);
176
177
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000178 void CallCode(Handle<Code> code,
179 RelocInfo::Mode mode,
180 LInstruction* instr);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000181
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000182 void CallRuntime(const Runtime::Function* function,
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000183 int num_arguments,
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +0000184 LInstruction* instr,
185 SaveFPRegsMode save_doubles = kDontSaveFPRegs);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000186
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000187 void CallRuntime(Runtime::FunctionId id,
188 int num_arguments,
189 LInstruction* instr) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000190 const Runtime::Function* function = Runtime::FunctionForId(id);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000191 CallRuntime(function, num_arguments, instr);
192 }
193
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000194 void CallRuntimeFromDeferred(Runtime::FunctionId id,
195 int argc,
machenbach@chromium.org935a7792013-11-12 09:05:18 +0000196 LInstruction* instr,
197 LOperand* context);
198
199 void LoadContextFromDeferred(LOperand* context);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000200
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000201 enum RDIState {
202 RDI_UNINITIALIZED,
203 RDI_CONTAINS_TARGET
204 };
205
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000206 // Generate a direct call to a known function. Expects the function
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000207 // to be in rdi.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000208 void CallKnownFunction(Handle<JSFunction> function,
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000209 int formal_parameter_count,
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000210 int arity,
danno@chromium.org40cb8782011-05-25 07:58:50 +0000211 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000212 CallKind call_kind,
213 RDIState rdi_state);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000214
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000215 void RecordSafepointWithLazyDeopt(LInstruction* instr,
216 SafepointMode safepoint_mode,
217 int argc);
218 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
219 Safepoint::DeoptMode mode);
danno@chromium.orgaefd6072013-05-14 14:11:47 +0000220 void DeoptimizeIf(Condition cc,
221 LEnvironment* environment,
222 Deoptimizer::BailoutType bailout_type);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000223 void DeoptimizeIf(Condition cc, LEnvironment* environment);
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000224 void ApplyCheckIf(Condition cc, LBoundsCheck* check);
danno@chromium.org59400602013-08-13 17:09:37 +0000225
machenbach@chromium.org935a7792013-11-12 09:05:18 +0000226 bool DeoptEveryNTimes() {
227 return FLAG_deopt_every_n_times != 0 && !info()->IsStub();
228 }
229
danno@chromium.org59400602013-08-13 17:09:37 +0000230 void AddToTranslation(LEnvironment* environment,
231 Translation* translation,
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000232 LOperand* op,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000233 bool is_tagged,
danno@chromium.org59400602013-08-13 17:09:37 +0000234 bool is_uint32,
235 int* object_index_pointer,
236 int* dematerialized_index_pointer);
ulan@chromium.org6ba1fd02013-02-14 14:56:11 +0000237 void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000238 void PopulateDeoptimizationData(Handle<Code> code);
239 int DefineDeoptimizationLiteral(Handle<Object> literal);
240
241 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
242
243 Register ToRegister(int index) const;
244 XMMRegister ToDoubleRegister(int index) const;
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000245 Operand BuildFastArrayOperand(
danno@chromium.orgb6451162011-08-17 14:33:23 +0000246 LOperand* elements_pointer,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000247 LOperand* key,
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000248 ElementsKind elements_kind,
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +0000249 uint32_t offset,
250 uint32_t additional_index = 0);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000251
machenbach@chromium.orge8412be2013-11-08 10:23:52 +0000252 Operand BuildSeqStringOperand(Register string,
253 LOperand* index,
254 String::Encoding encoding);
255
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000256 void EmitIntegerMathAbs(LMathAbs* instr);
danno@chromium.org59400602013-08-13 17:09:37 +0000257 void EmitSmiMathAbs(LMathAbs* instr);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000258
259 // Support for recording safepoint and position information.
ager@chromium.org378b34e2011-01-28 08:04:38 +0000260 void RecordSafepoint(LPointerMap* pointers,
261 Safepoint::Kind kind,
262 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000263 Safepoint::DeoptMode mode);
264 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
265 void RecordSafepoint(Safepoint::DeoptMode mode);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000266 void RecordSafepointWithRegisters(LPointerMap* pointers,
267 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000268 Safepoint::DeoptMode mode);
bmeurer@chromium.org71f9fca2013-10-22 08:00:09 +0000269 void RecordAndWritePosition(int position) V8_OVERRIDE;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000270
271 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
ager@chromium.org04921a82011-06-27 13:21:41 +0000272 void EmitGoto(int block);
machenbach@chromium.org0cc09502013-11-13 12:20:55 +0000273
274 // EmitBranch expects to be the last instruction of a block.
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000275 template<class InstrType>
276 void EmitBranch(InstrType instr, Condition cc);
danno@chromium.orgc00ec2b2013-08-14 17:13:49 +0000277 template<class InstrType>
278 void EmitFalseBranch(InstrType instr, Condition cc);
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000279 void EmitNumberUntagD(
280 Register input,
281 XMMRegister result,
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000282 bool allow_undefined_as_nan,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000283 bool deoptimize_on_minus_zero,
284 LEnvironment* env,
285 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000286
287 // Emits optimized code for typeof x == "y". Modifies input register.
288 // Returns the condition on which a final split to
289 // true and false label should be made, to optimize fallthrough.
machenbach@chromium.orgaf9cfcb2013-11-19 11:05:18 +0000290 Condition EmitTypeofIs(LTypeofIsAndBranch* instr, Register input);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000291
292 // Emits optimized code for %_IsObject(x). Preserves input register.
293 // Returns the condition on which a final split to
294 // true and false label should be made, to optimize fallthrough.
295 Condition EmitIsObject(Register input,
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000296 Label* is_not_object,
297 Label* is_object);
298
erikcorry0ad885c2011-11-21 13:51:57 +0000299 // Emits optimized code for %_IsString(x). Preserves input register.
300 // Returns the condition on which a final split to
301 // true and false label should be made, to optimize fallthrough.
302 Condition EmitIsString(Register input,
303 Register temp1,
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000304 Label* is_not_string,
305 SmiCheck check_needed);
erikcorry0ad885c2011-11-21 13:51:57 +0000306
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000307 // Emits optimized code for %_IsConstructCall().
308 // Caller should branch on equal condition.
309 void EmitIsConstructCall(Register temp);
310
danno@chromium.org160a7b02011-04-18 15:51:38 +0000311 // Emits code for pushing either a tagged constant, a (non-double)
312 // register, or a stack slot operand.
313 void EmitPushTaggedOperand(LOperand* operand);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000314
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000315 // Emits optimized code to deep-copy the contents of statically known
316 // object graphs (e.g. object literal boilerplate).
317 void EmitDeepCopy(Handle<JSObject> object,
318 Register result,
319 Register source,
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000320 int* offset,
321 AllocationSiteMode mode);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000322
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +0000323 void EnsureSpaceForLazyDeopt(int space_needed) V8_OVERRIDE;
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000324 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
325 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
326 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
327 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
328 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
329 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000330#ifdef _MSC_VER
331 // On windows, you may not access the stack more than one page below
332 // the most recently mapped page. To make the allocated area randomly
333 // accessible, we write an arbitrary value to each page in range
334 // rsp + offset - page_size .. rsp in turn.
335 void MakeSureStackPagesMapped(int offset);
336#endif
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000337
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000338 ZoneList<LEnvironment*> deoptimizations_;
danno@chromium.orgaefd6072013-05-14 14:11:47 +0000339 ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000340 ZoneList<Handle<Object> > deoptimization_literals_;
341 int inlined_function_count_;
342 Scope* const scope_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000343 TranslationBuffer translations_;
344 ZoneList<LDeferredCode*> deferred_;
345 int osr_pc_offset_;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000346 bool frame_is_built_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000347
348 // Builder that keeps track of safepoints in the code. The table
349 // itself is emitted at the end of the generated code.
350 SafepointTableBuilder safepoints_;
351
352 // Compiler from a set of parallel moves to a sequential list of moves.
353 LGapResolver resolver_;
354
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000355 Safepoint::Kind expected_safepoint_kind_;
356
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000357 class PushSafepointRegistersScope V8_FINAL BASE_EMBEDDED {
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000358 public:
359 explicit PushSafepointRegistersScope(LCodeGen* codegen)
360 : codegen_(codegen) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000361 ASSERT(codegen_->info()->is_calling());
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000362 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
363 codegen_->masm_->PushSafepointRegisters();
364 codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
365 }
366
367 ~PushSafepointRegistersScope() {
368 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
369 codegen_->masm_->PopSafepointRegisters();
370 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
371 }
372
373 private:
374 LCodeGen* codegen_;
375 };
376
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000377 friend class LDeferredCode;
378 friend class LEnvironment;
379 friend class SafepointGenerator;
380 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
381};
382
383
384class LDeferredCode: public ZoneObject {
385 public:
386 explicit LDeferredCode(LCodeGen* codegen)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000387 : codegen_(codegen),
388 external_exit_(NULL),
389 instruction_index_(codegen->current_instruction_) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000390 codegen->AddDeferredCode(this);
391 }
392
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000393 virtual ~LDeferredCode() {}
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000394 virtual void Generate() = 0;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000395 virtual LInstruction* instr() = 0;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000396
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000397 void SetExit(Label* exit) { external_exit_ = exit; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000398 Label* entry() { return &entry_; }
399 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000400 Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000401 int instruction_index() const { return instruction_index_; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000402
403 protected:
404 LCodeGen* codegen() const { return codegen_; }
405 MacroAssembler* masm() const { return codegen_->masm(); }
406
407 private:
408 LCodeGen* codegen_;
409 Label entry_;
410 Label exit_;
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000411 Label done_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000412 Label* external_exit_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000413 int instruction_index_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000414};
415
416} } // namespace v8::internal
417
418#endif // V8_X64_LITHIUM_CODEGEN_X64_H_