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