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