V8 Project
lithium-codegen-mips.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_MIPS_LITHIUM_CODEGEN_MIPS_H_
6 #define V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
7 
8 #include "src/deoptimizer.h"
9 #include "src/lithium-codegen.h"
11 #include "src/mips/lithium-mips.h"
12 #include "src/safepoint-table.h"
13 #include "src/scopes.h"
14 #include "src/utils.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 // Forward declarations.
20 class LDeferredCode;
21 class SafepointGenerator;
22 
23 class LCodeGen: public LCodeGenBase {
24  public:
26  : LCodeGenBase(chunk, assembler, info),
27  deoptimizations_(4, info->zone()),
28  jump_table_(4, info->zone()),
29  deoptimization_literals_(8, info->zone()),
31  scope_(info->scope()),
32  translations_(info->zone()),
33  deferred_(8, info->zone()),
34  osr_pc_offset_(-1),
36  safepoints_(info->zone()),
37  resolver_(this),
38  expected_safepoint_kind_(Safepoint::kSimple) {
40  }
41 
42 
43  int LookupDestination(int block_id) const {
44  return chunk()->LookupDestination(block_id);
45  }
46 
47  bool IsNextEmittedBlock(int block_id) const {
48  return LookupDestination(block_id) == GetNextEmittedBlock();
49  }
50 
51  bool NeedsEagerFrame() const {
52  return GetStackSlotCount() > 0 ||
53  info()->is_non_deferred_calling() ||
54  !info()->IsStub() ||
55  info()->requires_frame();
56  }
57  bool NeedsDeferredFrame() const {
58  return !NeedsEagerFrame() && info()->is_deferred_calling();
59  }
60 
61  RAStatus GetRAState() const {
63  }
64 
65  // Support for converting LOperands to assembler types.
66  // LOperand must be a register.
68 
69  // LOperand is loaded into scratch, unless already a register.
71 
72  // LOperand must be a double register.
74 
75  // LOperand is loaded into dbl_scratch, unless already a double register.
77  FloatRegister flt_scratch,
78  DoubleRegister dbl_scratch);
79  int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const;
80  int32_t ToInteger32(LConstantOperand* op) const;
81  Smi* ToSmi(LConstantOperand* op) const;
82  double ToDouble(LConstantOperand* op) const;
85  // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
87 
88  bool IsInteger32(LConstantOperand* op) const;
89  bool IsSmi(LConstantOperand* op) const;
90  Handle<Object> ToHandle(LConstantOperand* op) const;
91 
92  // Try to generate code for the entire chunk, but it may fail if the
93  // chunk contains constructs we cannot handle. Returns true if the
94  // code generation attempt succeeded.
95  bool GenerateCode();
96 
97  // Finish the code by setting stack height, safepoint, and bailout
98  // information on it.
100 
101  void DoDeferredNumberTagD(LNumberTagD* instr);
102 
105  LOperand* value,
106  LOperand* temp1,
107  LOperand* temp2,
108  IntegerSignedness signedness);
109 
110  void DoDeferredTaggedToI(LTaggedToI* instr);
111  void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
112  void DoDeferredStackCheck(LStackCheck* instr);
113  void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
114  void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
115  void DoDeferredAllocate(LAllocate* instr);
116  void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
117  Label* map_check);
118 
119  void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
120  void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
121  Register result,
122  Register object,
123  Register index);
124 
125  // Parallel move support.
126  void DoParallelMove(LParallelMove* move);
127  void DoGap(LGap* instr);
128 
130  Register base,
131  bool key_is_constant,
132  int constant_key,
133  int element_size,
134  int shift_size,
135  int base_offset);
136 
137  // Emit frame translation commands for an environment.
138  void WriteTranslation(LEnvironment* environment, Translation* translation);
139 
140  // Declare methods that deal with the individual node types.
141 #define DECLARE_DO(type) void Do##type(L##type* node);
143 #undef DECLARE_DO
144 
145  private:
146  StrictMode strict_mode() const { return info()->strict_mode(); }
147 
148  Scope* scope() const { return scope_; }
149 
153 
155 
156  void EmitClassOfTest(Label* if_true,
157  Label* if_false,
158  Handle<String> class_name,
159  Register input,
160  Register temporary,
161  Register temporary2);
162 
163  int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
164 
165  void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
166 
169 
170  // Code generation passes. Returns true if code generation should
171  // continue.
177 
178  // Generates the custom OSR entrypoint and sets the osr_pc_offset.
180 
184  };
185 
188  LInstruction* instr);
189 
192  LInstruction* instr,
193  SafepointMode safepoint_mode);
194 
195  void CallRuntime(const Runtime::Function* function,
196  int num_arguments,
197  LInstruction* instr,
198  SaveFPRegsMode save_doubles = kDontSaveFPRegs);
199 
201  int num_arguments,
202  LInstruction* instr) {
203  const Runtime::Function* function = Runtime::FunctionForId(id);
204  CallRuntime(function, num_arguments, instr);
205  }
206 
209  int argc,
210  LInstruction* instr,
211  LOperand* context);
212 
213  enum A1State {
216  };
217 
218  // Generate a direct call to a known function. Expects the function
219  // to be in a1.
221  int formal_parameter_count,
222  int arity,
223  LInstruction* instr,
224  A1State a1_state);
225 
227  SafepointMode safepoint_mode);
228 
230  Safepoint::DeoptMode mode);
231  void DeoptimizeIf(Condition condition, LInstruction* instr,
232  Deoptimizer::BailoutType bailout_type, const char* detail,
233  Register src1 = zero_reg,
234  const Operand& src2 = Operand(zero_reg));
235  void DeoptimizeIf(Condition condition, LInstruction* instr,
236  const char* detail = NULL, Register src1 = zero_reg,
237  const Operand& src2 = Operand(zero_reg));
238 
239  void AddToTranslation(LEnvironment* environment,
240  Translation* translation,
241  LOperand* op,
242  bool is_tagged,
243  bool is_uint32,
244  int* object_index_pointer,
245  int* dematerialized_index_pointer);
248 
250 
251  Register ToRegister(int index) const;
253 
255  LOperand* index,
256  String::Encoding encoding);
257 
258  void EmitIntegerMathAbs(LMathAbs* instr);
259 
260  // Support for recording safepoint and position information.
261  void RecordSafepoint(LPointerMap* pointers,
262  Safepoint::Kind kind,
263  int arguments,
264  Safepoint::DeoptMode mode);
265  void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
266  void RecordSafepoint(Safepoint::DeoptMode mode);
267  void RecordSafepointWithRegisters(LPointerMap* pointers,
268  int arguments,
269  Safepoint::DeoptMode mode);
270 
271  void RecordAndWritePosition(int position) OVERRIDE;
272 
273  static Condition TokenToCondition(Token::Value op, bool is_unsigned);
274  void EmitGoto(int block);
275 
276  // EmitBranch expects to be the last instruction of a block.
277  template<class InstrType>
278  void EmitBranch(InstrType instr,
279  Condition condition,
280  Register src1,
281  const Operand& src2);
282  template<class InstrType>
283  void EmitBranchF(InstrType instr,
284  Condition condition,
285  FPURegister src1,
286  FPURegister src2);
287  template<class InstrType>
288  void EmitFalseBranch(InstrType instr,
289  Condition condition,
290  Register src1,
291  const Operand& src2);
292  template<class InstrType>
293  void EmitFalseBranchF(InstrType instr,
294  Condition condition,
295  FPURegister src1,
296  FPURegister src2);
297  void EmitCmpI(LOperand* left, LOperand* right);
298  void EmitNumberUntagD(LNumberUntagD* instr, Register input,
300 
301  // Emits optimized code for typeof x == "y". Modifies input register.
302  // Returns the condition on which a final split to
303  // true and false label should be made, to optimize fallthrough.
304  // Returns two registers in cmp1 and cmp2 that can be used in the
305  // Branch instruction after EmitTypeofIs.
306  Condition EmitTypeofIs(Label* true_label,
307  Label* false_label,
308  Register input,
309  Handle<String> type_name,
310  Register* cmp1,
311  Operand* cmp2);
312 
313  // Emits optimized code for %_IsObject(x). Preserves input register.
314  // Returns the condition on which a final split to
315  // true and false label should be made, to optimize fallthrough.
317  Register temp1,
318  Register temp2,
319  Label* is_not_object,
320  Label* is_object);
321 
322  // Emits optimized code for %_IsString(x). Preserves input register.
323  // Returns the condition on which a final split to
324  // true and false label should be made, to optimize fallthrough.
326  Register temp1,
327  Label* is_not_string,
328  SmiCheck check_needed);
329 
330  // Emits optimized code for %_IsConstructCall().
331  // Caller should branch on equal condition.
333 
334  // Emits optimized code to deep-copy the contents of statically known
335  // object graphs (e.g. object literal boilerplate).
337  Register result,
338  Register source,
339  int* offset,
341  // Emit optimized code for integer division.
342  // Inputs are signed.
343  // All registers are clobbered.
344  // If 'remainder' is no_reg, it is not computed.
346  Register dividend,
347  int32_t divisor,
348  Register remainder,
349  Register scratch,
350  LEnvironment* environment);
351 
352 
353  void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE;
360 
361  template <class T>
363 
368  Scope* const scope_;
369  TranslationBuffer translations_;
371  int osr_pc_offset_;
372  bool frame_is_built_;
373 
374  // Builder that keeps track of safepoints in the code. The table
375  // itself is emitted at the end of the generated code.
376  SafepointTableBuilder safepoints_;
377 
378  // Compiler from a set of parallel moves to a sequential list of moves.
380 
381  Safepoint::Kind expected_safepoint_kind_;
382 
383  class PushSafepointRegistersScope FINAL BASE_EMBEDDED {
384  public:
386  : codegen_(codegen) {
387  DCHECK(codegen_->info()->is_calling());
388  DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
389  codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
390 
391  StoreRegistersStateStub stub(codegen_->isolate());
392  codegen_->masm_->push(ra);
393  codegen_->masm_->CallStub(&stub);
394  }
395 
397  DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
398  RestoreRegistersStateStub stub(codegen_->isolate());
399  codegen_->masm_->push(ra);
400  codegen_->masm_->CallStub(&stub);
401  codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
402  }
403 
404  private:
405  LCodeGen* codegen_;
406  };
407 
408  friend class LDeferredCode;
409  friend class LEnvironment;
410  friend class SafepointGenerator;
412 };
413 
414 
415 class LDeferredCode : public ZoneObject {
416  public:
418  : codegen_(codegen),
420  instruction_index_(codegen->current_instruction_) {
421  codegen->AddDeferredCode(this);
422  }
423 
424  virtual ~LDeferredCode() {}
425  virtual void Generate() = 0;
426  virtual LInstruction* instr() = 0;
427 
428  void SetExit(Label* exit) { external_exit_ = exit; }
429  Label* entry() { return &entry_; }
430  Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
431  int instruction_index() const { return instruction_index_; }
432 
433  protected:
434  LCodeGen* codegen() const { return codegen_; }
435  MacroAssembler* masm() const { return codegen_->masm(); }
436 
437  private:
439  Label entry_;
440  Label exit_;
441  Label* external_exit_;
442  int instruction_index_;
443 };
444 
445 } } // namespace v8::internal
446 
447 #endif // V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
#define kLithiumScratchReg2
#define kLithiumScratchReg
#define kLithiumScratchDouble
Source to read snapshot and builtins files from.
Definition: lithium-arm.h:372
bool IsNextEmittedBlock(int block_id) const
Register ToRegister(int index) const
void DoStoreKeyedFixedArray(LStoreKeyed *instr)
void AddDeferredCode(LDeferredCode *code)
DoubleRegister ToDoubleRegister(LOperand *op) const
void RecordSafepointWithRegisters(LPointerMap *pointers, int arguments, Safepoint::DeoptMode mode)
void EmitBranchF(InstrType instr, Condition condition, FPURegister src1, FPURegister src2)
void EmitDeepCopy(Handle< JSObject > object, Register result, Register source, int *offset, AllocationSiteMode mode)
bool IsSmi(LConstantOperand *op) const
TranslationBuffer translations_
MemOperand BuildSeqStringOperand(Register string, LOperand *index, String::Encoding encoding)
Condition EmitIsString(Register input, Register temp1, Label *is_not_string, SmiCheck check_needed)
DwVfpRegister EmitLoadDoubleRegister(LOperand *op, SwVfpRegister flt_scratch, DwVfpRegister dbl_scratch)
void DoDeferredStackCheck(LStackCheck *instr)
SafepointTableBuilder safepoints_
LInstruction * GetNextInstruction()
void EmitVectorLoadICRegisters(T *instr)
ZoneList< Handle< Object > > deoptimization_literals_
void DoGap(LGap *instr)
void RecordSafepoint(Safepoint::DeoptMode mode)
MemOperand PrepareKeyedOperand(Register key, Register base, bool key_is_constant, int constant_key, int element_size, int shift_size, int base_offset)
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 EmitIsConstructCall(Register temp1, Register temp2)
void EmitFalseBranchF(InstrType instr, Condition condition, FPURegister src1, FPURegister src2)
DoubleRegister double_scratch0()
int32_t ToInteger32(LConstantOperand *op) const
LPlatformChunk * chunk() const
void FinishCode(Handle< Code > code)
Handle< Object > ToHandle(LConstantOperand *op) const
int LookupDestination(int block_id) const
Condition EmitTypeofIs(Label *true_label, Label *false_label, Register input, Handle< String > type_name)
void DoDeferredAllocate(LAllocate *instr)
void RecordSafepoint(LPointerMap *pointers, Safepoint::Kind kind, int arguments, Safepoint::DeoptMode mode)
void DoDeferredTaggedToI(LTaggedToI *instr)
void DoDeferredStringCharCodeAt(LStringCharCodeAt *instr)
Safepoint::Kind expected_safepoint_kind_
ZoneList< LDeferredCode * > deferred_
void EmitGoto(int block)
DoubleRegister ToDoubleRegister(int index) const
void RecordSafepoint(LPointerMap *pointers, Safepoint::DeoptMode mode)
void DoDeferredNumberTagIU(LInstruction *instr, LOperand *value, LOperand *temp1, LOperand *temp2, IntegerSignedness signedness)
StrictMode strict_mode() const
void RegisterEnvironmentForDeoptimization(LEnvironment *environment, Safepoint::DeoptMode mode)
void LoadContextFromDeferred(LOperand *context)
void CallCodeGeneric(Handle< Code > code, RelocInfo::Mode mode, LInstruction *instr, SafepointMode safepoint_mode)
void EmitSignedIntegerDivisionByConstant(Register result, Register dividend, int32_t divisor, Register remainder, Register scratch, LEnvironment *environment)
void DoDeferredInstanceMigration(LCheckMaps *instr, Register object)
void DoDeferredLoadMutableDouble(LLoadFieldByIndex *instr, Register result, Register object, Register index)
int DefineDeoptimizationLiteral(Handle< Object > literal)
void DeoptimizeIf(Condition condition, LInstruction *instr, const char *detail, Deoptimizer::BailoutType bailout_type)
void CallKnownFunction(Handle< JSFunction > function, int formal_parameter_count, int arity, LInstruction *instr, R1State r1_state)
void WriteTranslation(LEnvironment *environment, Translation *translation)
void DoDeferredMathAbsTaggedHeapNumber(LMathAbs *instr)
void DoLoadKeyedFixedDoubleArray(LLoadKeyed *instr)
static Condition TokenToCondition(Token::Value op, bool is_unsigned)
Operand ToOperand(LOperand *op)
Register EmitLoadRegister(LOperand *op, Register scratch)
void EmitClassOfTest(Label *if_true, Label *if_false, Handle< String > class_name, Register input, Register temporary, Register temporary2)
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
bool IsInteger32(LConstantOperand *op) const
void PopulateDeoptimizationData(Handle< Code > code)
void DoParallelMove(LParallelMove *move)
void CallRuntime(const Runtime::Function *function, int num_arguments, LInstruction *instr, SaveFPRegsMode save_doubles=kDontSaveFPRegs)
void CallCode(Handle< Code > code, RelocInfo::Mode mode, LInstruction *instr)
void DoDeferredStringCharFromCode(LStringCharFromCode *instr)
void EmitCmpI(LOperand *left, LOperand *right)
ZoneList< Deoptimizer::JumpTableEntry > jump_table_
Condition EmitIsObject(Register input, Register temp1, Label *is_not_object, Label *is_object)
void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE
MemOperand ToMemOperand(LOperand *op) const
void GenerateBodyInstructionPre(LInstruction *instr) OVERRIDE
MemOperand ToHighMemOperand(LOperand *op) const
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal *instr, Label *map_check)
void RecordSafepointWithLazyDeopt(LInstruction *instr, SafepointMode safepoint_mode)
void EmitFalseBranch(InstrType instr, Condition condition)
void DoLoadKeyedFixedArray(LLoadKeyed *instr)
Smi * ToSmi(LConstantOperand *op) const
LCodeGen(LChunk *chunk, MacroAssembler *assembler, CompilationInfo *info)
void EmitBranch(InstrType instr, Condition condition)
void DoDeferredNumberTagD(LNumberTagD *instr)
void DoStoreKeyedFixedDoubleArray(LStoreKeyed *instr)
void EmitNumberUntagD(LNumberUntagD *instr, Register input, DoubleRegister result, NumberUntagDMode mode)
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
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define T(name, string, precedence)
Definition: token.cc:25