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