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