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