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