Home | History | Annotate | Download | only in x64
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_X64_LITHIUM_X64_H_
     29 #define V8_X64_LITHIUM_X64_H_
     30 
     31 #include "hydrogen.h"
     32 #include "lithium-allocator.h"
     33 #include "lithium.h"
     34 #include "safepoint-table.h"
     35 #include "utils.h"
     36 
     37 namespace v8 {
     38 namespace internal {
     39 
     40 // Forward declarations.
     41 class LCodeGen;
     42 
     43 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V)    \
     44   V(AccessArgumentsAt)                          \
     45   V(AddI)                                       \
     46   V(Allocate)                                   \
     47   V(ApplyArguments)                             \
     48   V(ArgumentsElements)                          \
     49   V(ArgumentsLength)                            \
     50   V(ArithmeticD)                                \
     51   V(ArithmeticT)                                \
     52   V(BitI)                                       \
     53   V(BoundsCheck)                                \
     54   V(Branch)                                     \
     55   V(CallConstantFunction)                       \
     56   V(CallFunction)                               \
     57   V(CallGlobal)                                 \
     58   V(CallKeyed)                                  \
     59   V(CallKnownGlobal)                            \
     60   V(CallNamed)                                  \
     61   V(CallNew)                                    \
     62   V(CallNewArray)                               \
     63   V(CallRuntime)                                \
     64   V(CallStub)                                   \
     65   V(CheckFunction)                              \
     66   V(CheckInstanceType)                          \
     67   V(CheckMaps)                                  \
     68   V(CheckMapValue)                              \
     69   V(CheckNonSmi)                                \
     70   V(CheckSmi)                                   \
     71   V(ClampDToUint8)                              \
     72   V(ClampIToUint8)                              \
     73   V(ClampTToUint8)                              \
     74   V(ClassOfTestAndBranch)                       \
     75   V(CompareNumericAndBranch)                    \
     76   V(CmpObjectEqAndBranch)                       \
     77   V(CmpHoleAndBranch)                           \
     78   V(CmpMapAndBranch)                            \
     79   V(CmpT)                                       \
     80   V(ConstantD)                                  \
     81   V(ConstantE)                                  \
     82   V(ConstantI)                                  \
     83   V(ConstantS)                                  \
     84   V(ConstantT)                                  \
     85   V(Context)                                    \
     86   V(DateField)                                  \
     87   V(DebugBreak)                                 \
     88   V(DeclareGlobals)                             \
     89   V(Deoptimize)                                 \
     90   V(DivI)                                       \
     91   V(DoubleToI)                                  \
     92   V(DoubleToSmi)                                \
     93   V(Drop)                                       \
     94   V(DummyUse)                                   \
     95   V(ElementsKind)                               \
     96   V(ForInCacheArray)                            \
     97   V(ForInPrepareMap)                            \
     98   V(FunctionLiteral)                            \
     99   V(GetCachedArrayIndex)                        \
    100   V(GlobalObject)                               \
    101   V(GlobalReceiver)                             \
    102   V(Goto)                                       \
    103   V(HasCachedArrayIndexAndBranch)               \
    104   V(HasInstanceTypeAndBranch)                   \
    105   V(InnerAllocatedObject)                       \
    106   V(InstanceOf)                                 \
    107   V(InstanceOfKnownGlobal)                      \
    108   V(InstanceSize)                               \
    109   V(InstructionGap)                             \
    110   V(Integer32ToDouble)                          \
    111   V(Integer32ToSmi)                             \
    112   V(InvokeFunction)                             \
    113   V(IsConstructCallAndBranch)                   \
    114   V(IsObjectAndBranch)                          \
    115   V(IsStringAndBranch)                          \
    116   V(IsSmiAndBranch)                             \
    117   V(IsNumberAndBranch)                          \
    118   V(IsUndetectableAndBranch)                    \
    119   V(Label)                                      \
    120   V(LazyBailout)                                \
    121   V(LoadContextSlot)                            \
    122   V(LoadExternalArrayPointer)                   \
    123   V(LoadFieldByIndex)                           \
    124   V(LoadFunctionPrototype)                      \
    125   V(LoadGlobalCell)                             \
    126   V(LoadGlobalGeneric)                          \
    127   V(LoadKeyed)                                  \
    128   V(LoadKeyedGeneric)                           \
    129   V(LoadNamedField)                             \
    130   V(LoadNamedGeneric)                           \
    131   V(MapEnumLength)                              \
    132   V(MathAbs)                                    \
    133   V(MathCos)                                    \
    134   V(MathExp)                                    \
    135   V(MathFloor)                                  \
    136   V(MathFloorOfDiv)                             \
    137   V(MathLog)                                    \
    138   V(MathMinMax)                                 \
    139   V(MathPowHalf)                                \
    140   V(MathRound)                                  \
    141   V(MathSin)                                    \
    142   V(MathSqrt)                                   \
    143   V(MathTan)                                    \
    144   V(ModI)                                       \
    145   V(MulI)                                       \
    146   V(NumberTagD)                                 \
    147   V(NumberTagI)                                 \
    148   V(NumberTagU)                                 \
    149   V(NumberUntagD)                               \
    150   V(OsrEntry)                                   \
    151   V(OuterContext)                               \
    152   V(Parameter)                                  \
    153   V(Power)                                      \
    154   V(PushArgument)                               \
    155   V(Random)                                     \
    156   V(RegExpLiteral)                              \
    157   V(Return)                                     \
    158   V(SeqStringSetChar)                           \
    159   V(ShiftI)                                     \
    160   V(SmiTag)                                     \
    161   V(SmiUntag)                                   \
    162   V(StackCheck)                                 \
    163   V(StoreContextSlot)                           \
    164   V(StoreGlobalCell)                            \
    165   V(StoreGlobalGeneric)                         \
    166   V(StoreKeyed)                                 \
    167   V(StoreKeyedGeneric)                          \
    168   V(StoreNamedField)                            \
    169   V(StoreNamedGeneric)                          \
    170   V(StringAdd)                                  \
    171   V(StringCharCodeAt)                           \
    172   V(StringCharFromCode)                         \
    173   V(StringCompareAndBranch)                     \
    174   V(SubI)                                       \
    175   V(TaggedToI)                                  \
    176   V(ThisFunction)                               \
    177   V(Throw)                                      \
    178   V(ToFastProperties)                           \
    179   V(TransitionElementsKind)                     \
    180   V(TrapAllocationMemento)                      \
    181   V(Typeof)                                     \
    182   V(TypeofIsAndBranch)                          \
    183   V(Uint32ToDouble)                             \
    184   V(Uint32ToSmi)                                \
    185   V(UnknownOSRValue)                            \
    186   V(ValueOf)                                    \
    187   V(WrapReceiver)
    188 
    189 
    190 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)              \
    191   virtual Opcode opcode() const { return LInstruction::k##type; } \
    192   virtual void CompileToNative(LCodeGen* generator);              \
    193   virtual const char* Mnemonic() const { return mnemonic; }       \
    194   static L##type* cast(LInstruction* instr) {                     \
    195     ASSERT(instr->Is##type());                                    \
    196     return reinterpret_cast<L##type*>(instr);                     \
    197   }
    198 
    199 
    200 #define DECLARE_HYDROGEN_ACCESSOR(type)     \
    201   H##type* hydrogen() const {               \
    202     return H##type::cast(hydrogen_value()); \
    203   }
    204 
    205 
    206 class LInstruction: public ZoneObject {
    207  public:
    208   LInstruction()
    209       : environment_(NULL),
    210         hydrogen_value_(NULL),
    211         bit_field_(IsCallBits::encode(false)) {
    212     set_position(RelocInfo::kNoPosition);
    213   }
    214 
    215   virtual ~LInstruction() { }
    216 
    217   virtual void CompileToNative(LCodeGen* generator) = 0;
    218   virtual const char* Mnemonic() const = 0;
    219   virtual void PrintTo(StringStream* stream);
    220   virtual void PrintDataTo(StringStream* stream);
    221   virtual void PrintOutputOperandTo(StringStream* stream);
    222 
    223   enum Opcode {
    224     // Declare a unique enum value for each instruction.
    225 #define DECLARE_OPCODE(type) k##type,
    226     LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
    227     kNumberOfInstructions
    228 #undef DECLARE_OPCODE
    229   };
    230 
    231   virtual Opcode opcode() const = 0;
    232 
    233   // Declare non-virtual type testers for all leaf IR classes.
    234 #define DECLARE_PREDICATE(type) \
    235   bool Is##type() const { return opcode() == k##type; }
    236   LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
    237 #undef DECLARE_PREDICATE
    238 
    239   // Declare virtual predicates for instructions that don't have
    240   // an opcode.
    241   virtual bool IsGap() const { return false; }
    242 
    243   virtual bool IsControl() const { return false; }
    244 
    245   void set_environment(LEnvironment* env) { environment_ = env; }
    246   LEnvironment* environment() const { return environment_; }
    247   bool HasEnvironment() const { return environment_ != NULL; }
    248 
    249   void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
    250   LPointerMap* pointer_map() const { return pointer_map_.get(); }
    251   bool HasPointerMap() const { return pointer_map_.is_set(); }
    252 
    253   // The 31 bits PositionBits is used to store the int position value. And the
    254   // position value may be RelocInfo::kNoPosition (-1). The accessor always
    255   // +1/-1 so that the encoded value of position in bit_field_ is always >= 0
    256   // and can fit into the 31 bits PositionBits.
    257   void set_position(int pos) {
    258     bit_field_ = PositionBits::update(bit_field_, pos + 1);
    259   }
    260   int position() { return PositionBits::decode(bit_field_) - 1; }
    261 
    262   void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
    263   HValue* hydrogen_value() const { return hydrogen_value_; }
    264 
    265   void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); }
    266   bool IsCall() const { return IsCallBits::decode(bit_field_); }
    267 
    268   // Interface to the register allocator and iterators.
    269   bool ClobbersTemps() const { return IsCall(); }
    270   bool ClobbersRegisters() const { return IsCall(); }
    271   bool ClobbersDoubleRegisters() const { return IsCall(); }
    272 
    273   virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
    274 
    275   // Interface to the register allocator and iterators.
    276   bool IsMarkedAsCall() const { return IsCall(); }
    277 
    278   virtual bool HasResult() const = 0;
    279   virtual LOperand* result() const = 0;
    280 
    281   LOperand* FirstInput() { return InputAt(0); }
    282   LOperand* Output() { return HasResult() ? result() : NULL; }
    283 
    284   virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
    285 
    286 #ifdef DEBUG
    287   void VerifyCall();
    288 #endif
    289 
    290  private:
    291   // Iterator support.
    292   friend class InputIterator;
    293   virtual int InputCount() = 0;
    294   virtual LOperand* InputAt(int i) = 0;
    295 
    296   friend class TempIterator;
    297   virtual int TempCount() = 0;
    298   virtual LOperand* TempAt(int i) = 0;
    299 
    300   class IsCallBits: public BitField<bool, 0, 1> {};
    301   class PositionBits: public BitField<int, 1, 31> {};
    302 
    303   LEnvironment* environment_;
    304   SetOncePointer<LPointerMap> pointer_map_;
    305   HValue* hydrogen_value_;
    306   int bit_field_;
    307 };
    308 
    309 
    310 // R = number of result operands (0 or 1).
    311 // I = number of input operands.
    312 // T = number of temporary operands.
    313 template<int R, int I, int T>
    314 class LTemplateInstruction: public LInstruction {
    315  public:
    316   // Allow 0 or 1 output operands.
    317   STATIC_ASSERT(R == 0 || R == 1);
    318   virtual bool HasResult() const { return R != 0 && result() != NULL; }
    319   void set_result(LOperand* operand) { results_[0] = operand; }
    320   LOperand* result() const { return results_[0]; }
    321 
    322  protected:
    323   EmbeddedContainer<LOperand*, R> results_;
    324   EmbeddedContainer<LOperand*, I> inputs_;
    325   EmbeddedContainer<LOperand*, T> temps_;
    326 
    327  private:
    328   // Iterator support.
    329   virtual int InputCount() { return I; }
    330   virtual LOperand* InputAt(int i) { return inputs_[i]; }
    331 
    332   virtual int TempCount() { return T; }
    333   virtual LOperand* TempAt(int i) { return temps_[i]; }
    334 };
    335 
    336 
    337 class LGap: public LTemplateInstruction<0, 0, 0> {
    338  public:
    339   explicit LGap(HBasicBlock* block)
    340       : block_(block) {
    341     parallel_moves_[BEFORE] = NULL;
    342     parallel_moves_[START] = NULL;
    343     parallel_moves_[END] = NULL;
    344     parallel_moves_[AFTER] = NULL;
    345   }
    346 
    347   // Can't use the DECLARE-macro here because of sub-classes.
    348   virtual bool IsGap() const { return true; }
    349   virtual void PrintDataTo(StringStream* stream);
    350   static LGap* cast(LInstruction* instr) {
    351     ASSERT(instr->IsGap());
    352     return reinterpret_cast<LGap*>(instr);
    353   }
    354 
    355   bool IsRedundant() const;
    356 
    357   HBasicBlock* block() const { return block_; }
    358 
    359   enum InnerPosition {
    360     BEFORE,
    361     START,
    362     END,
    363     AFTER,
    364     FIRST_INNER_POSITION = BEFORE,
    365     LAST_INNER_POSITION = AFTER
    366   };
    367 
    368   LParallelMove* GetOrCreateParallelMove(InnerPosition pos,
    369                                          Zone* zone)  {
    370     if (parallel_moves_[pos] == NULL) {
    371       parallel_moves_[pos] = new(zone) LParallelMove(zone);
    372     }
    373     return parallel_moves_[pos];
    374   }
    375 
    376   LParallelMove* GetParallelMove(InnerPosition pos)  {
    377     return parallel_moves_[pos];
    378   }
    379 
    380  private:
    381   LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
    382   HBasicBlock* block_;
    383 };
    384 
    385 
    386 class LInstructionGap: public LGap {
    387  public:
    388   explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
    389 
    390   virtual bool HasInterestingComment(LCodeGen* gen) const {
    391     return !IsRedundant();
    392   }
    393 
    394   DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
    395 };
    396 
    397 
    398 class LGoto: public LTemplateInstruction<0, 0, 0> {
    399  public:
    400   explicit LGoto(int block_id) : block_id_(block_id) { }
    401 
    402   virtual bool HasInterestingComment(LCodeGen* gen) const;
    403   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
    404   virtual void PrintDataTo(StringStream* stream);
    405   virtual bool IsControl() const { return true; }
    406 
    407   int block_id() const { return block_id_; }
    408 
    409  private:
    410   int block_id_;
    411 };
    412 
    413 
    414 class LLazyBailout: public LTemplateInstruction<0, 0, 0> {
    415  public:
    416   LLazyBailout() : gap_instructions_size_(0) { }
    417 
    418   DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
    419 
    420   void set_gap_instructions_size(int gap_instructions_size) {
    421     gap_instructions_size_ = gap_instructions_size;
    422   }
    423   int gap_instructions_size() { return gap_instructions_size_; }
    424 
    425  private:
    426   int gap_instructions_size_;
    427 };
    428 
    429 
    430 class LDummyUse: public LTemplateInstruction<1, 1, 0> {
    431  public:
    432   explicit LDummyUse(LOperand* value) {
    433     inputs_[0] = value;
    434   }
    435   DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
    436 };
    437 
    438 
    439 class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
    440  public:
    441   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
    442   DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
    443 };
    444 
    445 
    446 class LLabel: public LGap {
    447  public:
    448   explicit LLabel(HBasicBlock* block)
    449       : LGap(block), replacement_(NULL) { }
    450 
    451   virtual bool HasInterestingComment(LCodeGen* gen) const { return false; }
    452   DECLARE_CONCRETE_INSTRUCTION(Label, "label")
    453 
    454   virtual void PrintDataTo(StringStream* stream);
    455 
    456   int block_id() const { return block()->block_id(); }
    457   bool is_loop_header() const { return block()->IsLoopHeader(); }
    458   bool is_osr_entry() const { return block()->is_osr_entry(); }
    459   Label* label() { return &label_; }
    460   LLabel* replacement() const { return replacement_; }
    461   void set_replacement(LLabel* label) { replacement_ = label; }
    462   bool HasReplacement() const { return replacement_ != NULL; }
    463 
    464  private:
    465   Label label_;
    466   LLabel* replacement_;
    467 };
    468 
    469 
    470 class LParameter: public LTemplateInstruction<1, 0, 0> {
    471  public:
    472   virtual bool HasInterestingComment(LCodeGen* gen) const { return false; }
    473   DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
    474 };
    475 
    476 
    477 class LCallStub: public LTemplateInstruction<1, 0, 0> {
    478  public:
    479   DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
    480   DECLARE_HYDROGEN_ACCESSOR(CallStub)
    481 
    482   TranscendentalCache::Type transcendental_type() {
    483     return hydrogen()->transcendental_type();
    484   }
    485 };
    486 
    487 
    488 class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
    489  public:
    490   virtual bool HasInterestingComment(LCodeGen* gen) const { return false; }
    491   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
    492 };
    493 
    494 
    495 template<int I, int T>
    496 class LControlInstruction: public LTemplateInstruction<0, I, T> {
    497  public:
    498   LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
    499 
    500   virtual bool IsControl() const { return true; }
    501 
    502   int SuccessorCount() { return hydrogen()->SuccessorCount(); }
    503   HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
    504 
    505   int TrueDestination(LChunk* chunk) {
    506     return chunk->LookupDestination(true_block_id());
    507   }
    508   int FalseDestination(LChunk* chunk) {
    509     return chunk->LookupDestination(false_block_id());
    510   }
    511 
    512   Label* TrueLabel(LChunk* chunk) {
    513     if (true_label_ == NULL) {
    514       true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
    515     }
    516     return true_label_;
    517   }
    518   Label* FalseLabel(LChunk* chunk) {
    519     if (false_label_ == NULL) {
    520       false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
    521     }
    522     return false_label_;
    523   }
    524 
    525  protected:
    526   int true_block_id() { return SuccessorAt(0)->block_id(); }
    527   int false_block_id() { return SuccessorAt(1)->block_id(); }
    528 
    529  private:
    530   HControlInstruction* hydrogen() {
    531     return HControlInstruction::cast(this->hydrogen_value());
    532   }
    533 
    534   Label* false_label_;
    535   Label* true_label_;
    536 };
    537 
    538 
    539 class LWrapReceiver: public LTemplateInstruction<1, 2, 0> {
    540  public:
    541   LWrapReceiver(LOperand* receiver, LOperand* function) {
    542     inputs_[0] = receiver;
    543     inputs_[1] = function;
    544   }
    545 
    546   LOperand* receiver() { return inputs_[0]; }
    547   LOperand* function() { return inputs_[1]; }
    548 
    549   DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
    550 };
    551 
    552 
    553 class LApplyArguments: public LTemplateInstruction<1, 4, 0> {
    554  public:
    555   LApplyArguments(LOperand* function,
    556                   LOperand* receiver,
    557                   LOperand* length,
    558                   LOperand* elements) {
    559     inputs_[0] = function;
    560     inputs_[1] = receiver;
    561     inputs_[2] = length;
    562     inputs_[3] = elements;
    563   }
    564 
    565   LOperand* function() { return inputs_[0]; }
    566   LOperand* receiver() { return inputs_[1]; }
    567   LOperand* length() { return inputs_[2]; }
    568   LOperand* elements() { return inputs_[3]; }
    569 
    570   DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
    571 };
    572 
    573 
    574 class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> {
    575  public:
    576   LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
    577     inputs_[0] = arguments;
    578     inputs_[1] = length;
    579     inputs_[2] = index;
    580   }
    581 
    582   LOperand* arguments() { return inputs_[0]; }
    583   LOperand* length() { return inputs_[1]; }
    584   LOperand* index() { return inputs_[2]; }
    585 
    586   DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
    587 
    588   virtual void PrintDataTo(StringStream* stream);
    589 };
    590 
    591 
    592 class LArgumentsLength: public LTemplateInstruction<1, 1, 0> {
    593  public:
    594   explicit LArgumentsLength(LOperand* elements) {
    595     inputs_[0] = elements;
    596   }
    597 
    598   LOperand* elements() { return inputs_[0]; }
    599 
    600   DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
    601 };
    602 
    603 
    604 class LArgumentsElements: public LTemplateInstruction<1, 0, 0> {
    605  public:
    606   DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
    607   DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
    608 };
    609 
    610 
    611 class LModI: public LTemplateInstruction<1, 2, 1> {
    612  public:
    613   LModI(LOperand* left, LOperand* right, LOperand* temp) {
    614     inputs_[0] = left;
    615     inputs_[1] = right;
    616     temps_[0] = temp;
    617   }
    618 
    619   LOperand* left() { return inputs_[0]; }
    620   LOperand* right() { return inputs_[1]; }
    621   LOperand* temp() { return temps_[0]; }
    622 
    623   DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
    624   DECLARE_HYDROGEN_ACCESSOR(Mod)
    625 };
    626 
    627 
    628 class LDivI: public LTemplateInstruction<1, 2, 1> {
    629  public:
    630   LDivI(LOperand* left, LOperand* right, LOperand* temp) {
    631     inputs_[0] = left;
    632     inputs_[1] = right;
    633     temps_[0] = temp;
    634   }
    635 
    636   LOperand* left() { return inputs_[0]; }
    637   LOperand* right() { return inputs_[1]; }
    638   LOperand* temp() { return temps_[0]; }
    639 
    640   bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
    641 
    642   DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
    643   DECLARE_HYDROGEN_ACCESSOR(Div)
    644 };
    645 
    646 
    647 class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> {
    648  public:
    649   LMathFloorOfDiv(LOperand* left,
    650                   LOperand* right,
    651                   LOperand* temp = NULL) {
    652     inputs_[0] = left;
    653     inputs_[1] = right;
    654     temps_[0] = temp;
    655   }
    656 
    657   LOperand* left() { return inputs_[0]; }
    658   LOperand* right() { return inputs_[1]; }
    659   LOperand* temp() { return temps_[0]; }
    660 
    661   DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
    662   DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
    663 };
    664 
    665 
    666 class LMulI: public LTemplateInstruction<1, 2, 0> {
    667  public:
    668   LMulI(LOperand* left, LOperand* right) {
    669     inputs_[0] = left;
    670     inputs_[1] = right;
    671   }
    672 
    673   LOperand* left() { return inputs_[0]; }
    674   LOperand* right() { return inputs_[1]; }
    675 
    676   DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
    677   DECLARE_HYDROGEN_ACCESSOR(Mul)
    678 };
    679 
    680 
    681 class LCompareNumericAndBranch: public LControlInstruction<2, 0> {
    682  public:
    683   LCompareNumericAndBranch(LOperand* left, LOperand* right) {
    684     inputs_[0] = left;
    685     inputs_[1] = right;
    686   }
    687 
    688   LOperand* left() { return inputs_[0]; }
    689   LOperand* right() { return inputs_[1]; }
    690 
    691   DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
    692                                "compare-numeric-and-branch")
    693   DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
    694 
    695   Token::Value op() const { return hydrogen()->token(); }
    696   bool is_double() const {
    697     return hydrogen()->representation().IsDouble();
    698   }
    699 
    700   virtual void PrintDataTo(StringStream* stream);
    701 };
    702 
    703 
    704 class LMathFloor: public LTemplateInstruction<1, 1, 0> {
    705  public:
    706   explicit LMathFloor(LOperand* value) {
    707     inputs_[0] = value;
    708   }
    709 
    710   LOperand* value() { return inputs_[0]; }
    711 
    712   DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
    713   DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
    714 };
    715 
    716 
    717 class LMathRound: public LTemplateInstruction<1, 1, 0> {
    718  public:
    719   explicit LMathRound(LOperand* value) {
    720     inputs_[0] = value;
    721   }
    722 
    723   LOperand* value() { return inputs_[0]; }
    724 
    725   DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
    726   DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
    727 };
    728 
    729 
    730 class LMathAbs: public LTemplateInstruction<1, 1, 0> {
    731  public:
    732   explicit LMathAbs(LOperand* value) {
    733     inputs_[0] = value;
    734   }
    735 
    736   LOperand* value() { return inputs_[0]; }
    737 
    738   DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
    739   DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
    740 };
    741 
    742 
    743 class LMathLog: public LTemplateInstruction<1, 1, 0> {
    744  public:
    745   explicit LMathLog(LOperand* value) {
    746     inputs_[0] = value;
    747   }
    748 
    749   LOperand* value() { return inputs_[0]; }
    750 
    751   DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
    752 };
    753 
    754 
    755 class LMathSin: public LTemplateInstruction<1, 1, 0> {
    756  public:
    757   explicit LMathSin(LOperand* value) {
    758     inputs_[0] = value;
    759   }
    760 
    761   LOperand* value() { return inputs_[0]; }
    762 
    763   DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
    764 };
    765 
    766 
    767 class LMathCos: public LTemplateInstruction<1, 1, 0> {
    768  public:
    769   explicit LMathCos(LOperand* value) {
    770     inputs_[0] = value;
    771   }
    772 
    773   LOperand* value() { return inputs_[0]; }
    774 
    775   DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
    776 };
    777 
    778 
    779 class LMathTan: public LTemplateInstruction<1, 1, 0> {
    780  public:
    781   explicit LMathTan(LOperand* value) {
    782     inputs_[0] = value;
    783   }
    784 
    785   LOperand* value() { return inputs_[0]; }
    786 
    787   DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
    788 };
    789 
    790 
    791 class LMathExp: public LTemplateInstruction<1, 1, 2> {
    792  public:
    793   LMathExp(LOperand* value, LOperand* temp1, LOperand* temp2) {
    794     inputs_[0] = value;
    795     temps_[0] = temp1;
    796     temps_[1] = temp2;
    797     ExternalReference::InitializeMathExpData();
    798   }
    799 
    800   LOperand* value() { return inputs_[0]; }
    801   LOperand* temp1() { return temps_[0]; }
    802   LOperand* temp2() { return temps_[1]; }
    803 
    804   DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
    805 };
    806 
    807 
    808 class LMathSqrt: public LTemplateInstruction<1, 1, 0> {
    809  public:
    810   explicit LMathSqrt(LOperand* value) {
    811     inputs_[0] = value;
    812   }
    813 
    814   LOperand* value() { return inputs_[0]; }
    815 
    816   DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
    817 };
    818 
    819 
    820 class LMathPowHalf: public LTemplateInstruction<1, 1, 0> {
    821  public:
    822   explicit LMathPowHalf(LOperand* value) {
    823     inputs_[0] = value;
    824   }
    825 
    826   LOperand* value() { return inputs_[0]; }
    827 
    828   DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
    829 };
    830 
    831 
    832 class LCmpObjectEqAndBranch: public LControlInstruction<2, 0> {
    833  public:
    834   LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
    835     inputs_[0] = left;
    836     inputs_[1] = right;
    837   }
    838 
    839   LOperand* left() { return inputs_[0]; }
    840   LOperand* right() { return inputs_[1]; }
    841 
    842   DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
    843 };
    844 
    845 
    846 class LCmpHoleAndBranch: public LControlInstruction<1, 0> {
    847  public:
    848   explicit LCmpHoleAndBranch(LOperand* object) {
    849     inputs_[0] = object;
    850   }
    851 
    852   LOperand* object() { return inputs_[0]; }
    853 
    854   DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
    855   DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
    856 };
    857 
    858 
    859 class LIsObjectAndBranch: public LControlInstruction<1, 0> {
    860  public:
    861   explicit LIsObjectAndBranch(LOperand* value) {
    862     inputs_[0] = value;
    863   }
    864 
    865   LOperand* value() { return inputs_[0]; }
    866 
    867   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
    868   DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
    869 
    870   virtual void PrintDataTo(StringStream* stream);
    871 };
    872 
    873 
    874 class LIsNumberAndBranch: public LControlInstruction<1, 0> {
    875  public:
    876   explicit LIsNumberAndBranch(LOperand* value) {
    877     inputs_[0] = value;
    878   }
    879 
    880   LOperand* value() { return inputs_[0]; }
    881 
    882   DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch, "is-number-and-branch")
    883   DECLARE_HYDROGEN_ACCESSOR(IsNumberAndBranch)
    884 };
    885 
    886 
    887 class LIsStringAndBranch: public LControlInstruction<1, 1> {
    888  public:
    889   explicit LIsStringAndBranch(LOperand* value, LOperand* temp) {
    890     inputs_[0] = value;
    891     temps_[0] = temp;
    892   }
    893 
    894   LOperand* value() { return inputs_[0]; }
    895   LOperand* temp() { return temps_[0]; }
    896 
    897   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
    898   DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
    899 
    900   virtual void PrintDataTo(StringStream* stream);
    901 };
    902 
    903 
    904 class LIsSmiAndBranch: public LControlInstruction<1, 0> {
    905  public:
    906   explicit LIsSmiAndBranch(LOperand* value) {
    907     inputs_[0] = value;
    908   }
    909 
    910   LOperand* value() { return inputs_[0]; }
    911 
    912   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
    913   DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
    914 
    915   virtual void PrintDataTo(StringStream* stream);
    916 };
    917 
    918 
    919 class LIsUndetectableAndBranch: public LControlInstruction<1, 1> {
    920  public:
    921   explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
    922     inputs_[0] = value;
    923     temps_[0] = temp;
    924   }
    925 
    926   LOperand* value() { return inputs_[0]; }
    927   LOperand* temp() { return temps_[0]; }
    928 
    929   DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
    930                                "is-undetectable-and-branch")
    931   DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
    932 
    933   virtual void PrintDataTo(StringStream* stream);
    934 };
    935 
    936 
    937 class LStringCompareAndBranch: public LControlInstruction<2, 0> {
    938  public:
    939   explicit LStringCompareAndBranch(LOperand* left, LOperand* right) {
    940     inputs_[0] = left;
    941     inputs_[1] = right;
    942   }
    943 
    944   LOperand* left() { return inputs_[0]; }
    945   LOperand* right() { return inputs_[1]; }
    946 
    947   DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
    948                                "string-compare-and-branch")
    949   DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
    950 
    951   virtual void PrintDataTo(StringStream* stream);
    952 
    953   Token::Value op() const { return hydrogen()->token(); }
    954 };
    955 
    956 
    957 class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
    958  public:
    959   explicit LHasInstanceTypeAndBranch(LOperand* value) {
    960     inputs_[0] = value;
    961   }
    962 
    963   LOperand* value() { return inputs_[0]; }
    964 
    965   DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
    966                                "has-instance-type-and-branch")
    967   DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
    968 
    969   virtual void PrintDataTo(StringStream* stream);
    970 };
    971 
    972 
    973 class LGetCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
    974  public:
    975   explicit LGetCachedArrayIndex(LOperand* value) {
    976     inputs_[0] = value;
    977   }
    978 
    979   LOperand* value() { return inputs_[0]; }
    980 
    981   DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
    982   DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
    983 };
    984 
    985 
    986 class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
    987  public:
    988   explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
    989     inputs_[0] = value;
    990   }
    991 
    992   LOperand* value() { return inputs_[0]; }
    993 
    994   DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
    995                                "has-cached-array-index-and-branch")
    996   DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
    997 
    998   virtual void PrintDataTo(StringStream* stream);
    999 };
   1000 
   1001 
   1002 class LClassOfTestAndBranch: public LControlInstruction<1, 2> {
   1003  public:
   1004   LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
   1005     inputs_[0] = value;
   1006     temps_[0] = temp;
   1007     temps_[1] = temp2;
   1008   }
   1009 
   1010   LOperand* value() { return inputs_[0]; }
   1011   LOperand* temp() { return temps_[0]; }
   1012   LOperand* temp2() { return temps_[1]; }
   1013 
   1014   DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
   1015                                "class-of-test-and-branch")
   1016   DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
   1017 
   1018   virtual void PrintDataTo(StringStream* stream);
   1019 };
   1020 
   1021 
   1022 class LCmpT: public LTemplateInstruction<1, 2, 0> {
   1023  public:
   1024   LCmpT(LOperand* left, LOperand* right) {
   1025     inputs_[0] = left;
   1026     inputs_[1] = right;
   1027   }
   1028 
   1029   LOperand* left() { return inputs_[0]; }
   1030   LOperand* right() { return inputs_[1]; }
   1031 
   1032   DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
   1033   DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
   1034 
   1035   Token::Value op() const { return hydrogen()->token(); }
   1036 };
   1037 
   1038 
   1039 class LInstanceOf: public LTemplateInstruction<1, 2, 0> {
   1040  public:
   1041   LInstanceOf(LOperand* left, LOperand* right) {
   1042     inputs_[0] = left;
   1043     inputs_[1] = right;
   1044   }
   1045 
   1046   LOperand* left() { return inputs_[0]; }
   1047   LOperand* right() { return inputs_[1]; }
   1048 
   1049   DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
   1050 };
   1051 
   1052 
   1053 class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
   1054  public:
   1055   LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) {
   1056     inputs_[0] = value;
   1057     temps_[0] = temp;
   1058   }
   1059 
   1060   LOperand* value() { return inputs_[0]; }
   1061   LOperand* temp() { return temps_[0]; }
   1062 
   1063   DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
   1064                                "instance-of-known-global")
   1065   DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
   1066 
   1067   Handle<JSFunction> function() const { return hydrogen()->function(); }
   1068   LEnvironment* GetDeferredLazyDeoptimizationEnvironment() {
   1069     return lazy_deopt_env_;
   1070   }
   1071   virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) {
   1072     lazy_deopt_env_ = env;
   1073   }
   1074 
   1075  private:
   1076   LEnvironment* lazy_deopt_env_;
   1077 };
   1078 
   1079 
   1080 class LInstanceSize: public LTemplateInstruction<1, 1, 0> {
   1081  public:
   1082   explicit LInstanceSize(LOperand* object) {
   1083     inputs_[0] = object;
   1084   }
   1085 
   1086   LOperand* object() { return inputs_[0]; }
   1087 
   1088   DECLARE_CONCRETE_INSTRUCTION(InstanceSize, "instance-size")
   1089   DECLARE_HYDROGEN_ACCESSOR(InstanceSize)
   1090 };
   1091 
   1092 
   1093 class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
   1094  public:
   1095   LBoundsCheck(LOperand* index, LOperand* length) {
   1096     inputs_[0] = index;
   1097     inputs_[1] = length;
   1098   }
   1099 
   1100   LOperand* index() { return inputs_[0]; }
   1101   LOperand* length() { return inputs_[1]; }
   1102 
   1103   DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
   1104   DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
   1105 };
   1106 
   1107 
   1108 class LBitI: public LTemplateInstruction<1, 2, 0> {
   1109  public:
   1110   LBitI(LOperand* left, LOperand* right) {
   1111     inputs_[0] = left;
   1112     inputs_[1] = right;
   1113   }
   1114 
   1115   LOperand* left() { return inputs_[0]; }
   1116   LOperand* right() { return inputs_[1]; }
   1117 
   1118   Token::Value op() const { return hydrogen()->op(); }
   1119 
   1120   DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
   1121   DECLARE_HYDROGEN_ACCESSOR(Bitwise)
   1122 };
   1123 
   1124 
   1125 class LShiftI: public LTemplateInstruction<1, 2, 0> {
   1126  public:
   1127   LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
   1128       : op_(op), can_deopt_(can_deopt) {
   1129     inputs_[0] = left;
   1130     inputs_[1] = right;
   1131   }
   1132 
   1133   Token::Value op() const { return op_; }
   1134   LOperand* left() { return inputs_[0]; }
   1135   LOperand* right() { return inputs_[1]; }
   1136   bool can_deopt() const { return can_deopt_; }
   1137 
   1138   DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
   1139 
   1140  private:
   1141   Token::Value op_;
   1142   bool can_deopt_;
   1143 };
   1144 
   1145 
   1146 class LSubI: public LTemplateInstruction<1, 2, 0> {
   1147  public:
   1148   LSubI(LOperand* left, LOperand* right) {
   1149     inputs_[0] = left;
   1150     inputs_[1] = right;
   1151   }
   1152 
   1153   LOperand* left() { return inputs_[0]; }
   1154   LOperand* right() { return inputs_[1]; }
   1155 
   1156   DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
   1157   DECLARE_HYDROGEN_ACCESSOR(Sub)
   1158 };
   1159 
   1160 
   1161 class LConstantI: public LTemplateInstruction<1, 0, 0> {
   1162  public:
   1163   DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
   1164   DECLARE_HYDROGEN_ACCESSOR(Constant)
   1165 
   1166   int32_t value() const { return hydrogen()->Integer32Value(); }
   1167 };
   1168 
   1169 
   1170 class LConstantS: public LTemplateInstruction<1, 0, 0> {
   1171  public:
   1172   DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
   1173   DECLARE_HYDROGEN_ACCESSOR(Constant)
   1174 
   1175   Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
   1176 };
   1177 
   1178 
   1179 class LConstantD: public LTemplateInstruction<1, 0, 1> {
   1180  public:
   1181   explicit LConstantD(LOperand* temp) {
   1182     temps_[0] = temp;
   1183   }
   1184 
   1185   LOperand* temp() { return temps_[0]; }
   1186 
   1187   DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
   1188   DECLARE_HYDROGEN_ACCESSOR(Constant)
   1189 
   1190   double value() const { return hydrogen()->DoubleValue(); }
   1191 };
   1192 
   1193 
   1194 class LConstantE: public LTemplateInstruction<1, 0, 0> {
   1195  public:
   1196   DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
   1197   DECLARE_HYDROGEN_ACCESSOR(Constant)
   1198 
   1199   ExternalReference value() const {
   1200     return hydrogen()->ExternalReferenceValue();
   1201   }
   1202 };
   1203 
   1204 
   1205 class LConstantT: public LTemplateInstruction<1, 0, 0> {
   1206  public:
   1207   DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
   1208   DECLARE_HYDROGEN_ACCESSOR(Constant)
   1209 
   1210   Handle<Object> value() const { return hydrogen()->handle(); }
   1211 };
   1212 
   1213 
   1214 class LBranch: public LControlInstruction<1, 0> {
   1215  public:
   1216   explicit LBranch(LOperand* value) {
   1217     inputs_[0] = value;
   1218   }
   1219 
   1220   LOperand* value() { return inputs_[0]; }
   1221 
   1222   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
   1223   DECLARE_HYDROGEN_ACCESSOR(Branch)
   1224 
   1225   virtual void PrintDataTo(StringStream* stream);
   1226 };
   1227 
   1228 
   1229 class LDebugBreak: public LTemplateInstruction<0, 0, 0> {
   1230  public:
   1231   DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
   1232 };
   1233 
   1234 
   1235 class LCmpMapAndBranch: public LControlInstruction<1, 0> {
   1236  public:
   1237   explicit LCmpMapAndBranch(LOperand* value) {
   1238     inputs_[0] = value;
   1239   }
   1240 
   1241   LOperand* value() { return inputs_[0]; }
   1242 
   1243   DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
   1244   DECLARE_HYDROGEN_ACCESSOR(CompareMap)
   1245 
   1246   Handle<Map> map() const { return hydrogen()->map(); }
   1247 };
   1248 
   1249 
   1250 class LMapEnumLength: public LTemplateInstruction<1, 1, 0> {
   1251  public:
   1252   explicit LMapEnumLength(LOperand* value) {
   1253     inputs_[0] = value;
   1254   }
   1255 
   1256   LOperand* value() { return inputs_[0]; }
   1257 
   1258   DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
   1259 };
   1260 
   1261 
   1262 class LElementsKind: public LTemplateInstruction<1, 1, 0> {
   1263  public:
   1264   explicit LElementsKind(LOperand* value) {
   1265     inputs_[0] = value;
   1266   }
   1267 
   1268   LOperand* value() { return inputs_[0]; }
   1269 
   1270   DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind")
   1271   DECLARE_HYDROGEN_ACCESSOR(ElementsKind)
   1272 };
   1273 
   1274 
   1275 class LValueOf: public LTemplateInstruction<1, 1, 0> {
   1276  public:
   1277   explicit LValueOf(LOperand* value) {
   1278     inputs_[0] = value;
   1279   }
   1280 
   1281   LOperand* value() { return inputs_[0]; }
   1282 
   1283   DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
   1284   DECLARE_HYDROGEN_ACCESSOR(ValueOf)
   1285 };
   1286 
   1287 
   1288 class LDateField: public LTemplateInstruction<1, 1, 0> {
   1289  public:
   1290   LDateField(LOperand* date, Smi* index) : index_(index) {
   1291     inputs_[0] = date;
   1292   }
   1293 
   1294   LOperand* date() { return inputs_[0]; }
   1295   Smi* index() const { return index_; }
   1296 
   1297   DECLARE_CONCRETE_INSTRUCTION(ValueOf, "date-field")
   1298   DECLARE_HYDROGEN_ACCESSOR(ValueOf)
   1299 
   1300  private:
   1301   Smi* index_;
   1302 };
   1303 
   1304 
   1305 class LSeqStringSetChar: public LTemplateInstruction<1, 3, 0> {
   1306  public:
   1307   LSeqStringSetChar(String::Encoding encoding,
   1308                     LOperand* string,
   1309                     LOperand* index,
   1310                     LOperand* value) : encoding_(encoding) {
   1311     inputs_[0] = string;
   1312     inputs_[1] = index;
   1313     inputs_[2] = value;
   1314   }
   1315 
   1316   String::Encoding encoding() { return encoding_; }
   1317   LOperand* string() { return inputs_[0]; }
   1318   LOperand* index() { return inputs_[1]; }
   1319   LOperand* value() { return inputs_[2]; }
   1320 
   1321   DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
   1322   DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
   1323 
   1324  private:
   1325   String::Encoding encoding_;
   1326 };
   1327 
   1328 
   1329 class LThrow: public LTemplateInstruction<0, 1, 0> {
   1330  public:
   1331   explicit LThrow(LOperand* value) {
   1332     inputs_[0] = value;
   1333   }
   1334 
   1335   LOperand* value() { return inputs_[0]; }
   1336 
   1337   DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
   1338 };
   1339 
   1340 
   1341 class LAddI: public LTemplateInstruction<1, 2, 0> {
   1342  public:
   1343   LAddI(LOperand* left, LOperand* right) {
   1344     inputs_[0] = left;
   1345     inputs_[1] = right;
   1346   }
   1347 
   1348   LOperand* left() { return inputs_[0]; }
   1349   LOperand* right() { return inputs_[1]; }
   1350 
   1351   static bool UseLea(HAdd* add) {
   1352     return !add->CheckFlag(HValue::kCanOverflow) &&
   1353         add->BetterLeftOperand()->UseCount() > 1;
   1354   }
   1355 
   1356   DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
   1357   DECLARE_HYDROGEN_ACCESSOR(Add)
   1358 };
   1359 
   1360 
   1361 class LMathMinMax: public LTemplateInstruction<1, 2, 0> {
   1362  public:
   1363   LMathMinMax(LOperand* left, LOperand* right) {
   1364     inputs_[0] = left;
   1365     inputs_[1] = right;
   1366   }
   1367 
   1368   LOperand* left() { return inputs_[0]; }
   1369   LOperand* right() { return inputs_[1]; }
   1370 
   1371   DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
   1372   DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
   1373 };
   1374 
   1375 
   1376 class LPower: public LTemplateInstruction<1, 2, 0> {
   1377  public:
   1378   LPower(LOperand* left, LOperand* right) {
   1379     inputs_[0] = left;
   1380     inputs_[1] = right;
   1381   }
   1382 
   1383   LOperand* left() { return inputs_[0]; }
   1384   LOperand* right() { return inputs_[1]; }
   1385 
   1386   DECLARE_CONCRETE_INSTRUCTION(Power, "power")
   1387   DECLARE_HYDROGEN_ACCESSOR(Power)
   1388 };
   1389 
   1390 
   1391 class LRandom: public LTemplateInstruction<1, 1, 0> {
   1392  public:
   1393   explicit LRandom(LOperand* global_object) {
   1394     inputs_[0] = global_object;
   1395   }
   1396 
   1397   LOperand* global_object() { return inputs_[0]; }
   1398 
   1399   DECLARE_CONCRETE_INSTRUCTION(Random, "random")
   1400   DECLARE_HYDROGEN_ACCESSOR(Random)
   1401 };
   1402 
   1403 
   1404 class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
   1405  public:
   1406   LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
   1407       : op_(op) {
   1408     inputs_[0] = left;
   1409     inputs_[1] = right;
   1410   }
   1411 
   1412   Token::Value op() const { return op_; }
   1413   LOperand* left() { return inputs_[0]; }
   1414   LOperand* right() { return inputs_[1]; }
   1415 
   1416   virtual Opcode opcode() const { return LInstruction::kArithmeticD; }
   1417   virtual void CompileToNative(LCodeGen* generator);
   1418   virtual const char* Mnemonic() const;
   1419 
   1420  private:
   1421   Token::Value op_;
   1422 };
   1423 
   1424 
   1425 class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
   1426  public:
   1427   LArithmeticT(Token::Value op, LOperand* left, LOperand* right)
   1428       : op_(op) {
   1429     inputs_[0] = left;
   1430     inputs_[1] = right;
   1431   }
   1432 
   1433   Token::Value op() const { return op_; }
   1434   LOperand* left() { return inputs_[0]; }
   1435   LOperand* right() { return inputs_[1]; }
   1436 
   1437   virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
   1438   virtual void CompileToNative(LCodeGen* generator);
   1439   virtual const char* Mnemonic() const;
   1440 
   1441  private:
   1442   Token::Value op_;
   1443 };
   1444 
   1445 
   1446 class LReturn: public LTemplateInstruction<0, 2, 0> {
   1447  public:
   1448   explicit LReturn(LOperand* value, LOperand* parameter_count) {
   1449     inputs_[0] = value;
   1450     inputs_[1] = parameter_count;
   1451   }
   1452 
   1453   LOperand* value() { return inputs_[0]; }
   1454 
   1455   bool has_constant_parameter_count() {
   1456     return parameter_count()->IsConstantOperand();
   1457   }
   1458   LConstantOperand* constant_parameter_count() {
   1459     ASSERT(has_constant_parameter_count());
   1460     return LConstantOperand::cast(parameter_count());
   1461   }
   1462   LOperand* parameter_count() { return inputs_[1]; }
   1463 
   1464   DECLARE_CONCRETE_INSTRUCTION(Return, "return")
   1465   DECLARE_HYDROGEN_ACCESSOR(Return)
   1466 };
   1467 
   1468 
   1469 class LLoadNamedField: public LTemplateInstruction<1, 1, 0> {
   1470  public:
   1471   explicit LLoadNamedField(LOperand* object) {
   1472     inputs_[0] = object;
   1473   }
   1474 
   1475   LOperand* object() { return inputs_[0]; }
   1476 
   1477   DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
   1478   DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
   1479 };
   1480 
   1481 
   1482 class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
   1483  public:
   1484   explicit LLoadNamedGeneric(LOperand* object) {
   1485     inputs_[0] = object;
   1486   }
   1487 
   1488   DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
   1489   DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
   1490 
   1491   LOperand* object() { return inputs_[0]; }
   1492   Handle<Object> name() const { return hydrogen()->name(); }
   1493 };
   1494 
   1495 
   1496 class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> {
   1497  public:
   1498   explicit LLoadFunctionPrototype(LOperand* function) {
   1499     inputs_[0] = function;
   1500   }
   1501 
   1502   DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
   1503   DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
   1504 
   1505   LOperand* function() { return inputs_[0]; }
   1506 };
   1507 
   1508 
   1509 class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> {
   1510  public:
   1511   explicit LLoadExternalArrayPointer(LOperand* object) {
   1512     inputs_[0] = object;
   1513   }
   1514 
   1515   LOperand* object() { return inputs_[0]; }
   1516 
   1517   DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
   1518                                "load-external-array-pointer")
   1519 };
   1520 
   1521 
   1522 class LLoadKeyed: public LTemplateInstruction<1, 2, 0> {
   1523  public:
   1524   LLoadKeyed(LOperand* elements, LOperand* key) {
   1525     inputs_[0] = elements;
   1526     inputs_[1] = key;
   1527   }
   1528 
   1529   DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
   1530   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
   1531 
   1532   bool is_external() const {
   1533     return hydrogen()->is_external();
   1534   }
   1535   LOperand* elements() { return inputs_[0]; }
   1536   LOperand* key() { return inputs_[1]; }
   1537   virtual void PrintDataTo(StringStream* stream);
   1538   uint32_t additional_index() const { return hydrogen()->index_offset(); }
   1539   ElementsKind elements_kind() const {
   1540     return hydrogen()->elements_kind();
   1541   }
   1542 };
   1543 
   1544 
   1545 class LLoadKeyedGeneric: public LTemplateInstruction<1, 2, 0> {
   1546  public:
   1547   LLoadKeyedGeneric(LOperand* obj, LOperand* key) {
   1548     inputs_[0] = obj;
   1549     inputs_[1] = key;
   1550   }
   1551 
   1552   DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
   1553 
   1554   LOperand* object() { return inputs_[0]; }
   1555   LOperand* key() { return inputs_[1]; }
   1556 };
   1557 
   1558 
   1559 class LLoadGlobalCell: public LTemplateInstruction<1, 0, 0> {
   1560  public:
   1561   DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
   1562   DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
   1563 };
   1564 
   1565 
   1566 class LLoadGlobalGeneric: public LTemplateInstruction<1, 1, 0> {
   1567  public:
   1568   explicit LLoadGlobalGeneric(LOperand* global_object) {
   1569     inputs_[0] = global_object;
   1570   }
   1571 
   1572   DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
   1573   DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
   1574 
   1575   LOperand* global_object() { return inputs_[0]; }
   1576   Handle<Object> name() const { return hydrogen()->name(); }
   1577   bool for_typeof() const { return hydrogen()->for_typeof(); }
   1578 };
   1579 
   1580 
   1581 class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
   1582  public:
   1583   explicit LStoreGlobalCell(LOperand* value, LOperand* temp) {
   1584     inputs_[0] = value;
   1585     temps_[0] = temp;
   1586   }
   1587 
   1588   LOperand* value() { return inputs_[0]; }
   1589   LOperand* temp() { return temps_[0]; }
   1590 
   1591   DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
   1592   DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
   1593 };
   1594 
   1595 
   1596 class LStoreGlobalGeneric: public LTemplateInstruction<0, 2, 0> {
   1597  public:
   1598   explicit LStoreGlobalGeneric(LOperand* global_object,
   1599                                LOperand* value) {
   1600     inputs_[0] = global_object;
   1601     inputs_[1] = value;
   1602   }
   1603 
   1604   LOperand* global_object() { return inputs_[0]; }
   1605   LOperand* value() { return inputs_[1]; }
   1606 
   1607   DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic")
   1608   DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric)
   1609 
   1610   Handle<Object> name() const { return hydrogen()->name(); }
   1611   StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
   1612 };
   1613 
   1614 
   1615 class LLoadContextSlot: public LTemplateInstruction<1, 1, 0> {
   1616  public:
   1617   explicit LLoadContextSlot(LOperand* context) {
   1618     inputs_[0] = context;
   1619   }
   1620 
   1621   LOperand* context() { return inputs_[0]; }
   1622 
   1623   DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
   1624   DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
   1625 
   1626   int slot_index() { return hydrogen()->slot_index(); }
   1627 
   1628   virtual void PrintDataTo(StringStream* stream);
   1629 };
   1630 
   1631 
   1632 class LStoreContextSlot: public LTemplateInstruction<0, 2, 1> {
   1633  public:
   1634   LStoreContextSlot(LOperand* context, LOperand* value, LOperand* temp) {
   1635     inputs_[0] = context;
   1636     inputs_[1] = value;
   1637     temps_[0] = temp;
   1638   }
   1639 
   1640   LOperand* context() { return inputs_[0]; }
   1641   LOperand* value() { return inputs_[1]; }
   1642   LOperand* temp() { return temps_[0]; }
   1643 
   1644   DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
   1645   DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
   1646 
   1647   int slot_index() { return hydrogen()->slot_index(); }
   1648 
   1649   virtual void PrintDataTo(StringStream* stream);
   1650 };
   1651 
   1652 
   1653 class LPushArgument: public LTemplateInstruction<0, 1, 0> {
   1654  public:
   1655   explicit LPushArgument(LOperand* value) {
   1656     inputs_[0] = value;
   1657   }
   1658 
   1659   LOperand* value() { return inputs_[0]; }
   1660 
   1661   DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
   1662 };
   1663 
   1664 
   1665 class LDrop: public LTemplateInstruction<0, 0, 0> {
   1666  public:
   1667   explicit LDrop(int count) : count_(count) { }
   1668 
   1669   int count() const { return count_; }
   1670 
   1671   DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
   1672 
   1673  private:
   1674   int count_;
   1675 };
   1676 
   1677 
   1678 class LInnerAllocatedObject: public LTemplateInstruction<1, 1, 0> {
   1679  public:
   1680   explicit LInnerAllocatedObject(LOperand* base_object) {
   1681     inputs_[0] = base_object;
   1682   }
   1683 
   1684   LOperand* base_object() { return inputs_[0]; }
   1685   int offset() { return hydrogen()->offset(); }
   1686 
   1687   virtual void PrintDataTo(StringStream* stream);
   1688 
   1689   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
   1690   DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
   1691 };
   1692 
   1693 
   1694 class LThisFunction: public LTemplateInstruction<1, 0, 0> {
   1695  public:
   1696   DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
   1697   DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
   1698 };
   1699 
   1700 
   1701 class LContext: public LTemplateInstruction<1, 0, 0> {
   1702  public:
   1703   DECLARE_CONCRETE_INSTRUCTION(Context, "context")
   1704   DECLARE_HYDROGEN_ACCESSOR(Context)
   1705 };
   1706 
   1707 
   1708 class LOuterContext: public LTemplateInstruction<1, 1, 0> {
   1709  public:
   1710   explicit LOuterContext(LOperand* context) {
   1711     inputs_[0] = context;
   1712   }
   1713 
   1714   LOperand* context() { return inputs_[0]; }
   1715 
   1716   DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
   1717 };
   1718 
   1719 
   1720 class LDeclareGlobals: public LTemplateInstruction<0, 0, 0> {
   1721  public:
   1722   DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
   1723   DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
   1724 };
   1725 
   1726 
   1727 class LGlobalObject: public LTemplateInstruction<1, 0, 0> {
   1728  public:
   1729   DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
   1730 };
   1731 
   1732 
   1733 class LGlobalReceiver: public LTemplateInstruction<1, 1, 0> {
   1734  public:
   1735   explicit LGlobalReceiver(LOperand* global_object) {
   1736     inputs_[0] = global_object;
   1737   }
   1738 
   1739   LOperand* global() { return inputs_[0]; }
   1740 
   1741   DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
   1742 };
   1743 
   1744 
   1745 class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> {
   1746  public:
   1747   DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
   1748   DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
   1749 
   1750   virtual void PrintDataTo(StringStream* stream);
   1751 
   1752   Handle<JSFunction> function() { return hydrogen()->function(); }
   1753   int arity() const { return hydrogen()->argument_count() - 1; }
   1754 };
   1755 
   1756 
   1757 class LInvokeFunction: public LTemplateInstruction<1, 1, 0> {
   1758  public:
   1759   explicit LInvokeFunction(LOperand* function) {
   1760     inputs_[0] = function;
   1761   }
   1762 
   1763   LOperand* function() { return inputs_[0]; }
   1764 
   1765   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
   1766   DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
   1767 
   1768   virtual void PrintDataTo(StringStream* stream);
   1769 
   1770   int arity() const { return hydrogen()->argument_count() - 1; }
   1771 };
   1772 
   1773 
   1774 class LCallKeyed: public LTemplateInstruction<1, 1, 0> {
   1775  public:
   1776   explicit LCallKeyed(LOperand* key) {
   1777     inputs_[0] = key;
   1778   }
   1779 
   1780   DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
   1781   DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
   1782 
   1783   LOperand* key() { return inputs_[0]; }
   1784 
   1785   virtual void PrintDataTo(StringStream* stream);
   1786 
   1787   int arity() const { return hydrogen()->argument_count() - 1; }
   1788 };
   1789 
   1790 
   1791 class LCallNamed: public LTemplateInstruction<1, 0, 0> {
   1792  public:
   1793   DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
   1794   DECLARE_HYDROGEN_ACCESSOR(CallNamed)
   1795 
   1796   virtual void PrintDataTo(StringStream* stream);
   1797 
   1798   Handle<String> name() const { return hydrogen()->name(); }
   1799   int arity() const { return hydrogen()->argument_count() - 1; }
   1800 };
   1801 
   1802 
   1803 class LCallFunction: public LTemplateInstruction<1, 1, 0> {
   1804  public:
   1805   explicit LCallFunction(LOperand* function) {
   1806     inputs_[0] = function;
   1807   }
   1808 
   1809   DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
   1810   DECLARE_HYDROGEN_ACCESSOR(CallFunction)
   1811 
   1812   LOperand* function() { return inputs_[0]; }
   1813   int arity() const { return hydrogen()->argument_count() - 1; }
   1814 };
   1815 
   1816 
   1817 class LCallGlobal: public LTemplateInstruction<1, 0, 0> {
   1818  public:
   1819   DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
   1820   DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
   1821 
   1822   virtual void PrintDataTo(StringStream* stream);
   1823 
   1824   Handle<String> name() const {return hydrogen()->name(); }
   1825   int arity() const { return hydrogen()->argument_count() - 1; }
   1826 };
   1827 
   1828 
   1829 class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> {
   1830  public:
   1831   DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
   1832   DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
   1833 
   1834   virtual void PrintDataTo(StringStream* stream);
   1835 
   1836   int arity() const { return hydrogen()->argument_count() - 1;  }
   1837 };
   1838 
   1839 
   1840 class LCallNew: public LTemplateInstruction<1, 1, 0> {
   1841  public:
   1842   explicit LCallNew(LOperand* constructor) {
   1843     inputs_[0] = constructor;
   1844   }
   1845 
   1846   LOperand* constructor() { return inputs_[0]; }
   1847 
   1848   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
   1849   DECLARE_HYDROGEN_ACCESSOR(CallNew)
   1850 
   1851   virtual void PrintDataTo(StringStream* stream);
   1852 
   1853   int arity() const { return hydrogen()->argument_count() - 1; }
   1854 };
   1855 
   1856 
   1857 class LCallNewArray: public LTemplateInstruction<1, 1, 0> {
   1858  public:
   1859   explicit LCallNewArray(LOperand* constructor) {
   1860     inputs_[0] = constructor;
   1861   }
   1862 
   1863   LOperand* constructor() { return inputs_[0]; }
   1864 
   1865   DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
   1866   DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
   1867 
   1868   virtual void PrintDataTo(StringStream* stream);
   1869 
   1870   int arity() const { return hydrogen()->argument_count() - 1; }
   1871 };
   1872 
   1873 
   1874 class LCallRuntime: public LTemplateInstruction<1, 0, 0> {
   1875  public:
   1876   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   1877   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
   1878 
   1879   const Runtime::Function* function() const { return hydrogen()->function(); }
   1880   int arity() const { return hydrogen()->argument_count(); }
   1881 };
   1882 
   1883 
   1884 class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
   1885  public:
   1886   explicit LInteger32ToDouble(LOperand* value) {
   1887     inputs_[0] = value;
   1888   }
   1889 
   1890   LOperand* value() { return inputs_[0]; }
   1891 
   1892   DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
   1893 };
   1894 
   1895 
   1896 class LInteger32ToSmi: public LTemplateInstruction<1, 1, 0> {
   1897  public:
   1898   explicit LInteger32ToSmi(LOperand* value) {
   1899     inputs_[0] = value;
   1900   }
   1901 
   1902   LOperand* value() { return inputs_[0]; }
   1903 
   1904   DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
   1905   DECLARE_HYDROGEN_ACCESSOR(Change)
   1906 };
   1907 
   1908 
   1909 class LUint32ToDouble: public LTemplateInstruction<1, 1, 1> {
   1910  public:
   1911   explicit LUint32ToDouble(LOperand* value, LOperand* temp) {
   1912     inputs_[0] = value;
   1913     temps_[0] = temp;
   1914   }
   1915 
   1916   LOperand* value() { return inputs_[0]; }
   1917   LOperand* temp() { return temps_[0]; }
   1918 
   1919   DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
   1920 };
   1921 
   1922 
   1923 class LUint32ToSmi: public LTemplateInstruction<1, 1, 0> {
   1924  public:
   1925   explicit LUint32ToSmi(LOperand* value) {
   1926     inputs_[0] = value;
   1927   }
   1928 
   1929   LOperand* value() { return inputs_[0]; }
   1930 
   1931   DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi")
   1932   DECLARE_HYDROGEN_ACCESSOR(Change)
   1933 };
   1934 
   1935 
   1936 class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
   1937  public:
   1938   explicit LNumberTagI(LOperand* value) {
   1939     inputs_[0] = value;
   1940   }
   1941 
   1942   LOperand* value() { return inputs_[0]; }
   1943 
   1944   DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
   1945 };
   1946 
   1947 
   1948 class LNumberTagU: public LTemplateInstruction<1, 1, 1> {
   1949  public:
   1950   explicit LNumberTagU(LOperand* value, LOperand* temp) {
   1951     inputs_[0] = value;
   1952     temps_[0] = temp;
   1953   }
   1954 
   1955   LOperand* value() { return inputs_[0]; }
   1956   LOperand* temp() { return temps_[0]; }
   1957 
   1958   DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
   1959 };
   1960 
   1961 
   1962 class LNumberTagD: public LTemplateInstruction<1, 1, 1> {
   1963  public:
   1964   explicit LNumberTagD(LOperand* value, LOperand* temp) {
   1965     inputs_[0] = value;
   1966     temps_[0] = temp;
   1967   }
   1968 
   1969   LOperand* value() { return inputs_[0]; }
   1970   LOperand* temp() { return temps_[0]; }
   1971 
   1972   DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
   1973   DECLARE_HYDROGEN_ACCESSOR(Change)
   1974 };
   1975 
   1976 
   1977 // Sometimes truncating conversion from a tagged value to an int32.
   1978 class LDoubleToI: public LTemplateInstruction<1, 1, 0> {
   1979  public:
   1980   explicit LDoubleToI(LOperand* value) {
   1981     inputs_[0] = value;
   1982   }
   1983 
   1984   LOperand* value() { return inputs_[0]; }
   1985 
   1986   DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
   1987   DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
   1988 
   1989   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
   1990 };
   1991 
   1992 
   1993 class LDoubleToSmi: public LTemplateInstruction<1, 1, 0> {
   1994  public:
   1995   explicit LDoubleToSmi(LOperand* value) {
   1996     inputs_[0] = value;
   1997   }
   1998 
   1999   LOperand* value() { return inputs_[0]; }
   2000 
   2001   DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
   2002   DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
   2003 };
   2004 
   2005 
   2006 // Truncating conversion from a tagged value to an int32.
   2007 class LTaggedToI: public LTemplateInstruction<1, 1, 1> {
   2008  public:
   2009   LTaggedToI(LOperand* value, LOperand* temp) {
   2010     inputs_[0] = value;
   2011     temps_[0] = temp;
   2012   }
   2013 
   2014   LOperand* value() { return inputs_[0]; }
   2015   LOperand* temp() { return temps_[0]; }
   2016 
   2017   DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
   2018   DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
   2019 
   2020   bool truncating() { return hydrogen()->CanTruncateToInt32(); }
   2021 };
   2022 
   2023 
   2024 class LSmiTag: public LTemplateInstruction<1, 1, 0> {
   2025  public:
   2026   explicit LSmiTag(LOperand* value) {
   2027     inputs_[0] = value;
   2028   }
   2029 
   2030   LOperand* value() { return inputs_[0]; }
   2031 
   2032   DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
   2033 };
   2034 
   2035 
   2036 class LNumberUntagD: public LTemplateInstruction<1, 1, 0> {
   2037  public:
   2038   explicit LNumberUntagD(LOperand* value) {
   2039     inputs_[0] = value;
   2040   }
   2041 
   2042   LOperand* value() { return inputs_[0]; }
   2043 
   2044   DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
   2045   DECLARE_HYDROGEN_ACCESSOR(Change);
   2046 };
   2047 
   2048 
   2049 class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
   2050  public:
   2051   LSmiUntag(LOperand* value, bool needs_check)
   2052       : needs_check_(needs_check) {
   2053     inputs_[0] = value;
   2054   }
   2055 
   2056   LOperand* value() { return inputs_[0]; }
   2057   bool needs_check() const { return needs_check_; }
   2058 
   2059   DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
   2060 
   2061  private:
   2062   bool needs_check_;
   2063 };
   2064 
   2065 
   2066 class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
   2067  public:
   2068   LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
   2069     inputs_[0] = object;
   2070     inputs_[1] = value;
   2071     temps_[0] = temp;
   2072   }
   2073 
   2074   LOperand* object() { return inputs_[0]; }
   2075   LOperand* value() { return inputs_[1]; }
   2076   LOperand* temp() { return temps_[0]; }
   2077 
   2078   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   2079   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
   2080 
   2081   virtual void PrintDataTo(StringStream* stream);
   2082 
   2083   Handle<Map> transition() const { return hydrogen()->transition_map(); }
   2084   Representation representation() const {
   2085     return hydrogen()->field_representation();
   2086   }
   2087 };
   2088 
   2089 
   2090 class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
   2091  public:
   2092   LStoreNamedGeneric(LOperand* object, LOperand* value) {
   2093     inputs_[0] = object;
   2094     inputs_[1] = value;
   2095   }
   2096 
   2097   LOperand* object() { return inputs_[0]; }
   2098   LOperand* value() { return inputs_[1]; }
   2099 
   2100   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   2101   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
   2102 
   2103   virtual void PrintDataTo(StringStream* stream);
   2104 
   2105   Handle<Object> name() const { return hydrogen()->name(); }
   2106   StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
   2107 };
   2108 
   2109 
   2110 class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
   2111  public:
   2112   LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) {
   2113     inputs_[0] = object;
   2114     inputs_[1] = key;
   2115     inputs_[2] = value;
   2116   }
   2117 
   2118   bool is_external() const { return hydrogen()->is_external(); }
   2119   LOperand* elements() { return inputs_[0]; }
   2120   LOperand* key() { return inputs_[1]; }
   2121   LOperand* value() { return inputs_[2]; }
   2122   ElementsKind elements_kind() const { return hydrogen()->elements_kind(); }
   2123 
   2124   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
   2125   DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
   2126 
   2127   virtual void PrintDataTo(StringStream* stream);
   2128   bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
   2129   uint32_t additional_index() const { return hydrogen()->index_offset(); }
   2130 };
   2131 
   2132 
   2133 class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> {
   2134  public:
   2135   LStoreKeyedGeneric(LOperand* object, LOperand* key, LOperand* value) {
   2136     inputs_[0] = object;
   2137     inputs_[1] = key;
   2138     inputs_[2] = value;
   2139   }
   2140 
   2141   LOperand* object() { return inputs_[0]; }
   2142   LOperand* key() { return inputs_[1]; }
   2143   LOperand* value() { return inputs_[2]; }
   2144 
   2145   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
   2146   DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
   2147 
   2148   virtual void PrintDataTo(StringStream* stream);
   2149 
   2150   StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); }
   2151 };
   2152 
   2153 
   2154 class LTransitionElementsKind: public LTemplateInstruction<0, 1, 2> {
   2155  public:
   2156   LTransitionElementsKind(LOperand* object,
   2157                           LOperand* new_map_temp,
   2158                           LOperand* temp) {
   2159     inputs_[0] = object;
   2160     temps_[0] = new_map_temp;
   2161     temps_[1] = temp;
   2162   }
   2163 
   2164   LOperand* object() { return inputs_[0]; }
   2165   LOperand* new_map_temp() { return temps_[0]; }
   2166   LOperand* temp() { return temps_[1]; }
   2167 
   2168   DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
   2169                                "transition-elements-kind")
   2170   DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
   2171 
   2172   virtual void PrintDataTo(StringStream* stream);
   2173 
   2174   Handle<Map> original_map() { return hydrogen()->original_map(); }
   2175   Handle<Map> transitioned_map() { return hydrogen()->transitioned_map(); }
   2176   ElementsKind from_kind() { return hydrogen()->from_kind(); }
   2177   ElementsKind to_kind() { return hydrogen()->to_kind(); }
   2178 };
   2179 
   2180 
   2181 class LTrapAllocationMemento : public LTemplateInstruction<0, 1, 1> {
   2182  public:
   2183   LTrapAllocationMemento(LOperand* object,
   2184                          LOperand* temp) {
   2185     inputs_[0] = object;
   2186     temps_[0] = temp;
   2187   }
   2188 
   2189   LOperand* object() { return inputs_[0]; }
   2190   LOperand* temp() { return temps_[0]; }
   2191 
   2192   DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
   2193                                "trap-allocation-memento")
   2194 };
   2195 
   2196 
   2197 class LStringAdd: public LTemplateInstruction<1, 2, 0> {
   2198  public:
   2199   LStringAdd(LOperand* left, LOperand* right) {
   2200     inputs_[0] = left;
   2201     inputs_[1] = right;
   2202   }
   2203 
   2204   LOperand* left() { return inputs_[0]; }
   2205   LOperand* right() { return inputs_[1]; }
   2206 
   2207   DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
   2208   DECLARE_HYDROGEN_ACCESSOR(StringAdd)
   2209 };
   2210 
   2211 
   2212 class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
   2213  public:
   2214   LStringCharCodeAt(LOperand* string, LOperand* index) {
   2215     inputs_[0] = string;
   2216     inputs_[1] = index;
   2217   }
   2218 
   2219   LOperand* string() { return inputs_[0]; }
   2220   LOperand* index() { return inputs_[1]; }
   2221 
   2222   DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
   2223   DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
   2224 };
   2225 
   2226 
   2227 class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> {
   2228  public:
   2229   explicit LStringCharFromCode(LOperand* char_code) {
   2230     inputs_[0] = char_code;
   2231   }
   2232 
   2233   LOperand* char_code() { return inputs_[0]; }
   2234 
   2235   DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
   2236   DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
   2237 };
   2238 
   2239 
   2240 class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
   2241  public:
   2242   explicit LCheckFunction(LOperand* value) {
   2243     inputs_[0] = value;
   2244   }
   2245 
   2246   LOperand* value() { return inputs_[0]; }
   2247 
   2248   DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
   2249   DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
   2250 };
   2251 
   2252 
   2253 class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> {
   2254  public:
   2255   explicit LCheckInstanceType(LOperand* value) {
   2256     inputs_[0] = value;
   2257   }
   2258 
   2259   LOperand* value() { return inputs_[0]; }
   2260 
   2261   DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
   2262   DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
   2263 };
   2264 
   2265 
   2266 class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
   2267  public:
   2268   explicit LCheckMaps(LOperand* value) {
   2269     inputs_[0] = value;
   2270   }
   2271 
   2272   LOperand* value() { return inputs_[0]; }
   2273 
   2274   DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
   2275   DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
   2276 };
   2277 
   2278 
   2279 class LCheckSmi: public LTemplateInstruction<1, 1, 0> {
   2280  public:
   2281   explicit LCheckSmi(LOperand* value) {
   2282     inputs_[0] = value;
   2283   }
   2284 
   2285   LOperand* value() { return inputs_[0]; }
   2286 
   2287   DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
   2288 };
   2289 
   2290 
   2291 class LClampDToUint8: public LTemplateInstruction<1, 1, 0> {
   2292  public:
   2293   explicit LClampDToUint8(LOperand* unclamped) {
   2294     inputs_[0] = unclamped;
   2295   }
   2296 
   2297   LOperand* unclamped() { return inputs_[0]; }
   2298 
   2299   DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
   2300 };
   2301 
   2302 
   2303 class LClampIToUint8: public LTemplateInstruction<1, 1, 0> {
   2304  public:
   2305   explicit LClampIToUint8(LOperand* unclamped) {
   2306     inputs_[0] = unclamped;
   2307   }
   2308 
   2309   LOperand* unclamped() { return inputs_[0]; }
   2310 
   2311   DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
   2312 };
   2313 
   2314 
   2315 class LClampTToUint8: public LTemplateInstruction<1, 1, 1> {
   2316  public:
   2317   LClampTToUint8(LOperand* unclamped,
   2318                  LOperand* temp_xmm) {
   2319     inputs_[0] = unclamped;
   2320     temps_[0] = temp_xmm;
   2321   }
   2322 
   2323   LOperand* unclamped() { return inputs_[0]; }
   2324   LOperand* temp_xmm() { return temps_[0]; }
   2325 
   2326   DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
   2327 };
   2328 
   2329 
   2330 class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> {
   2331  public:
   2332   explicit LCheckNonSmi(LOperand* value) {
   2333     inputs_[0] = value;
   2334   }
   2335 
   2336   LOperand* value() { return inputs_[0]; }
   2337 
   2338   DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
   2339   DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
   2340 };
   2341 
   2342 
   2343 class LAllocate: public LTemplateInstruction<1, 1, 1> {
   2344  public:
   2345   LAllocate(LOperand* size, LOperand* temp) {
   2346     inputs_[0] = size;
   2347     temps_[0] = temp;
   2348   }
   2349 
   2350   LOperand* size() { return inputs_[0]; }
   2351   LOperand* temp() { return temps_[0]; }
   2352 
   2353   DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
   2354   DECLARE_HYDROGEN_ACCESSOR(Allocate)
   2355 };
   2356 
   2357 
   2358 class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> {
   2359  public:
   2360   DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
   2361   DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
   2362 };
   2363 
   2364 
   2365 class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> {
   2366  public:
   2367   DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
   2368   DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
   2369 };
   2370 
   2371 
   2372 class LToFastProperties: public LTemplateInstruction<1, 1, 0> {
   2373  public:
   2374   explicit LToFastProperties(LOperand* value) {
   2375     inputs_[0] = value;
   2376   }
   2377 
   2378   LOperand* value() { return inputs_[0]; }
   2379 
   2380   DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
   2381   DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
   2382 };
   2383 
   2384 
   2385 class LTypeof: public LTemplateInstruction<1, 1, 0> {
   2386  public:
   2387   explicit LTypeof(LOperand* value) {
   2388     inputs_[0] = value;
   2389   }
   2390 
   2391   LOperand* value() { return inputs_[0]; }
   2392 
   2393   DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
   2394 };
   2395 
   2396 
   2397 class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
   2398  public:
   2399   explicit LTypeofIsAndBranch(LOperand* value) {
   2400     inputs_[0] = value;
   2401   }
   2402 
   2403   LOperand* value() { return inputs_[0]; }
   2404 
   2405   DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
   2406   DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
   2407 
   2408   Handle<String> type_literal() { return hydrogen()->type_literal(); }
   2409 
   2410   virtual void PrintDataTo(StringStream* stream);
   2411 };
   2412 
   2413 
   2414 class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
   2415  public:
   2416   explicit LIsConstructCallAndBranch(LOperand* temp) {
   2417     temps_[0] = temp;
   2418   }
   2419 
   2420   LOperand* temp() { return temps_[0]; }
   2421 
   2422   DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
   2423                                "is-construct-call-and-branch")
   2424   DECLARE_HYDROGEN_ACCESSOR(IsConstructCallAndBranch)
   2425 };
   2426 
   2427 
   2428 class LOsrEntry: public LTemplateInstruction<0, 0, 0> {
   2429  public:
   2430   LOsrEntry() {}
   2431 
   2432   virtual bool HasInterestingComment(LCodeGen* gen) const { return false; }
   2433   DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
   2434 };
   2435 
   2436 
   2437 class LStackCheck: public LTemplateInstruction<0, 0, 0> {
   2438  public:
   2439   DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
   2440   DECLARE_HYDROGEN_ACCESSOR(StackCheck)
   2441 
   2442   Label* done_label() { return &done_label_; }
   2443 
   2444  private:
   2445   Label done_label_;
   2446 };
   2447 
   2448 
   2449 class LForInPrepareMap: public LTemplateInstruction<1, 1, 0> {
   2450  public:
   2451   explicit LForInPrepareMap(LOperand* object) {
   2452     inputs_[0] = object;
   2453   }
   2454 
   2455   LOperand* object() { return inputs_[0]; }
   2456 
   2457   DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
   2458 };
   2459 
   2460 
   2461 class LForInCacheArray: public LTemplateInstruction<1, 1, 0> {
   2462  public:
   2463   explicit LForInCacheArray(LOperand* map) {
   2464     inputs_[0] = map;
   2465   }
   2466 
   2467   LOperand* map() { return inputs_[0]; }
   2468 
   2469   DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
   2470 
   2471   int idx() {
   2472     return HForInCacheArray::cast(this->hydrogen_value())->idx();
   2473   }
   2474 };
   2475 
   2476 
   2477 class LCheckMapValue: public LTemplateInstruction<0, 2, 0> {
   2478  public:
   2479   LCheckMapValue(LOperand* value, LOperand* map) {
   2480     inputs_[0] = value;
   2481     inputs_[1] = map;
   2482   }
   2483 
   2484   LOperand* value() { return inputs_[0]; }
   2485   LOperand* map() { return inputs_[1]; }
   2486 
   2487   DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
   2488 };
   2489 
   2490 
   2491 class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
   2492  public:
   2493   LLoadFieldByIndex(LOperand* object, LOperand* index) {
   2494     inputs_[0] = object;
   2495     inputs_[1] = index;
   2496   }
   2497 
   2498   LOperand* object() { return inputs_[0]; }
   2499   LOperand* index() { return inputs_[1]; }
   2500 
   2501   DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
   2502 };
   2503 
   2504 
   2505 class LChunkBuilder;
   2506 class LPlatformChunk: public LChunk {
   2507  public:
   2508   LPlatformChunk(CompilationInfo* info, HGraph* graph)
   2509       : LChunk(info, graph) { }
   2510 
   2511   int GetNextSpillIndex(bool is_double);
   2512   LOperand* GetNextSpillSlot(bool is_double);
   2513 };
   2514 
   2515 
   2516 class LChunkBuilder BASE_EMBEDDED {
   2517  public:
   2518   LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
   2519       : chunk_(NULL),
   2520         info_(info),
   2521         graph_(graph),
   2522         zone_(graph->zone()),
   2523         status_(UNUSED),
   2524         current_instruction_(NULL),
   2525         current_block_(NULL),
   2526         next_block_(NULL),
   2527         argument_count_(0),
   2528         allocator_(allocator),
   2529         position_(RelocInfo::kNoPosition),
   2530         instruction_pending_deoptimization_environment_(NULL),
   2531         pending_deoptimization_ast_id_(BailoutId::None()) { }
   2532 
   2533   // Build the sequence for the graph.
   2534   LPlatformChunk* Build();
   2535 
   2536   // Declare methods that deal with the individual node types.
   2537 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
   2538   HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
   2539 #undef DECLARE_DO
   2540 
   2541   static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
   2542 
   2543   LInstruction* DoMathFloor(HUnaryMathOperation* instr);
   2544   LInstruction* DoMathRound(HUnaryMathOperation* instr);
   2545   LInstruction* DoMathAbs(HUnaryMathOperation* instr);
   2546   LInstruction* DoMathLog(HUnaryMathOperation* instr);
   2547   LInstruction* DoMathSin(HUnaryMathOperation* instr);
   2548   LInstruction* DoMathCos(HUnaryMathOperation* instr);
   2549   LInstruction* DoMathTan(HUnaryMathOperation* instr);
   2550   LInstruction* DoMathExp(HUnaryMathOperation* instr);
   2551   LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
   2552   LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
   2553 
   2554  private:
   2555   enum Status {
   2556     UNUSED,
   2557     BUILDING,
   2558     DONE,
   2559     ABORTED
   2560   };
   2561 
   2562   LPlatformChunk* chunk() const { return chunk_; }
   2563   CompilationInfo* info() const { return info_; }
   2564   HGraph* graph() const { return graph_; }
   2565   Zone* zone() const { return zone_; }
   2566 
   2567   bool is_unused() const { return status_ == UNUSED; }
   2568   bool is_building() const { return status_ == BUILDING; }
   2569   bool is_done() const { return status_ == DONE; }
   2570   bool is_aborted() const { return status_ == ABORTED; }
   2571 
   2572   void Abort(BailoutReason reason);
   2573 
   2574   // Methods for getting operands for Use / Define / Temp.
   2575   LUnallocated* ToUnallocated(Register reg);
   2576   LUnallocated* ToUnallocated(XMMRegister reg);
   2577 
   2578   // Methods for setting up define-use relationships.
   2579   MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
   2580   MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
   2581   MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
   2582                                            XMMRegister fixed_register);
   2583 
   2584   // A value that is guaranteed to be allocated to a register.
   2585   // Operand created by UseRegister is guaranteed to be live until the end of
   2586   // instruction. This means that register allocator will not reuse it's
   2587   // register for any other operand inside instruction.
   2588   // Operand created by UseRegisterAtStart is guaranteed to be live only at
   2589   // instruction start. Register allocator is free to assign the same register
   2590   // to some other operand used inside instruction (i.e. temporary or
   2591   // output).
   2592   MUST_USE_RESULT LOperand* UseRegister(HValue* value);
   2593   MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
   2594 
   2595   // An input operand in a register that may be trashed.
   2596   MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
   2597 
   2598   // An input operand in a register or stack slot.
   2599   MUST_USE_RESULT LOperand* Use(HValue* value);
   2600   MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
   2601 
   2602   // An input operand in a register, stack slot or a constant operand.
   2603   MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
   2604   MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
   2605 
   2606   // An input operand in a register or a constant operand.
   2607   MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
   2608   MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
   2609 
   2610   // An input operand in a constant operand.
   2611   MUST_USE_RESULT LOperand* UseConstant(HValue* value);
   2612 
   2613   // An input operand in register, stack slot or a constant operand.
   2614   // Will not be moved to a register even if one is freely available.
   2615   MUST_USE_RESULT LOperand* UseAny(HValue* value);
   2616 
   2617   // Temporary operand that must be in a register.
   2618   MUST_USE_RESULT LUnallocated* TempRegister();
   2619   MUST_USE_RESULT LOperand* FixedTemp(Register reg);
   2620   MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg);
   2621 
   2622   // Methods for setting up define-use relationships.
   2623   // Return the same instruction that they are passed.
   2624   template<int I, int T>
   2625       LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
   2626                            LUnallocated* result);
   2627   template<int I, int T>
   2628       LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
   2629   template<int I, int T>
   2630       LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
   2631                                     int index);
   2632   template<int I, int T>
   2633       LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
   2634   template<int I, int T>
   2635       LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
   2636                                 Register reg);
   2637   template<int I, int T>
   2638       LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
   2639                                       XMMRegister reg);
   2640   // Assigns an environment to an instruction.  An instruction which can
   2641   // deoptimize must have an environment.
   2642   LInstruction* AssignEnvironment(LInstruction* instr);
   2643   // Assigns a pointer map to an instruction.  An instruction which can
   2644   // trigger a GC or a lazy deoptimization must have a pointer map.
   2645   LInstruction* AssignPointerMap(LInstruction* instr);
   2646 
   2647   enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
   2648 
   2649   // Marks a call for the register allocator.  Assigns a pointer map to
   2650   // support GC and lazy deoptimization.  Assigns an environment to support
   2651   // eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
   2652   LInstruction* MarkAsCall(
   2653       LInstruction* instr,
   2654       HInstruction* hinstr,
   2655       CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
   2656 
   2657   LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
   2658                                   int* argument_index_accumulator,
   2659                                   ZoneList<HValue*>* objects_to_materialize);
   2660 
   2661   void VisitInstruction(HInstruction* current);
   2662 
   2663   void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
   2664   LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
   2665   LInstruction* DoArithmeticD(Token::Value op,
   2666                               HArithmeticBinaryOperation* instr);
   2667   LInstruction* DoArithmeticT(Token::Value op,
   2668                               HArithmeticBinaryOperation* instr);
   2669 
   2670   LPlatformChunk* chunk_;
   2671   CompilationInfo* info_;
   2672   HGraph* const graph_;
   2673   Zone* zone_;
   2674   Status status_;
   2675   HInstruction* current_instruction_;
   2676   HBasicBlock* current_block_;
   2677   HBasicBlock* next_block_;
   2678   int argument_count_;
   2679   LAllocator* allocator_;
   2680   int position_;
   2681   LInstruction* instruction_pending_deoptimization_environment_;
   2682   BailoutId pending_deoptimization_ast_id_;
   2683 
   2684   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
   2685 };
   2686 
   2687 #undef DECLARE_HYDROGEN_ACCESSOR
   2688 #undef DECLARE_CONCRETE_INSTRUCTION
   2689 
   2690 } }  // namespace v8::int
   2691 
   2692 #endif  // V8_X64_LITHIUM_X64_H_
   2693