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