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