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