v8  3.11.10(node0.8.26)
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_ALL_INSTRUCTION_LIST(V) \
44  V(ControlInstruction) \
45  V(Call) \
46  LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
47 
48 
49 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
50  V(AccessArgumentsAt) \
51  V(AddI) \
52  V(AllocateObject) \
53  V(ApplyArguments) \
54  V(ArgumentsElements) \
55  V(ArgumentsLength) \
56  V(ArithmeticD) \
57  V(ArithmeticT) \
58  V(ArrayLiteral) \
59  V(BitI) \
60  V(BitNotI) \
61  V(BoundsCheck) \
62  V(Branch) \
63  V(CallConstantFunction) \
64  V(CallFunction) \
65  V(CallGlobal) \
66  V(CallKeyed) \
67  V(CallKnownGlobal) \
68  V(CallNamed) \
69  V(CallNew) \
70  V(CallRuntime) \
71  V(CallStub) \
72  V(CheckFunction) \
73  V(CheckInstanceType) \
74  V(CheckNonSmi) \
75  V(CheckMaps) \
76  V(CheckPrototypeMaps) \
77  V(CheckSmi) \
78  V(ClampDToUint8) \
79  V(ClampIToUint8) \
80  V(ClampTToUint8) \
81  V(ClassOfTestAndBranch) \
82  V(CmpConstantEqAndBranch) \
83  V(CmpIDAndBranch) \
84  V(CmpObjectEqAndBranch) \
85  V(CmpMapAndBranch) \
86  V(CmpT) \
87  V(ConstantD) \
88  V(ConstantI) \
89  V(ConstantT) \
90  V(Context) \
91  V(DeclareGlobals) \
92  V(DeleteProperty) \
93  V(Deoptimize) \
94  V(DivI) \
95  V(DoubleToI) \
96  V(ElementsKind) \
97  V(FastLiteral) \
98  V(FixedArrayBaseLength) \
99  V(FunctionLiteral) \
100  V(GetCachedArrayIndex) \
101  V(GlobalObject) \
102  V(GlobalReceiver) \
103  V(Goto) \
104  V(HasCachedArrayIndexAndBranch) \
105  V(HasInstanceTypeAndBranch) \
106  V(In) \
107  V(InstanceOf) \
108  V(InstanceOfKnownGlobal) \
109  V(InstructionGap) \
110  V(Integer32ToDouble) \
111  V(InvokeFunction) \
112  V(IsConstructCallAndBranch) \
113  V(IsNilAndBranch) \
114  V(IsObjectAndBranch) \
115  V(IsStringAndBranch) \
116  V(IsSmiAndBranch) \
117  V(IsUndetectableAndBranch) \
118  V(StringCompareAndBranch) \
119  V(JSArrayLength) \
120  V(Label) \
121  V(LazyBailout) \
122  V(LoadContextSlot) \
123  V(LoadElements) \
124  V(LoadExternalArrayPointer) \
125  V(LoadFunctionPrototype) \
126  V(LoadGlobalCell) \
127  V(LoadGlobalGeneric) \
128  V(LoadKeyedFastDoubleElement) \
129  V(LoadKeyedFastElement) \
130  V(LoadKeyedGeneric) \
131  V(LoadKeyedSpecializedArrayElement) \
132  V(LoadNamedField) \
133  V(LoadNamedFieldPolymorphic) \
134  V(LoadNamedGeneric) \
135  V(MathFloorOfDiv) \
136  V(ModI) \
137  V(MulI) \
138  V(NumberTagD) \
139  V(NumberTagI) \
140  V(NumberUntagD) \
141  V(ObjectLiteral) \
142  V(OsrEntry) \
143  V(OuterContext) \
144  V(Parameter) \
145  V(Power) \
146  V(PushArgument) \
147  V(Random) \
148  V(RegExpLiteral) \
149  V(Return) \
150  V(ShiftI) \
151  V(SmiTag) \
152  V(SmiUntag) \
153  V(StackCheck) \
154  V(StoreContextSlot) \
155  V(StoreGlobalCell) \
156  V(StoreGlobalGeneric) \
157  V(StoreKeyedFastDoubleElement) \
158  V(StoreKeyedFastElement) \
159  V(StoreKeyedGeneric) \
160  V(StoreKeyedSpecializedArrayElement) \
161  V(StoreNamedField) \
162  V(StoreNamedGeneric) \
163  V(StringAdd) \
164  V(StringCharCodeAt) \
165  V(StringCharFromCode) \
166  V(StringLength) \
167  V(SubI) \
168  V(TaggedToI) \
169  V(ThisFunction) \
170  V(Throw) \
171  V(ToFastProperties) \
172  V(TransitionElementsKind) \
173  V(Typeof) \
174  V(TypeofIsAndBranch) \
175  V(UnaryMathOperation) \
176  V(UnknownOSRValue) \
177  V(ValueOf) \
178  V(ForInPrepareMap) \
179  V(ForInCacheArray) \
180  V(CheckMapValue) \
181  V(LoadFieldByIndex) \
182  V(DateField) \
183  V(WrapReceiver) \
184  V(Drop)
185 
186 
187 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
188  virtual Opcode opcode() const { return LInstruction::k##type; } \
189  virtual void CompileToNative(LCodeGen* generator); \
190  virtual const char* Mnemonic() const { return mnemonic; } \
191  static L##type* cast(LInstruction* instr) { \
192  ASSERT(instr->Is##type()); \
193  return reinterpret_cast<L##type*>(instr); \
194  }
195 
196 
197 #define DECLARE_HYDROGEN_ACCESSOR(type) \
198  H##type* hydrogen() const { \
199  return H##type::cast(hydrogen_value()); \
200  }
201 
202 
203 class LInstruction: public ZoneObject {
204  public:
206  : environment_(NULL),
207  hydrogen_value_(NULL),
208  is_call_(false) { }
209  virtual ~LInstruction() { }
210 
211  virtual void CompileToNative(LCodeGen* generator) = 0;
212  virtual const char* Mnemonic() const = 0;
213  virtual void PrintTo(StringStream* stream);
214  virtual void PrintDataTo(StringStream* stream);
215  virtual void PrintOutputOperandTo(StringStream* stream);
216 
217  enum Opcode {
218  // Declare a unique enum value for each instruction.
219 #define DECLARE_OPCODE(type) k##type,
222 #undef DECLARE_OPCODE
223  };
224 
225  virtual Opcode opcode() const = 0;
226 
227  // Declare non-virtual type testers for all leaf IR classes.
228 #define DECLARE_PREDICATE(type) \
229  bool Is##type() const { return opcode() == k##type; }
231 #undef DECLARE_PREDICATE
232 
233  // Declare virtual predicates for instructions that don't have
234  // an opcode.
235  virtual bool IsGap() const { return false; }
236 
237  virtual bool IsControl() const { return false; }
238 
239  void set_environment(LEnvironment* env) { environment_ = env; }
240  LEnvironment* environment() const { return environment_; }
241  bool HasEnvironment() const { return environment_ != NULL; }
242 
243  void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
244  LPointerMap* pointer_map() const { return pointer_map_.get(); }
245  bool HasPointerMap() const { return pointer_map_.is_set(); }
246 
247  void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
248  HValue* hydrogen_value() const { return hydrogen_value_; }
249 
251 
252  void MarkAsCall() { is_call_ = true; }
253 
254  // Interface to the register allocator and iterators.
255  bool IsMarkedAsCall() const { return is_call_; }
256 
257  virtual bool HasResult() const = 0;
258  virtual LOperand* result() = 0;
259 
260  virtual int InputCount() = 0;
261  virtual LOperand* InputAt(int i) = 0;
262  virtual int TempCount() = 0;
263  virtual LOperand* TempAt(int i) = 0;
264 
265  LOperand* FirstInput() { return InputAt(0); }
266  LOperand* Output() { return HasResult() ? result() : NULL; }
267 
268 #ifdef DEBUG
269  void VerifyCall();
270 #endif
271 
272  private:
273  LEnvironment* environment_;
274  SetOncePointer<LPointerMap> pointer_map_;
275  HValue* hydrogen_value_;
276  bool is_call_;
277 };
278 
279 
280 // R = number of result operands (0 or 1).
281 // I = number of input operands.
282 // T = number of temporary operands.
283 template<int R, int I, int T>
285  public:
286  // Allow 0 or 1 output operands.
287  STATIC_ASSERT(R == 0 || R == 1);
288  virtual bool HasResult() const { return R != 0; }
289  void set_result(LOperand* operand) { results_[0] = operand; }
290  LOperand* result() { return results_[0]; }
291 
292  int InputCount() { return I; }
293  LOperand* InputAt(int i) { return inputs_[i]; }
294 
295  int TempCount() { return T; }
296  LOperand* TempAt(int i) { return temps_[i]; }
297 
298  protected:
302 };
303 
304 
305 class LGap: public LTemplateInstruction<0, 0, 0> {
306  public:
307  explicit LGap(HBasicBlock* block)
308  : block_(block) {
309  parallel_moves_[BEFORE] = NULL;
310  parallel_moves_[START] = NULL;
311  parallel_moves_[END] = NULL;
312  parallel_moves_[AFTER] = NULL;
313  }
314 
315  // Can't use the DECLARE-macro here because of sub-classes.
316  virtual bool IsGap() const { return true; }
317  virtual void PrintDataTo(StringStream* stream);
318  static LGap* cast(LInstruction* instr) {
319  ASSERT(instr->IsGap());
320  return reinterpret_cast<LGap*>(instr);
321  }
322 
323  bool IsRedundant() const;
324 
325  HBasicBlock* block() const { return block_; }
326 
334  };
335 
337  if (parallel_moves_[pos] == NULL) {
338  parallel_moves_[pos] = new(zone) LParallelMove(zone);
339  }
340  return parallel_moves_[pos];
341  }
342 
344  return parallel_moves_[pos];
345  }
346 
347  private:
348  LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
349  HBasicBlock* block_;
350 };
351 
352 
353 class LInstructionGap: public LGap {
354  public:
355  explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
356 
357  DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
358 };
359 
360 
361 class LGoto: public LTemplateInstruction<0, 0, 0> {
362  public:
363  explicit LGoto(int block_id) : block_id_(block_id) { }
364 
365  DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
366  virtual void PrintDataTo(StringStream* stream);
367  virtual bool IsControl() const { return true; }
368 
369  int block_id() const { return block_id_; }
370 
371  private:
372  int block_id_;
373 };
374 
375 
376 class LLazyBailout: public LTemplateInstruction<0, 0, 0> {
377  public:
378  LLazyBailout() : gap_instructions_size_(0) { }
379 
380  DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
381 
383  gap_instructions_size_ = gap_instructions_size;
384  }
385  int gap_instructions_size() { return gap_instructions_size_; }
386 
387  private:
388  int gap_instructions_size_;
389 };
390 
391 
392 class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
393  public:
394  DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
395 };
396 
397 
398 class LLabel: public LGap {
399  public:
401  : LGap(block), replacement_(NULL) { }
402 
403  DECLARE_CONCRETE_INSTRUCTION(Label, "label")
404 
405  virtual void PrintDataTo(StringStream* stream);
406 
407  int block_id() const { return block()->block_id(); }
408  bool is_loop_header() const { return block()->IsLoopHeader(); }
409  Label* label() { return &label_; }
410  LLabel* replacement() const { return replacement_; }
411  void set_replacement(LLabel* label) { replacement_ = label; }
412  bool HasReplacement() const { return replacement_ != NULL; }
413 
414  private:
415  Label label_;
416  LLabel* replacement_;
417 };
418 
419 
420 class LParameter: public LTemplateInstruction<1, 0, 0> {
421  public:
422  DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
423 };
424 
425 
426 class LCallStub: public LTemplateInstruction<1, 0, 0> {
427  public:
428  DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
429  DECLARE_HYDROGEN_ACCESSOR(CallStub)
430 
432  return hydrogen()->transcendental_type();
433  }
434 };
435 
436 
437 class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
438  public:
439  DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
440 };
441 
442 
443 template<int I, int T>
445  public:
446  virtual bool IsControl() const { return true; }
447 
448  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
449  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
450  int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); }
451  int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); }
452 
453  private:
454  HControlInstruction* hydrogen() {
456  }
457 };
458 
459 
460 class LWrapReceiver: public LTemplateInstruction<1, 2, 0> {
461  public:
463  inputs_[0] = receiver;
464  inputs_[1] = function;
465  }
466 
467  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
468 
469  LOperand* receiver() { return inputs_[0]; }
470  LOperand* function() { return inputs_[1]; }
471 };
472 
473 
474 class LApplyArguments: public LTemplateInstruction<1, 4, 0> {
475  public:
478  LOperand* length,
479  LOperand* elements) {
480  inputs_[0] = function;
481  inputs_[1] = receiver;
482  inputs_[2] = length;
483  inputs_[3] = elements;
484  }
485 
486  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
487 
488  LOperand* function() { return inputs_[0]; }
489  LOperand* receiver() { return inputs_[1]; }
490  LOperand* length() { return inputs_[2]; }
491  LOperand* elements() { return inputs_[3]; }
492 };
493 
494 
495 class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> {
496  public:
498  inputs_[0] = arguments;
499  inputs_[1] = length;
500  inputs_[2] = index;
501  }
502 
503  DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
504 
505  LOperand* arguments() { return inputs_[0]; }
506  LOperand* length() { return inputs_[1]; }
507  LOperand* index() { return inputs_[2]; }
508 
509  virtual void PrintDataTo(StringStream* stream);
510 };
511 
512 
513 class LArgumentsLength: public LTemplateInstruction<1, 1, 0> {
514  public:
515  explicit LArgumentsLength(LOperand* elements) {
516  inputs_[0] = elements;
517  }
518 
519  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
520 };
521 
522 
523 class LArgumentsElements: public LTemplateInstruction<1, 0, 0> {
524  public:
525  DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
526  DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
527 };
528 
529 
530 class LModI: public LTemplateInstruction<1, 2, 3> {
531  public:
532  // Used when the right hand is a constant power of 2.
534  LOperand* right) {
535  inputs_[0] = left;
536  inputs_[1] = right;
537  temps_[0] = NULL;
538  temps_[1] = NULL;
539  temps_[2] = NULL;
540  }
541 
542  // Used for the standard case.
544  LOperand* right,
545  LOperand* temp1,
546  LOperand* temp2,
547  LOperand* temp3) {
548  inputs_[0] = left;
549  inputs_[1] = right;
550  temps_[0] = temp1;
551  temps_[1] = temp2;
552  temps_[2] = temp3;
553  }
554 
555  DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
557 };
558 
559 
560 class LDivI: public LTemplateInstruction<1, 2, 0> {
561  public:
562  LDivI(LOperand* left, LOperand* right) {
563  inputs_[0] = left;
564  inputs_[1] = right;
565  }
566 
567  DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
569 };
570 
571 
572 class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> {
573  public:
575  LOperand* right,
576  LOperand* temp = NULL) {
577  inputs_[0] = left;
578  inputs_[1] = right;
579  temps_[0] = temp;
580  }
581 
582  DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
583  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
584 };
585 
586 
587 class LMulI: public LTemplateInstruction<1, 2, 1> {
588  public:
589  LMulI(LOperand* left, LOperand* right, LOperand* temp) {
590  inputs_[0] = left;
591  inputs_[1] = right;
592  temps_[0] = temp;
593  }
594 
595  DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
597 };
598 
599 
601  public:
603  inputs_[0] = left;
604  inputs_[1] = right;
605  }
606 
607  DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
608  DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
609 
610  Token::Value op() const { return hydrogen()->token(); }
611  bool is_double() const {
612  return hydrogen()->GetInputRepresentation().IsDouble();
613  }
614 
615  virtual void PrintDataTo(StringStream* stream);
616 };
617 
618 
619 class LUnaryMathOperation: public LTemplateInstruction<1, 1, 1> {
620  public:
622  inputs_[0] = value;
623  temps_[0] = temp;
624  }
625 
626  DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
627  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
628 
629  virtual void PrintDataTo(StringStream* stream);
630  BuiltinFunctionId op() const { return hydrogen()->op(); }
631 };
632 
633 
635  public:
637  inputs_[0] = left;
638  inputs_[1] = right;
639  }
640 
641  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch,
642  "cmp-object-eq-and-branch")
643  DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch)
644 };
645 
646 
648  public:
650  inputs_[0] = left;
651  }
652 
653  DECLARE_CONCRETE_INSTRUCTION(CmpConstantEqAndBranch,
654  "cmp-constant-eq-and-branch")
655  DECLARE_HYDROGEN_ACCESSOR(CompareConstantEqAndBranch)
656 };
657 
658 
659 class LIsNilAndBranch: public LControlInstruction<1, 0> {
660  public:
661  explicit LIsNilAndBranch(LOperand* value) {
662  inputs_[0] = value;
663  }
664 
665  DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch, "is-nil-and-branch")
666  DECLARE_HYDROGEN_ACCESSOR(IsNilAndBranch)
667 
668  EqualityKind kind() const { return hydrogen()->kind(); }
669  NilValue nil() const { return hydrogen()->nil(); }
670 
671  virtual void PrintDataTo(StringStream* stream);
672 };
673 
674 
675 class LIsObjectAndBranch: public LControlInstruction<1, 1> {
676  public:
678  inputs_[0] = value;
679  temps_[0] = temp;
680  }
681 
682  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
683  DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
684 
685  virtual void PrintDataTo(StringStream* stream);
686 };
687 
688 
689 class LIsStringAndBranch: public LControlInstruction<1, 1> {
690  public:
692  inputs_[0] = value;
693  temps_[0] = temp;
694  }
695 
696  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
697  DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
698 
699  virtual void PrintDataTo(StringStream* stream);
700 };
701 
702 
703 class LIsSmiAndBranch: public LControlInstruction<1, 0> {
704  public:
705  explicit LIsSmiAndBranch(LOperand* value) {
706  inputs_[0] = value;
707  }
708 
709  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
710  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
711 
712  virtual void PrintDataTo(StringStream* stream);
713 };
714 
715 
716 class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
717  public:
718  explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
719  inputs_[0] = value;
720  temps_[0] = temp;
721  }
722 
723  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
724  "is-undetectable-and-branch")
725  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
726 
727  virtual void PrintDataTo(StringStream* stream);
728 };
729 
730 
731 class LStringCompareAndBranch: public LControlInstruction<2, 0> {
732  public:
734  inputs_[0] = left;
735  inputs_[1] = right;
736  }
737 
738  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
739  "string-compare-and-branch")
740  DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
741 
742  Token::Value op() const { return hydrogen()->token(); }
743 
744  virtual void PrintDataTo(StringStream* stream);
745 };
746 
747 
748 class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
749  public:
751  inputs_[0] = value;
752  }
753 
754  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
755  "has-instance-type-and-branch")
756  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
757 
758  virtual void PrintDataTo(StringStream* stream);
759 };
760 
761 
762 class LGetCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
763  public:
764  explicit LGetCachedArrayIndex(LOperand* value) {
765  inputs_[0] = value;
766  }
767 
768  DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
769  DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
770 };
771 
772 
773 class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
774  public:
776  inputs_[0] = value;
777  }
778 
779  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
780  "has-cached-array-index-and-branch")
781  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
782 
783  virtual void PrintDataTo(StringStream* stream);
784 };
785 
786 
787 class LClassOfTestAndBranch: public LControlInstruction<1, 1> {
788  public:
790  inputs_[0] = value;
791  temps_[0] = temp;
792  }
793 
794  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
795  "class-of-test-and-branch")
796  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
797 
798  virtual void PrintDataTo(StringStream* stream);
799 };
800 
801 
802 class LCmpT: public LTemplateInstruction<1, 2, 0> {
803  public:
804  LCmpT(LOperand* left, LOperand* right) {
805  inputs_[0] = left;
806  inputs_[1] = right;
807  }
808 
809  DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
810  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
811 
812  Token::Value op() const { return hydrogen()->token(); }
813 };
814 
815 
816 class LInstanceOf: public LTemplateInstruction<1, 2, 0> {
817  public:
818  LInstanceOf(LOperand* left, LOperand* right) {
819  inputs_[0] = left;
820  inputs_[1] = right;
821  }
822 
823  DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
824 };
825 
826 
827 class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
828  public:
830  inputs_[0] = value;
831  temps_[0] = temp;
832  }
833 
834  DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
835  "instance-of-known-global")
836  DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
837 
838  Handle<JSFunction> function() const { return hydrogen()->function(); }
840  return lazy_deopt_env_;
841  }
843  lazy_deopt_env_ = env;
844  }
845 
846  private:
847  LEnvironment* lazy_deopt_env_;
848 };
849 
850 
851 class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
852  public:
853  LBoundsCheck(LOperand* index, LOperand* length) {
854  inputs_[0] = index;
855  inputs_[1] = length;
856  }
857 
858  LOperand* index() { return inputs_[0]; }
859  LOperand* length() { return inputs_[1]; }
860 
861  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
862 };
863 
864 
865 class LBitI: public LTemplateInstruction<1, 2, 0> {
866  public:
867  LBitI(LOperand* left, LOperand* right) {
868  inputs_[0] = left;
869  inputs_[1] = right;
870  }
871 
872  Token::Value op() const { return hydrogen()->op(); }
873 
874  DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
876 };
877 
878 
879 class LShiftI: public LTemplateInstruction<1, 2, 0> {
880  public:
881  LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
882  : op_(op), can_deopt_(can_deopt) {
883  inputs_[0] = left;
884  inputs_[1] = right;
885  }
886 
887  Token::Value op() const { return op_; }
888 
889  bool can_deopt() const { return can_deopt_; }
890 
891  DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
892 
893  private:
894  Token::Value op_;
895  bool can_deopt_;
896 };
897 
898 
899 class LSubI: public LTemplateInstruction<1, 2, 0> {
900  public:
901  LSubI(LOperand* left, LOperand* right) {
902  inputs_[0] = left;
903  inputs_[1] = right;
904  }
905 
906  DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
908 };
909 
910 
911 class LConstantI: public LTemplateInstruction<1, 0, 0> {
912  public:
913  DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
914  DECLARE_HYDROGEN_ACCESSOR(Constant)
915 
916  int32_t value() const { return hydrogen()->Integer32Value(); }
917 };
918 
919 
920 class LConstantD: public LTemplateInstruction<1, 0, 0> {
921  public:
922  DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
923  DECLARE_HYDROGEN_ACCESSOR(Constant)
924 
925  double value() const { return hydrogen()->DoubleValue(); }
926 };
927 
928 
929 class LConstantT: public LTemplateInstruction<1, 0, 0> {
930  public:
931  DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
932  DECLARE_HYDROGEN_ACCESSOR(Constant)
933 
934  Handle<Object> value() const { return hydrogen()->handle(); }
935 };
936 
937 
938 class LBranch: public LControlInstruction<1, 0> {
939  public:
940  explicit LBranch(LOperand* value) {
941  inputs_[0] = value;
942  }
943 
944  DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
946 
947  virtual void PrintDataTo(StringStream* stream);
948 };
949 
950 
951 class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> {
952  public:
954  inputs_[0] = value;
955  temps_[0] = temp;
956  }
957 
958  DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
959  DECLARE_HYDROGEN_ACCESSOR(CompareMap)
960 
961  virtual bool IsControl() const { return true; }
962 
963  Handle<Map> map() const { return hydrogen()->map(); }
964  int true_block_id() const {
965  return hydrogen()->FirstSuccessor()->block_id();
966  }
967  int false_block_id() const {
968  return hydrogen()->SecondSuccessor()->block_id();
969  }
970 };
971 
972 
973 class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
974  public:
975  explicit LJSArrayLength(LOperand* value) {
976  inputs_[0] = value;
977  }
978 
979  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
980  DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
981 };
982 
983 
984 class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
985  public:
986  explicit LFixedArrayBaseLength(LOperand* value) {
987  inputs_[0] = value;
988  }
989 
990  DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength,
991  "fixed-array-base-length")
992  DECLARE_HYDROGEN_ACCESSOR(FixedArrayBaseLength)
993 };
994 
995 
996 class LElementsKind: public LTemplateInstruction<1, 1, 0> {
997  public:
998  explicit LElementsKind(LOperand* value) {
999  inputs_[0] = value;
1000  }
1001 
1002  DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
1004 };
1005 
1006 
1007 class LValueOf: public LTemplateInstruction<1, 1, 1> {
1008  public:
1009  LValueOf(LOperand* value, LOperand* temp) {
1010  inputs_[0] = value;
1011  temps_[0] = temp;
1012  }
1013 
1014  DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1015  DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1016 };
1017 
1018 
1019 class LDateField: public LTemplateInstruction<1, 1, 1> {
1020  public:
1021  LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
1022  inputs_[0] = date;
1023  temps_[0] = temp;
1024  }
1025 
1026  DECLARE_CONCRETE_INSTRUCTION(ValueOf, "date-field")
1027  DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1028  Smi* index() const { return index_; }
1029 
1030  private:
1031  Smi* index_;
1032 };
1033 
1034 
1035 class LSetDateField: public LTemplateInstruction<1, 2, 1> {
1036  public:
1037  LSetDateField(LOperand* date, LOperand* value, LOperand* temp, int index)
1038  : index_(index) {
1039  inputs_[0] = date;
1040  inputs_[1] = value;
1041  temps_[0] = temp;
1042  }
1043 
1044  DECLARE_CONCRETE_INSTRUCTION(DateField, "date-set-field")
1045  DECLARE_HYDROGEN_ACCESSOR(DateField)
1046 
1047  int index() const { return index_; }
1048 
1049  private:
1050  int index_;
1051 };
1052 
1053 
1054 class LThrow: public LTemplateInstruction<0, 1, 0> {
1055  public:
1056  explicit LThrow(LOperand* value) {
1057  inputs_[0] = value;
1058  }
1059 
1061 };
1062 
1063 
1064 class LBitNotI: public LTemplateInstruction<1, 1, 0> {
1065  public:
1066  explicit LBitNotI(LOperand* value) {
1067  inputs_[0] = value;
1068  }
1069 
1070  DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
1071 };
1072 
1073 
1074 class LAddI: public LTemplateInstruction<1, 2, 0> {
1075  public:
1076  LAddI(LOperand* left, LOperand* right) {
1077  inputs_[0] = left;
1078  inputs_[1] = right;
1079  }
1080 
1081  DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1083 };
1084 
1085 
1086 class LPower: public LTemplateInstruction<1, 2, 0> {
1087  public:
1088  LPower(LOperand* left, LOperand* right) {
1089  inputs_[0] = left;
1090  inputs_[1] = right;
1091  }
1092 
1093  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1095 };
1096 
1097 
1098 class LRandom: public LTemplateInstruction<1, 1, 0> {
1099  public:
1100  explicit LRandom(LOperand* global_object) {
1101  inputs_[0] = global_object;
1102  }
1103 
1104  DECLARE_CONCRETE_INSTRUCTION(Random, "random")
1106 };
1107 
1108 
1109 class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
1110  public:
1112  : op_(op) {
1113  inputs_[0] = left;
1114  inputs_[1] = right;
1115  }
1116 
1117  Token::Value op() const { return op_; }
1118 
1119  virtual Opcode opcode() const { return LInstruction::kArithmeticD; }
1120  virtual void CompileToNative(LCodeGen* generator);
1121  virtual const char* Mnemonic() const;
1122 
1123  private:
1124  Token::Value op_;
1125 };
1126 
1127 
1128 class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
1129  public:
1131  : op_(op) {
1132  inputs_[0] = left;
1133  inputs_[1] = right;
1134  }
1135 
1136  virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
1137  virtual void CompileToNative(LCodeGen* generator);
1138  virtual const char* Mnemonic() const;
1139 
1140  Token::Value op() const { return op_; }
1141 
1142  private:
1143  Token::Value op_;
1144 };
1145 
1146 
1147 class LReturn: public LTemplateInstruction<0, 1, 0> {
1148  public:
1149  explicit LReturn(LOperand* value) {
1150  inputs_[0] = value;
1151  }
1152 
1153  DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1154 };
1155 
1156 
1157 class LLoadNamedField: public LTemplateInstruction<1, 1, 0> {
1158  public:
1159  explicit LLoadNamedField(LOperand* object) {
1160  inputs_[0] = object;
1161  }
1162 
1163  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1164  DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1165 };
1166 
1167 
1168 class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
1169  public:
1171  inputs_[0] = object;
1172  }
1173 
1174  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
1175  DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
1176 
1177  LOperand* object() { return inputs_[0]; }
1178 };
1179 
1180 
1181 class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
1182  public:
1183  explicit LLoadNamedGeneric(LOperand* object) {
1184  inputs_[0] = object;
1185  }
1186 
1187  DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1188  DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1189 
1190  LOperand* object() { return inputs_[0]; }
1191  Handle<Object> name() const { return hydrogen()->name(); }
1192 };
1193 
1194 
1195 class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> {
1196  public:
1197  explicit LLoadFunctionPrototype(LOperand* function) {
1198  inputs_[0] = function;
1199  }
1200 
1201  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1202  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1203 
1204  LOperand* function() { return inputs_[0]; }
1205 };
1206 
1207 
1208 class LLoadElements: public LTemplateInstruction<1, 1, 0> {
1209  public:
1210  explicit LLoadElements(LOperand* object) {
1211  inputs_[0] = object;
1212  }
1213 
1214  DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
1215 };
1216 
1217 
1218 class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> {
1219  public:
1221  inputs_[0] = object;
1222  }
1223 
1224  DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1225  "load-external-array-pointer")
1226 };
1227 
1228 
1229 class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
1230  public:
1232  inputs_[0] = elements;
1233  inputs_[1] = key;
1234  }
1235 
1236  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
1237  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
1238 
1239  LOperand* elements() { return inputs_[0]; }
1240  LOperand* key() { return inputs_[1]; }
1241  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1242 };
1243 
1244 
1245 class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
1246  public:
1248  inputs_[0] = elements;
1249  inputs_[1] = key;
1250  }
1251 
1252  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,
1253  "load-keyed-fast-double-element")
1254  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastDoubleElement)
1255 
1256  LOperand* elements() { return inputs_[0]; }
1257  LOperand* key() { return inputs_[1]; }
1258  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1259 };
1260 
1261 
1262 class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
1263  public:
1265  inputs_[0] = external_pointer;
1266  inputs_[1] = key;
1267  }
1268 
1269  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
1270  "load-keyed-specialized-array-element")
1271  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
1272 
1273  LOperand* external_pointer() { return inputs_[0]; }
1274  LOperand* key() { return inputs_[1]; }
1275  ElementsKind elements_kind() const {
1276  return hydrogen()->elements_kind();
1277  }
1278  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1279 };
1280 
1281 
1282 class LLoadKeyedGeneric: public LTemplateInstruction<1, 2, 0> {
1283  public:
1285  inputs_[0] = obj;
1286  inputs_[1] = key;
1287  }
1288 
1289  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1290 
1291  LOperand* object() { return inputs_[0]; }
1292  LOperand* key() { return inputs_[1]; }
1293 };
1294 
1295 
1296 class LLoadGlobalCell: public LTemplateInstruction<1, 0, 0> {
1297  public:
1298  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
1299  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
1300 };
1301 
1302 
1303 class LLoadGlobalGeneric: public LTemplateInstruction<1, 1, 0> {
1304  public:
1305  explicit LLoadGlobalGeneric(LOperand* global_object) {
1306  inputs_[0] = global_object;
1307  }
1308 
1309  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
1310  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
1311 
1312  LOperand* global_object() { return inputs_[0]; }
1313  Handle<Object> name() const { return hydrogen()->name(); }
1314  bool for_typeof() const { return hydrogen()->for_typeof(); }
1315 };
1316 
1317 
1318 class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
1319  public:
1321  inputs_[0] = value;
1322  temps_[0] = temp;
1323  }
1324 
1325  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
1326  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
1327 
1328  LOperand* value() { return inputs_[0]; }
1329 };
1330 
1331 
1332 class LStoreGlobalGeneric: public LTemplateInstruction<0, 2, 0> {
1333  public:
1334  explicit LStoreGlobalGeneric(LOperand* global_object,
1335  LOperand* value) {
1336  inputs_[0] = global_object;
1337  inputs_[1] = value;
1338  }
1339 
1340  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
1341  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
1342 
1343  LOperand* global_object() { return InputAt(0); }
1344  Handle<Object> name() const { return hydrogen()->name(); }
1345  LOperand* value() { return InputAt(1); }
1346  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
1347 };
1348 
1349 
1350 class LLoadContextSlot: public LTemplateInstruction<1, 1, 0> {
1351  public:
1352  explicit LLoadContextSlot(LOperand* context) {
1353  inputs_[0] = context;
1354  }
1355 
1356  DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1357  DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1358 
1359  LOperand* context() { return InputAt(0); }
1360  int slot_index() { return hydrogen()->slot_index(); }
1361 
1362  virtual void PrintDataTo(StringStream* stream);
1363 };
1364 
1365 
1366 class LStoreContextSlot: public LTemplateInstruction<0, 2, 0> {
1367  public:
1369  inputs_[0] = context;
1370  inputs_[1] = value;
1371  }
1372 
1373  DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
1374  DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
1375 
1376  LOperand* context() { return InputAt(0); }
1377  LOperand* value() { return InputAt(1); }
1378  int slot_index() { return hydrogen()->slot_index(); }
1379 
1380  virtual void PrintDataTo(StringStream* stream);
1381 };
1382 
1383 
1384 class LPushArgument: public LTemplateInstruction<0, 1, 0> {
1385  public:
1386  explicit LPushArgument(LOperand* value) {
1387  inputs_[0] = value;
1388  }
1389 
1390  DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1391 };
1392 
1393 
1394 class LDrop: public LTemplateInstruction<0, 0, 0> {
1395  public:
1396  explicit LDrop(int count) : count_(count) { }
1397 
1398  int count() const { return count_; }
1399 
1400  DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
1401 
1402  private:
1403  int count_;
1404 };
1405 
1406 
1407 class LThisFunction: public LTemplateInstruction<1, 0, 0> {
1408  public:
1409  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
1411 };
1412 
1413 
1414 class LContext: public LTemplateInstruction<1, 0, 0> {
1415  public:
1417 };
1418 
1419 
1420 class LOuterContext: public LTemplateInstruction<1, 1, 0> {
1421  public:
1422  explicit LOuterContext(LOperand* context) {
1423  inputs_[0] = context;
1424  }
1425 
1426  DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
1427 
1428  LOperand* context() { return InputAt(0); }
1429 };
1430 
1431 
1432 class LDeclareGlobals: public LTemplateInstruction<0, 0, 0> {
1433  public:
1434  DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
1435  DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
1436 };
1437 
1438 
1439 class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
1440  public:
1441  explicit LGlobalObject(LOperand* context) {
1442  inputs_[0] = context;
1443  }
1444 
1445  DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1446 
1447  LOperand* context() { return InputAt(0); }
1448 };
1449 
1450 
1451 class LGlobalReceiver: public LTemplateInstruction<1, 1, 0> {
1452  public:
1453  explicit LGlobalReceiver(LOperand* global_object) {
1454  inputs_[0] = global_object;
1455  }
1456 
1457  DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
1458 
1459  LOperand* global() { return InputAt(0); }
1460 };
1461 
1462 
1463 class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> {
1464  public:
1465  DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
1466  DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
1467 
1468  virtual void PrintDataTo(StringStream* stream);
1469 
1470  Handle<JSFunction> function() { return hydrogen()->function(); }
1471  int arity() const { return hydrogen()->argument_count() - 1; }
1472 };
1473 
1474 
1475 class LInvokeFunction: public LTemplateInstruction<1, 1, 0> {
1476  public:
1477  explicit LInvokeFunction(LOperand* function) {
1478  inputs_[0] = function;
1479  }
1480 
1481  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
1482  DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
1483 
1484  LOperand* function() { return inputs_[0]; }
1485 
1486  virtual void PrintDataTo(StringStream* stream);
1487 
1488  int arity() const { return hydrogen()->argument_count() - 1; }
1489  Handle<JSFunction> known_function() { return hydrogen()->known_function(); }
1490 };
1491 
1492 
1493 class LCallKeyed: public LTemplateInstruction<1, 1, 0> {
1494  public:
1495  explicit LCallKeyed(LOperand* key) {
1496  inputs_[0] = key;
1497  }
1498 
1499  DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
1500  DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
1501 
1502  virtual void PrintDataTo(StringStream* stream);
1503 
1504  int arity() const { return hydrogen()->argument_count() - 1; }
1505 };
1506 
1507 
1508 
1509 class LCallNamed: public LTemplateInstruction<1, 0, 0> {
1510  public:
1511  DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
1512  DECLARE_HYDROGEN_ACCESSOR(CallNamed)
1513 
1514  virtual void PrintDataTo(StringStream* stream);
1515 
1516  Handle<String> name() const { return hydrogen()->name(); }
1517  int arity() const { return hydrogen()->argument_count() - 1; }
1518 };
1519 
1520 
1521 class LCallFunction: public LTemplateInstruction<1, 1, 0> {
1522  public:
1523  explicit LCallFunction(LOperand* function) {
1524  inputs_[0] = function;
1525  }
1526 
1527  DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1528  DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1529 
1530  LOperand* function() { return inputs_[0]; }
1531  int arity() const { return hydrogen()->argument_count() - 1; }
1532 };
1533 
1534 
1535 class LCallGlobal: public LTemplateInstruction<1, 0, 0> {
1536  public:
1537  DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
1538  DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
1539 
1540  virtual void PrintDataTo(StringStream* stream);
1541 
1542  Handle<String> name() const {return hydrogen()->name(); }
1543  int arity() const { return hydrogen()->argument_count() - 1; }
1544 };
1545 
1546 
1547 class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> {
1548  public:
1549  DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
1550  DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
1551 
1552  virtual void PrintDataTo(StringStream* stream);
1553 
1554  Handle<JSFunction> target() const { return hydrogen()->target(); }
1555  int arity() const { return hydrogen()->argument_count() - 1; }
1556 };
1557 
1558 
1559 class LCallNew: public LTemplateInstruction<1, 1, 0> {
1560  public:
1561  explicit LCallNew(LOperand* constructor) {
1562  inputs_[0] = constructor;
1563  }
1564 
1567 
1568  virtual void PrintDataTo(StringStream* stream);
1569 
1570  int arity() const { return hydrogen()->argument_count() - 1; }
1571 };
1572 
1573 
1574 class LCallRuntime: public LTemplateInstruction<1, 0, 0> {
1575  public:
1576  DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1578 
1579  const Runtime::Function* function() const { return hydrogen()->function(); }
1580  int arity() const { return hydrogen()->argument_count(); }
1581 };
1582 
1583 
1584 class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
1585  public:
1586  explicit LInteger32ToDouble(LOperand* value) {
1587  inputs_[0] = value;
1588  }
1589 
1590  DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1591 };
1592 
1593 
1594 class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
1595  public:
1596  explicit LNumberTagI(LOperand* value) {
1597  inputs_[0] = value;
1598  }
1599 
1600  DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
1601 };
1602 
1603 
1604 class LNumberTagD: public LTemplateInstruction<1, 1, 2> {
1605  public:
1606  LNumberTagD(LOperand* value, LOperand* temp1, LOperand* temp2) {
1607  inputs_[0] = value;
1608  temps_[0] = temp1;
1609  temps_[1] = temp2;
1610  }
1611 
1612  DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
1613 };
1614 
1615 
1616 // Sometimes truncating conversion from a tagged value to an int32.
1617 class LDoubleToI: public LTemplateInstruction<1, 1, 2> {
1618  public:
1619  LDoubleToI(LOperand* value, LOperand* temp1, LOperand* temp2) {
1620  inputs_[0] = value;
1621  temps_[0] = temp1;
1622  temps_[1] = temp2;
1623  }
1624 
1625  DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
1627 
1628  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1629 };
1630 
1631 
1632 // Truncating conversion from a tagged value to an int32.
1633 class LTaggedToI: public LTemplateInstruction<1, 1, 3> {
1634  public:
1636  LOperand* temp1,
1637  LOperand* temp2,
1638  LOperand* temp3) {
1639  inputs_[0] = value;
1640  temps_[0] = temp1;
1641  temps_[1] = temp2;
1642  temps_[2] = temp3;
1643  }
1644 
1645  DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
1647 
1648  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1649 };
1650 
1651 
1652 class LSmiTag: public LTemplateInstruction<1, 1, 0> {
1653  public:
1654  explicit LSmiTag(LOperand* value) {
1655  inputs_[0] = value;
1656  }
1657 
1658  DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
1659 };
1660 
1661 
1662 class LNumberUntagD: public LTemplateInstruction<1, 1, 0> {
1663  public:
1664  explicit LNumberUntagD(LOperand* value) {
1665  inputs_[0] = value;
1666  }
1667 
1668  DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
1670 };
1671 
1672 
1673 class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
1674  public:
1675  LSmiUntag(LOperand* value, bool needs_check)
1676  : needs_check_(needs_check) {
1677  inputs_[0] = value;
1678  }
1679 
1680  DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
1681 
1682  bool needs_check() const { return needs_check_; }
1683 
1684  private:
1685  bool needs_check_;
1686 };
1687 
1688 
1689 class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
1690  public:
1692  inputs_[0] = obj;
1693  inputs_[1] = val;
1694  temps_[0] = temp;
1695  }
1696 
1697  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
1698  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
1699 
1700  virtual void PrintDataTo(StringStream* stream);
1701 
1702  LOperand* object() { return inputs_[0]; }
1703  LOperand* value() { return inputs_[1]; }
1704 
1705  Handle<Object> name() const { return hydrogen()->name(); }
1706  bool is_in_object() { return hydrogen()->is_in_object(); }
1707  int offset() { return hydrogen()->offset(); }
1708  Handle<Map> transition() const { return hydrogen()->transition(); }
1709 };
1710 
1711 
1712 class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
1713  public:
1715  inputs_[0] = obj;
1716  inputs_[1] = val;
1717  }
1718 
1719  DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
1720  DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
1721 
1722  virtual void PrintDataTo(StringStream* stream);
1723 
1724  LOperand* object() { return inputs_[0]; }
1725  LOperand* value() { return inputs_[1]; }
1726  Handle<Object> name() const { return hydrogen()->name(); }
1727  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
1728 };
1729 
1730 
1731 class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
1732  public:
1734  inputs_[0] = obj;
1735  inputs_[1] = key;
1736  inputs_[2] = val;
1737  }
1738 
1739  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
1740  "store-keyed-fast-element")
1741  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
1742 
1743  virtual void PrintDataTo(StringStream* stream);
1744 
1745  LOperand* object() { return inputs_[0]; }
1746  LOperand* key() { return inputs_[1]; }
1747  LOperand* value() { return inputs_[2]; }
1748  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1749 };
1750 
1751 
1752 class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
1753  public:
1755  LOperand* key,
1756  LOperand* val) {
1757  inputs_[0] = elements;
1758  inputs_[1] = key;
1759  inputs_[2] = val;
1760  }
1761 
1762  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement,
1763  "store-keyed-fast-double-element")
1764  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastDoubleElement)
1765 
1766  virtual void PrintDataTo(StringStream* stream);
1767 
1768  LOperand* elements() { return inputs_[0]; }
1769  LOperand* key() { return inputs_[1]; }
1770  LOperand* value() { return inputs_[2]; }
1771  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1772 
1773  bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
1774 };
1775 
1776 
1777 class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> {
1778  public:
1780  inputs_[0] = obj;
1781  inputs_[1] = key;
1782  inputs_[2] = val;
1783  }
1784 
1785  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
1786  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
1787 
1788  virtual void PrintDataTo(StringStream* stream);
1789 
1790  LOperand* object() { return inputs_[0]; }
1791  LOperand* key() { return inputs_[1]; }
1792  LOperand* value() { return inputs_[2]; }
1793  StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
1794 };
1795 
1796 class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
1797  public:
1799  LOperand* key,
1800  LOperand* val) {
1801  inputs_[0] = external_pointer;
1802  inputs_[1] = key;
1803  inputs_[2] = val;
1804  }
1805 
1806  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
1807  "store-keyed-specialized-array-element")
1808  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
1809 
1810  LOperand* external_pointer() { return inputs_[0]; }
1811  LOperand* key() { return inputs_[1]; }
1812  LOperand* value() { return inputs_[2]; }
1813  ElementsKind elements_kind() const {
1814  return hydrogen()->elements_kind();
1815  }
1816  uint32_t additional_index() const { return hydrogen()->index_offset(); }
1817 };
1818 
1819 
1820 class LTransitionElementsKind: public LTemplateInstruction<1, 1, 2> {
1821  public:
1823  LOperand* new_map_temp,
1824  LOperand* temp_reg) {
1825  inputs_[0] = object;
1826  temps_[0] = new_map_temp;
1827  temps_[1] = temp_reg;
1828  }
1829 
1830  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
1831  "transition-elements-kind")
1832  DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
1833 
1834  virtual void PrintDataTo(StringStream* stream);
1835 
1836  LOperand* object() { return inputs_[0]; }
1837  LOperand* new_map_reg() { return temps_[0]; }
1838  LOperand* temp_reg() { return temps_[1]; }
1839  Handle<Map> original_map() { return hydrogen()->original_map(); }
1840  Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); }
1841 };
1842 
1843 
1844 class LStringAdd: public LTemplateInstruction<1, 2, 0> {
1845  public:
1846  LStringAdd(LOperand* left, LOperand* right) {
1847  inputs_[0] = left;
1848  inputs_[1] = right;
1849  }
1850 
1851  DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
1852  DECLARE_HYDROGEN_ACCESSOR(StringAdd)
1853 
1854  LOperand* left() { return inputs_[0]; }
1855  LOperand* right() { return inputs_[1]; }
1856 };
1857 
1858 
1859 
1860 class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
1861  public:
1863  inputs_[0] = string;
1864  inputs_[1] = index;
1865  }
1866 
1867  DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
1868  DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
1869 
1870  LOperand* string() { return inputs_[0]; }
1871  LOperand* index() { return inputs_[1]; }
1872 };
1873 
1874 
1875 class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> {
1876  public:
1877  explicit LStringCharFromCode(LOperand* char_code) {
1878  inputs_[0] = char_code;
1879  }
1880 
1881  DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
1882  DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
1883 
1884  LOperand* char_code() { return inputs_[0]; }
1885 };
1886 
1887 
1888 class LStringLength: public LTemplateInstruction<1, 1, 0> {
1889  public:
1890  explicit LStringLength(LOperand* string) {
1891  inputs_[0] = string;
1892  }
1893 
1894  DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
1895  DECLARE_HYDROGEN_ACCESSOR(StringLength)
1896 
1897  LOperand* string() { return inputs_[0]; }
1898 };
1899 
1900 
1901 class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
1902  public:
1903  explicit LCheckFunction(LOperand* value) {
1904  inputs_[0] = value;
1905  }
1906 
1907  LOperand* value() { return InputAt(0); }
1908 
1909  DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
1910  DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
1911 };
1912 
1913 
1914 class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> {
1915  public:
1916  explicit LCheckInstanceType(LOperand* value) {
1917  inputs_[0] = value;
1918  }
1919 
1920  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
1921  DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
1922 };
1923 
1924 
1925 class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
1926  public:
1927  explicit LCheckMaps(LOperand* value) {
1928  inputs_[0] = value;
1929  }
1930 
1931  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
1932  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
1933 };
1934 
1935 
1936 class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 2> {
1937  public:
1939  temps_[0] = temp1;
1940  temps_[1] = temp2;
1941  }
1942 
1943  DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
1944  DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
1945 
1946  Handle<JSObject> prototype() const { return hydrogen()->prototype(); }
1947  Handle<JSObject> holder() const { return hydrogen()->holder(); }
1948 };
1949 
1950 
1951 class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
1952  public:
1953  explicit LCheckSmi(LOperand* value) {
1954  inputs_[0] = value;
1955  }
1956 
1957  DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
1958 };
1959 
1960 
1961 class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> {
1962  public:
1963  explicit LCheckNonSmi(LOperand* value) {
1964  inputs_[0] = value;
1965  }
1966 
1967  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
1968 };
1969 
1970 
1971 class LClampDToUint8: public LTemplateInstruction<1, 1, 1> {
1972  public:
1974  inputs_[0] = value;
1975  temps_[0] = temp;
1976  }
1977 
1978  LOperand* unclamped() { return inputs_[0]; }
1979 
1980  DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
1981 };
1982 
1983 
1984 class LClampIToUint8: public LTemplateInstruction<1, 1, 0> {
1985  public:
1986  explicit LClampIToUint8(LOperand* value) {
1987  inputs_[0] = value;
1988  }
1989 
1990  LOperand* unclamped() { return inputs_[0]; }
1991 
1992  DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
1993 };
1994 
1995 
1996 class LClampTToUint8: public LTemplateInstruction<1, 1, 1> {
1997  public:
1999  inputs_[0] = value;
2000  temps_[0] = temp;
2001  }
2002 
2003  LOperand* unclamped() { return inputs_[0]; }
2004 
2005  DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
2006 };
2007 
2008 
2009 class LAllocateObject: public LTemplateInstruction<1, 0, 2> {
2010  public:
2012  temps_[0] = temp1;
2013  temps_[1] = temp2;
2014  }
2015 
2016  DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
2017  DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
2018 };
2019 
2020 
2021 class LFastLiteral: public LTemplateInstruction<1, 0, 0> {
2022  public:
2023  DECLARE_CONCRETE_INSTRUCTION(FastLiteral, "fast-literal")
2024  DECLARE_HYDROGEN_ACCESSOR(FastLiteral)
2025 };
2026 
2027 
2028 class LArrayLiteral: public LTemplateInstruction<1, 0, 0> {
2029  public:
2030  DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
2032 };
2033 
2034 
2035 class LObjectLiteral: public LTemplateInstruction<1, 0, 0> {
2036  public:
2037  DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
2039 };
2040 
2041 
2042 class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> {
2043  public:
2044  DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
2046 };
2047 
2048 
2049 class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> {
2050  public:
2051  DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
2053 
2054  Handle<SharedFunctionInfo> shared_info() { return hydrogen()->shared_info(); }
2055 };
2056 
2057 
2058 class LToFastProperties: public LTemplateInstruction<1, 1, 0> {
2059  public:
2060  explicit LToFastProperties(LOperand* value) {
2061  inputs_[0] = value;
2062  }
2063 
2064  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
2065  DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
2066 };
2067 
2068 
2069 class LTypeof: public LTemplateInstruction<1, 1, 0> {
2070  public:
2071  explicit LTypeof(LOperand* value) {
2072  inputs_[0] = value;
2073  }
2074 
2075  DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
2076 };
2077 
2078 
2079 class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
2080  public:
2081  explicit LTypeofIsAndBranch(LOperand* value) {
2082  inputs_[0] = value;
2083  }
2084 
2085  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
2086  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
2087 
2088  Handle<String> type_literal() { return hydrogen()->type_literal(); }
2089 
2090  virtual void PrintDataTo(StringStream* stream);
2091 };
2092 
2093 
2094 class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
2095  public:
2097  temps_[0] = temp;
2098  }
2099 
2100  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
2101  "is-construct-call-and-branch")
2102 };
2103 
2104 
2105 class LDeleteProperty: public LTemplateInstruction<1, 2, 0> {
2106  public:
2108  inputs_[0] = obj;
2109  inputs_[1] = key;
2110  }
2111 
2112  DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
2113 
2114  LOperand* object() { return inputs_[0]; }
2115  LOperand* key() { return inputs_[1]; }
2116 };
2117 
2118 
2119 class LOsrEntry: public LTemplateInstruction<0, 0, 0> {
2120  public:
2121  LOsrEntry();
2122 
2123  DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
2124 
2125  LOperand** SpilledRegisterArray() { return register_spills_; }
2126  LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; }
2127 
2128  void MarkSpilledRegister(int allocation_index, LOperand* spill_operand);
2129  void MarkSpilledDoubleRegister(int allocation_index,
2130  LOperand* spill_operand);
2131 
2132  private:
2133  // Arrays of spill slot operands for registers with an assigned spill
2134  // slot, i.e., that must also be restored to the spill slot on OSR entry.
2135  // NULL if the register has no assigned spill slot. Indexed by allocation
2136  // index.
2137  LOperand* register_spills_[Register::kNumAllocatableRegisters];
2138  LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters];
2139 };
2140 
2141 
2142 class LStackCheck: public LTemplateInstruction<0, 0, 0> {
2143  public:
2144  DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
2145  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
2146 
2147  Label* done_label() { return &done_label_; }
2148 
2149  private:
2150  Label done_label_;
2151 };
2152 
2153 
2154 class LIn: public LTemplateInstruction<1, 2, 0> {
2155  public:
2156  LIn(LOperand* key, LOperand* object) {
2157  inputs_[0] = key;
2158  inputs_[1] = object;
2159  }
2160 
2161  LOperand* key() { return inputs_[0]; }
2162  LOperand* object() { return inputs_[1]; }
2163 
2165 };
2166 
2167 
2168 class LForInPrepareMap: public LTemplateInstruction<1, 1, 0> {
2169  public:
2170  explicit LForInPrepareMap(LOperand* object) {
2171  inputs_[0] = object;
2172  }
2173 
2174  LOperand* object() { return inputs_[0]; }
2175 
2176  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
2177 };
2178 
2179 
2180 class LForInCacheArray: public LTemplateInstruction<1, 1, 0> {
2181  public:
2182  explicit LForInCacheArray(LOperand* map) {
2183  inputs_[0] = map;
2184  }
2185 
2186  LOperand* map() { return inputs_[0]; }
2187 
2188  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
2189 
2190  int idx() {
2191  return HForInCacheArray::cast(this->hydrogen_value())->idx();
2192  }
2193 };
2194 
2195 
2196 class LCheckMapValue: public LTemplateInstruction<0, 2, 0> {
2197  public:
2199  inputs_[0] = value;
2200  inputs_[1] = map;
2201  }
2202 
2203  LOperand* value() { return inputs_[0]; }
2204  LOperand* map() { return inputs_[1]; }
2205 
2206  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
2207 };
2208 
2209 
2210 class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
2211  public:
2213  inputs_[0] = object;
2214  inputs_[1] = index;
2215  }
2216 
2217  LOperand* object() { return inputs_[0]; }
2218  LOperand* index() { return inputs_[1]; }
2219 
2220  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
2221 };
2222 
2223 
2224 class LChunkBuilder;
2225 class LChunk: public ZoneObject {
2226  public:
2227  explicit LChunk(CompilationInfo* info, HGraph* graph);
2228 
2229  void AddInstruction(LInstruction* instruction, HBasicBlock* block);
2230  LConstantOperand* DefineConstantOperand(HConstant* constant);
2231  Handle<Object> LookupLiteral(LConstantOperand* operand) const;
2232  Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
2233 
2234  int GetNextSpillIndex(bool is_double);
2235  LOperand* GetNextSpillSlot(bool is_double);
2236 
2237  int ParameterAt(int index);
2238  int GetParameterStackSlot(int index) const;
2239  int spill_slot_count() const { return spill_slot_count_; }
2240  CompilationInfo* info() const { return info_; }
2241  HGraph* graph() const { return graph_; }
2242  const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
2243  void AddGapMove(int index, LOperand* from, LOperand* to);
2244  LGap* GetGapAt(int index) const;
2245  bool IsGapAt(int index) const;
2246  int NearestGapPos(int index) const;
2247  void MarkEmptyBlocks();
2248  const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
2249  LLabel* GetLabel(int block_id) const {
2250  HBasicBlock* block = graph_->blocks()->at(block_id);
2251  int first_instruction = block->first_instruction_index();
2252  return LLabel::cast(instructions_[first_instruction]);
2253  }
2254  int LookupDestination(int block_id) const {
2255  LLabel* cur = GetLabel(block_id);
2256  while (cur->replacement() != NULL) {
2257  cur = cur->replacement();
2258  }
2259  return cur->block_id();
2260  }
2261  Label* GetAssemblyLabel(int block_id) const {
2262  LLabel* label = GetLabel(block_id);
2263  ASSERT(!label->HasReplacement());
2264  return label->label();
2265  }
2266 
2268  return &inlined_closures_;
2269  }
2270 
2272  inlined_closures_.Add(closure, zone());
2273  }
2274 
2275  Zone* zone() const { return graph_->zone(); }
2276 
2277  private:
2278  int spill_slot_count_;
2279  CompilationInfo* info_;
2280  HGraph* const graph_;
2281  ZoneList<LInstruction*> instructions_;
2282  ZoneList<LPointerMap*> pointer_maps_;
2283  ZoneList<Handle<JSFunction> > inlined_closures_;
2284 };
2285 
2286 
2287 class LChunkBuilder BASE_EMBEDDED {
2288  public:
2289  LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
2290  : chunk_(NULL),
2291  info_(info),
2292  graph_(graph),
2293  zone_(graph->zone()),
2294  status_(UNUSED),
2295  current_instruction_(NULL),
2296  current_block_(NULL),
2297  next_block_(NULL),
2298  argument_count_(0),
2299  allocator_(allocator),
2300  position_(RelocInfo::kNoPosition),
2301  instruction_pending_deoptimization_environment_(NULL),
2302  pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
2303 
2304  // Build the sequence for the graph.
2305  LChunk* Build();
2306 
2307  // Declare methods that deal with the individual node types.
2308 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2310 #undef DECLARE_DO
2311 
2312  static bool HasMagicNumberForDivisor(int32_t divisor);
2313  static HValue* SimplifiedDividendForMathFloorOfDiv(HValue* val);
2314  static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
2315 
2316  private:
2317  enum Status {
2318  UNUSED,
2319  BUILDING,
2320  DONE,
2321  ABORTED
2322  };
2323 
2324  LChunk* chunk() const { return chunk_; }
2325  CompilationInfo* info() const { return info_; }
2326  HGraph* graph() const { return graph_; }
2327  Zone* zone() const { return zone_; }
2328 
2329  bool is_unused() const { return status_ == UNUSED; }
2330  bool is_building() const { return status_ == BUILDING; }
2331  bool is_done() const { return status_ == DONE; }
2332  bool is_aborted() const { return status_ == ABORTED; }
2333 
2334  void Abort(const char* format, ...);
2335 
2336  // Methods for getting operands for Use / Define / Temp.
2337  LUnallocated* ToUnallocated(Register reg);
2338  LUnallocated* ToUnallocated(DoubleRegister reg);
2339 
2340  // Methods for setting up define-use relationships.
2341  MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
2342  MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
2343  MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
2344  DoubleRegister fixed_register);
2345 
2346  // A value that is guaranteed to be allocated to a register.
2347  // Operand created by UseRegister is guaranteed to be live until the end of
2348  // instruction. This means that register allocator will not reuse it's
2349  // register for any other operand inside instruction.
2350  // Operand created by UseRegisterAtStart is guaranteed to be live only at
2351  // instruction start. Register allocator is free to assign the same register
2352  // to some other operand used inside instruction (i.e. temporary or
2353  // output).
2354  MUST_USE_RESULT LOperand* UseRegister(HValue* value);
2355  MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
2356 
2357  // An input operand in a register that may be trashed.
2358  MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
2359 
2360  // An input operand in a register or stack slot.
2361  MUST_USE_RESULT LOperand* Use(HValue* value);
2362  MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
2363 
2364  // An input operand in a register, stack slot or a constant operand.
2365  MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
2366  MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
2367 
2368  // An input operand in a register or a constant operand.
2369  MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
2370  MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
2371 
2372  // An input operand in register, stack slot or a constant operand.
2373  // Will not be moved to a register even if one is freely available.
2374  MUST_USE_RESULT LOperand* UseAny(HValue* value);
2375 
2376  // Temporary operand that must be in a register.
2377  MUST_USE_RESULT LUnallocated* TempRegister();
2378  MUST_USE_RESULT LOperand* FixedTemp(Register reg);
2379  MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg);
2380 
2381  // Methods for setting up define-use relationships.
2382  // Return the same instruction that they are passed.
2383  template<int I, int T>
2384  LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
2385  LUnallocated* result);
2386  template<int I, int T>
2387  LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
2388  template<int I, int T>
2389  LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
2390  int index);
2391  template<int I, int T>
2392  LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
2393  template<int I, int T>
2394  LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
2395  Register reg);
2396  template<int I, int T>
2397  LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
2398  DoubleRegister reg);
2399  LInstruction* AssignEnvironment(LInstruction* instr);
2400  LInstruction* AssignPointerMap(LInstruction* instr);
2401 
2402  enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2403 
2404  // By default we assume that instruction sequences generated for calls
2405  // cannot deoptimize eagerly and we do not attach environment to this
2406  // instruction.
2408  LInstruction* instr,
2409  HInstruction* hinstr,
2410  CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2411 
2412  LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
2413  int* argument_index_accumulator);
2414 
2415  void VisitInstruction(HInstruction* current);
2416 
2417  void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2418  LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2419  LInstruction* DoArithmeticD(Token::Value op,
2420  HArithmeticBinaryOperation* instr);
2421  LInstruction* DoArithmeticT(Token::Value op,
2422  HArithmeticBinaryOperation* instr);
2423 
2424  LChunk* chunk_;
2425  CompilationInfo* info_;
2426  HGraph* const graph_;
2427  Zone* zone_;
2428  Status status_;
2429  HInstruction* current_instruction_;
2430  HBasicBlock* current_block_;
2431  HBasicBlock* next_block_;
2432  int argument_count_;
2433  LAllocator* allocator_;
2434  int position_;
2435  LInstruction* instruction_pending_deoptimization_environment_;
2436  int pending_deoptimization_ast_id_;
2437 
2438  DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2439 };
2440 
2441 #undef DECLARE_HYDROGEN_ACCESSOR
2442 #undef DECLARE_CONCRETE_INSTRUCTION
2443 
2444 } } // namespace v8::internal
2445 
2446 #endif // V8_ARM_LITHIUM_ARM_H_
LCmpT(LOperand *left, LOperand *right)
Definition: lithium-arm.h:804
LStringCharCodeAt(LOperand *string, LOperand *index)
Definition: lithium-arm.h:1862
LDateField(LOperand *date, LOperand *temp, Smi *index)
Definition: lithium-arm.h:1021
LArgumentsLength(LOperand *elements)
Definition: lithium-arm.h:515
LLoadContextSlot(LOperand *context)
Definition: lithium-arm.h:1352
LGlobalReceiver(LOperand *global_object)
Definition: lithium-arm.h:1453
static LGap * cast(LInstruction *instr)
Definition: lithium-arm.h:318
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment *env)
Definition: lithium-arm.h:250
LLoadFieldByIndex(LOperand *object, LOperand *index)
Definition: lithium-arm.h:2212
Handle< Object > name() const
Definition: lithium-arm.h:1344
LGetCachedArrayIndex(LOperand *value)
Definition: lithium-arm.h:764
LCallKeyed(LOperand *key)
Definition: lithium-arm.h:1495
void set_pointer_map(LPointerMap *p)
Definition: lithium-arm.h:243
LThrow(LOperand *value)
Definition: lithium-arm.h:1056
bool IsMarkedAsCall() const
Definition: lithium-arm.h:255
Handle< Object > name() const
Definition: lithium-arm.h:1726
virtual LOperand * InputAt(int i)=0
LStoreKeyedGeneric(LOperand *obj, LOperand *key, LOperand *val)
Definition: lithium-arm.h:1779
int count() const
Definition: lithium-arm.h:1398
LClassOfTestAndBranch(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:789
#define DECLARE_OPCODE(type)
Definition: lithium-arm.h:219
LClampDToUint8(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:1973
void set_environment(LEnvironment *env)
Definition: lithium-arm.h:239
void set_result(LOperand *operand)
Definition: lithium-arm.h:289
LReturn(LOperand *value)
Definition: lithium-arm.h:1149
virtual void PrintOutputOperandTo(StringStream *stream)
Definition: lithium-arm.cc:120
EmbeddedContainer< LOperand *, T > temps_
Definition: lithium-arm.h:301
LSmiTag(LOperand *value)
Definition: lithium-arm.h:1654
Definition: v8.h:863
Token::Value op() const
Definition: lithium-arm.h:1117
LWrapReceiver(LOperand *receiver, LOperand *function)
Definition: lithium-arm.h:462
LParallelMove * GetOrCreateParallelMove(InnerPosition pos, Zone *zone)
Definition: lithium-arm.h:336
LNumberTagI(LOperand *value)
Definition: lithium-arm.h:1596
LInstructionGap(HBasicBlock *block)
Definition: lithium-arm.h:355
LLoadGlobalGeneric(LOperand *global_object)
Definition: lithium-arm.h:1305
Handle< JSFunction > target() const
Definition: lithium-arm.h:1554
LCheckSmi(LOperand *value)
Definition: lithium-arm.h:1953
LLoadFunctionPrototype(LOperand *function)
Definition: lithium-arm.h:1197
LStringLength(LOperand *string)
Definition: lithium-arm.h:1890
LIsObjectAndBranch(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:677
Handle< Object > name() const
Definition: lithium-arm.h:1191
LUnaryMathOperation(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:621
#define DECLARE_DO(type)
Definition: lithium-arm.h:2308
LStoreNamedField(LOperand *obj, LOperand *val, LOperand *temp)
Definition: lithium-arm.h:1691
LLabel(HBasicBlock *block)
Definition: lithium-arm.h:400
LJSArrayLength(LOperand *value)
Definition: lithium-arm.h:975
Handle< String > name() const
Definition: lithium-arm.h:1542
LChunkBuilder(CompilationInfo *info, HGraph *graph, LAllocator *allocator)
Definition: lithium-arm.h:2289
int int32_t
Definition: unicode.cc:47
LMathFloorOfDiv(LOperand *left, LOperand *right, LOperand *temp=NULL)
Definition: lithium-arm.h:574
LOuterContext(LOperand *context)
Definition: lithium-arm.h:1422
static const int kNumAllocatableRegisters
Handle< Object > name() const
Definition: lithium-arm.h:1705
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)
Definition: lithium-arm.h:187
Handle< Map > transition() const
Definition: lithium-arm.h:1708
EqualityKind
Definition: v8.h:145
LEnvironment * environment() const
Definition: lithium-arm.h:240
LStoreContextSlot(LOperand *context, LOperand *value)
Definition: lithium-arm.h:1368
virtual HBasicBlock * SuccessorAt(int i)=0
LCheckNonSmi(LOperand *value)
Definition: lithium-arm.h:1963
#define ASSERT(condition)
Definition: checks.h:270
Token::Value op() const
Definition: lithium-arm.h:887
LBoundsCheck(LOperand *index, LOperand *length)
Definition: lithium-arm.h:853
LClampTToUint8(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:1998
virtual const char * Mnemonic() const =0
LFixedArrayBaseLength(LOperand *value)
Definition: lithium-arm.h:986
LCheckPrototypeMaps(LOperand *temp1, LOperand *temp2)
Definition: lithium-arm.h:1938
LAllocateObject(LOperand *temp1, LOperand *temp2)
Definition: lithium-arm.h:2011
LCheckInstanceType(LOperand *value)
Definition: lithium-arm.h:1916
virtual void PrintDataTo(StringStream *stream)
Definition: lithium-arm.cc:111
LInvokeFunction(LOperand *function)
Definition: lithium-arm.h:1477
Definition: lithium-arm.h:2119
#define DECLARE_HYDROGEN_ACCESSOR(type)
Definition: lithium-arm.h:197
#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
Definition: lithium-arm.h:49
LBranch(LOperand *value)
Definition: lithium-arm.h:940
LTransitionElementsKind(LOperand *object, LOperand *new_map_temp, LOperand *temp_reg)
Definition: lithium-arm.h:1822
LNumberUntagD(LOperand *value)
Definition: lithium-arm.h:1664
LForInPrepareMap(LOperand *object)
Definition: lithium-arm.h:2170
void set_hydrogen_value(HValue *value)
Definition: lithium-arm.h:247
LLoadNamedField(LOperand *object)
Definition: lithium-arm.h:1159
#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
LPower(LOperand *left, LOperand *right)
Definition: lithium-arm.h:1088
virtual bool HasResult() const =0
bool can_deopt() const
Definition: lithium-arm.h:889
Handle< JSObject > holder() const
Definition: lithium-arm.h:1947
DwVfpRegister DoubleRegister
Token::Value op() const
Definition: lithium-arm.h:872
virtual Opcode opcode() const =0
Handle< Object > name() const
Definition: lithium-arm.h:1313
Handle< Map > map() const
Definition: lithium-arm.h:963
#define MUST_USE_RESULT
Definition: globals.h:360
LGlobalObject(LOperand *context)
Definition: lithium-arm.h:1441
EmbeddedContainer< LOperand *, R > results_
Definition: lithium-arm.h:299
LLabel * replacement() const
Definition: lithium-arm.h:410
LDeleteProperty(LOperand *obj, LOperand *key)
Definition: lithium-arm.h:2107
virtual LOperand * TempAt(int i)=0
Handle< JSFunction > known_function()
Definition: lithium-arm.h:1489
LAddI(LOperand *left, LOperand *right)
Definition: lithium-arm.h:1076
bool is_loop_header() const
Definition: lithium-arm.h:408
NilValue
Definition: v8.h:141
LCmpObjectEqAndBranch(LOperand *left, LOperand *right)
Definition: lithium-arm.h:636
LOperand ** SpilledDoubleRegisterArray()
Definition: lithium-arm.h:2126
LOperand * key()
Definition: lithium-arm.h:2161
LNumberTagD(LOperand *value, LOperand *temp1, LOperand *temp2)
Definition: lithium-arm.h:1606
int spill_slot_count() const
Definition: lithium-arm.h:2239
LElementsKind(LOperand *value)
Definition: lithium-arm.h:998
virtual Opcode opcode() const
Definition: lithium-arm.h:1119
HBasicBlock * SuccessorAt(int i)
Definition: lithium-arm.h:449
LStoreKeyedFastElement(LOperand *obj, LOperand *key, LOperand *val)
Definition: lithium-arm.h:1733
LIsStringAndBranch(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:691
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,"load-keyed-fast-double-element") LOperand *elements()
Definition: lithium-arm.h:1252
int block_id() const
Definition: lithium-arm.h:407
LStoreNamedGeneric(LOperand *obj, LOperand *val)
Definition: lithium-arm.h:1714
LLoadKeyedFastElement(LOperand *elements, LOperand *key)
Definition: lithium-arm.h:1231
bool HasEnvironment() const
Definition: lithium-arm.h:241
virtual bool HasResult() const
Definition: lithium-arm.h:288
LBitI(LOperand *left, LOperand *right)
Definition: lithium-arm.h:867
virtual int TempCount()=0
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:321
virtual bool IsControl() const
Definition: lithium-arm.h:446
LTypeofIsAndBranch(LOperand *value)
Definition: lithium-arm.h:2081
virtual LOperand * result()=0
LDoubleToI(LOperand *value, LOperand *temp1, LOperand *temp2)
Definition: lithium-arm.h:1619
Zone * zone() const
Definition: lithium-arm.h:2275
LStoreGlobalGeneric(LOperand *global_object, LOperand *value)
Definition: lithium-arm.h:1334
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment *env)
Definition: lithium-arm.h:842
virtual bool IsControl() const
Definition: lithium-arm.h:367
LStringCharFromCode(LOperand *char_code)
Definition: lithium-arm.h:1877
HBasicBlock * block() const
Definition: lithium-arm.h:325
LSubI(LOperand *left, LOperand *right)
Definition: lithium-arm.h:901
TranscendentalCache::Type transcendental_type()
Definition: lithium-arm.h:431
LMulI(LOperand *left, LOperand *right, LOperand *temp)
Definition: lithium-arm.h:589
virtual void PrintTo(StringStream *stream)
Definition: lithium-arm.cc:92
#define BASE_EMBEDDED
Definition: allocation.h:68
LDivI(LOperand *left, LOperand *right)
Definition: lithium-arm.h:562
virtual void PrintDataTo(StringStream *stream)
Definition: lithium-arm.cc:125
LStoreKeyedFastDoubleElement(LOperand *elements, LOperand *key, LOperand *val)
Definition: lithium-arm.h:1754
#define T(name, string, precedence)
Definition: token.cc:48
LToFastProperties(LOperand *value)
Definition: lithium-arm.h:2060
LInstanceOf(LOperand *left, LOperand *right)
Definition: lithium-arm.h:818
LStoreKeyedSpecializedArrayElement(LOperand *external_pointer, LOperand *key, LOperand *val)
Definition: lithium-arm.h:1798
LCmpMapAndBranch(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:953
LRandom(LOperand *global_object)
Definition: lithium-arm.h:1100
virtual bool IsControl() const
Definition: lithium-arm.h:237
LPointerMap * pointer_map() const
Definition: lithium-arm.h:244
LShiftI(Token::Value op, LOperand *left, LOperand *right, bool can_deopt)
Definition: lithium-arm.h:881
Label * GetAssemblyLabel(int block_id) const
Definition: lithium-arm.h:2261
int first_instruction_index() const
Definition: hydrogen.h:86
EmbeddedContainer< LOperand *, I > inputs_
Definition: lithium-arm.h:300
LLabel * GetLabel(int block_id) const
Definition: lithium-arm.h:2249
virtual bool IsGap() const
Definition: lithium-arm.h:235
HGraph * graph() const
Definition: lithium-arm.h:2241
LCheckFunction(LOperand *value)
Definition: lithium-arm.h:1903
const ZoneList< Handle< JSFunction > > * inlined_closures() const
Definition: lithium-arm.h:2267
LAccessArgumentsAt(LOperand *arguments, LOperand *length, LOperand *index)
Definition: lithium-arm.h:497
LArithmeticT(Token::Value op, LOperand *left, LOperand *right)
Definition: lithium-arm.h:1130
virtual void PrintDataTo(StringStream *stream)
Definition: lithium-arm.cc:145
int block_id() const
Definition: lithium-arm.h:369
CompilationInfo * info() const
Definition: lithium-arm.h:2240
void set_gap_instructions_size(int gap_instructions_size)
Definition: lithium-arm.h:382
LLoadElements(LOperand *object)
Definition: lithium-arm.h:1210
virtual void CompileToNative(LCodeGen *generator)=0
#define DECLARE_PREDICATE(type)
Definition: lithium-arm.h:228
virtual bool IsGap() const
Definition: lithium-arm.h:316
static const int kNumAllocatableRegisters
Definition: assembler-arm.h:74
LTypeof(LOperand *value)
Definition: lithium-arm.h:2071
LStringAdd(LOperand *left, LOperand *right)
Definition: lithium-arm.h:1846
LCheckMaps(LOperand *value)
Definition: lithium-arm.h:1927
Token::Value op() const
Definition: lithium-arm.h:1140
LModI(LOperand *left, LOperand *right, LOperand *temp1, LOperand *temp2, LOperand *temp3)
Definition: lithium-arm.h:543
bool IsLoopHeader() const
Definition: hydrogen.h:97
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
LLoadKeyedFastDoubleElement(LOperand *elements, LOperand *key)
Definition: lithium-arm.h:1247
LArithmeticD(Token::Value op, LOperand *left, LOperand *right)
Definition: lithium-arm.h:1111
const ZoneList< LPointerMap * > * pointer_maps() const
Definition: lithium-arm.h:2248
virtual void PrintDataTo(StringStream *stream)
Definition: lithium-arm.cc:190
Handle< String > name() const
Definition: lithium-arm.h:1516
LEnvironment * GetDeferredLazyDeoptimizationEnvironment()
Definition: lithium-arm.h:839
void set_replacement(LLabel *label)
Definition: lithium-arm.h:411
LCmpIDAndBranch(LOperand *left, LOperand *right)
Definition: lithium-arm.h:602
LParallelMove * GetParallelMove(InnerPosition pos)
Definition: lithium-arm.h:343
virtual Opcode opcode() const
Definition: lithium-arm.h:1136
LInstanceOfKnownGlobal(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:829
bool HasPointerMap() const
Definition: lithium-arm.h:245
LCheckMapValue(LOperand *value, LOperand *map)
Definition: lithium-arm.h:2198
LIsSmiAndBranch(LOperand *value)
Definition: lithium-arm.h:705
int block_id() const
Definition: hydrogen.h:61
LInteger32ToDouble(LOperand *value)
Definition: lithium-arm.h:1586
bool IsRedundant() const
Definition: lithium-arm.cc:134
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,"load-keyed-specialized-array-element") LOperand *external_pointer()
Definition: lithium-arm.h:1269
int LookupDestination(int block_id) const
Definition: lithium-arm.h:2254
LGoto(int block_id)
Definition: lithium-arm.h:363
LCallNew(LOperand *constructor)
Definition: lithium-arm.h:1561
LClampIToUint8(LOperand *value)
Definition: lithium-arm.h:1986
virtual int InputCount()=0
LIn(LOperand *key, LOperand *object)
Definition: lithium-arm.h:2156
static HValue * cast(HValue *value)
LLoadNamedGeneric(LOperand *object)
Definition: lithium-arm.h:1183
LTaggedToI(LOperand *value, LOperand *temp1, LOperand *temp2, LOperand *temp3)
Definition: lithium-arm.h:1635
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,"instance-of-known-global") Handle< JSFunction > function() const
Definition: lithium-arm.h:834
HValue * hydrogen_value() const
Definition: lithium-arm.h:248
LPushArgument(LOperand *value)
Definition: lithium-arm.h:1386
LStringCompareAndBranch(LOperand *left, LOperand *right)
Definition: lithium-arm.h:733
bool HasReplacement() const
Definition: lithium-arm.h:412
LOperand * object()
Definition: lithium-arm.h:2162
LSetDateField(LOperand *date, LOperand *value, LOperand *temp, int index)
Definition: lithium-arm.h:1037
LValueOf(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:1009
LBitNotI(LOperand *value)
Definition: lithium-arm.h:1066
LApplyArguments(LOperand *function, LOperand *receiver, LOperand *length, LOperand *elements)
Definition: lithium-arm.h:476
LModI(LOperand *left, LOperand *right)
Definition: lithium-arm.h:533
LCallFunction(LOperand *function)
Definition: lithium-arm.h:1523
LIsNilAndBranch(LOperand *value)
Definition: lithium-arm.h:661
LLoadKeyedGeneric(LOperand *obj, LOperand *key)
Definition: lithium-arm.h:1284
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,"store-keyed-specialized-array-element") LOperand *external_pointer()
Definition: lithium-arm.h:1806
LStoreGlobalCell(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:1320
LIsUndetectableAndBranch(LOperand *value, LOperand *temp)
Definition: lithium-arm.h:718
const ZoneList< LInstruction * > * instructions() const
Definition: lithium-arm.h:2242
LSmiUntag(LOperand *value, bool needs_check)
Definition: lithium-arm.h:1675
LLoadKeyedSpecializedArrayElement(LOperand *external_pointer, LOperand *key)
Definition: lithium-arm.h:1264
LGap(HBasicBlock *block)
Definition: lithium-arm.h:307
virtual void PrintDataTo(StringStream *stream)
Definition: lithium-arm.cc:348
void AddInlinedClosure(Handle< JSFunction > closure)
Definition: lithium-arm.h:2271