V8 Project
lithium-codegen-x64.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_X64_LITHIUM_CODEGEN_X64_H_
6 #define V8_X64_LITHIUM_CODEGEN_X64_H_
7 
8 #include "src/x64/lithium-x64.h"
9 
10 #include "src/base/logging.h"
11 #include "src/deoptimizer.h"
12 #include "src/lithium-codegen.h"
13 #include "src/safepoint-table.h"
14 #include "src/scopes.h"
15 #include "src/utils.h"
17 
18 namespace v8 {
19 namespace internal {
20 
21 // Forward declarations.
22 class LDeferredCode;
23 class SafepointGenerator;
24 
25 class LCodeGen: public LCodeGenBase {
26  public:
28  : LCodeGenBase(chunk, assembler, info),
29  deoptimizations_(4, info->zone()),
30  jump_table_(4, info->zone()),
31  deoptimization_literals_(8, info->zone()),
33  scope_(info->scope()),
34  translations_(info->zone()),
35  deferred_(8, info->zone()),
36  osr_pc_offset_(-1),
38  safepoints_(info->zone()),
39  resolver_(this),
40  expected_safepoint_kind_(Safepoint::kSimple) {
42  }
43 
44  int LookupDestination(int block_id) const {
45  return chunk()->LookupDestination(block_id);
46  }
47 
48  bool IsNextEmittedBlock(int block_id) const {
49  return LookupDestination(block_id) == GetNextEmittedBlock();
50  }
51 
52  bool NeedsEagerFrame() const {
53  return GetStackSlotCount() > 0 ||
54  info()->is_non_deferred_calling() ||
55  !info()->IsStub() ||
56  info()->requires_frame();
57  }
58  bool NeedsDeferredFrame() const {
59  return !NeedsEagerFrame() && info()->is_deferred_calling();
60  }
61 
62  // Support for converting LOperands to assembler types.
65  bool IsInteger32Constant(LConstantOperand* op) const;
66  bool IsDehoistedKeyConstant(LConstantOperand* op) const;
67  bool IsSmiConstant(LConstantOperand* op) const;
68  int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const;
69  int32_t ToInteger32(LConstantOperand* op) const;
70  Smi* ToSmi(LConstantOperand* op) const;
71  double ToDouble(LConstantOperand* op) const;
72  ExternalReference ToExternalReference(LConstantOperand* op) const;
73  Handle<Object> ToHandle(LConstantOperand* op) const;
75 
76  // Try to generate code for the entire chunk, but it may fail if the
77  // chunk contains constructs we cannot handle. Returns true if the
78  // code generation attempt succeeded.
79  bool GenerateCode();
80 
81  // Finish the code by setting stack height, safepoint, and bailout
82  // information on it.
84 
85  // Deferred code support.
86  void DoDeferredNumberTagD(LNumberTagD* instr);
87 
90  LOperand* value,
91  LOperand* temp1,
92  LOperand* temp2,
93  IntegerSignedness signedness);
94 
95  void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
96  void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
97  void DoDeferredStackCheck(LStackCheck* instr);
98  void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
99  void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
100  void DoDeferredAllocate(LAllocate* instr);
101  void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
102  Label* map_check);
103  void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
104  void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
105  Register object,
106  Register index);
107 
108 // Parallel move support.
109  void DoParallelMove(LParallelMove* move);
110  void DoGap(LGap* instr);
111 
112  // Emit frame translation commands for an environment.
113  void WriteTranslation(LEnvironment* environment, Translation* translation);
114 
115  // Declare methods that deal with the individual node types.
116 #define DECLARE_DO(type) void Do##type(L##type* node);
118 #undef DECLARE_DO
119 
120  private:
121  StrictMode strict_mode() const { return info()->strict_mode(); }
122 
123  LPlatformChunk* chunk() const { return chunk_; }
124  Scope* scope() const { return scope_; }
125  HGraph* graph() const { return chunk()->graph(); }
126 
127  XMMRegister double_scratch0() const { return xmm0; }
128 
129  void EmitClassOfTest(Label* if_true,
130  Label* if_false,
131  Handle<String> class_name,
132  Register input,
133  Register temporary,
134  Register scratch);
135 
136  int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
137 
138  void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
139 
140 
143 
144  // Code generation passes. Returns true if code generation should
145  // continue.
152 
153  // Generates the custom OSR entrypoint and sets the osr_pc_offset.
155 
159  };
160 
163  LInstruction* instr,
164  SafepointMode safepoint_mode,
165  int argc);
166 
167 
170  LInstruction* instr);
171 
172  void CallRuntime(const Runtime::Function* function,
173  int num_arguments,
174  LInstruction* instr,
175  SaveFPRegsMode save_doubles = kDontSaveFPRegs);
176 
178  int num_arguments,
179  LInstruction* instr) {
180  const Runtime::Function* function = Runtime::FunctionForId(id);
181  CallRuntime(function, num_arguments, instr);
182  }
183 
185  int argc,
186  LInstruction* instr,
187  LOperand* context);
188 
190 
191  enum RDIState {
194  };
195 
196  // Generate a direct call to a known function. Expects the function
197  // to be in rdi.
199  int formal_parameter_count,
200  int arity,
201  LInstruction* instr,
202  RDIState rdi_state);
203 
205  SafepointMode safepoint_mode,
206  int argc);
208  Safepoint::DeoptMode mode);
209  void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail,
210  Deoptimizer::BailoutType bailout_type);
211  void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail);
212 
214  return FLAG_deopt_every_n_times != 0 && !info()->IsStub();
215  }
216 
217  void AddToTranslation(LEnvironment* environment,
218  Translation* translation,
219  LOperand* op,
220  bool is_tagged,
221  bool is_uint32,
222  int* object_index_pointer,
223  int* dematerialized_index_pointer);
226 
228 
229  Register ToRegister(int index) const;
230  XMMRegister ToDoubleRegister(int index) const;
232  LOperand* elements_pointer,
233  LOperand* key,
234  Representation key_representation,
235  ElementsKind elements_kind,
236  uint32_t base_offset);
237 
239  LOperand* index,
240  String::Encoding encoding);
241 
242  void EmitIntegerMathAbs(LMathAbs* instr);
243  void EmitSmiMathAbs(LMathAbs* instr);
244 
245  // Support for recording safepoint and position information.
246  void RecordSafepoint(LPointerMap* pointers,
247  Safepoint::Kind kind,
248  int arguments,
249  Safepoint::DeoptMode mode);
250  void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
251  void RecordSafepoint(Safepoint::DeoptMode mode);
252  void RecordSafepointWithRegisters(LPointerMap* pointers,
253  int arguments,
254  Safepoint::DeoptMode mode);
255  void RecordAndWritePosition(int position) OVERRIDE;
256 
257  static Condition TokenToCondition(Token::Value op, bool is_unsigned);
258  void EmitGoto(int block);
259 
260  // EmitBranch expects to be the last instruction of a block.
261  template<class InstrType>
262  void EmitBranch(InstrType instr, Condition cc);
263  template<class InstrType>
264  void EmitFalseBranch(InstrType instr, Condition cc);
265  void EmitNumberUntagD(LNumberUntagD* instr, Register input,
267 
268  // Emits optimized code for typeof x == "y". Modifies input register.
269  // Returns the condition on which a final split to
270  // true and false label should be made, to optimize fallthrough.
271  Condition EmitTypeofIs(LTypeofIsAndBranch* instr, Register input);
272 
273  // Emits optimized code for %_IsObject(x). Preserves input register.
274  // Returns the condition on which a final split to
275  // true and false label should be made, to optimize fallthrough.
277  Label* is_not_object,
278  Label* is_object);
279 
280  // Emits optimized code for %_IsString(x). Preserves input register.
281  // Returns the condition on which a final split to
282  // true and false label should be made, to optimize fallthrough.
284  Register temp1,
285  Label* is_not_string,
286  SmiCheck check_needed);
287 
288  // Emits optimized code for %_IsConstructCall().
289  // Caller should branch on equal condition.
291 
292  // Emits code for pushing either a tagged constant, a (non-double)
293  // register, or a stack slot operand.
295 
296  // Emits optimized code to deep-copy the contents of statically known
297  // object graphs (e.g. object literal boilerplate).
299  Register result,
300  Register source,
301  int* offset,
303 
304  void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE;
311 
312  template <class T>
314 
315 #ifdef _MSC_VER
316  // On windows, you may not access the stack more than one page below
317  // the most recently mapped page. To make the allocated area randomly
318  // accessible, we write an arbitrary value to each page in range
319  // rsp + offset - page_size .. rsp in turn.
320  void MakeSureStackPagesMapped(int offset);
321 #endif
322 
327  Scope* const scope_;
328  TranslationBuffer translations_;
330  int osr_pc_offset_;
331  bool frame_is_built_;
332 
333  // Builder that keeps track of safepoints in the code. The table
334  // itself is emitted at the end of the generated code.
335  SafepointTableBuilder safepoints_;
336 
337  // Compiler from a set of parallel moves to a sequential list of moves.
339 
340  Safepoint::Kind expected_safepoint_kind_;
341 
342  class PushSafepointRegistersScope FINAL BASE_EMBEDDED {
343  public:
345  : codegen_(codegen) {
346  DCHECK(codegen_->info()->is_calling());
347  DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
348  codegen_->masm_->PushSafepointRegisters();
349  codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
350  }
351 
353  DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
354  codegen_->masm_->PopSafepointRegisters();
355  codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
356  }
357 
358  private:
359  LCodeGen* codegen_;
360  };
361 
362  friend class LDeferredCode;
363  friend class LEnvironment;
364  friend class SafepointGenerator;
366 };
367 
368 
369 class LDeferredCode: public ZoneObject {
370  public:
372  : codegen_(codegen),
374  instruction_index_(codegen->current_instruction_) {
375  codegen->AddDeferredCode(this);
376  }
377 
378  virtual ~LDeferredCode() {}
379  virtual void Generate() = 0;
380  virtual LInstruction* instr() = 0;
381 
382  void SetExit(Label* exit) { external_exit_ = exit; }
383  Label* entry() { return &entry_; }
384  Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
385  Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); }
386  int instruction_index() const { return instruction_index_; }
387 
388  protected:
389  LCodeGen* codegen() const { return codegen_; }
390  MacroAssembler* masm() const { return codegen_->masm(); }
391 
392  private:
394  Label entry_;
395  Label exit_;
396  Label done_;
397  Label* external_exit_;
398  int instruction_index_;
399 };
400 
401 } } // namespace v8::internal
402 
403 #endif // V8_X64_LITHIUM_CODEGEN_X64_H_
Source to read snapshot and builtins files from.
Definition: lithium-arm.h:372
bool IsNextEmittedBlock(int block_id) const
Condition EmitTypeofIs(LTypeofIsAndBranch *instr, Register input)
Register ToRegister(int index) const
void DoStoreKeyedFixedArray(LStoreKeyed *instr)
void AddDeferredCode(LDeferredCode *code)
void RecordSafepointWithRegisters(LPointerMap *pointers, int arguments, Safepoint::DeoptMode mode)
void EmitDeepCopy(Handle< JSObject > object, Register result, Register source, int *offset, AllocationSiteMode mode)
void EmitBranch(InstrType instr, Condition cc)
TranslationBuffer translations_
bool IsSmiConstant(LConstantOperand *op) const
Condition EmitIsString(Register input, Register temp1, Label *is_not_string, SmiCheck check_needed)
void EmitFalseBranch(InstrType instr, Condition cc)
Operand BuildSeqStringOperand(Register string, LOperand *index, String::Encoding encoding)
void DoDeferredStackCheck(LStackCheck *instr)
void DeoptimizeIf(Condition cc, LInstruction *instr, const char *detail)
SafepointTableBuilder safepoints_
void EmitVectorLoadICRegisters(T *instr)
ZoneList< Handle< Object > > deoptimization_literals_
void DoGap(LGap *instr)
void RecordSafepoint(Safepoint::DeoptMode mode)
void PopulateDeoptimizationLiteralsWithInlinedFunctions()
void AddToTranslation(LEnvironment *environment, Translation *translation, LOperand *op, bool is_tagged, bool is_uint32, int *object_index_pointer, int *dematerialized_index_pointer)
ZoneList< LEnvironment * > deoptimizations_
DISALLOW_COPY_AND_ASSIGN(LCodeGen)
void EmitIntegerMathAbs(LMathAbs *instr)
int32_t ToRepresentation(LConstantOperand *op, const Representation &r) const
void CallRuntimeFromDeferred(Runtime::FunctionId id, int argc, LInstruction *instr, LOperand *context)
void EmitPushTaggedOperand(LOperand *operand)
int32_t ToInteger32(LConstantOperand *op) const
LPlatformChunk * chunk() const
void FinishCode(Handle< Code > code)
Handle< Object > ToHandle(LConstantOperand *op) const
ExternalReference ToExternalReference(LConstantOperand *op) const
int LookupDestination(int block_id) const
void DoDeferredAllocate(LAllocate *instr)
void RecordSafepoint(LPointerMap *pointers, Safepoint::Kind kind, int arguments, Safepoint::DeoptMode mode)
void DoDeferredLoadMutableDouble(LLoadFieldByIndex *instr, Register object, Register index)
void DeoptimizeIf(Condition cc, LInstruction *instr, const char *detail, Deoptimizer::BailoutType bailout_type)
XMMRegister ToDoubleRegister(LOperand *op) const
void CallKnownFunction(Handle< JSFunction > function, int formal_parameter_count, int arity, LInstruction *instr, RDIState rdi_state)
void DoDeferredStringCharCodeAt(LStringCharCodeAt *instr)
Safepoint::Kind expected_safepoint_kind_
ZoneList< LDeferredCode * > deferred_
void EmitNumberUntagD(LNumberUntagD *instr, Register input, XMMRegister result, NumberUntagDMode mode)
void EmitGoto(int block)
void CallCodeGeneric(Handle< Code > code, RelocInfo::Mode mode, LInstruction *instr, SafepointMode safepoint_mode, int argc)
void RecordSafepoint(LPointerMap *pointers, Safepoint::DeoptMode mode)
void DoDeferredNumberTagIU(LInstruction *instr, LOperand *value, LOperand *temp1, LOperand *temp2, IntegerSignedness signedness)
StrictMode strict_mode() const
void GenerateBodyInstructionPost(LInstruction *instr) OVERRIDE
void RegisterEnvironmentForDeoptimization(LEnvironment *environment, Safepoint::DeoptMode mode)
void LoadContextFromDeferred(LOperand *context)
bool IsDehoistedKeyConstant(LConstantOperand *op) const
Operand BuildFastArrayOperand(LOperand *elements_pointer, LOperand *key, Representation key_representation, ElementsKind elements_kind, uint32_t base_offset)
void DoDeferredInstanceMigration(LCheckMaps *instr, Register object)
int DefineDeoptimizationLiteral(Handle< Object > literal)
void EmitIsConstructCall(Register temp)
void EmitClassOfTest(Label *if_true, Label *if_false, Handle< String > class_name, Register input, Register temporary, Register scratch)
void WriteTranslation(LEnvironment *environment, Translation *translation)
void DoDeferredMathAbsTaggedHeapNumber(LMathAbs *instr)
void DoLoadKeyedFixedDoubleArray(LLoadKeyed *instr)
void DoDeferredTaggedToI(LTaggedToI *instr, Label *done)
void RecordSafepointWithLazyDeopt(LInstruction *instr, SafepointMode safepoint_mode, int argc)
static Condition TokenToCondition(Token::Value op, bool is_unsigned)
void DoLoadKeyedExternalArray(LLoadKeyed *instr)
double ToDouble(LConstantOperand *op) const
Register ToRegister(LOperand *op) const
void CallRuntime(Runtime::FunctionId id, int num_arguments, LInstruction *instr)
void DoStoreKeyedExternalArray(LStoreKeyed *instr)
void RecordAndWritePosition(int position) OVERRIDE
void PopulateDeoptimizationData(Handle< Code > code)
void DoParallelMove(LParallelMove *move)
Condition EmitIsObject(Register input, Label *is_not_object, Label *is_object)
void CallRuntime(const Runtime::Function *function, int num_arguments, LInstruction *instr, SaveFPRegsMode save_doubles=kDontSaveFPRegs)
Operand ToOperand(LOperand *op) const
void CallCode(Handle< Code > code, RelocInfo::Mode mode, LInstruction *instr)
bool IsInteger32Constant(LConstantOperand *op) const
void DoDeferredStringCharFromCode(LStringCharFromCode *instr)
ZoneList< Deoptimizer::JumpTableEntry > jump_table_
void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE
XMMRegister double_scratch0() const
void GenerateBodyInstructionPre(LInstruction *instr) OVERRIDE
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal *instr, Label *map_check)
void DoLoadKeyedFixedArray(LLoadKeyed *instr)
Smi * ToSmi(LConstantOperand *op) const
LCodeGen(LChunk *chunk, MacroAssembler *assembler, CompilationInfo *info)
void DoDeferredNumberTagD(LNumberTagD *instr)
void DoStoreKeyedFixedDoubleArray(LStoreKeyed *instr)
XMMRegister ToDoubleRegister(int index) const
void EmitSmiMathAbs(LMathAbs *instr)
MacroAssembler * masm() const
virtual void Generate()=0
virtual LInstruction * instr()=0
static const Function * FunctionForId(FunctionId id)
Definition: runtime.cc:9312
#define OVERRIDE
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
Definition: lithium-arm.h:20
#define DECLARE_DO(type)
#define DCHECK(condition)
Definition: logging.h:205
int int32_t
Definition: unicode.cc:24
const XMMRegister xmm0
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define T(name, string, precedence)
Definition: token.cc:25