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