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