V8 Project
lithium-ia32.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_IA32_LITHIUM_IA32_H_
6 #define V8_IA32_LITHIUM_IA32_H_
7 
8 #include "src/hydrogen.h"
9 #include "src/lithium.h"
10 #include "src/lithium-allocator.h"
11 #include "src/safepoint-table.h"
12 #include "src/utils.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 namespace compiler {
18 class RCodeVisualizer;
19 }
20 
21 // Forward declarations.
22 class LCodeGen;
23 
24 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
25  V(AccessArgumentsAt) \
26  V(AddI) \
27  V(AllocateBlockContext) \
28  V(Allocate) \
29  V(ApplyArguments) \
30  V(ArgumentsElements) \
31  V(ArgumentsLength) \
32  V(ArithmeticD) \
33  V(ArithmeticT) \
34  V(BitI) \
35  V(BoundsCheck) \
36  V(Branch) \
37  V(CallJSFunction) \
38  V(CallWithDescriptor) \
39  V(CallFunction) \
40  V(CallNew) \
41  V(CallNewArray) \
42  V(CallRuntime) \
43  V(CallStub) \
44  V(CheckInstanceType) \
45  V(CheckMaps) \
46  V(CheckMapValue) \
47  V(CheckNonSmi) \
48  V(CheckSmi) \
49  V(CheckValue) \
50  V(ClampDToUint8) \
51  V(ClampIToUint8) \
52  V(ClampTToUint8) \
53  V(ClassOfTestAndBranch) \
54  V(CompareMinusZeroAndBranch) \
55  V(CompareNumericAndBranch) \
56  V(CmpObjectEqAndBranch) \
57  V(CmpHoleAndBranch) \
58  V(CmpMapAndBranch) \
59  V(CmpT) \
60  V(ConstantD) \
61  V(ConstantE) \
62  V(ConstantI) \
63  V(ConstantS) \
64  V(ConstantT) \
65  V(ConstructDouble) \
66  V(Context) \
67  V(DateField) \
68  V(DebugBreak) \
69  V(DeclareGlobals) \
70  V(Deoptimize) \
71  V(DivByConstI) \
72  V(DivByPowerOf2I) \
73  V(DivI) \
74  V(DoubleBits) \
75  V(DoubleToI) \
76  V(DoubleToSmi) \
77  V(Drop) \
78  V(Dummy) \
79  V(DummyUse) \
80  V(FlooringDivByConstI) \
81  V(FlooringDivByPowerOf2I) \
82  V(FlooringDivI) \
83  V(ForInCacheArray) \
84  V(ForInPrepareMap) \
85  V(FunctionLiteral) \
86  V(GetCachedArrayIndex) \
87  V(Goto) \
88  V(HasCachedArrayIndexAndBranch) \
89  V(HasInstanceTypeAndBranch) \
90  V(InnerAllocatedObject) \
91  V(InstanceOf) \
92  V(InstanceOfKnownGlobal) \
93  V(InstructionGap) \
94  V(Integer32ToDouble) \
95  V(InvokeFunction) \
96  V(IsConstructCallAndBranch) \
97  V(IsObjectAndBranch) \
98  V(IsStringAndBranch) \
99  V(IsSmiAndBranch) \
100  V(IsUndetectableAndBranch) \
101  V(Label) \
102  V(LazyBailout) \
103  V(LoadContextSlot) \
104  V(LoadFieldByIndex) \
105  V(LoadFunctionPrototype) \
106  V(LoadGlobalCell) \
107  V(LoadGlobalGeneric) \
108  V(LoadKeyed) \
109  V(LoadKeyedGeneric) \
110  V(LoadNamedField) \
111  V(LoadNamedGeneric) \
112  V(LoadRoot) \
113  V(MapEnumLength) \
114  V(MathAbs) \
115  V(MathClz32) \
116  V(MathExp) \
117  V(MathFloor) \
118  V(MathFround) \
119  V(MathLog) \
120  V(MathMinMax) \
121  V(MathPowHalf) \
122  V(MathRound) \
123  V(MathSqrt) \
124  V(ModByConstI) \
125  V(ModByPowerOf2I) \
126  V(ModI) \
127  V(MulI) \
128  V(NumberTagD) \
129  V(NumberTagI) \
130  V(NumberTagU) \
131  V(NumberUntagD) \
132  V(OsrEntry) \
133  V(Parameter) \
134  V(Power) \
135  V(PushArgument) \
136  V(RegExpLiteral) \
137  V(Return) \
138  V(SeqStringGetChar) \
139  V(SeqStringSetChar) \
140  V(ShiftI) \
141  V(SmiTag) \
142  V(SmiUntag) \
143  V(StackCheck) \
144  V(StoreCodeEntry) \
145  V(StoreContextSlot) \
146  V(StoreFrameContext) \
147  V(StoreGlobalCell) \
148  V(StoreKeyed) \
149  V(StoreKeyedGeneric) \
150  V(StoreNamedField) \
151  V(StoreNamedGeneric) \
152  V(StringAdd) \
153  V(StringCharCodeAt) \
154  V(StringCharFromCode) \
155  V(StringCompareAndBranch) \
156  V(SubI) \
157  V(TaggedToI) \
158  V(TailCallThroughMegamorphicCache) \
159  V(ThisFunction) \
160  V(ToFastProperties) \
161  V(TransitionElementsKind) \
162  V(TrapAllocationMemento) \
163  V(Typeof) \
164  V(TypeofIsAndBranch) \
165  V(Uint32ToDouble) \
166  V(UnknownOSRValue) \
167  V(WrapReceiver)
168 
169 
170 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
171  virtual Opcode opcode() const FINAL OVERRIDE { \
172  return LInstruction::k##type; \
173  } \
174  virtual void CompileToNative(LCodeGen* generator) FINAL OVERRIDE; \
175  virtual const char* Mnemonic() const FINAL OVERRIDE { \
176  return mnemonic; \
177  } \
178  static L##type* cast(LInstruction* instr) { \
179  DCHECK(instr->Is##type()); \
180  return reinterpret_cast<L##type*>(instr); \
181  }
182 
183 
184 #define DECLARE_HYDROGEN_ACCESSOR(type) \
185  H##type* hydrogen() const { \
186  return H##type::cast(hydrogen_value()); \
187  }
188 
189 
190 class LInstruction : public ZoneObject {
191  public:
193  : environment_(NULL),
195  bit_field_(IsCallBits::encode(false)) {
196  }
197 
198  virtual ~LInstruction() {}
199 
200  virtual void CompileToNative(LCodeGen* generator) = 0;
201  virtual const char* Mnemonic() const = 0;
202  virtual void PrintTo(StringStream* stream);
203  virtual void PrintDataTo(StringStream* stream);
204  virtual void PrintOutputOperandTo(StringStream* stream);
205 
206  enum Opcode {
207  // Declare a unique enum value for each instruction.
208 #define DECLARE_OPCODE(type) k##type,
211 #undef DECLARE_OPCODE
212  };
213 
214  virtual Opcode opcode() const = 0;
215 
216  // Declare non-virtual type testers for all leaf IR classes.
217 #define DECLARE_PREDICATE(type) \
218  bool Is##type() const { return opcode() == k##type; }
220 #undef DECLARE_PREDICATE
221 
222  // Declare virtual predicates for instructions that don't have
223  // an opcode.
224  virtual bool IsGap() const { return false; }
225 
226  virtual bool IsControl() const { return false; }
227 
228  // Try deleting this instruction if possible.
229  virtual bool TryDelete() { return false; }
230 
231  void set_environment(LEnvironment* env) { environment_ = env; }
232  LEnvironment* environment() const { return environment_; }
233  bool HasEnvironment() const { return environment_ != NULL; }
234 
235  void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
236  LPointerMap* pointer_map() const { return pointer_map_.get(); }
237  bool HasPointerMap() const { return pointer_map_.is_set(); }
238 
239  void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
240  HValue* hydrogen_value() const { return hydrogen_value_; }
241 
242  virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
243 
245  bool IsCall() const { return IsCallBits::decode(bit_field_); }
246 
247  // Interface to the register allocator and iterators.
248  bool ClobbersTemps() const { return IsCall(); }
249  bool ClobbersRegisters() const { return IsCall(); }
250  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
251  return IsCall();
252  }
253 
254  virtual bool HasResult() const = 0;
255  virtual LOperand* result() const = 0;
256 
259 
260  LOperand* FirstInput() { return InputAt(0); }
261  LOperand* Output() { return HasResult() ? result() : NULL; }
262 
263  virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
264 
265 #ifdef DEBUG
266  void VerifyCall();
267 #endif
268 
269  virtual int InputCount() = 0;
270  virtual LOperand* InputAt(int i) = 0;
271 
272  private:
273  // Iterator support.
274  friend class InputIterator;
275 
276  friend class TempIterator;
277  virtual int TempCount() = 0;
278  virtual LOperand* TempAt(int i) = 0;
279 
280  class IsCallBits: public BitField<bool, 0, 1> {};
281 
282  LEnvironment* environment_;
285  int bit_field_;
286 };
287 
288 
289 // R = number of result operands (0 or 1).
290 template<int R>
291 class LTemplateResultInstruction : public LInstruction {
292  public:
293  // Allow 0 or 1 output operands.
294  STATIC_ASSERT(R == 0 || R == 1);
295  virtual bool HasResult() const FINAL OVERRIDE {
296  return R != 0 && result() != NULL;
297  }
298  void set_result(LOperand* operand) { results_[0] = operand; }
299  LOperand* result() const { return results_[0]; }
300 
301  protected:
303 };
304 
305 
306 // R = number of result operands (0 or 1).
307 // I = number of input operands.
308 // T = number of temporary operands.
309 template<int R, int I, int T>
310 class LTemplateInstruction : public LTemplateResultInstruction<R> {
311  protected:
312  EmbeddedContainer<LOperand*, I> inputs_;
313  EmbeddedContainer<LOperand*, T> temps_;
314 
315  private:
316  // Iterator support.
317  virtual int InputCount() FINAL OVERRIDE { return I; }
318  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
319 
320  virtual int TempCount() FINAL OVERRIDE { return T; }
321  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; }
322 };
323 
324 
325 class LGap : public LTemplateInstruction<0, 0, 0> {
326  public:
327  explicit LGap(HBasicBlock* block) : block_(block) {
332  }
333 
334  // Can't use the DECLARE-macro here because of sub-classes.
335  virtual bool IsGap() const FINAL OVERRIDE { return true; }
336  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
337  static LGap* cast(LInstruction* instr) {
338  DCHECK(instr->IsGap());
339  return reinterpret_cast<LGap*>(instr);
340  }
341 
342  bool IsRedundant() const;
343 
344  HBasicBlock* block() const { return block_; }
345 
347  BEFORE,
348  START,
349  END,
350  AFTER,
353  };
354 
355  LParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) {
356  if (parallel_moves_[pos] == NULL) {
357  parallel_moves_[pos] = new(zone) LParallelMove(zone);
358  }
359  return parallel_moves_[pos];
360  }
361 
362  LParallelMove* GetParallelMove(InnerPosition pos) {
363  return parallel_moves_[pos];
364  }
365 
366  private:
367  LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
368  HBasicBlock* block_;
369 };
370 
371 
372 class LInstructionGap FINAL : public LGap {
373  public:
374  explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
375 
376  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
377  return !IsRedundant();
378  }
379 
380  DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
381 };
382 
383 
384 class LGoto FINAL : public LTemplateInstruction<0, 0, 0> {
385  public:
386  explicit LGoto(HBasicBlock* block) : block_(block) { }
387 
388  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
389  DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
390  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
391  virtual bool IsControl() const OVERRIDE { return true; }
392 
393  int block_id() const { return block_->block_id(); }
394  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
395  return false;
396  }
397 
398  bool jumps_to_join() const { return block_->predecessors()->length() > 1; }
399 
400  private:
401  HBasicBlock* block_;
402 };
403 
404 
405 class LLazyBailout FINAL : public LTemplateInstruction<0, 0, 0> {
406  public:
407  DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
408 };
409 
410 
411 class LDummy FINAL : public LTemplateInstruction<1, 0, 0> {
412  public:
413  LDummy() {}
414  DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
415 };
416 
417 
418 class LDummyUse FINAL : public LTemplateInstruction<1, 1, 0> {
419  public:
420  explicit LDummyUse(LOperand* value) {
421  inputs_[0] = value;
422  }
423  DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
424 };
425 
426 
427 class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
428  public:
429  virtual bool IsControl() const OVERRIDE { return true; }
430  DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
431  DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
432 };
433 
434 
435 class LLabel FINAL : public LGap {
436  public:
437  explicit LLabel(HBasicBlock* block)
438  : LGap(block), replacement_(NULL) { }
439 
440  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
441  return false;
442  }
443  DECLARE_CONCRETE_INSTRUCTION(Label, "label")
444 
445  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
446 
447  int block_id() const { return block()->block_id(); }
448  bool is_loop_header() const { return block()->IsLoopHeader(); }
449  bool is_osr_entry() const { return block()->is_osr_entry(); }
450  Label* label() { return &label_; }
451  LLabel* replacement() const { return replacement_; }
452  void set_replacement(LLabel* label) { replacement_ = label; }
453  bool HasReplacement() const { return replacement_ != NULL; }
454 
455  private:
456  Label label_;
457  LLabel* replacement_;
458 };
459 
460 
461 class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
462  public:
463  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
464  return false;
465  }
466  DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
467 };
468 
469 
470 class LCallStub FINAL : public LTemplateInstruction<1, 1, 0> {
471  public:
472  explicit LCallStub(LOperand* context) {
473  inputs_[0] = context;
474  }
475 
476  LOperand* context() { return inputs_[0]; }
477 
478  DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
479  DECLARE_HYDROGEN_ACCESSOR(CallStub)
480 };
481 
482 
483 class LTailCallThroughMegamorphicCache FINAL
484  : public LTemplateInstruction<0, 3, 0> {
485  public:
487  LOperand* receiver,
488  LOperand* name) {
489  inputs_[0] = context;
490  inputs_[1] = receiver;
491  inputs_[2] = name;
492  }
493 
494  LOperand* context() { return inputs_[0]; }
495  LOperand* receiver() { return inputs_[1]; }
496  LOperand* name() { return inputs_[2]; }
497 
498  DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
499  "tail-call-through-megamorphic-cache")
500  DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
501 };
502 
503 
504 class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
505  public:
506  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
507  return false;
508  }
509  DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
510 };
511 
512 
513 template<int I, int T>
514 class LControlInstruction: public LTemplateInstruction<0, I, T> {
515  public:
516  LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
517 
518  virtual bool IsControl() const FINAL OVERRIDE { return true; }
519 
520  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
521  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
522 
523  int TrueDestination(LChunk* chunk) {
524  return chunk->LookupDestination(true_block_id());
525  }
526  int FalseDestination(LChunk* chunk) {
527  return chunk->LookupDestination(false_block_id());
528  }
529 
530  Label* TrueLabel(LChunk* chunk) {
531  if (true_label_ == NULL) {
532  true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
533  }
534  return true_label_;
535  }
536  Label* FalseLabel(LChunk* chunk) {
537  if (false_label_ == NULL) {
538  false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
539  }
540  return false_label_;
541  }
542 
543  protected:
544  int true_block_id() { return SuccessorAt(0)->block_id(); }
545  int false_block_id() { return SuccessorAt(1)->block_id(); }
546 
547  private:
549  return HControlInstruction::cast(this->hydrogen_value());
550  }
551 
552  Label* false_label_;
553  Label* true_label_;
554 };
555 
556 
557 class LWrapReceiver FINAL : public LTemplateInstruction<1, 2, 1> {
558  public:
560  LOperand* function,
561  LOperand* temp) {
562  inputs_[0] = receiver;
563  inputs_[1] = function;
564  temps_[0] = temp;
565  }
566 
567  LOperand* receiver() { return inputs_[0]; }
568  LOperand* function() { return inputs_[1]; }
569  LOperand* temp() { return temps_[0]; }
570 
571  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
572  DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)
573 };
574 
575 
576 class LApplyArguments FINAL : public LTemplateInstruction<1, 4, 0> {
577  public:
579  LOperand* receiver,
580  LOperand* length,
581  LOperand* elements) {
582  inputs_[0] = function;
583  inputs_[1] = receiver;
584  inputs_[2] = length;
585  inputs_[3] = elements;
586  }
587 
588  LOperand* function() { return inputs_[0]; }
589  LOperand* receiver() { return inputs_[1]; }
590  LOperand* length() { return inputs_[2]; }
591  LOperand* elements() { return inputs_[3]; }
592 
593  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
594 };
595 
596 
597 class LAccessArgumentsAt FINAL : public LTemplateInstruction<1, 3, 0> {
598  public:
599  LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
600  inputs_[0] = arguments;
601  inputs_[1] = length;
602  inputs_[2] = index;
603  }
604 
605  LOperand* arguments() { return inputs_[0]; }
606  LOperand* length() { return inputs_[1]; }
607  LOperand* index() { return inputs_[2]; }
608 
609  DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
610 
611  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
612 };
613 
614 
615 class LArgumentsLength FINAL : public LTemplateInstruction<1, 1, 0> {
616  public:
617  explicit LArgumentsLength(LOperand* elements) {
618  inputs_[0] = elements;
619  }
620 
621  LOperand* elements() { return inputs_[0]; }
622 
623  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
624 };
625 
626 
627 class LArgumentsElements FINAL : public LTemplateInstruction<1, 0, 0> {
628  public:
629  DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
630  DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
631 };
632 
633 
634 class LDebugBreak FINAL : public LTemplateInstruction<0, 0, 0> {
635  public:
636  DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
637 };
638 
639 
640 class LModByPowerOf2I FINAL : public LTemplateInstruction<1, 1, 0> {
641  public:
642  LModByPowerOf2I(LOperand* dividend, int32_t divisor) {
643  inputs_[0] = dividend;
644  divisor_ = divisor;
645  }
646 
647  LOperand* dividend() { return inputs_[0]; }
648  int32_t divisor() const { return divisor_; }
649 
650  DECLARE_CONCRETE_INSTRUCTION(ModByPowerOf2I, "mod-by-power-of-2-i")
652 
653  private:
654  int32_t divisor_;
655 };
656 
657 
658 class LModByConstI FINAL : public LTemplateInstruction<1, 1, 2> {
659  public:
661  int32_t divisor,
662  LOperand* temp1,
663  LOperand* temp2) {
664  inputs_[0] = dividend;
665  divisor_ = divisor;
666  temps_[0] = temp1;
667  temps_[1] = temp2;
668  }
669 
670  LOperand* dividend() { return inputs_[0]; }
671  int32_t divisor() const { return divisor_; }
672  LOperand* temp1() { return temps_[0]; }
673  LOperand* temp2() { return temps_[1]; }
674 
675  DECLARE_CONCRETE_INSTRUCTION(ModByConstI, "mod-by-const-i")
677 
678  private:
679  int32_t divisor_;
680 };
681 
682 
683 class LModI FINAL : public LTemplateInstruction<1, 2, 1> {
684  public:
685  LModI(LOperand* left, LOperand* right, LOperand* temp) {
686  inputs_[0] = left;
687  inputs_[1] = right;
688  temps_[0] = temp;
689  }
690 
691  LOperand* left() { return inputs_[0]; }
692  LOperand* right() { return inputs_[1]; }
693  LOperand* temp() { return temps_[0]; }
694 
695  DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
697 };
698 
699 
700 class LDivByPowerOf2I FINAL : public LTemplateInstruction<1, 1, 0> {
701  public:
702  LDivByPowerOf2I(LOperand* dividend, int32_t divisor) {
703  inputs_[0] = dividend;
704  divisor_ = divisor;
705  }
706 
707  LOperand* dividend() { return inputs_[0]; }
708  int32_t divisor() const { return divisor_; }
709 
710  DECLARE_CONCRETE_INSTRUCTION(DivByPowerOf2I, "div-by-power-of-2-i")
712 
713  private:
714  int32_t divisor_;
715 };
716 
717 
718 class LDivByConstI FINAL : public LTemplateInstruction<1, 1, 2> {
719  public:
721  int32_t divisor,
722  LOperand* temp1,
723  LOperand* temp2) {
724  inputs_[0] = dividend;
725  divisor_ = divisor;
726  temps_[0] = temp1;
727  temps_[1] = temp2;
728  }
729 
730  LOperand* dividend() { return inputs_[0]; }
731  int32_t divisor() const { return divisor_; }
732  LOperand* temp1() { return temps_[0]; }
733  LOperand* temp2() { return temps_[1]; }
734 
735  DECLARE_CONCRETE_INSTRUCTION(DivByConstI, "div-by-const-i")
737 
738  private:
739  int32_t divisor_;
740 };
741 
742 
743 class LDivI FINAL : public LTemplateInstruction<1, 2, 1> {
744  public:
745  LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
746  inputs_[0] = dividend;
747  inputs_[1] = divisor;
748  temps_[0] = temp;
749  }
750 
751  LOperand* dividend() { return inputs_[0]; }
752  LOperand* divisor() { return inputs_[1]; }
753  LOperand* temp() { return temps_[0]; }
754 
755  DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
756  DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
757 };
758 
759 
760 class LFlooringDivByPowerOf2I FINAL : public LTemplateInstruction<1, 1, 0> {
761  public:
763  inputs_[0] = dividend;
764  divisor_ = divisor;
765  }
766 
767  LOperand* dividend() { return inputs_[0]; }
768  int32_t divisor() const { return divisor_; }
769 
770  DECLARE_CONCRETE_INSTRUCTION(FlooringDivByPowerOf2I,
771  "flooring-div-by-power-of-2-i")
772  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
773 
774  private:
775  int32_t divisor_;
776 };
777 
778 
779 class LFlooringDivByConstI FINAL : public LTemplateInstruction<1, 1, 3> {
780  public:
782  int32_t divisor,
783  LOperand* temp1,
784  LOperand* temp2,
785  LOperand* temp3) {
786  inputs_[0] = dividend;
787  divisor_ = divisor;
788  temps_[0] = temp1;
789  temps_[1] = temp2;
790  temps_[2] = temp3;
791  }
792 
793  LOperand* dividend() { return inputs_[0]; }
794  int32_t divisor() const { return divisor_; }
795  LOperand* temp1() { return temps_[0]; }
796  LOperand* temp2() { return temps_[1]; }
797  LOperand* temp3() { return temps_[2]; }
798 
799  DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
800  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
801 
802  private:
803  int32_t divisor_;
804 };
805 
806 
807 class LFlooringDivI FINAL : public LTemplateInstruction<1, 2, 1> {
808  public:
809  LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
810  inputs_[0] = dividend;
811  inputs_[1] = divisor;
812  temps_[0] = temp;
813  }
814 
815  LOperand* dividend() { return inputs_[0]; }
816  LOperand* divisor() { return inputs_[1]; }
817  LOperand* temp() { return temps_[0]; }
818 
819  DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
820  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
821 };
822 
823 
824 class LMulI FINAL : public LTemplateInstruction<1, 2, 1> {
825  public:
826  LMulI(LOperand* left, LOperand* right, LOperand* temp) {
827  inputs_[0] = left;
828  inputs_[1] = right;
829  temps_[0] = temp;
830  }
831 
832  LOperand* left() { return inputs_[0]; }
833  LOperand* right() { return inputs_[1]; }
834  LOperand* temp() { return temps_[0]; }
835 
836  DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
838 };
839 
840 
841 class LCompareNumericAndBranch FINAL : public LControlInstruction<2, 0> {
842  public:
844  inputs_[0] = left;
845  inputs_[1] = right;
846  }
847 
848  LOperand* left() { return inputs_[0]; }
849  LOperand* right() { return inputs_[1]; }
850 
851  DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
852  "compare-numeric-and-branch")
853  DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
854 
855  Token::Value op() const { return hydrogen()->token(); }
856  bool is_double() const {
857  return hydrogen()->representation().IsDouble();
858  }
859 
860  virtual void PrintDataTo(StringStream* stream);
861 };
862 
863 
864 class LMathFloor FINAL : public LTemplateInstruction<1, 1, 0> {
865  public:
866  explicit LMathFloor(LOperand* value) {
867  inputs_[0] = value;
868  }
869 
870  LOperand* value() { return inputs_[0]; }
871 
872  DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
873  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
874 };
875 
876 
877 class LMathRound FINAL : public LTemplateInstruction<1, 1, 1> {
878  public:
879  LMathRound(LOperand* value, LOperand* temp) {
880  inputs_[0] = value;
881  temps_[0] = temp;
882  }
883 
884  LOperand* temp() { return temps_[0]; }
885  LOperand* value() { return inputs_[0]; }
886 
887  DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
888  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
889 };
890 
891 
892 class LMathFround FINAL : public LTemplateInstruction<1, 1, 0> {
893  public:
894  explicit LMathFround(LOperand* value) { inputs_[0] = value; }
895 
896  LOperand* value() { return inputs_[0]; }
897 
898  DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround")
899 };
900 
901 
902 class LMathAbs FINAL : public LTemplateInstruction<1, 2, 0> {
903  public:
904  LMathAbs(LOperand* context, LOperand* value) {
905  inputs_[1] = context;
906  inputs_[0] = value;
907  }
908 
909  LOperand* context() { return inputs_[1]; }
910  LOperand* value() { return inputs_[0]; }
911 
912  DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
913  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
914 };
915 
916 
917 class LMathLog FINAL : public LTemplateInstruction<1, 1, 0> {
918  public:
919  explicit LMathLog(LOperand* value) {
920  inputs_[0] = value;
921  }
922 
923  LOperand* value() { return inputs_[0]; }
924 
925  DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
926 };
927 
928 
929 class LMathClz32 FINAL : public LTemplateInstruction<1, 1, 0> {
930  public:
931  explicit LMathClz32(LOperand* value) {
932  inputs_[0] = value;
933  }
934 
935  LOperand* value() { return inputs_[0]; }
936 
937  DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32")
938 };
939 
940 
941 class LMathExp FINAL : public LTemplateInstruction<1, 1, 2> {
942  public:
944  LOperand* temp1,
945  LOperand* temp2) {
946  inputs_[0] = value;
947  temps_[0] = temp1;
948  temps_[1] = temp2;
949  ExternalReference::InitializeMathExpData();
950  }
951 
952  LOperand* value() { return inputs_[0]; }
953  LOperand* temp1() { return temps_[0]; }
954  LOperand* temp2() { return temps_[1]; }
955 
956  DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
957 };
958 
959 
960 class LMathSqrt FINAL : public LTemplateInstruction<1, 1, 0> {
961  public:
962  explicit LMathSqrt(LOperand* value) {
963  inputs_[0] = value;
964  }
965 
966  LOperand* value() { return inputs_[0]; }
967 
968  DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
969 };
970 
971 
972 class LMathPowHalf FINAL : public LTemplateInstruction<1, 1, 1> {
973  public:
974  LMathPowHalf(LOperand* value, LOperand* temp) {
975  inputs_[0] = value;
976  temps_[0] = temp;
977  }
978 
979  LOperand* value() { return inputs_[0]; }
980  LOperand* temp() { return temps_[0]; }
981 
982  DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
983 };
984 
985 
986 class LCmpObjectEqAndBranch FINAL : public LControlInstruction<2, 0> {
987  public:
989  inputs_[0] = left;
990  inputs_[1] = right;
991  }
992 
993  LOperand* left() { return inputs_[0]; }
994  LOperand* right() { return inputs_[1]; }
995 
996  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
997 };
998 
999 
1000 class LCmpHoleAndBranch FINAL : public LControlInstruction<1, 0> {
1001  public:
1002  explicit LCmpHoleAndBranch(LOperand* object) {
1003  inputs_[0] = object;
1004  }
1005 
1006  LOperand* object() { return inputs_[0]; }
1007 
1008  DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
1009  DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
1010 };
1011 
1012 
1013 class LCompareMinusZeroAndBranch FINAL : public LControlInstruction<1, 1> {
1014  public:
1016  inputs_[0] = value;
1017  temps_[0] = temp;
1018  }
1019 
1020  LOperand* value() { return inputs_[0]; }
1021  LOperand* temp() { return temps_[0]; }
1022 
1023  DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
1024  "cmp-minus-zero-and-branch")
1025  DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
1026 };
1027 
1028 
1029 class LIsObjectAndBranch FINAL : public LControlInstruction<1, 1> {
1030  public:
1032  inputs_[0] = value;
1033  temps_[0] = temp;
1034  }
1035 
1036  LOperand* value() { return inputs_[0]; }
1037  LOperand* temp() { return temps_[0]; }
1038 
1039  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
1040 
1041  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1042 };
1043 
1044 
1045 class LIsStringAndBranch FINAL : public LControlInstruction<1, 1> {
1046  public:
1048  inputs_[0] = value;
1049  temps_[0] = temp;
1050  }
1051 
1052  LOperand* value() { return inputs_[0]; }
1053  LOperand* temp() { return temps_[0]; }
1054 
1055  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
1056  DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
1057 
1058  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1059 };
1060 
1061 
1062 class LIsSmiAndBranch FINAL : public LControlInstruction<1, 0> {
1063  public:
1064  explicit LIsSmiAndBranch(LOperand* value) {
1065  inputs_[0] = value;
1066  }
1067 
1068  LOperand* value() { return inputs_[0]; }
1069 
1070  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
1071  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
1072 
1073  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1074 };
1075 
1076 
1077 class LIsUndetectableAndBranch FINAL : public LControlInstruction<1, 1> {
1078  public:
1080  inputs_[0] = value;
1081  temps_[0] = temp;
1082  }
1083 
1084  LOperand* value() { return inputs_[0]; }
1085  LOperand* temp() { return temps_[0]; }
1086 
1087  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
1088  "is-undetectable-and-branch")
1089  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
1090 
1091  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1092 };
1093 
1094 
1095 class LStringCompareAndBranch FINAL : public LControlInstruction<3, 0> {
1096  public:
1098  inputs_[0] = context;
1099  inputs_[1] = left;
1100  inputs_[2] = right;
1101  }
1102 
1103  LOperand* context() { return inputs_[1]; }
1104  LOperand* left() { return inputs_[1]; }
1105  LOperand* right() { return inputs_[2]; }
1106 
1107  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
1108  "string-compare-and-branch")
1109  DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
1110 
1111  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1112 
1113  Token::Value op() const { return hydrogen()->token(); }
1114 };
1115 
1116 
1117 class LHasInstanceTypeAndBranch FINAL : public LControlInstruction<1, 1> {
1118  public:
1120  inputs_[0] = value;
1121  temps_[0] = temp;
1122  }
1123 
1124  LOperand* value() { return inputs_[0]; }
1125  LOperand* temp() { return temps_[0]; }
1126 
1127  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
1128  "has-instance-type-and-branch")
1129  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
1130 
1131  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1132 };
1133 
1134 
1135 class LGetCachedArrayIndex FINAL : public LTemplateInstruction<1, 1, 0> {
1136  public:
1137  explicit LGetCachedArrayIndex(LOperand* value) {
1138  inputs_[0] = value;
1139  }
1140 
1141  LOperand* value() { return inputs_[0]; }
1142 
1143  DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
1144  DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
1145 };
1146 
1147 
1148 class LHasCachedArrayIndexAndBranch FINAL
1149  : public LControlInstruction<1, 0> {
1150  public:
1152  inputs_[0] = value;
1153  }
1154 
1155  LOperand* value() { return inputs_[0]; }
1156 
1157  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
1158  "has-cached-array-index-and-branch")
1159 
1160  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1161 };
1162 
1163 
1164 class LIsConstructCallAndBranch FINAL : public LControlInstruction<0, 1> {
1165  public:
1167  temps_[0] = temp;
1168  }
1169 
1170  LOperand* temp() { return temps_[0]; }
1171 
1172  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
1173  "is-construct-call-and-branch")
1174 };
1175 
1176 
1177 class LClassOfTestAndBranch FINAL : public LControlInstruction<1, 2> {
1178  public:
1180  inputs_[0] = value;
1181  temps_[0] = temp;
1182  temps_[1] = temp2;
1183  }
1184 
1185  LOperand* value() { return inputs_[0]; }
1186  LOperand* temp() { return temps_[0]; }
1187  LOperand* temp2() { return temps_[1]; }
1188 
1189  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
1190  "class-of-test-and-branch")
1191  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
1192 
1193  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1194 };
1195 
1196 
1197 class LCmpT FINAL : public LTemplateInstruction<1, 3, 0> {
1198  public:
1199  LCmpT(LOperand* context, LOperand* left, LOperand* right) {
1200  inputs_[0] = context;
1201  inputs_[1] = left;
1202  inputs_[2] = right;
1203  }
1204 
1205  DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
1206  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
1207 
1208  LOperand* context() { return inputs_[0]; }
1209  Token::Value op() const { return hydrogen()->token(); }
1210 };
1211 
1212 
1213 class LInstanceOf FINAL : public LTemplateInstruction<1, 3, 0> {
1214  public:
1215  LInstanceOf(LOperand* context, LOperand* left, LOperand* right) {
1216  inputs_[0] = context;
1217  inputs_[1] = left;
1218  inputs_[2] = right;
1219  }
1220 
1221  LOperand* context() { return inputs_[0]; }
1222 
1223  DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
1224 };
1225 
1226 
1227 class LInstanceOfKnownGlobal FINAL : public LTemplateInstruction<1, 2, 1> {
1228  public:
1230  inputs_[0] = context;
1231  inputs_[1] = value;
1232  temps_[0] = temp;
1233  }
1234 
1235  LOperand* context() { return inputs_[0]; }
1236  LOperand* value() { return inputs_[1]; }
1237  LOperand* temp() { return temps_[0]; }
1238 
1239  DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
1240  "instance-of-known-global")
1241  DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
1242 
1243  Handle<JSFunction> function() const { return hydrogen()->function(); }
1245  return lazy_deopt_env_;
1246  }
1248  LEnvironment* env) OVERRIDE {
1249  lazy_deopt_env_ = env;
1250  }
1251 
1252  private:
1253  LEnvironment* lazy_deopt_env_;
1254 };
1255 
1256 
1257 class LBoundsCheck FINAL : public LTemplateInstruction<0, 2, 0> {
1258  public:
1259  LBoundsCheck(LOperand* index, LOperand* length) {
1260  inputs_[0] = index;
1261  inputs_[1] = length;
1262  }
1263 
1264  LOperand* index() { return inputs_[0]; }
1265  LOperand* length() { return inputs_[1]; }
1266 
1267  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1268  DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
1269 };
1270 
1271 
1272 class LBitI FINAL : public LTemplateInstruction<1, 2, 0> {
1273  public:
1274  LBitI(LOperand* left, LOperand* right) {
1275  inputs_[0] = left;
1276  inputs_[1] = right;
1277  }
1278 
1279  LOperand* left() { return inputs_[0]; }
1280  LOperand* right() { return inputs_[1]; }
1281 
1282  DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1283  DECLARE_HYDROGEN_ACCESSOR(Bitwise)
1284 
1285  Token::Value op() const { return hydrogen()->op(); }
1286 };
1287 
1288 
1289 class LShiftI FINAL : public LTemplateInstruction<1, 2, 0> {
1290  public:
1291  LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1292  : op_(op), can_deopt_(can_deopt) {
1293  inputs_[0] = left;
1294  inputs_[1] = right;
1295  }
1296 
1297  LOperand* left() { return inputs_[0]; }
1298  LOperand* right() { return inputs_[1]; }
1299 
1300  DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1301 
1302  Token::Value op() const { return op_; }
1303  bool can_deopt() const { return can_deopt_; }
1304 
1305  private:
1306  Token::Value op_;
1307  bool can_deopt_;
1308 };
1309 
1310 
1311 class LSubI FINAL : public LTemplateInstruction<1, 2, 0> {
1312  public:
1313  LSubI(LOperand* left, LOperand* right) {
1314  inputs_[0] = left;
1315  inputs_[1] = right;
1316  }
1317 
1318  LOperand* left() { return inputs_[0]; }
1319  LOperand* right() { return inputs_[1]; }
1320 
1321  DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1323 };
1324 
1325 
1326 class LConstantI FINAL : public LTemplateInstruction<1, 0, 0> {
1327  public:
1328  DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1329  DECLARE_HYDROGEN_ACCESSOR(Constant)
1330 
1331  int32_t value() const { return hydrogen()->Integer32Value(); }
1332 };
1333 
1334 
1335 class LConstantS FINAL : public LTemplateInstruction<1, 0, 0> {
1336  public:
1337  DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
1338  DECLARE_HYDROGEN_ACCESSOR(Constant)
1339 
1340  Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
1341 };
1342 
1343 
1344 class LConstantD FINAL : public LTemplateInstruction<1, 0, 1> {
1345  public:
1346  explicit LConstantD(LOperand* temp) {
1347  temps_[0] = temp;
1348  }
1349 
1350  LOperand* temp() { return temps_[0]; }
1351 
1352  DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1353  DECLARE_HYDROGEN_ACCESSOR(Constant)
1354 
1355  double value() const { return hydrogen()->DoubleValue(); }
1356 };
1357 
1358 
1359 class LConstantE FINAL : public LTemplateInstruction<1, 0, 0> {
1360  public:
1361  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
1362  DECLARE_HYDROGEN_ACCESSOR(Constant)
1363 
1364  ExternalReference value() const {
1365  return hydrogen()->ExternalReferenceValue();
1366  }
1367 };
1368 
1369 
1370 class LConstantT FINAL : public LTemplateInstruction<1, 0, 0> {
1371  public:
1372  DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1373  DECLARE_HYDROGEN_ACCESSOR(Constant)
1374 
1375  Handle<Object> value(Isolate* isolate) const {
1376  return hydrogen()->handle(isolate);
1377  }
1378 };
1379 
1380 
1381 class LBranch FINAL : public LControlInstruction<1, 1> {
1382  public:
1383  LBranch(LOperand* value, LOperand* temp) {
1384  inputs_[0] = value;
1385  temps_[0] = temp;
1386  }
1387 
1388  LOperand* value() { return inputs_[0]; }
1389  LOperand* temp() { return temps_[0]; }
1390 
1391  DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1393 
1394  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1395 };
1396 
1397 
1398 class LCmpMapAndBranch FINAL : public LControlInstruction<1, 0> {
1399  public:
1400  explicit LCmpMapAndBranch(LOperand* value) {
1401  inputs_[0] = value;
1402  }
1403 
1404  LOperand* value() { return inputs_[0]; }
1405 
1406  DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1407  DECLARE_HYDROGEN_ACCESSOR(CompareMap)
1408 
1409  Handle<Map> map() const { return hydrogen()->map().handle(); }
1410 };
1411 
1412 
1413 class LMapEnumLength FINAL : public LTemplateInstruction<1, 1, 0> {
1414  public:
1415  explicit LMapEnumLength(LOperand* value) {
1416  inputs_[0] = value;
1417  }
1418 
1419  LOperand* value() { return inputs_[0]; }
1420 
1421  DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
1422 };
1423 
1424 
1425 class LDateField FINAL : public LTemplateInstruction<1, 1, 1> {
1426  public:
1427  LDateField(LOperand* date, LOperand* temp, Smi* index)
1428  : index_(index) {
1429  inputs_[0] = date;
1430  temps_[0] = temp;
1431  }
1432 
1433  LOperand* date() { return inputs_[0]; }
1434  LOperand* temp() { return temps_[0]; }
1435 
1436  DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
1437  DECLARE_HYDROGEN_ACCESSOR(DateField)
1438 
1439  Smi* index() const { return index_; }
1440 
1441  private:
1442  Smi* index_;
1443 };
1444 
1445 
1446 class LSeqStringGetChar FINAL : public LTemplateInstruction<1, 2, 0> {
1447  public:
1449  inputs_[0] = string;
1450  inputs_[1] = index;
1451  }
1452 
1453  LOperand* string() const { return inputs_[0]; }
1454  LOperand* index() const { return inputs_[1]; }
1455 
1456  DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar, "seq-string-get-char")
1457  DECLARE_HYDROGEN_ACCESSOR(SeqStringGetChar)
1458 };
1459 
1460 
1461 class LSeqStringSetChar FINAL : public LTemplateInstruction<1, 4, 0> {
1462  public:
1464  LOperand* string,
1465  LOperand* index,
1466  LOperand* value) {
1467  inputs_[0] = context;
1468  inputs_[1] = string;
1469  inputs_[2] = index;
1470  inputs_[3] = value;
1471  }
1472 
1473  LOperand* string() { return inputs_[1]; }
1474  LOperand* index() { return inputs_[2]; }
1475  LOperand* value() { return inputs_[3]; }
1476 
1477  DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
1478  DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
1479 };
1480 
1481 
1482 class LAddI FINAL : public LTemplateInstruction<1, 2, 0> {
1483  public:
1484  LAddI(LOperand* left, LOperand* right) {
1485  inputs_[0] = left;
1486  inputs_[1] = right;
1487  }
1488 
1489  LOperand* left() { return inputs_[0]; }
1490  LOperand* right() { return inputs_[1]; }
1491 
1492  static bool UseLea(HAdd* add) {
1493  return !add->CheckFlag(HValue::kCanOverflow) &&
1494  add->BetterLeftOperand()->UseCount() > 1;
1495  }
1496 
1497  DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1499 };
1500 
1501 
1502 class LMathMinMax FINAL : public LTemplateInstruction<1, 2, 0> {
1503  public:
1504  LMathMinMax(LOperand* left, LOperand* right) {
1505  inputs_[0] = left;
1506  inputs_[1] = right;
1507  }
1508 
1509  LOperand* left() { return inputs_[0]; }
1510  LOperand* right() { return inputs_[1]; }
1511 
1512  DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
1513  DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
1514 };
1515 
1516 
1517 class LPower FINAL : public LTemplateInstruction<1, 2, 0> {
1518  public:
1519  LPower(LOperand* left, LOperand* right) {
1520  inputs_[0] = left;
1521  inputs_[1] = right;
1522  }
1523 
1524  LOperand* left() { return inputs_[0]; }
1525  LOperand* right() { return inputs_[1]; }
1526 
1527  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1529 };
1530 
1531 
1532 class LArithmeticD FINAL : public LTemplateInstruction<1, 2, 0> {
1533  public:
1535  : op_(op) {
1536  inputs_[0] = left;
1537  inputs_[1] = right;
1538  }
1539 
1540  LOperand* left() { return inputs_[0]; }
1541  LOperand* right() { return inputs_[1]; }
1542 
1543  Token::Value op() const { return op_; }
1544 
1545  virtual Opcode opcode() const OVERRIDE {
1546  return LInstruction::kArithmeticD;
1547  }
1548  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
1549  virtual const char* Mnemonic() const OVERRIDE;
1550 
1551  private:
1552  Token::Value op_;
1553 };
1554 
1555 
1556 class LArithmeticT FINAL : public LTemplateInstruction<1, 3, 0> {
1557  public:
1559  LOperand* context,
1560  LOperand* left,
1561  LOperand* right)
1562  : op_(op) {
1563  inputs_[0] = context;
1564  inputs_[1] = left;
1565  inputs_[2] = right;
1566  }
1567 
1568  LOperand* context() { return inputs_[0]; }
1569  LOperand* left() { return inputs_[1]; }
1570  LOperand* right() { return inputs_[2]; }
1571 
1572  virtual Opcode opcode() const OVERRIDE {
1573  return LInstruction::kArithmeticT;
1574  }
1575  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
1576  virtual const char* Mnemonic() const OVERRIDE;
1577 
1578  Token::Value op() const { return op_; }
1579 
1580  private:
1581  Token::Value op_;
1582 };
1583 
1584 
1585 class LReturn FINAL : public LTemplateInstruction<0, 3, 0> {
1586  public:
1587  explicit LReturn(LOperand* value,
1588  LOperand* context,
1589  LOperand* parameter_count) {
1590  inputs_[0] = value;
1591  inputs_[1] = context;
1592  inputs_[2] = parameter_count;
1593  }
1594 
1596  return parameter_count()->IsConstantOperand();
1597  }
1598  LConstantOperand* constant_parameter_count() {
1599  DCHECK(has_constant_parameter_count());
1600  return LConstantOperand::cast(parameter_count());
1601  }
1602  LOperand* parameter_count() { return inputs_[2]; }
1603 
1604  DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1606 };
1607 
1608 
1609 class LLoadNamedField FINAL : public LTemplateInstruction<1, 1, 0> {
1610  public:
1611  explicit LLoadNamedField(LOperand* object) {
1612  inputs_[0] = object;
1613  }
1614 
1615  LOperand* object() { return inputs_[0]; }
1616 
1617  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1618  DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1619 };
1620 
1621 
1622 class LLoadNamedGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
1623  public:
1624  LLoadNamedGeneric(LOperand* context, LOperand* object, LOperand* vector) {
1625  inputs_[0] = context;
1626  inputs_[1] = object;
1627  temps_[0] = vector;
1628  }
1629 
1630  LOperand* context() { return inputs_[0]; }
1631  LOperand* object() { return inputs_[1]; }
1632  LOperand* temp_vector() { return temps_[0]; }
1633 
1634  DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1635  DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1636 
1637  Handle<Object> name() const { return hydrogen()->name(); }
1638 };
1639 
1640 
1641 class LLoadFunctionPrototype FINAL : public LTemplateInstruction<1, 1, 1> {
1642  public:
1644  inputs_[0] = function;
1645  temps_[0] = temp;
1646  }
1647 
1648  LOperand* function() { return inputs_[0]; }
1649  LOperand* temp() { return temps_[0]; }
1650 
1651  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1652  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1653 };
1654 
1655 
1656 class LLoadRoot FINAL : public LTemplateInstruction<1, 0, 0> {
1657  public:
1658  DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
1659  DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
1660 
1661  Heap::RootListIndex index() const { return hydrogen()->index(); }
1662 };
1663 
1664 
1665 class LLoadKeyed FINAL : public LTemplateInstruction<1, 2, 0> {
1666  public:
1667  LLoadKeyed(LOperand* elements, LOperand* key) {
1668  inputs_[0] = elements;
1669  inputs_[1] = key;
1670  }
1671  LOperand* elements() { return inputs_[0]; }
1672  LOperand* key() { return inputs_[1]; }
1674  return hydrogen()->elements_kind();
1675  }
1676  bool is_external() const {
1677  return hydrogen()->is_external();
1678  }
1679  bool is_fixed_typed_array() const {
1680  return hydrogen()->is_fixed_typed_array();
1681  }
1682  bool is_typed_elements() const {
1683  return is_external() || is_fixed_typed_array();
1684  }
1685 
1686  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
1687  DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
1688 
1689  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1690  uint32_t base_offset() const { return hydrogen()->base_offset(); }
1691  bool key_is_smi() {
1692  return hydrogen()->key()->representation().IsTagged();
1693  }
1694 };
1695 
1696 
1697 inline static bool ExternalArrayOpRequiresTemp(
1698  Representation key_representation,
1699  ElementsKind elements_kind) {
1700  // Operations that require the key to be divided by two to be converted into
1701  // an index cannot fold the scale operation into a load and need an extra
1702  // temp register to do the work.
1703  return key_representation.IsSmi() &&
1704  (elements_kind == EXTERNAL_INT8_ELEMENTS ||
1705  elements_kind == EXTERNAL_UINT8_ELEMENTS ||
1706  elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS ||
1707  elements_kind == UINT8_ELEMENTS ||
1708  elements_kind == INT8_ELEMENTS ||
1709  elements_kind == UINT8_CLAMPED_ELEMENTS);
1710 }
1711 
1712 
1713 class LLoadKeyedGeneric FINAL : public LTemplateInstruction<1, 3, 1> {
1714  public:
1716  LOperand* vector) {
1717  inputs_[0] = context;
1718  inputs_[1] = obj;
1719  inputs_[2] = key;
1720  temps_[0] = vector;
1721  }
1722 
1723  LOperand* context() { return inputs_[0]; }
1724  LOperand* object() { return inputs_[1]; }
1725  LOperand* key() { return inputs_[2]; }
1726  LOperand* temp_vector() { return temps_[0]; }
1727 
1728  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1729  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedGeneric)
1730 };
1731 
1732 
1733 class LLoadGlobalCell FINAL : public LTemplateInstruction<1, 0, 0> {
1734  public:
1735  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
1736  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
1737 };
1738 
1739 
1740 class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
1741  public:
1742  LLoadGlobalGeneric(LOperand* context, LOperand* global_object,
1743  LOperand* vector) {
1744  inputs_[0] = context;
1745  inputs_[1] = global_object;
1746  temps_[0] = vector;
1747  }
1748 
1749  LOperand* context() { return inputs_[0]; }
1750  LOperand* global_object() { return inputs_[1]; }
1751  LOperand* temp_vector() { return temps_[0]; }
1752 
1753  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
1754  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
1755 
1756  Handle<Object> name() const { return hydrogen()->name(); }
1757  bool for_typeof() const { return hydrogen()->for_typeof(); }
1758 };
1759 
1760 
1761 class LStoreGlobalCell FINAL : public LTemplateInstruction<0, 1, 0> {
1762  public:
1763  explicit LStoreGlobalCell(LOperand* value) {
1764  inputs_[0] = value;
1765  }
1766 
1767  LOperand* value() { return inputs_[0]; }
1768 
1769  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
1770  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
1771 };
1772 
1773 
1774 class LLoadContextSlot FINAL : public LTemplateInstruction<1, 1, 0> {
1775  public:
1776  explicit LLoadContextSlot(LOperand* context) {
1777  inputs_[0] = context;
1778  }
1779 
1780  LOperand* context() { return inputs_[0]; }
1781 
1782  DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1783  DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1784 
1785  int slot_index() { return hydrogen()->slot_index(); }
1786 
1787  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1788 };
1789 
1790 
1791 class LStoreContextSlot FINAL : public LTemplateInstruction<0, 2, 1> {
1792  public:
1793  LStoreContextSlot(LOperand* context, LOperand* value, LOperand* temp) {
1794  inputs_[0] = context;
1795  inputs_[1] = value;
1796  temps_[0] = temp;
1797  }
1798 
1799  LOperand* context() { return inputs_[0]; }
1800  LOperand* value() { return inputs_[1]; }
1801  LOperand* temp() { return temps_[0]; }
1802 
1803  DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
1804  DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
1805 
1806  int slot_index() { return hydrogen()->slot_index(); }
1807 
1808  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1809 };
1810 
1811 
1812 class LPushArgument FINAL : public LTemplateInstruction<0, 1, 0> {
1813  public:
1814  explicit LPushArgument(LOperand* value) {
1815  inputs_[0] = value;
1816  }
1817 
1818  LOperand* value() { return inputs_[0]; }
1819 
1820  DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1821 };
1822 
1823 
1824 class LDrop FINAL : public LTemplateInstruction<0, 0, 0> {
1825  public:
1826  explicit LDrop(int count) : count_(count) { }
1827 
1828  int count() const { return count_; }
1829 
1830  DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
1831 
1832  private:
1833  int count_;
1834 };
1835 
1836 
1837 class LStoreCodeEntry FINAL: public LTemplateInstruction<0, 2, 0> {
1838  public:
1839  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
1840  inputs_[0] = function;
1841  inputs_[1] = code_object;
1842  }
1843 
1844  LOperand* function() { return inputs_[0]; }
1845  LOperand* code_object() { return inputs_[1]; }
1846 
1847  virtual void PrintDataTo(StringStream* stream);
1848 
1849  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
1850  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
1851 };
1852 
1853 
1854 class LInnerAllocatedObject FINAL: public LTemplateInstruction<1, 2, 0> {
1855  public:
1856  LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
1857  inputs_[0] = base_object;
1858  inputs_[1] = offset;
1859  }
1860 
1861  LOperand* base_object() const { return inputs_[0]; }
1862  LOperand* offset() const { return inputs_[1]; }
1863 
1864  virtual void PrintDataTo(StringStream* stream);
1865 
1866  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
1867 };
1868 
1869 
1870 class LThisFunction FINAL : public LTemplateInstruction<1, 0, 0> {
1871  public:
1872  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
1873  DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
1874 };
1875 
1876 
1877 class LContext FINAL : public LTemplateInstruction<1, 0, 0> {
1878  public:
1881 };
1882 
1883 
1884 class LDeclareGlobals FINAL : public LTemplateInstruction<0, 1, 0> {
1885  public:
1886  explicit LDeclareGlobals(LOperand* context) {
1887  inputs_[0] = context;
1888  }
1889 
1890  LOperand* context() { return inputs_[0]; }
1891 
1892  DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
1894 };
1895 
1896 
1897 class LCallJSFunction FINAL : public LTemplateInstruction<1, 1, 0> {
1898  public:
1899  explicit LCallJSFunction(LOperand* function) {
1900  inputs_[0] = function;
1901  }
1902 
1903  LOperand* function() { return inputs_[0]; }
1904 
1905  DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
1906  DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
1907 
1908  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1909 
1910  int arity() const { return hydrogen()->argument_count() - 1; }
1911 };
1912 
1913 
1914 class LCallWithDescriptor FINAL : public LTemplateResultInstruction<1> {
1915  public:
1917  const ZoneList<LOperand*>& operands, Zone* zone)
1918  : inputs_(descriptor.GetRegisterParameterCount() + 1, zone) {
1919  DCHECK(descriptor.GetRegisterParameterCount() + 1 == operands.length());
1920  inputs_.AddAll(operands, zone);
1921  }
1922 
1923  LOperand* target() const { return inputs_[0]; }
1924 
1925  DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
1926 
1927  private:
1928  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
1929 
1930  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1931 
1932  int arity() const { return hydrogen()->argument_count() - 1; }
1933 
1934  ZoneList<LOperand*> inputs_;
1935 
1936  // Iterator support.
1937  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
1938  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
1939 
1940  virtual int TempCount() FINAL OVERRIDE { return 0; }
1941  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
1942 };
1943 
1944 
1945 class LInvokeFunction FINAL : public LTemplateInstruction<1, 2, 0> {
1946  public:
1947  LInvokeFunction(LOperand* context, LOperand* function) {
1948  inputs_[0] = context;
1949  inputs_[1] = function;
1950  }
1951 
1952  LOperand* context() { return inputs_[0]; }
1953  LOperand* function() { return inputs_[1]; }
1954 
1955  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
1956  DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
1957 
1958  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1959 
1960  int arity() const { return hydrogen()->argument_count() - 1; }
1961 };
1962 
1963 
1964 class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> {
1965  public:
1966  explicit LCallFunction(LOperand* context, LOperand* function) {
1967  inputs_[0] = context;
1968  inputs_[1] = function;
1969  }
1970 
1971  LOperand* context() { return inputs_[0]; }
1972  LOperand* function() { return inputs_[1]; }
1973 
1974  DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1975  DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1976 
1977  int arity() const { return hydrogen()->argument_count() - 1; }
1978 };
1979 
1980 
1981 class LCallNew FINAL : public LTemplateInstruction<1, 2, 0> {
1982  public:
1983  LCallNew(LOperand* context, LOperand* constructor) {
1984  inputs_[0] = context;
1985  inputs_[1] = constructor;
1986  }
1987 
1988  LOperand* context() { return inputs_[0]; }
1989  LOperand* constructor() { return inputs_[1]; }
1990 
1991  DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1992  DECLARE_HYDROGEN_ACCESSOR(CallNew)
1993 
1994  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1995 
1996  int arity() const { return hydrogen()->argument_count() - 1; }
1997 };
1998 
1999 
2000 class LCallNewArray FINAL : public LTemplateInstruction<1, 2, 0> {
2001  public:
2002  LCallNewArray(LOperand* context, LOperand* constructor) {
2003  inputs_[0] = context;
2004  inputs_[1] = constructor;
2005  }
2006 
2007  LOperand* context() { return inputs_[0]; }
2008  LOperand* constructor() { return inputs_[1]; }
2009 
2010  DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
2011  DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
2012 
2013  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2014 
2015  int arity() const { return hydrogen()->argument_count() - 1; }
2016 };
2017 
2018 
2019 class LCallRuntime FINAL : public LTemplateInstruction<1, 1, 0> {
2020  public:
2021  explicit LCallRuntime(LOperand* context) {
2022  inputs_[0] = context;
2023  }
2024 
2025  LOperand* context() { return inputs_[0]; }
2026 
2027  DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
2028  DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
2029 
2030  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
2031  return save_doubles() == kDontSaveFPRegs;
2032  }
2033 
2034  const Runtime::Function* function() const { return hydrogen()->function(); }
2035  int arity() const { return hydrogen()->argument_count(); }
2036  SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
2037 };
2038 
2039 
2040 class LInteger32ToDouble FINAL : public LTemplateInstruction<1, 1, 0> {
2041  public:
2042  explicit LInteger32ToDouble(LOperand* value) {
2043  inputs_[0] = value;
2044  }
2045 
2046  LOperand* value() { return inputs_[0]; }
2047 
2048  DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
2049 };
2050 
2051 
2052 class LUint32ToDouble FINAL : public LTemplateInstruction<1, 1, 0> {
2053  public:
2054  explicit LUint32ToDouble(LOperand* value) {
2055  inputs_[0] = value;
2056  }
2057 
2058  LOperand* value() { return inputs_[0]; }
2059 
2060  DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
2061 };
2062 
2063 
2064 class LNumberTagI FINAL : public LTemplateInstruction<1, 1, 1> {
2065  public:
2066  LNumberTagI(LOperand* value, LOperand* temp) {
2067  inputs_[0] = value;
2068  temps_[0] = temp;
2069  }
2070 
2071  LOperand* value() { return inputs_[0]; }
2072  LOperand* temp() { return temps_[0]; }
2073 
2074  DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
2075 };
2076 
2077 
2078 class LNumberTagU FINAL : public LTemplateInstruction<1, 1, 1> {
2079  public:
2080  LNumberTagU(LOperand* value, LOperand* temp) {
2081  inputs_[0] = value;
2082  temps_[0] = temp;
2083  }
2084 
2085  LOperand* value() { return inputs_[0]; }
2086  LOperand* temp() { return temps_[0]; }
2087 
2088  DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
2089 };
2090 
2091 
2092 class LNumberTagD FINAL : public LTemplateInstruction<1, 1, 1> {
2093  public:
2094  LNumberTagD(LOperand* value, LOperand* temp) {
2095  inputs_[0] = value;
2096  temps_[0] = temp;
2097  }
2098 
2099  LOperand* value() { return inputs_[0]; }
2100  LOperand* temp() { return temps_[0]; }
2101 
2102  DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
2104 };
2105 
2106 
2107 // Sometimes truncating conversion from a tagged value to an int32.
2108 class LDoubleToI FINAL : public LTemplateInstruction<1, 1, 1> {
2109  public:
2110  LDoubleToI(LOperand* value, LOperand* temp) {
2111  inputs_[0] = value;
2112  temps_[0] = temp;
2113  }
2114 
2115  LOperand* value() { return inputs_[0]; }
2116  LOperand* temp() { return temps_[0]; }
2117 
2118  DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
2119  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2120 
2121  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2122 };
2123 
2124 
2125 class LDoubleToSmi FINAL : public LTemplateInstruction<1, 1, 0> {
2126  public:
2127  explicit LDoubleToSmi(LOperand* value) {
2128  inputs_[0] = value;
2129  }
2130 
2131  LOperand* value() { return inputs_[0]; }
2132 
2133  DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
2134  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2135 };
2136 
2137 
2138 // Truncating conversion from a tagged value to an int32.
2139 class LTaggedToI FINAL : public LTemplateInstruction<1, 1, 1> {
2140  public:
2141  LTaggedToI(LOperand* value, LOperand* temp) {
2142  inputs_[0] = value;
2143  temps_[0] = temp;
2144  }
2145 
2146  LOperand* value() { return inputs_[0]; }
2147  LOperand* temp() { return temps_[0]; }
2148 
2149  DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
2151 
2152  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2153 };
2154 
2155 
2156 class LSmiTag FINAL : public LTemplateInstruction<1, 1, 0> {
2157  public:
2158  explicit LSmiTag(LOperand* value) {
2159  inputs_[0] = value;
2160  }
2161 
2162  LOperand* value() { return inputs_[0]; }
2163 
2164  DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
2166 };
2167 
2168 
2169 class LNumberUntagD FINAL : public LTemplateInstruction<1, 1, 1> {
2170  public:
2171  explicit LNumberUntagD(LOperand* value, LOperand* temp) {
2172  inputs_[0] = value;
2173  temps_[0] = temp;
2174  }
2175 
2176  LOperand* value() { return inputs_[0]; }
2177  LOperand* temp() { return temps_[0]; }
2178 
2179  DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
2181 };
2182 
2183 
2184 class LSmiUntag FINAL : public LTemplateInstruction<1, 1, 0> {
2185  public:
2186  LSmiUntag(LOperand* value, bool needs_check)
2187  : needs_check_(needs_check) {
2188  inputs_[0] = value;
2189  }
2190 
2191  LOperand* value() { return inputs_[0]; }
2192 
2193  DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
2194 
2195  bool needs_check() const { return needs_check_; }
2196 
2197  private:
2198  bool needs_check_;
2199 };
2200 
2201 
2202 class LStoreNamedField FINAL : public LTemplateInstruction<0, 2, 2> {
2203  public:
2205  LOperand* val,
2206  LOperand* temp,
2207  LOperand* temp_map) {
2208  inputs_[0] = obj;
2209  inputs_[1] = val;
2210  temps_[0] = temp;
2211  temps_[1] = temp_map;
2212  }
2213 
2214  LOperand* object() { return inputs_[0]; }
2215  LOperand* value() { return inputs_[1]; }
2216  LOperand* temp() { return temps_[0]; }
2217  LOperand* temp_map() { return temps_[1]; }
2218 
2219  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
2220  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
2221 
2222  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2223 };
2224 
2225 
2226 class LStoreNamedGeneric FINAL : public LTemplateInstruction<0, 3, 0> {
2227  public:
2228  LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value) {
2229  inputs_[0] = context;
2230  inputs_[1] = object;
2231  inputs_[2] = value;
2232  }
2233 
2234  LOperand* context() { return inputs_[0]; }
2235  LOperand* object() { return inputs_[1]; }
2236  LOperand* value() { return inputs_[2]; }
2237 
2238  DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
2239  DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
2240 
2241  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2242  Handle<Object> name() const { return hydrogen()->name(); }
2243  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
2244 };
2245 
2246 
2247 class LStoreKeyed FINAL : public LTemplateInstruction<0, 3, 0> {
2248  public:
2250  inputs_[0] = obj;
2251  inputs_[1] = key;
2252  inputs_[2] = val;
2253  }
2254 
2255  bool is_external() const { return hydrogen()->is_external(); }
2256  bool is_fixed_typed_array() const {
2257  return hydrogen()->is_fixed_typed_array();
2258  }
2259  bool is_typed_elements() const {
2260  return is_external() || is_fixed_typed_array();
2261  }
2262  LOperand* elements() { return inputs_[0]; }
2263  LOperand* key() { return inputs_[1]; }
2264  LOperand* value() { return inputs_[2]; }
2266  return hydrogen()->elements_kind();
2267  }
2268 
2269  DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
2270  DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
2271 
2272  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2273  uint32_t base_offset() const { return hydrogen()->base_offset(); }
2274  bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
2275 };
2276 
2277 
2278 class LStoreKeyedGeneric FINAL : public LTemplateInstruction<0, 4, 0> {
2279  public:
2281  LOperand* object,
2282  LOperand* key,
2283  LOperand* value) {
2284  inputs_[0] = context;
2285  inputs_[1] = object;
2286  inputs_[2] = key;
2287  inputs_[3] = value;
2288  }
2289 
2290  LOperand* context() { return inputs_[0]; }
2291  LOperand* object() { return inputs_[1]; }
2292  LOperand* key() { return inputs_[2]; }
2293  LOperand* value() { return inputs_[3]; }
2294 
2295  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
2296  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
2297 
2298  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2299 
2300  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
2301 };
2302 
2303 
2304 class LTransitionElementsKind FINAL : public LTemplateInstruction<0, 2, 2> {
2305  public:
2307  LOperand* context,
2308  LOperand* new_map_temp,
2309  LOperand* temp) {
2310  inputs_[0] = object;
2311  inputs_[1] = context;
2312  temps_[0] = new_map_temp;
2313  temps_[1] = temp;
2314  }
2315 
2316  LOperand* context() { return inputs_[1]; }
2317  LOperand* object() { return inputs_[0]; }
2318  LOperand* new_map_temp() { return temps_[0]; }
2319  LOperand* temp() { return temps_[1]; }
2320 
2321  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
2322  "transition-elements-kind")
2323  DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
2324 
2325  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2326 
2327  Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
2329  return hydrogen()->transitioned_map().handle();
2330  }
2331  ElementsKind from_kind() { return hydrogen()->from_kind(); }
2332  ElementsKind to_kind() { return hydrogen()->to_kind(); }
2333 };
2334 
2335 
2336 class LTrapAllocationMemento FINAL : public LTemplateInstruction<0, 1, 1> {
2337  public:
2339  LOperand* temp) {
2340  inputs_[0] = object;
2341  temps_[0] = temp;
2342  }
2343 
2344  LOperand* object() { return inputs_[0]; }
2345  LOperand* temp() { return temps_[0]; }
2346 
2347  DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
2348  "trap-allocation-memento")
2349 };
2350 
2351 
2352 class LStringAdd FINAL : public LTemplateInstruction<1, 3, 0> {
2353  public:
2354  LStringAdd(LOperand* context, LOperand* left, LOperand* right) {
2355  inputs_[0] = context;
2356  inputs_[1] = left;
2357  inputs_[2] = right;
2358  }
2359 
2360  LOperand* context() { return inputs_[0]; }
2361  LOperand* left() { return inputs_[1]; }
2362  LOperand* right() { return inputs_[2]; }
2363 
2364  DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
2365  DECLARE_HYDROGEN_ACCESSOR(StringAdd)
2366 };
2367 
2368 
2369 class LStringCharCodeAt FINAL : public LTemplateInstruction<1, 3, 0> {
2370  public:
2371  LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) {
2372  inputs_[0] = context;
2373  inputs_[1] = string;
2374  inputs_[2] = index;
2375  }
2376 
2377  LOperand* context() { return inputs_[0]; }
2378  LOperand* string() { return inputs_[1]; }
2379  LOperand* index() { return inputs_[2]; }
2380 
2381  DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
2382  DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
2383 };
2384 
2385 
2386 class LStringCharFromCode FINAL : public LTemplateInstruction<1, 2, 0> {
2387  public:
2388  LStringCharFromCode(LOperand* context, LOperand* char_code) {
2389  inputs_[0] = context;
2390  inputs_[1] = char_code;
2391  }
2392 
2393  LOperand* context() { return inputs_[0]; }
2394  LOperand* char_code() { return inputs_[1]; }
2395 
2396  DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
2397  DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
2398 };
2399 
2400 
2401 class LCheckValue FINAL : public LTemplateInstruction<0, 1, 0> {
2402  public:
2403  explicit LCheckValue(LOperand* value) {
2404  inputs_[0] = value;
2405  }
2406 
2407  LOperand* value() { return inputs_[0]; }
2408 
2409  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
2410  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
2411 };
2412 
2413 
2414 class LCheckInstanceType FINAL : public LTemplateInstruction<0, 1, 1> {
2415  public:
2417  inputs_[0] = value;
2418  temps_[0] = temp;
2419  }
2420 
2421  LOperand* value() { return inputs_[0]; }
2422  LOperand* temp() { return temps_[0]; }
2423 
2424  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
2425  DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
2426 };
2427 
2428 
2429 class LCheckMaps FINAL : public LTemplateInstruction<0, 1, 0> {
2430  public:
2431  explicit LCheckMaps(LOperand* value = NULL) {
2432  inputs_[0] = value;
2433  }
2434 
2435  LOperand* value() { return inputs_[0]; }
2436 
2437  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
2438  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
2439 };
2440 
2441 
2442 class LCheckSmi FINAL : public LTemplateInstruction<1, 1, 0> {
2443  public:
2444  explicit LCheckSmi(LOperand* value) {
2445  inputs_[0] = value;
2446  }
2447 
2448  LOperand* value() { return inputs_[0]; }
2449 
2450  DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
2451 };
2452 
2453 
2454 class LClampDToUint8 FINAL : public LTemplateInstruction<1, 1, 0> {
2455  public:
2456  explicit LClampDToUint8(LOperand* value) {
2457  inputs_[0] = value;
2458  }
2459 
2460  LOperand* unclamped() { return inputs_[0]; }
2461 
2462  DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
2463 };
2464 
2465 
2466 class LClampIToUint8 FINAL : public LTemplateInstruction<1, 1, 0> {
2467  public:
2468  explicit LClampIToUint8(LOperand* value) {
2469  inputs_[0] = value;
2470  }
2471 
2472  LOperand* unclamped() { return inputs_[0]; }
2473 
2474  DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
2475 };
2476 
2477 
2478 class LClampTToUint8 FINAL : public LTemplateInstruction<1, 1, 1> {
2479  public:
2480  LClampTToUint8(LOperand* value, LOperand* temp_xmm) {
2481  inputs_[0] = value;
2482  temps_[0] = temp_xmm;
2483  }
2484 
2485  LOperand* unclamped() { return inputs_[0]; }
2486  LOperand* temp_xmm() { return temps_[0]; }
2487 
2488  DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
2489 };
2490 
2491 
2492 class LCheckNonSmi FINAL : public LTemplateInstruction<0, 1, 0> {
2493  public:
2494  explicit LCheckNonSmi(LOperand* value) {
2495  inputs_[0] = value;
2496  }
2497 
2498  LOperand* value() { return inputs_[0]; }
2499 
2500  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
2501  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
2502 };
2503 
2504 
2505 class LDoubleBits FINAL : public LTemplateInstruction<1, 1, 0> {
2506  public:
2507  explicit LDoubleBits(LOperand* value) {
2508  inputs_[0] = value;
2509  }
2510 
2511  LOperand* value() { return inputs_[0]; }
2512 
2513  DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
2514  DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
2515 };
2516 
2517 
2518 class LConstructDouble FINAL : public LTemplateInstruction<1, 2, 0> {
2519  public:
2521  inputs_[0] = hi;
2522  inputs_[1] = lo;
2523  }
2524 
2525  LOperand* hi() { return inputs_[0]; }
2526  LOperand* lo() { return inputs_[1]; }
2527 
2528  DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
2529 };
2530 
2531 
2532 class LAllocate FINAL : public LTemplateInstruction<1, 2, 1> {
2533  public:
2534  LAllocate(LOperand* context, LOperand* size, LOperand* temp) {
2535  inputs_[0] = context;
2536  inputs_[1] = size;
2537  temps_[0] = temp;
2538  }
2539 
2540  LOperand* context() { return inputs_[0]; }
2541  LOperand* size() { return inputs_[1]; }
2542  LOperand* temp() { return temps_[0]; }
2543 
2544  DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
2545  DECLARE_HYDROGEN_ACCESSOR(Allocate)
2546 };
2547 
2548 
2549 class LRegExpLiteral FINAL : public LTemplateInstruction<1, 1, 0> {
2550  public:
2551  explicit LRegExpLiteral(LOperand* context) {
2552  inputs_[0] = context;
2553  }
2554 
2555  LOperand* context() { return inputs_[0]; }
2556 
2557  DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
2558  DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
2559 };
2560 
2561 
2562 class LFunctionLiteral FINAL : public LTemplateInstruction<1, 1, 0> {
2563  public:
2564  explicit LFunctionLiteral(LOperand* context) {
2565  inputs_[0] = context;
2566  }
2567 
2568  LOperand* context() { return inputs_[0]; }
2569 
2570  DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
2571  DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
2572 };
2573 
2574 
2575 class LToFastProperties FINAL : public LTemplateInstruction<1, 1, 0> {
2576  public:
2577  explicit LToFastProperties(LOperand* value) {
2578  inputs_[0] = value;
2579  }
2580 
2581  LOperand* value() { return inputs_[0]; }
2582 
2583  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
2584  DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
2585 };
2586 
2587 
2588 class LTypeof FINAL : public LTemplateInstruction<1, 2, 0> {
2589  public:
2590  LTypeof(LOperand* context, LOperand* value) {
2591  inputs_[0] = context;
2592  inputs_[1] = value;
2593  }
2594 
2595  LOperand* context() { return inputs_[0]; }
2596  LOperand* value() { return inputs_[1]; }
2597 
2598  DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
2599 };
2600 
2601 
2602 class LTypeofIsAndBranch FINAL : public LControlInstruction<1, 0> {
2603  public:
2604  explicit LTypeofIsAndBranch(LOperand* value) {
2605  inputs_[0] = value;
2606  }
2607 
2608  LOperand* value() { return inputs_[0]; }
2609 
2610  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
2611  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
2612 
2613  Handle<String> type_literal() { return hydrogen()->type_literal(); }
2614 
2615  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2616 };
2617 
2618 
2619 class LOsrEntry FINAL : public LTemplateInstruction<0, 0, 0> {
2620  public:
2621  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
2622  return false;
2623  }
2624  DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
2625 };
2626 
2627 
2628 class LStackCheck FINAL : public LTemplateInstruction<0, 1, 0> {
2629  public:
2630  explicit LStackCheck(LOperand* context) {
2631  inputs_[0] = context;
2632  }
2633 
2634  LOperand* context() { return inputs_[0]; }
2635 
2636  DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
2637  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
2638 
2639  Label* done_label() { return &done_label_; }
2640 
2641  private:
2642  Label done_label_;
2643 };
2644 
2645 
2646 class LForInPrepareMap FINAL : public LTemplateInstruction<1, 2, 0> {
2647  public:
2648  LForInPrepareMap(LOperand* context, LOperand* object) {
2649  inputs_[0] = context;
2650  inputs_[1] = object;
2651  }
2652 
2653  LOperand* context() { return inputs_[0]; }
2654  LOperand* object() { return inputs_[1]; }
2655 
2656  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
2657 };
2658 
2659 
2660 class LForInCacheArray FINAL : public LTemplateInstruction<1, 1, 0> {
2661  public:
2663  inputs_[0] = map;
2664  }
2665 
2666  LOperand* map() { return inputs_[0]; }
2667 
2668  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
2669 
2670  int idx() {
2671  return HForInCacheArray::cast(this->hydrogen_value())->idx();
2672  }
2673 };
2674 
2675 
2676 class LCheckMapValue FINAL : public LTemplateInstruction<0, 2, 0> {
2677  public:
2679  inputs_[0] = value;
2680  inputs_[1] = map;
2681  }
2682 
2683  LOperand* value() { return inputs_[0]; }
2684  LOperand* map() { return inputs_[1]; }
2685 
2686  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
2687 };
2688 
2689 
2690 class LLoadFieldByIndex FINAL : public LTemplateInstruction<1, 2, 0> {
2691  public:
2693  inputs_[0] = object;
2694  inputs_[1] = index;
2695  }
2696 
2697  LOperand* object() { return inputs_[0]; }
2698  LOperand* index() { return inputs_[1]; }
2699 
2700  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
2701 };
2702 
2703 
2704 class LStoreFrameContext: public LTemplateInstruction<0, 1, 0> {
2705  public:
2706  explicit LStoreFrameContext(LOperand* context) {
2707  inputs_[0] = context;
2708  }
2709 
2710  LOperand* context() { return inputs_[0]; }
2711 
2712  DECLARE_CONCRETE_INSTRUCTION(StoreFrameContext, "store-frame-context")
2713 };
2714 
2715 
2716 class LAllocateBlockContext: public LTemplateInstruction<1, 2, 0> {
2717  public:
2718  LAllocateBlockContext(LOperand* context, LOperand* function) {
2719  inputs_[0] = context;
2720  inputs_[1] = function;
2721  }
2722 
2723  LOperand* context() { return inputs_[0]; }
2724  LOperand* function() { return inputs_[1]; }
2725 
2726  Handle<ScopeInfo> scope_info() { return hydrogen()->scope_info(); }
2727 
2728  DECLARE_CONCRETE_INSTRUCTION(AllocateBlockContext, "allocate-block-context")
2729  DECLARE_HYDROGEN_ACCESSOR(AllocateBlockContext)
2730 };
2731 
2732 
2733 class LChunkBuilder;
2734 class LPlatformChunk FINAL : public LChunk {
2735  public:
2736  LPlatformChunk(CompilationInfo* info, HGraph* graph)
2737  : LChunk(info, graph),
2738  num_double_slots_(0) { }
2739 
2742 
2743  int num_double_slots() const { return num_double_slots_; }
2744 
2745  private:
2747 };
2748 
2749 
2750 class LChunkBuilder FINAL : public LChunkBuilderBase {
2751  public:
2752  LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
2753  : LChunkBuilderBase(info, graph),
2754  current_instruction_(NULL),
2755  current_block_(NULL),
2756  next_block_(NULL),
2757  allocator_(allocator) {}
2758 
2759  // Build the sequence for the graph.
2760  LPlatformChunk* Build();
2761 
2762  // Declare methods that deal with the individual node types.
2763 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2765 #undef DECLARE_DO
2766 
2767  LInstruction* DoMathFloor(HUnaryMathOperation* instr);
2768  LInstruction* DoMathRound(HUnaryMathOperation* instr);
2769  LInstruction* DoMathFround(HUnaryMathOperation* instr);
2770  LInstruction* DoMathAbs(HUnaryMathOperation* instr);
2771  LInstruction* DoMathLog(HUnaryMathOperation* instr);
2772  LInstruction* DoMathExp(HUnaryMathOperation* instr);
2773  LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
2774  LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
2775  LInstruction* DoMathClz32(HUnaryMathOperation* instr);
2778  LInstruction* DoDivI(HDiv* instr);
2781  LInstruction* DoModI(HMod* instr);
2782  LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
2783  LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
2784  LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
2785 
2786  private:
2787  // Methods for getting operands for Use / Define / Temp.
2790 
2791  // Methods for setting up define-use relationships.
2795  XMMRegister fixed_register);
2796 
2797  // A value that is guaranteed to be allocated to a register.
2798  // Operand created by UseRegister is guaranteed to be live until the end of
2799  // instruction. This means that register allocator will not reuse it's
2800  // register for any other operand inside instruction.
2801  // Operand created by UseRegisterAtStart is guaranteed to be live only at
2802  // instruction start. Register allocator is free to assign the same register
2803  // to some other operand used inside instruction (i.e. temporary or
2804  // output).
2807 
2808  // An input operand in a register that may be trashed.
2810 
2811  // An input operand in a register or stack slot.
2814 
2815  // An input operand in a register, stack slot or a constant operand.
2818 
2819  // An input operand in a fixed register or a constant operand.
2821  Register fixed_register);
2822 
2823  // An input operand in a register or a constant operand.
2826 
2827  // An input operand in a constant operand.
2829 
2830  // An input operand in register, stack slot or a constant operand.
2831  // Will not be moved to a register even if one is freely available.
2833 
2834  // Temporary operand that must be in a register.
2838 
2839  // Methods for setting up define-use relationships.
2840  // Return the same instruction that they are passed.
2842  LUnallocated* result);
2845  int index);
2848  Register reg);
2850  XMMRegister reg);
2851  // Assigns an environment to an instruction. An instruction which can
2852  // deoptimize must have an environment.
2854  // Assigns a pointer map to an instruction. An instruction which can
2855  // trigger a GC or a lazy deoptimization must have a pointer map.
2857 
2858  enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2859 
2860  LOperand* GetSeqStringSetCharOperand(HSeqStringSetChar* instr);
2861 
2862  // Marks a call for the register allocator. Assigns a pointer map to
2863  // support GC and lazy deoptimization. Assigns an environment to support
2864  // eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
2866  LInstruction* instr,
2867  HInstruction* hinstr,
2868  CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2869 
2871  void AddInstruction(LInstruction* instr, HInstruction* current);
2872 
2873  void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2878  HBinaryOperation* instr);
2879 
2880  LOperand* GetStoreKeyedValueOperand(HStoreKeyed* instr);
2881 
2882  HInstruction* current_instruction_;
2883  HBasicBlock* current_block_;
2884  HBasicBlock* next_block_;
2885  LAllocator* allocator_;
2886 
2888 };
2889 
2890 #undef DECLARE_HYDROGEN_ACCESSOR
2891 #undef DECLARE_CONCRETE_INSTRUCTION
2892 
2893 } } // namespace v8::internal
2894 
2895 #endif // V8_IA32_LITHIUM_IA32_H_
The superclass of all JavaScript values and objects.
Definition: v8.h:1440
static U update(U previous, T value)
Definition: utils.h:223
static T decode(U value)
Definition: utils.h:228
Source to read snapshot and builtins files from.
Definition: lithium-arm.h:372
LInstructionGap(HBasicBlock *block)
Definition: lithium-ia32.h:374
LCallJSFunction(LOperand *function)
LSmiUntag(LOperand *value, bool needs_check)
LInstruction * DoDivByPowerOf2I(HDiv *instr)
LCheckSmi(LOperand *value)
LOperand * temp_vector()
LTypeofIsAndBranch(LOperand *value)
MUST_USE_RESULT LOperand * UseFixedDouble(HValue *value, XMMRegister fixed_register)
LBoundsCheck(LOperand *index, LOperand *length)
DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch, "is-undetectable-and-branch") virtual void PrintDataTo(StringStream *stream) OVERRIDE
virtual LOperand * TempAt(int i) FINAL OVERRIDE
MUST_USE_RESULT LUnallocated * TempRegister()
LTrapAllocationMemento(LOperand *object, LOperand *temp)
LIsSmiAndBranch(LOperand *value)
LMathExp(LOperand *value, LOperand *temp1, LOperand *temp2)
Definition: lithium-ia32.h:943
LDivByPowerOf2I(LOperand *dividend, int32_t divisor)
Definition: lithium-ia32.h:702
LOperand * unclamped()
LUint32ToDouble(LOperand *value)
LModByPowerOf2I(LOperand *dividend, int32_t divisor)
Definition: lithium-ia32.h:642
LStringCharCodeAt(LOperand *context, LOperand *string, LOperand *index)
LInstruction * DoArithmeticT(Token::Value op, HBinaryOperation *instr)
LPower(LOperand *left, LOperand *right)
ElementsKind to_kind()
LOperand * name()
Definition: lithium-ia32.h:496
LStringCompareAndBranch(LOperand *context, LOperand *left, LOperand *right)
LUnallocated * ToUnallocated(XMMRegister reg)
MUST_USE_RESULT LOperand * UseFixedOrConstant(HValue *value, Register fixed_register)
virtual bool ClobbersDoubleRegisters(Isolate *isolate) const OVERRIDE
Definition: lithium-ia32.h:394
LInnerAllocatedObject(LOperand *base_object, LOperand *offset)
LCmpObjectEqAndBranch(LOperand *left, LOperand *right)
Definition: lithium-ia32.h:988
LOperand * left()
Definition: lithium-ia32.h:691
LInstruction * DoFlooringDivByPowerOf2I(HMathFloorOfDiv *instr)
virtual Opcode opcode() const OVERRIDE
LOperand * index() const
LStoreNamedGeneric(LOperand *context, LOperand *object, LOperand *value)
ElementsKind from_kind()
LMathClz32(LOperand *value)
Definition: lithium-ia32.h:931
LMathMinMax(LOperand *left, LOperand *right)
LConstructDouble(LOperand *hi, LOperand *lo)
LMathPowHalf(LOperand *value, LOperand *temp)
Definition: lithium-ia32.h:974
LShiftI(Token::Value op, LOperand *left, LOperand *right, bool can_deopt)
LLoadContextSlot(LOperand *context)
virtual void PrintDataTo(StringStream *stream) OVERRIDE
LInstruction * DefineSameAsFirst(LTemplateResultInstruction< 1 > *instr)
LBitI(LOperand *left, LOperand *right)
MUST_USE_RESULT LOperand * FixedTemp(XMMRegister reg)
LDoubleBits(LOperand *value)
LSmiTag(LOperand *value)
LDeclareGlobals(LOperand *context)
LIsUndetectableAndBranch(LOperand *value, LOperand *temp)
virtual void CompileToNative(LCodeGen *generator) OVERRIDE
LApplyArguments(LOperand *function, LOperand *receiver, LOperand *length, LOperand *elements)
Definition: lithium-ia32.h:578
LCheckInstanceType(LOperand *value, LOperand *temp)
LOperand * temp()
Definition: lithium-ia32.h:569
LStringAdd(LOperand *context, LOperand *left, LOperand *right)
MUST_USE_RESULT LOperand * Use(HValue *value)
MUST_USE_RESULT LOperand * UseAtStart(HValue *value)
MUST_USE_RESULT LOperand * UseConstant(HValue *value)
bool has_constant_parameter_count()
MUST_USE_RESULT LOperand * UseOrConstantAtStart(HValue *value)
SaveFPRegsMode save_doubles() const
LInteger32ToDouble(LOperand *value)
virtual int TempCount() FINAL OVERRIDE
LForInCacheArray(LOperand *map)
LModByConstI(LOperand *dividend, int32_t divisor, LOperand *temp1, LOperand *temp2)
Definition: lithium-ia32.h:660
LCmpT(LOperand *context, LOperand *left, LOperand *right)
LInstruction * DoMathAbs(HUnaryMathOperation *instr)
LBranch(LOperand *value, LOperand *temp)
LLabel * replacement() const
Definition: lithium-ia32.h:451
LCompareMinusZeroAndBranch(LOperand *value, LOperand *temp)
LOperand * value()
Definition: lithium-ia32.h:870
LLoadKeyedGeneric(LOperand *context, LOperand *obj, LOperand *key, LOperand *vector)
LClampIToUint8(LOperand *value)
LDummyUse(LOperand *value)
Definition: lithium-ia32.h:420
LInstruction * DoMathExp(HUnaryMathOperation *instr)
MUST_USE_RESULT LOperand * UseTempRegister(HValue *value)
DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch, "has-instance-type-and-branch") virtual void PrintDataTo(StringStream *stream) OVERRIDE
LInstruction * DoModByPowerOf2I(HMod *instr)
LInstruction * AssignEnvironment(LInstruction *instr)
bool is_fixed_typed_array() const
LDoubleToI(LOperand *value, LOperand *temp)
LLoadNamedField(LOperand *object)
LDateField(LOperand *date, LOperand *temp, Smi *index)
LAddI(LOperand *left, LOperand *right)
LMathRound(LOperand *value, LOperand *temp)
Definition: lithium-ia32.h:879
LInstruction * Define(LTemplateResultInstruction< 1 > *instr, LUnallocated *result)
LDoubleToSmi(LOperand *value)
LCmpHoleAndBranch(LOperand *object)
LOperand * elements()
Definition: lithium-ia32.h:591
LInstruction * AssignPointerMap(LInstruction *instr)
LMathFloor(LOperand *value)
Definition: lithium-ia32.h:866
LInstruction * DoMathFloor(HUnaryMathOperation *instr)
LIsStringAndBranch(LOperand *value, LOperand *temp)
LInstruction * DoMathRound(HUnaryMathOperation *instr)
LGoto(HBasicBlock *block)
Definition: lithium-ia32.h:386
LClassOfTestAndBranch(LOperand *value, LOperand *temp, LOperand *temp2)
LConstantD(LOperand *temp)
LCallNew(LOperand *context, LOperand *constructor)
LStackCheck(LOperand *context)
LOperand * char_code()
LAllocate(LOperand *context, LOperand *size, LOperand *temp)
LLoadFieldByIndex(LOperand *object, LOperand *index)
virtual LOperand * InputAt(int i) FINAL OVERRIDE
virtual bool IsControl() const OVERRIDE
Definition: lithium-ia32.h:429
void DoBasicBlock(HBasicBlock *block, HBasicBlock *next_block)
LNumberTagI(LOperand *value, LOperand *temp)
LDivByConstI(LOperand *dividend, int32_t divisor, LOperand *temp1, LOperand *temp2)
Definition: lithium-ia32.h:720
LArgumentsLength(LOperand *elements)
Definition: lithium-ia32.h:617
LTaggedToI(LOperand *value, LOperand *temp)
LIsConstructCallAndBranch(LOperand *temp)
LMathFround(LOperand *value)
Definition: lithium-ia32.h:894
LLoadNamedGeneric(LOperand *context, LOperand *object, LOperand *vector)
LCheckMapValue(LOperand *value, LOperand *map)
LOperand * receiver()
Definition: lithium-ia32.h:495
LArithmeticT(Token::Value op, LOperand *context, LOperand *left, LOperand *right)
bool jumps_to_join() const
Definition: lithium-ia32.h:398
LGetCachedArrayIndex(LOperand *value)
LOperand * temp_map()
int32_t divisor() const
Definition: lithium-ia32.h:648
LOperand * GetNextSpillSlot(RegisterKind kind)
LConstantOperand * constant_parameter_count()
LCallNewArray(LOperand *context, LOperand *constructor)
LFlooringDivI(LOperand *dividend, LOperand *divisor, LOperand *temp)
Definition: lithium-ia32.h:809
DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, "class-of-test-and-branch") virtual void PrintDataTo(StringStream *stream) OVERRIDE
LNumberTagU(LOperand *value, LOperand *temp)
DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch, "string-compare-and-branch") virtual void PrintDataTo(StringStream *stream) OVERRIDE
LOperand * context()
Definition: lithium-ia32.h:476
LOperand * dividend()
Definition: lithium-ia32.h:647
bool can_deopt() const
LNumberTagD(LOperand *value, LOperand *temp)
LClampTToUint8(LOperand *value, LOperand *temp_xmm)
LOperand * new_map_temp()
LForInPrepareMap(LOperand *context, LOperand *object)
LMapEnumLength(LOperand *value)
LInstruction * DefineAsSpilled(LTemplateResultInstruction< 1 > *instr, int index)
LStoreCodeEntry(LOperand *function, LOperand *code_object)
Token::Value op() const
LOperand * offset() const
LSeqStringGetChar(LOperand *string, LOperand *index)
bool is_external() const
MUST_USE_RESULT LOperand * UseRegisterAtStart(HValue *value)
LOperand * arguments()
Definition: lithium-ia32.h:605
LInstruction * DoMathPowHalf(HUnaryMathOperation *instr)
LInvokeFunction(LOperand *context, LOperand *function)
LSubI(LOperand *left, LOperand *right)
LOperand * temp3()
Definition: lithium-ia32.h:797
LCheckMaps(LOperand *value=NULL)
LInstruction * DoFlooringDivByConstI(HMathFloorOfDiv *instr)
bool is_typed_elements() const
LLabel(HBasicBlock *block)
Definition: lithium-ia32.h:437
LFlooringDivByConstI(LOperand *dividend, int32_t divisor, LOperand *temp1, LOperand *temp2, LOperand *temp3)
Definition: lithium-ia32.h:781
bool HasReplacement() const
Definition: lithium-ia32.h:453
LInstruction * DoModByConstI(HMod *instr)
MUST_USE_RESULT LOperand * Use(HValue *value, LUnallocated *operand)
LCheckValue(LOperand *value)
LModI(LOperand *left, LOperand *right, LOperand *temp)
Definition: lithium-ia32.h:685
LStringCharFromCode(LOperand *context, LOperand *char_code)
LInstruction * DoShift(Token::Value op, HBitwiseBinaryOperation *instr)
LOperand * object()
LOperand * index()
Definition: lithium-ia32.h:607
LInstruction * DoArithmeticD(Token::Value op, HArithmeticBinaryOperation *instr)
LSeqStringSetChar(LOperand *context, LOperand *string, LOperand *index, LOperand *value)
virtual int InputCount() FINAL OVERRIDE
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder)
LInstruction * DoMathClz32(HUnaryMathOperation *instr)
LInstruction * DoMathSqrt(HUnaryMathOperation *instr)
ElementsKind elements_kind() const
LOperand * temp1()
Definition: lithium-ia32.h:672
DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind, "transition-elements-kind") virtual void PrintDataTo(StringStream *stream) OVERRIDE
LCmpMapAndBranch(LOperand *value)
LCallWithDescriptor(CallInterfaceDescriptor descriptor, const ZoneList< LOperand * > &operands, Zone *zone)
LOperand * global_object()
LCallRuntime(LOperand *context)
LOperand * constructor()
StrictMode strict_mode()
LLoadGlobalGeneric(LOperand *context, LOperand *global_object, LOperand *vector)
LPlatformChunk * Build()
MUST_USE_RESULT LOperand * UseFixed(HValue *value, Register fixed_register)
LWrapReceiver(LOperand *receiver, LOperand *function, LOperand *temp)
Definition: lithium-ia32.h:559
LOperand * base_object() const
LInstanceOfKnownGlobal(LOperand *context, LOperand *value, LOperand *temp)
LPlatformChunk(CompilationInfo *info, HGraph *graph)
LRegExpLiteral(LOperand *context)
LOperand * temp_xmm()
LOperand * GetSeqStringSetCharOperand(HSeqStringSetChar *instr)
virtual bool HasInterestingComment(LCodeGen *gen) const OVERRIDE
Definition: lithium-ia32.h:376
LOperand * string() const
LInstruction * DoMathLog(HUnaryMathOperation *instr)
LInstruction * DoDivByConstI(HDiv *instr)
bool for_typeof() const
void VisitInstruction(HInstruction *current)
LPushArgument(LOperand *value)
LStoreNamedField(LOperand *obj, LOperand *val, LOperand *temp, LOperand *temp_map)
LOperand * length()
Definition: lithium-ia32.h:590
LStoreKeyedGeneric(LOperand *context, LOperand *object, LOperand *key, LOperand *value)
int num_double_slots() const
DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch, "has-cached-array-index-and-branch") virtual void PrintDataTo(StringStream *stream) OVERRIDE
MUST_USE_RESULT LOperand * UseRegister(HValue *value)
bool is_osr_entry() const
Definition: lithium-ia32.h:449
LStoreContextSlot(LOperand *context, LOperand *value, LOperand *temp)
static bool UseLea(HAdd *add)
LClampDToUint8(LOperand *value)
virtual const char * Mnemonic() const OVERRIDE
LDivI(LOperand *dividend, LOperand *divisor, LOperand *temp)
Definition: lithium-ia32.h:745
MUST_USE_RESULT LOperand * UseOrConstant(HValue *value)
LCallStub(LOperand *context)
Definition: lithium-ia32.h:472
LInstruction * DoFlooringDivI(HMathFloorOfDiv *instr)
LMathAbs(LOperand *context, LOperand *value)
Definition: lithium-ia32.h:904
LInstruction * DefineFixed(LTemplateResultInstruction< 1 > *instr, Register reg)
LCompareNumericAndBranch(LOperand *left, LOperand *right)
Definition: lithium-ia32.h:843
LInstruction * DoDivI(HDiv *instr)
LFunctionLiteral(LOperand *context)
virtual MUST_USE_RESULT LOperand * UseAny(HValue *value) OVERRIDE
LMathSqrt(LOperand *value)
Definition: lithium-ia32.h:962
MUST_USE_RESULT LOperand * FixedTemp(Register reg)
LOperand * right()
Definition: lithium-ia32.h:692
LHasInstanceTypeAndBranch(LOperand *value, LOperand *temp)
virtual void PrintDataTo(StringStream *stream)
Handle< Map > transitioned_map()
LInstruction * DefineFixedDouble(LTemplateResultInstruction< 1 > *instr, XMMRegister reg)
LMathLog(LOperand *value)
Definition: lithium-ia32.h:919
LLoadKeyed(LOperand *elements, LOperand *key)
LOperand * parameter_count()
LReturn(LOperand *value, LOperand *context, LOperand *parameter_count)
LCallFunction(LOperand *context, LOperand *function)
LNumberUntagD(LOperand *value, LOperand *temp)
LHasCachedArrayIndexAndBranch(LOperand *value)
LInstruction * DoModI(HMod *instr)
MUST_USE_RESULT LOperand * UseRegisterOrConstantAtStart(HValue *value)
void AddInstruction(LInstruction *instr, HInstruction *current)
LMulI(LOperand *left, LOperand *right, LOperand *temp)
Definition: lithium-ia32.h:826
void set_replacement(LLabel *label)
Definition: lithium-ia32.h:452
bool is_loop_header() const
Definition: lithium-ia32.h:448
LInstanceOf(LOperand *context, LOperand *left, LOperand *right)
LOperand * string()
LFlooringDivByPowerOf2I(LOperand *dividend, int32_t divisor)
Definition: lithium-ia32.h:762
LOperand * temp2()
Definition: lithium-ia32.h:673
LCheckNonSmi(LOperand *value)
LAccessArgumentsAt(LOperand *arguments, LOperand *length, LOperand *index)
Definition: lithium-ia32.h:599
LOperand * GetStoreKeyedValueOperand(HStoreKeyed *instr)
LUnallocated * ToUnallocated(Register reg)
LOperand * target() const
LIsObjectAndBranch(LOperand *value, LOperand *temp)
LTypeof(LOperand *context, LOperand *value)
MUST_USE_RESULT LOperand * UseRegisterOrConstant(HValue *value)
LChunkBuilder(CompilationInfo *info, HGraph *graph, LAllocator *allocator)
LArithmeticD(Token::Value op, LOperand *left, LOperand *right)
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment *env) OVERRIDE
LOperand * code_object()
LEnvironment * GetDeferredLazyDeoptimizationEnvironment()
LStoreGlobalCell(LOperand *value)
LOperand * divisor()
Definition: lithium-ia32.h:752
LLoadFunctionPrototype(LOperand *function, LOperand *temp)
LTransitionElementsKind(LOperand *object, LOperand *context, LOperand *new_map_temp, LOperand *temp)
int block_id() const
Definition: lithium-ia32.h:393
LInstruction * DefineAsRegister(LTemplateResultInstruction< 1 > *instr)
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal, "instance-of-known-global") Handle< JSFunction > function() const
LToFastProperties(LOperand *value)
LTailCallThroughMegamorphicCache(LOperand *context, LOperand *receiver, LOperand *name)
Definition: lithium-ia32.h:486
LInstruction * MarkAsCall(LInstruction *instr, HInstruction *hinstr, CanDeoptimize can_deoptimize=CANNOT_DEOPTIMIZE_EAGERLY)
LInstruction * DoMathFround(HUnaryMathOperation *instr)
int GetNextSpillIndex(RegisterKind kind)
LStoreKeyed(LOperand *obj, LOperand *key, LOperand *val)
static HValue * cast(HValue *value)
Handle< ScopeInfo > scope_info()
LAllocateBlockContext(LOperand *context, LOperand *function)
int LookupDestination(int block_id) const
Definition: lithium.cc:285
Label * GetAssemblyLabel(int block_id) const
Definition: lithium.cc:293
HControlInstruction * hydrogen()
Definition: lithium-ia32.h:548
virtual bool IsControl() const FINAL OVERRIDE
Definition: lithium-ia32.h:518
int FalseDestination(LChunk *chunk)
Definition: lithium-ia32.h:526
HBasicBlock * SuccessorAt(int i)
Definition: lithium-ia32.h:521
Label * FalseLabel(LChunk *chunk)
Definition: lithium-ia32.h:536
int TrueDestination(LChunk *chunk)
Definition: lithium-ia32.h:523
Label * TrueLabel(LChunk *chunk)
Definition: lithium-ia32.h:530
LGap(HBasicBlock *block)
Definition: lithium-ia32.h:327
virtual void PrintDataTo(StringStream *stream) OVERRIDE
virtual bool IsGap() const FINAL OVERRIDE
Definition: lithium-ia32.h:335
static LGap * cast(LInstruction *instr)
Definition: lithium-ia32.h:337
LParallelMove * GetParallelMove(InnerPosition pos)
Definition: lithium-ia32.h:362
bool IsRedundant() const
HBasicBlock * block() const
Definition: lithium-arm.h:344
LParallelMove * parallel_moves_[LAST_INNER_POSITION+1]
Definition: lithium-arm.h:367
HBasicBlock * block_
Definition: lithium-arm.h:368
LParallelMove * GetOrCreateParallelMove(InnerPosition pos, Zone *zone)
Definition: lithium-ia32.h:355
SetOncePointer< LPointerMap > pointer_map_
Definition: lithium-arm.h:282
virtual int InputCount()=0
void set_environment(LEnvironment *env)
Definition: lithium-ia32.h:231
virtual bool HasResult() const =0
virtual void PrintDataTo(StringStream *stream)
virtual int TempCount()=0
virtual const char * Mnemonic() const =0
virtual LOperand * TempAt(int i)=0
LEnvironment * environment() const
Definition: lithium-ia32.h:232
virtual LOperand * InputAt(int i)=0
void set_hydrogen_value(HValue *value)
Definition: lithium-ia32.h:239
virtual LOperand * result() const =0
virtual void PrintTo(StringStream *stream)
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment *env)
Definition: lithium-ia32.h:242
HValue * hydrogen_value() const
Definition: lithium-ia32.h:240
void set_pointer_map(LPointerMap *p)
Definition: lithium-ia32.h:235
LEnvironment * environment_
Definition: lithium-arm.h:281
virtual Opcode opcode() const =0
virtual bool ClobbersDoubleRegisters(Isolate *isolate) const
Definition: lithium-ia32.h:250
bool ClobbersRegisters() const
Definition: lithium-ia32.h:249
virtual bool HasInterestingComment(LCodeGen *gen) const
Definition: lithium-ia32.h:263
virtual void CompileToNative(LCodeGen *generator)=0
virtual bool IsControl() const
Definition: lithium-ia32.h:226
LPointerMap * pointer_map() const
Definition: lithium-ia32.h:236
virtual bool IsGap() const
Definition: lithium-ia32.h:224
virtual void PrintOutputOperandTo(StringStream *stream)
LStoreFrameContext(LOperand *context)
EmbeddedContainer< LOperand *, I > inputs_
Definition: lithium-arm.h:311
virtual LOperand * TempAt(int i) FINAL OVERRIDE
Definition: lithium-ia32.h:321
virtual int TempCount() FINAL OVERRIDE
Definition: lithium-ia32.h:320
EmbeddedContainer< LOperand *, T > temps_
Definition: lithium-arm.h:312
virtual LOperand * InputAt(int i) FINAL OVERRIDE
Definition: lithium-ia32.h:318
virtual int InputCount() FINAL OVERRIDE
Definition: lithium-ia32.h:317
virtual bool HasResult() const FINAL OVERRIDE
Definition: lithium-ia32.h:295
EmbeddedContainer< LOperand *, R > results_
Definition: lithium-arm.h:301
void set(T *value)
Definition: utils.h:417
static Smi * FromInt(int value)
Definition: objects-inl.h:1321
#define OVERRIDE
#define FINAL
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 map
enable harmony numeric enable harmony object literal extensions Optimize object size
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 expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
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 HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)
Definition: lithium-ia32.h:170
#define DECLARE_DO(type)
#define DECLARE_PREDICATE(type)
Definition: lithium-ia32.h:217
#define DECLARE_OPCODE(type)
Definition: lithium-ia32.h:208
#define DECLARE_HYDROGEN_ACCESSOR(type)
Definition: lithium-ia32.h:184
#define DCHECK(condition)
Definition: logging.h:205
#define MUST_USE_RESULT
Definition: macros.h:266
int int32_t
Definition: unicode.cc:24
static bool ExternalArrayOpRequiresTemp(Representation key_representation, ElementsKind elements_kind)
static Object * DeclareGlobals(Isolate *isolate, Handle< GlobalObject > global, Handle< String > name, Handle< Object > value, PropertyAttributes attr, bool is_var, bool is_const, bool is_function)
Definition: runtime.cc:1038
@ UINT8_CLAMPED_ELEMENTS
Definition: elements-kind.h:52
@ EXTERNAL_UINT8_ELEMENTS
Definition: elements-kind.h:34
@ EXTERNAL_INT8_ELEMENTS
Definition: elements-kind.h:33
@ EXTERNAL_UINT8_CLAMPED_ELEMENTS
Definition: elements-kind.h:41
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define T(name, string, precedence)
Definition: token.cc:25