LCOV - code coverage report
Current view: top level - src/crankshaft - hydrogen-instructions.h (source / functions) Hit Total Coverage
Test: app.info Lines: 1402 1640 85.5 %
Date: 2017-04-26 Functions: 581 901 64.5 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_
       6             : #define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_
       7             : 
       8             : #include <cstring>
       9             : #include <iosfwd>
      10             : 
      11             : #include "src/allocation.h"
      12             : #include "src/ast/ast.h"
      13             : #include "src/base/bits.h"
      14             : #include "src/bit-vector.h"
      15             : #include "src/conversions.h"
      16             : #include "src/crankshaft/hydrogen-types.h"
      17             : #include "src/crankshaft/unique.h"
      18             : #include "src/deoptimizer.h"
      19             : #include "src/globals.h"
      20             : #include "src/interface-descriptors.h"
      21             : #include "src/small-pointer-list.h"
      22             : #include "src/utils.h"
      23             : #include "src/zone/zone.h"
      24             : 
      25             : namespace v8 {
      26             : namespace internal {
      27             : 
      28             : // Forward declarations.
      29             : struct ChangesOf;
      30             : class HBasicBlock;
      31             : class HDiv;
      32             : class HEnvironment;
      33             : class HInferRepresentationPhase;
      34             : class HInstruction;
      35             : class HLoopInformation;
      36             : class HStoreNamedField;
      37             : class HValue;
      38             : class LInstruction;
      39             : class LChunkBuilder;
      40             : class SmallMapList;
      41             : 
      42             : #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
      43             :   V(ArithmeticBinaryOperation)                \
      44             :   V(BinaryOperation)                          \
      45             :   V(BitwiseBinaryOperation)                   \
      46             :   V(ControlInstruction)                       \
      47             :   V(Instruction)
      48             : 
      49             : #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
      50             :   V(AbnormalExit)                             \
      51             :   V(AccessArgumentsAt)                        \
      52             :   V(Add)                                      \
      53             :   V(Allocate)                                 \
      54             :   V(ApplyArguments)                           \
      55             :   V(ArgumentsElements)                        \
      56             :   V(ArgumentsLength)                          \
      57             :   V(ArgumentsObject)                          \
      58             :   V(Bitwise)                                  \
      59             :   V(BlockEntry)                               \
      60             :   V(BoundsCheck)                              \
      61             :   V(Branch)                                   \
      62             :   V(CallWithDescriptor)                       \
      63             :   V(CallNewArray)                             \
      64             :   V(CallRuntime)                              \
      65             :   V(CapturedObject)                           \
      66             :   V(Change)                                   \
      67             :   V(CheckArrayBufferNotNeutered)              \
      68             :   V(CheckHeapObject)                          \
      69             :   V(CheckInstanceType)                        \
      70             :   V(CheckMaps)                                \
      71             :   V(CheckMapValue)                            \
      72             :   V(CheckSmi)                                 \
      73             :   V(CheckValue)                               \
      74             :   V(ClampToUint8)                             \
      75             :   V(ClassOfTestAndBranch)                     \
      76             :   V(CompareNumericAndBranch)                  \
      77             :   V(CompareHoleAndBranch)                     \
      78             :   V(CompareGeneric)                           \
      79             :   V(CompareObjectEqAndBranch)                 \
      80             :   V(CompareMap)                               \
      81             :   V(Constant)                                 \
      82             :   V(Context)                                  \
      83             :   V(DebugBreak)                               \
      84             :   V(DeclareGlobals)                           \
      85             :   V(Deoptimize)                               \
      86             :   V(Div)                                      \
      87             :   V(DummyUse)                                 \
      88             :   V(EnterInlined)                             \
      89             :   V(EnvironmentMarker)                        \
      90             :   V(ForceRepresentation)                      \
      91             :   V(ForInCacheArray)                          \
      92             :   V(ForInPrepareMap)                          \
      93             :   V(Goto)                                     \
      94             :   V(HasInstanceTypeAndBranch)                 \
      95             :   V(InnerAllocatedObject)                     \
      96             :   V(InvokeFunction)                           \
      97             :   V(HasInPrototypeChainAndBranch)             \
      98             :   V(IsStringAndBranch)                        \
      99             :   V(IsSmiAndBranch)                           \
     100             :   V(IsUndetectableAndBranch)                  \
     101             :   V(LeaveInlined)                             \
     102             :   V(LoadContextSlot)                          \
     103             :   V(LoadFieldByIndex)                         \
     104             :   V(LoadFunctionPrototype)                    \
     105             :   V(LoadKeyed)                                \
     106             :   V(LoadNamedField)                           \
     107             :   V(LoadRoot)                                 \
     108             :   V(MathFloorOfDiv)                           \
     109             :   V(MathMinMax)                               \
     110             :   V(MaybeGrowElements)                        \
     111             :   V(Mod)                                      \
     112             :   V(Mul)                                      \
     113             :   V(OsrEntry)                                 \
     114             :   V(Parameter)                                \
     115             :   V(Power)                                    \
     116             :   V(Prologue)                                 \
     117             :   V(PushArguments)                            \
     118             :   V(Return)                                   \
     119             :   V(Ror)                                      \
     120             :   V(Sar)                                      \
     121             :   V(SeqStringGetChar)                         \
     122             :   V(SeqStringSetChar)                         \
     123             :   V(Shl)                                      \
     124             :   V(Shr)                                      \
     125             :   V(Simulate)                                 \
     126             :   V(StackCheck)                               \
     127             :   V(StoreCodeEntry)                           \
     128             :   V(StoreContextSlot)                         \
     129             :   V(StoreKeyed)                               \
     130             :   V(StoreNamedField)                          \
     131             :   V(StringAdd)                                \
     132             :   V(StringCharCodeAt)                         \
     133             :   V(StringCharFromCode)                       \
     134             :   V(StringCompareAndBranch)                   \
     135             :   V(Sub)                                      \
     136             :   V(ThisFunction)                             \
     137             :   V(TransitionElementsKind)                   \
     138             :   V(TrapAllocationMemento)                    \
     139             :   V(Typeof)                                   \
     140             :   V(TypeofIsAndBranch)                        \
     141             :   V(UnaryMathOperation)                       \
     142             :   V(UnknownOSRValue)                          \
     143             :   V(UseConst)                                 \
     144             :   V(WrapReceiver)
     145             : 
     146             : #define GVN_TRACKED_FLAG_LIST(V)               \
     147             :   V(NewSpacePromotion)
     148             : 
     149             : #define GVN_UNTRACKED_FLAG_LIST(V)             \
     150             :   V(ArrayElements)                             \
     151             :   V(ArrayLengths)                              \
     152             :   V(StringLengths)                             \
     153             :   V(BackingStoreFields)                        \
     154             :   V(Calls)                                     \
     155             :   V(ContextSlots)                              \
     156             :   V(DoubleArrayElements)                       \
     157             :   V(DoubleFields)                              \
     158             :   V(ElementsKind)                              \
     159             :   V(ElementsPointer)                           \
     160             :   V(GlobalVars)                                \
     161             :   V(InobjectFields)                            \
     162             :   V(Maps)                                      \
     163             :   V(OsrEntries)                                \
     164             :   V(ExternalMemory)                            \
     165             :   V(StringChars)                               \
     166             :   V(TypedArrayElements)
     167             : 
     168             : 
     169             : #define DECLARE_ABSTRACT_INSTRUCTION(type)     \
     170             :   bool Is##type() const final { return true; } \
     171             :   static H##type* cast(HValue* value) {        \
     172             :     DCHECK(value->Is##type());                 \
     173             :     return reinterpret_cast<H##type*>(value);  \
     174             :   }
     175             : 
     176             : 
     177             : #define DECLARE_CONCRETE_INSTRUCTION(type)                      \
     178             :   LInstruction* CompileToLithium(LChunkBuilder* builder) final; \
     179             :   static H##type* cast(HValue* value) {                         \
     180             :     DCHECK(value->Is##type());                                  \
     181             :     return reinterpret_cast<H##type*>(value);                   \
     182             :   }                                                             \
     183             :   Opcode opcode() const final { return HValue::k##type; }
     184             : 
     185             : 
     186             : enum PropertyAccessType { LOAD, STORE };
     187             : 
     188             : Representation RepresentationFromMachineType(MachineType type);
     189             : 
     190             : class Range final : public ZoneObject {
     191             :  public:
     192             :   Range()
     193             :       : lower_(kMinInt),
     194             :         upper_(kMaxInt),
     195             :         next_(NULL),
     196     7856706 :         can_be_minus_zero_(false) { }
     197             : 
     198             :   Range(int32_t lower, int32_t upper)
     199             :       : lower_(lower),
     200             :         upper_(upper),
     201             :         next_(NULL),
     202     3639836 :         can_be_minus_zero_(false) { }
     203             : 
     204             :   int32_t upper() const { return upper_; }
     205             :   int32_t lower() const { return lower_; }
     206             :   Range* next() const { return next_; }
     207             :   Range* CopyClearLower(Zone* zone) const {
     208      149278 :     return new(zone) Range(kMinInt, upper_);
     209             :   }
     210             :   Range* CopyClearUpper(Zone* zone) const {
     211      149278 :     return new(zone) Range(lower_, kMaxInt);
     212             :   }
     213      748872 :   Range* Copy(Zone* zone) const {
     214      748874 :     Range* result = new(zone) Range(lower_, upper_);
     215             :     result->set_can_be_minus_zero(CanBeMinusZero());
     216      748874 :     return result;
     217             :   }
     218             :   int32_t Mask() const;
     219     9103544 :   void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
     220     2889321 :   bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
     221     1711810 :   bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
     222             :   bool CanBeNegative() const { return lower_ < 0; }
     223             :   bool CanBePositive() const { return upper_ > 0; }
     224       18790 :   bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
     225             :   bool IsMostGeneric() const {
     226      530758 :     return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
     227             :   }
     228             :   bool IsInSmiRange() const {
     229             :     return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
     230             :   }
     231             :   void ClampToSmi() {
     232             :     lower_ = Max(lower_, Smi::kMinValue);
     233      114828 :     upper_ = Min(upper_, Smi::kMaxValue);
     234             :   }
     235             :   void Clear();
     236             :   void KeepOrder();
     237             : #ifdef DEBUG
     238             :   void Verify() const;
     239             : #endif
     240             : 
     241             :   void StackUpon(Range* other) {
     242      438859 :     Intersect(other);
     243      438859 :     next_ = other;
     244             :   }
     245             : 
     246             :   void Intersect(Range* other);
     247             :   void Union(Range* other);
     248             :   void CombinedMax(Range* other);
     249             :   void CombinedMin(Range* other);
     250             : 
     251             :   void AddConstant(int32_t value);
     252             :   void Sar(int32_t value);
     253             :   void Shl(int32_t value);
     254             :   bool AddAndCheckOverflow(const Representation& r, Range* other);
     255             :   bool SubAndCheckOverflow(const Representation& r, Range* other);
     256             :   bool MulAndCheckOverflow(const Representation& r, Range* other);
     257             : 
     258             :  private:
     259             :   int32_t lower_;
     260             :   int32_t upper_;
     261             :   Range* next_;
     262             :   bool can_be_minus_zero_;
     263             : };
     264             : 
     265             : 
     266             : class HUseListNode: public ZoneObject {
     267             :  public:
     268             :   HUseListNode(HValue* value, int index, HUseListNode* tail)
     269    24165101 :       : tail_(tail), value_(value), index_(index) {
     270             :   }
     271             : 
     272             :   HUseListNode* tail();
     273             :   HValue* value() const { return value_; }
     274             :   int index() const { return index_; }
     275             : 
     276     9528944 :   void set_tail(HUseListNode* list) { tail_ = list; }
     277             : 
     278             : #ifdef DEBUG
     279             :   void Zap() {
     280             :     tail_ = reinterpret_cast<HUseListNode*>(1);
     281             :     value_ = NULL;
     282             :     index_ = -1;
     283             :   }
     284             : #endif
     285             : 
     286             :  private:
     287             :   HUseListNode* tail_;
     288             :   HValue* value_;
     289             :   int index_;
     290             : };
     291             : 
     292             : 
     293             : // We reuse use list nodes behind the scenes as uses are added and deleted.
     294             : // This class is the safe way to iterate uses while deleting them.
     295             : class HUseIterator final BASE_EMBEDDED {
     296             :  public:
     297       10949 :   bool Done() { return current_ == NULL; }
     298             :   void Advance();
     299             : 
     300        7446 :   HValue* value() {
     301             :     DCHECK(!Done());
     302        7446 :     return value_;
     303             :   }
     304             : 
     305             :   int index() {
     306             :     DCHECK(!Done());
     307             :     return index_;
     308             :   }
     309             : 
     310             :  private:
     311             :   explicit HUseIterator(HUseListNode* head);
     312             : 
     313             :   HUseListNode* current_;
     314             :   HUseListNode* next_;
     315             :   HValue* value_;
     316             :   int index_;
     317             : 
     318             :   friend class HValue;
     319             : };
     320             : 
     321             : 
     322             : // All tracked flags should appear before untracked ones.
     323             : enum GVNFlag {
     324             :   // Declare global value numbering flags.
     325             : #define DECLARE_FLAG(Type) k##Type,
     326             :   GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
     327             :   GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
     328             : #undef DECLARE_FLAG
     329             : #define COUNT_FLAG(Type) + 1
     330             :   kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG),
     331             :   kNumberOfUntrackedSideEffects = 0 GVN_UNTRACKED_FLAG_LIST(COUNT_FLAG),
     332             : #undef COUNT_FLAG
     333             :   kNumberOfFlags = kNumberOfTrackedSideEffects + kNumberOfUntrackedSideEffects
     334             : };
     335             : 
     336             : 
     337             : static inline GVNFlag GVNFlagFromInt(int i) {
     338             :   DCHECK(i >= 0);
     339             :   DCHECK(i < kNumberOfFlags);
     340      293087 :   return static_cast<GVNFlag>(i);
     341             : }
     342             : 
     343             : 
     344             : class DecompositionResult final BASE_EMBEDDED {
     345             :  public:
     346             :   DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
     347             : 
     348             :   HValue* base() { return base_; }
     349             :   int offset() { return offset_; }
     350             :   int scale() { return scale_; }
     351             : 
     352             :   bool Apply(HValue* other_base, int other_offset, int other_scale = 0) {
     353             :     if (base_ == NULL) {
     354             :       base_ = other_base;
     355             :       offset_ = other_offset;
     356             :       scale_ = other_scale;
     357             :       return true;
     358             :     } else {
     359             :       if (scale_ == 0) {
     360             :         base_ = other_base;
     361             :         offset_ += other_offset;
     362             :         scale_ = other_scale;
     363             :         return true;
     364             :       } else {
     365             :         return false;
     366             :       }
     367             :     }
     368             :   }
     369             : 
     370             :   void SwapValues(HValue** other_base, int* other_offset, int* other_scale) {
     371             :     swap(&base_, other_base);
     372             :     swap(&offset_, other_offset);
     373             :     swap(&scale_, other_scale);
     374             :   }
     375             : 
     376             :  private:
     377             :   template <class T> void swap(T* a, T* b) {
     378             :     T c(*a);
     379             :     *a = *b;
     380             :     *b = c;
     381             :   }
     382             : 
     383             :   HValue* base_;
     384             :   int offset_;
     385             :   int scale_;
     386             : };
     387             : 
     388             : 
     389             : typedef EnumSet<GVNFlag, int32_t> GVNFlagSet;
     390             : 
     391             : 
     392             : class HValue : public ZoneObject {
     393             :  public:
     394             :   static const int kNoNumber = -1;
     395             : 
     396             :   enum Flag {
     397             :     kFlexibleRepresentation,
     398             :     kCannotBeTagged,
     399             :     // Participate in Global Value Numbering, i.e. elimination of
     400             :     // unnecessary recomputations. If an instruction sets this flag, it must
     401             :     // implement DataEquals(), which will be used to determine if other
     402             :     // occurrences of the instruction are indeed the same.
     403             :     kUseGVN,
     404             :     // Track instructions that are dominating side effects. If an instruction
     405             :     // sets this flag, it must implement HandleSideEffectDominator() and should
     406             :     // indicate which side effects to track by setting GVN flags.
     407             :     kTrackSideEffectDominators,
     408             :     kCanOverflow,
     409             :     kBailoutOnMinusZero,
     410             :     kCanBeDivByZero,
     411             :     kLeftCanBeMinInt,
     412             :     kLeftCanBeNegative,
     413             :     kLeftCanBePositive,
     414             :     kTruncatingToNumber,
     415             :     kIsArguments,
     416             :     kTruncatingToInt32,
     417             :     kAllUsesTruncatingToInt32,
     418             :     kTruncatingToSmi,
     419             :     kAllUsesTruncatingToSmi,
     420             :     // Set after an instruction is killed.
     421             :     kIsDead,
     422             :     // Instructions that are allowed to produce full range unsigned integer
     423             :     // values are marked with kUint32 flag. If arithmetic shift or a load from
     424             :     // EXTERNAL_UINT32_ELEMENTS array is not marked with this flag
     425             :     // it will deoptimize if result does not fit into signed integer range.
     426             :     // HGraph::ComputeSafeUint32Operations is responsible for setting this
     427             :     // flag.
     428             :     kUint32,
     429             :     kHasNoObservableSideEffects,
     430             :     // Indicates an instruction shouldn't be replaced by optimization, this flag
     431             :     // is useful to set in cases where recomputing a value is cheaper than
     432             :     // extending the value's live range and spilling it.
     433             :     kCantBeReplaced,
     434             :     // Indicates the instruction is live during dead code elimination.
     435             :     kIsLive,
     436             : 
     437             :     // HEnvironmentMarkers are deleted before dead code
     438             :     // elimination takes place, so they can repurpose the kIsLive flag:
     439             :     kEndsLiveRange = kIsLive,
     440             : 
     441             :     // TODO(everyone): Don't forget to update this!
     442             :     kLastFlag = kIsLive
     443             :   };
     444             : 
     445             :   STATIC_ASSERT(kLastFlag < kBitsPerInt);
     446             : 
     447             :   static HValue* cast(HValue* value) { return value; }
     448             : 
     449             :   enum Opcode {
     450             :     // Declare a unique enum value for each hydrogen instruction.
     451             :   #define DECLARE_OPCODE(type) k##type,
     452             :     HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
     453             :     kPhi
     454             :   #undef DECLARE_OPCODE
     455             :   };
     456             :   virtual Opcode opcode() const = 0;
     457             : 
     458             :   // Declare a non-virtual predicates for each concrete HInstruction or HValue.
     459             :   #define DECLARE_PREDICATE(type) \
     460             :     bool Is##type() const { return opcode() == k##type; }
     461   527604391 :     HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
     462             :   #undef DECLARE_PREDICATE
     463    18613200 :     bool IsPhi() const { return opcode() == kPhi; }
     464             : 
     465             :   // Declare virtual predicates for abstract HInstruction or HValue
     466             :   #define DECLARE_PREDICATE(type) \
     467             :     virtual bool Is##type() const { return false; }
     468    71278816 :     HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
     469             :   #undef DECLARE_PREDICATE
     470             : 
     471             :   bool IsBitwiseBinaryShift() {
     472             :     return IsShl() || IsShr() || IsSar();
     473             :   }
     474             : 
     475             :   explicit HValue(HType type = HType::Tagged())
     476             :       : block_(NULL),
     477             :         id_(kNoNumber),
     478             :         type_(type),
     479             :         use_list_(NULL),
     480             :         range_(NULL),
     481             : #ifdef DEBUG
     482             :         range_poisoned_(false),
     483             : #endif
     484    66373426 :         flags_(0) {}
     485           0 :   virtual ~HValue() {}
     486             : 
     487           0 :   virtual SourcePosition position() const { return SourcePosition::Unknown(); }
     488             : 
     489             :   HBasicBlock* block() const { return block_; }
     490             :   void SetBlock(HBasicBlock* block);
     491             : 
     492             :   // Note: Never call this method for an unlinked value.
     493             :   Isolate* isolate() const;
     494             : 
     495             :   int id() const { return id_; }
     496             :   void set_id(int id) { id_ = id; }
     497             : 
     498    13247756 :   HUseIterator uses() const { return HUseIterator(use_list_); }
     499             : 
     500    49094980 :   virtual bool EmitAtUses() { return false; }
     501             : 
     502             :   Representation representation() const { return representation_; }
     503             :   void ChangeRepresentation(Representation r) {
     504             :     DCHECK(CheckFlag(kFlexibleRepresentation));
     505             :     DCHECK(!CheckFlag(kCannotBeTagged) || !r.IsTagged());
     506     1402140 :     RepresentationChanged(r);
     507     1402145 :     representation_ = r;
     508     1399814 :     if (r.IsTagged()) {
     509             :       // Tagged is the bottom of the lattice, don't go any further.
     510             :       ClearFlag(kFlexibleRepresentation);
     511             :     }
     512             :   }
     513             :   virtual void AssumeRepresentation(Representation r);
     514             : 
     515     1362103 :   virtual Representation KnownOptimalRepresentation() {
     516             :     Representation r = representation();
     517     1362103 :     if (r.IsTagged()) {
     518             :       HType t = type();
     519      150802 :       if (t.IsSmi()) return Representation::Smi();
     520      150802 :       if (t.IsHeapNumber()) return Representation::Double();
     521      150802 :       if (t.IsHeapObject()) return r;
     522             :       return Representation::None();
     523             :     }
     524     1211301 :     return r;
     525             :   }
     526             : 
     527             :   HType type() const { return type_; }
     528             :   void set_type(HType new_type) {
     529             :     DCHECK(new_type.IsSubtypeOf(type_));
     530     4087262 :     type_ = new_type;
     531             :   }
     532             : 
     533             :   // There are HInstructions that do not really change a value, they
     534             :   // only add pieces of information to it (like bounds checks, map checks,
     535             :   // smi checks...).
     536             :   // We call these instructions "informative definitions", or "iDef".
     537             :   // One of the iDef operands is special because it is the value that is
     538             :   // "transferred" to the output, we call it the "redefined operand".
     539             :   // If an HValue is an iDef it must override RedefinedOperandIndex() so that
     540             :   // it does not return kNoRedefinedOperand;
     541             :   static const int kNoRedefinedOperand = -1;
     542    27273961 :   virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; }
     543             :   bool IsInformativeDefinition() {
     544             :     return RedefinedOperandIndex() != kNoRedefinedOperand;
     545             :   }
     546           0 :   HValue* RedefinedOperand() {
     547           0 :     int index = RedefinedOperandIndex();
     548           0 :     return index == kNoRedefinedOperand ? NULL : OperandAt(index);
     549             :   }
     550             : 
     551             :   bool CanReplaceWithDummyUses();
     552             : 
     553    21934896 :   virtual int argument_delta() const { return 0; }
     554             : 
     555             :   // A purely informative definition is an idef that will not emit code and
     556             :   // should therefore be removed from the graph in the RestoreActualValues
     557             :   // phase (so that live ranges will be shorter).
     558      281128 :   virtual bool IsPurelyInformativeDefinition() { return false; }
     559             : 
     560             :   // This method must always return the original HValue SSA definition,
     561             :   // regardless of any chain of iDefs of this value.
     562    27257773 :   HValue* ActualValue() {
     563             :     HValue* value = this;
     564             :     int index;
     565    55430099 :     while ((index = value->RedefinedOperandIndex()) != kNoRedefinedOperand) {
     566      914553 :       value = value->OperandAt(index);
     567             :     }
     568    27257765 :     return value;
     569             :   }
     570             : 
     571             :   bool IsInteger32Constant();
     572             :   int32_t GetInteger32Constant();
     573             :   bool EqualsInteger32Constant(int32_t value);
     574             : 
     575             :   bool IsDefinedAfter(HBasicBlock* other) const;
     576             : 
     577             :   // Operands.
     578             :   virtual int OperandCount() const = 0;
     579             :   virtual HValue* OperandAt(int index) const = 0;
     580             :   void SetOperandAt(int index, HValue* value);
     581             : 
     582             :   void DeleteAndReplaceWith(HValue* other);
     583             :   void ReplaceAllUsesWith(HValue* other);
     584             :   bool HasNoUses() const { return use_list_ == NULL; }
     585        3341 :   bool HasOneUse() const {
     586      206934 :     return use_list_ != NULL && use_list_->tail() == NULL;
     587             :   }
     588             :   bool HasMultipleUses() const {
     589             :     return use_list_ != NULL && use_list_->tail() != NULL;
     590             :   }
     591             :   int UseCount() const;
     592             : 
     593             :   // Mark this HValue as dead and to be removed from other HValues' use lists.
     594             :   void Kill();
     595             : 
     596             :   int flags() const { return flags_; }
     597    24370669 :   void SetFlag(Flag f) { flags_ |= (1 << f); }
     598     4099497 :   void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
     599   257529040 :   bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
     600       15062 :   void CopyFlag(Flag f, HValue* other) {
     601       15062 :     if (other->CheckFlag(f)) SetFlag(f);
     602             :   }
     603             : 
     604             :   // Returns true if the flag specified is set for all uses, false otherwise.
     605             :   bool CheckUsesForFlag(Flag f) const;
     606             :   // Same as before and the first one without the flag is returned in value.
     607             :   bool CheckUsesForFlag(Flag f, HValue** value) const;
     608             :   // Returns true if the flag specified is set for all uses, and this set
     609             :   // of uses is non-empty.
     610             :   bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const;
     611             : 
     612             :   GVNFlagSet ChangesFlags() const { return changes_flags_; }
     613             :   GVNFlagSet DependsOnFlags() const { return depends_on_flags_; }
     614             :   void SetChangesFlag(GVNFlag f) { changes_flags_.Add(f); }
     615             :   void SetDependsOnFlag(GVNFlag f) { depends_on_flags_.Add(f); }
     616             :   void ClearChangesFlag(GVNFlag f) { changes_flags_.Remove(f); }
     617             :   void ClearDependsOnFlag(GVNFlag f) { depends_on_flags_.Remove(f); }
     618             :   bool CheckChangesFlag(GVNFlag f) const {
     619             :     return changes_flags_.Contains(f);
     620             :   }
     621             :   bool CheckDependsOnFlag(GVNFlag f) const {
     622             :     return depends_on_flags_.Contains(f);
     623             :   }
     624             :   void SetAllSideEffects() { changes_flags_.Add(AllSideEffectsFlagSet()); }
     625             :   void ClearAllSideEffects() {
     626             :     changes_flags_.Remove(AllSideEffectsFlagSet());
     627             :   }
     628             :   bool HasSideEffects() const {
     629             :     return changes_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
     630             :   }
     631    34586136 :   bool HasObservableSideEffects() const {
     632    67824187 :     return !CheckFlag(kHasNoObservableSideEffects) &&
     633             :         changes_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
     634             :   }
     635             : 
     636             :   GVNFlagSet SideEffectFlags() const {
     637             :     GVNFlagSet result = ChangesFlags();
     638             :     result.Intersect(AllSideEffectsFlagSet());
     639             :     return result;
     640             :   }
     641             : 
     642             :   GVNFlagSet ObservableChangesFlags() const {
     643             :     GVNFlagSet result = ChangesFlags();
     644             :     result.Intersect(AllObservableSideEffectsFlagSet());
     645             :     return result;
     646             :   }
     647             : 
     648             :   Range* range() const {
     649             :     DCHECK(!range_poisoned_);
     650             :     return range_;
     651             :   }
     652             :   bool HasRange() const {
     653             :     DCHECK(!range_poisoned_);
     654             :     return range_ != NULL;
     655             :   }
     656             : #ifdef DEBUG
     657             :   void PoisonRange() { range_poisoned_ = true; }
     658             : #endif
     659             :   void AddNewRange(Range* r, Zone* zone);
     660             :   void RemoveLastAddedRange();
     661             :   void ComputeInitialRange(Zone* zone);
     662             : 
     663             :   // Escape analysis helpers.
     664       11574 :   virtual bool HasEscapingOperandAt(int index) { return true; }
     665        9623 :   virtual bool HasOutOfBoundsAccess(int size) { return false; }
     666             : 
     667             :   // Representation helpers.
     668     1856531 :   virtual Representation observed_input_representation(int index) {
     669     1856531 :     return Representation::None();
     670             :   }
     671             :   virtual Representation RequiredInputRepresentation(int index) = 0;
     672             :   virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
     673             : 
     674             :   // This gives the instruction an opportunity to replace itself with an
     675             :   // instruction that does the same in some better way.  To replace an
     676             :   // instruction with a new one, first add the new instruction to the graph,
     677             :   // then return it.  Return NULL to have the instruction deleted.
     678    26183780 :   virtual HValue* Canonicalize() { return this; }
     679             : 
     680             :   bool Equals(HValue* other);
     681             :   virtual intptr_t Hashcode();
     682             : 
     683             :   // Compute unique ids upfront that is safe wrt GC and concurrent compilation.
     684    22305245 :   virtual void FinalizeUniqueness() { }
     685             : 
     686             :   // Printing support.
     687             :   virtual std::ostream& PrintTo(std::ostream& os) const = 0;  // NOLINT
     688             : 
     689             :   const char* Mnemonic() const;
     690             : 
     691             :   // Type information helpers.
     692             :   bool HasMonomorphicJSObjectType();
     693             : 
     694             :   // TODO(mstarzinger): For now instructions can override this function to
     695             :   // specify statically known types, once HType can convey more information
     696             :   // it should be based on the HType.
     697      627741 :   virtual Handle<Map> GetMonomorphicJSObjectMap() { return Handle<Map>(); }
     698             : 
     699             :   // Updated the inferred type of this instruction and returns true if
     700             :   // it has changed.
     701             :   bool UpdateInferredType();
     702             : 
     703             :   virtual HType CalculateInferredType();
     704             : 
     705             :   // This function must be overridden for instructions which have the
     706             :   // kTrackSideEffectDominators flag set, to track instructions that are
     707             :   // dominating side effects.
     708             :   // It returns true if it removed an instruction which had side effects.
     709           0 :   virtual bool HandleSideEffectDominator(GVNFlag side_effect,
     710             :                                          HValue* dominator) {
     711           0 :     UNREACHABLE();
     712             :     return false;
     713             :   }
     714             : 
     715             :   // Check if this instruction has some reason that prevents elimination.
     716       19994 :   bool CannotBeEliminated() const {
     717       19994 :     return HasObservableSideEffects() || !IsDeletable();
     718             :   }
     719             : 
     720             : #ifdef DEBUG
     721             :   virtual void Verify() = 0;
     722             : #endif
     723             : 
     724             :   // Returns true conservatively if the program might be able to observe a
     725             :   // ToString() operation on this value.
     726             :   bool ToStringCanBeObserved() const {
     727             :     return ToStringOrToNumberCanBeObserved();
     728             :   }
     729             : 
     730             :   // Returns true conservatively if the program might be able to observe a
     731             :   // ToNumber() operation on this value.
     732             :   bool ToNumberCanBeObserved() const {
     733       99829 :     return ToStringOrToNumberCanBeObserved();
     734             :   }
     735             : 
     736       53266 :   MinusZeroMode GetMinusZeroMode() {
     737             :     return CheckFlag(kBailoutOnMinusZero)
     738       55196 :         ? FAIL_ON_MINUS_ZERO : TREAT_MINUS_ZERO_AS_ZERO;
     739             :   }
     740             : 
     741             :  protected:
     742             :   // This function must be overridden for instructions with flag kUseGVN, to
     743             :   // compare the non-Operand parts of the instruction.
     744           0 :   virtual bool DataEquals(HValue* other) {
     745           0 :     UNREACHABLE();
     746             :     return false;
     747             :   }
     748             : 
     749       99829 :   bool ToStringOrToNumberCanBeObserved() const {
     750       99829 :     if (type().IsTaggedPrimitive()) return false;
     751       47903 :     if (type().IsJSReceiver()) return true;
     752       47625 :     return !representation().IsSmiOrInteger32() && !representation().IsDouble();
     753             :   }
     754             : 
     755       81459 :   virtual Representation RepresentationFromInputs() {
     756       81459 :     return representation();
     757             :   }
     758             :   virtual Representation RepresentationFromUses();
     759             :   Representation RepresentationFromUseRequirements();
     760             :   bool HasNonSmiUse();
     761             :   virtual void UpdateRepresentation(Representation new_rep,
     762             :                                     HInferRepresentationPhase* h_infer,
     763             :                                     const char* reason);
     764             :   void AddDependantsToWorklist(HInferRepresentationPhase* h_infer);
     765             : 
     766      776967 :   virtual void RepresentationChanged(Representation to) { }
     767             : 
     768             :   virtual Range* InferRange(Zone* zone);
     769             :   virtual void DeleteFromGraph() = 0;
     770             :   virtual void InternalSetOperandAt(int index, HValue* value) = 0;
     771             :   void clear_block() {
     772             :     DCHECK(block_ != NULL);
     773     7690492 :     block_ = NULL;
     774             :   }
     775             : 
     776             :   void set_representation(Representation r) {
     777             :     DCHECK(representation_.IsNone() && !r.IsNone());
     778    14635219 :     representation_ = r;
     779             :   }
     780             : 
     781             :   static GVNFlagSet AllFlagSet() {
     782             :     GVNFlagSet result;
     783             : #define ADD_FLAG(Type) result.Add(k##Type);
     784             :   GVN_TRACKED_FLAG_LIST(ADD_FLAG)
     785             :   GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
     786             : #undef ADD_FLAG
     787             :     return result;
     788             :   }
     789             : 
     790             :   // A flag mask to mark an instruction as having arbitrary side effects.
     791             :   static GVNFlagSet AllSideEffectsFlagSet() {
     792             :     GVNFlagSet result = AllFlagSet();
     793             :     result.Remove(kOsrEntries);
     794             :     return result;
     795             :   }
     796             :   friend std::ostream& operator<<(std::ostream& os, const ChangesOf& v);
     797             : 
     798             :   // A flag mask of all side effects that can make observable changes in
     799             :   // an executing program (i.e. are not safe to repeat, move or remove);
     800             :   static GVNFlagSet AllObservableSideEffectsFlagSet() {
     801             :     GVNFlagSet result = AllFlagSet();
     802             :     result.Remove(kNewSpacePromotion);
     803             :     result.Remove(kElementsKind);
     804             :     result.Remove(kElementsPointer);
     805             :     result.Remove(kMaps);
     806             :     return result;
     807             :   }
     808             : 
     809             :   // Remove the matching use from the use list if present.  Returns the
     810             :   // removed list node or NULL.
     811             :   HUseListNode* RemoveUse(HValue* value, int index);
     812             : 
     813             :   void RegisterUse(int index, HValue* new_value);
     814             : 
     815             :   HBasicBlock* block_;
     816             : 
     817             :   // The id of this instruction in the hydrogen graph, assigned when first
     818             :   // added to the graph. Reflects creation order.
     819             :   int id_;
     820             : 
     821             :   Representation representation_;
     822             :   HType type_;
     823             :   HUseListNode* use_list_;
     824             :   Range* range_;
     825             : #ifdef DEBUG
     826             :   bool range_poisoned_;
     827             : #endif
     828             :   int flags_;
     829             :   GVNFlagSet changes_flags_;
     830             :   GVNFlagSet depends_on_flags_;
     831             : 
     832             :  private:
     833       13038 :   virtual bool IsDeletable() const { return false; }
     834             : 
     835             :   DISALLOW_COPY_AND_ASSIGN(HValue);
     836             : };
     837             : 
     838             : // Support for printing various aspects of an HValue.
     839             : struct NameOf {
     840           0 :   explicit NameOf(const HValue* const v) : value(v) {}
     841             :   const HValue* value;
     842             : };
     843             : 
     844             : 
     845             : struct TypeOf {
     846           0 :   explicit TypeOf(const HValue* const v) : value(v) {}
     847             :   const HValue* value;
     848             : };
     849             : 
     850             : 
     851             : struct ChangesOf {
     852           0 :   explicit ChangesOf(const HValue* const v) : value(v) {}
     853             :   const HValue* value;
     854             : };
     855             : 
     856             : 
     857             : std::ostream& operator<<(std::ostream& os, const HValue& v);
     858             : std::ostream& operator<<(std::ostream& os, const NameOf& v);
     859             : std::ostream& operator<<(std::ostream& os, const TypeOf& v);
     860             : std::ostream& operator<<(std::ostream& os, const ChangesOf& v);
     861             : 
     862             : 
     863             : #define DECLARE_INSTRUCTION_FACTORY_P0(I)                        \
     864             :   static I* New(Isolate* isolate, Zone* zone, HValue* context) { \
     865             :     return new (zone) I();                                       \
     866             :   }
     867             : 
     868             : #define DECLARE_INSTRUCTION_FACTORY_P1(I, P1)                           \
     869             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1) { \
     870             :     return new (zone) I(p1);                                            \
     871             :   }
     872             : 
     873             : #define DECLARE_INSTRUCTION_FACTORY_P2(I, P1, P2)                              \
     874             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2) { \
     875             :     return new (zone) I(p1, p2);                                               \
     876             :   }
     877             : 
     878             : #define DECLARE_INSTRUCTION_FACTORY_P3(I, P1, P2, P3)                        \
     879             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
     880             :                 P3 p3) {                                                     \
     881             :     return new (zone) I(p1, p2, p3);                                         \
     882             :   }
     883             : 
     884             : #define DECLARE_INSTRUCTION_FACTORY_P4(I, P1, P2, P3, P4)                    \
     885             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
     886             :                 P3 p3, P4 p4) {                                              \
     887             :     return new (zone) I(p1, p2, p3, p4);                                     \
     888             :   }
     889             : 
     890             : #define DECLARE_INSTRUCTION_FACTORY_P5(I, P1, P2, P3, P4, P5)                \
     891             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
     892             :                 P3 p3, P4 p4, P5 p5) {                                       \
     893             :     return new (zone) I(p1, p2, p3, p4, p5);                                 \
     894             :   }
     895             : 
     896             : #define DECLARE_INSTRUCTION_FACTORY_P6(I, P1, P2, P3, P4, P5, P6)            \
     897             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
     898             :                 P3 p3, P4 p4, P5 p5, P6 p6) {                                \
     899             :     return new (zone) I(p1, p2, p3, p4, p5, p6);                             \
     900             :   }
     901             : 
     902             : #define DECLARE_INSTRUCTION_FACTORY_P7(I, P1, P2, P3, P4, P5, P6, P7)        \
     903             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
     904             :                 P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {                         \
     905             :     return new (zone) I(p1, p2, p3, p4, p5, p6, p7);                         \
     906             :   }
     907             : 
     908             : #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(I)           \
     909             :   static I* New(Isolate* isolate, Zone* zone, HValue* context) { \
     910             :     return new (zone) I(context);                                \
     911             :   }
     912             : 
     913             : #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(I, P1)              \
     914             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1) { \
     915             :     return new (zone) I(context, p1);                                   \
     916             :   }
     917             : 
     918             : #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(I, P1, P2)                 \
     919             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2) { \
     920             :     return new (zone) I(context, p1, p2);                                      \
     921             :   }
     922             : 
     923             : #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(I, P1, P2, P3)           \
     924             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
     925             :                 P3 p3) {                                                     \
     926             :     return new (zone) I(context, p1, p2, p3);                                \
     927             :   }
     928             : 
     929             : #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(I, P1, P2, P3, P4)       \
     930             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
     931             :                 P3 p3, P4 p4) {                                              \
     932             :     return new (zone) I(context, p1, p2, p3, p4);                            \
     933             :   }
     934             : 
     935             : #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(I, P1, P2, P3, P4, P5)   \
     936             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
     937             :                 P3 p3, P4 p4, P5 p5) {                                       \
     938             :     return new (zone) I(context, p1, p2, p3, p4, p5);                        \
     939             :   }
     940             : 
     941             : #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P6(I, P1, P2, P3, P4, P5, P6) \
     942             :   static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2,   \
     943             :                 P3 p3, P4 p4, P5 p5, P6 p6) {                                  \
     944             :     return new (zone) I(context, p1, p2, p3, p4, p5, p6);                      \
     945             :   }
     946             : 
     947           0 : class HInstruction : public HValue {
     948             :  public:
     949             :   HInstruction* next() const { return next_; }
     950             :   HInstruction* previous() const { return previous_; }
     951             : 
     952             :   std::ostream& PrintTo(std::ostream& os) const override;          // NOLINT
     953             :   virtual std::ostream& PrintDataTo(std::ostream& os) const;       // NOLINT
     954             : 
     955    40696258 :   bool IsLinked() const { return block() != NULL; }
     956             :   void Unlink();
     957             : 
     958             :   void InsertBefore(HInstruction* next);
     959             : 
     960             :   template<class T> T* Prepend(T* instr) {
     961       11101 :     instr->InsertBefore(this);
     962             :     return instr;
     963             :   }
     964             : 
     965             :   void InsertAfter(HInstruction* previous);
     966             : 
     967             :   template<class T> T* Append(T* instr) {
     968           0 :     instr->InsertAfter(this);
     969             :     return instr;
     970             :   }
     971             : 
     972             :   // The position is a write-once variable.
     973    53415633 :   SourcePosition position() const override { return position_; }
     974             :   bool has_position() const { return position_.IsKnown(); }
     975             :   void set_position(SourcePosition position) {
     976             :     DCHECK(position.IsKnown());
     977    24328091 :     position_ = position;
     978             :   }
     979             : 
     980             :   bool Dominates(HInstruction* other);
     981           0 :   bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); }
     982      182720 :   bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
     983       52946 :   bool CanTruncateToNumber() const { return CheckFlag(kTruncatingToNumber); }
     984             : 
     985             :   virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
     986             : 
     987             : #ifdef DEBUG
     988             :   void Verify() override;
     989             : #endif
     990             : 
     991             :   bool CanDeoptimize();
     992             : 
     993     1731955 :   virtual bool HasStackCheck() { return false; }
     994             : 
     995       96342 :   DECLARE_ABSTRACT_INSTRUCTION(Instruction)
     996             : 
     997             :  protected:
     998             :   explicit HInstruction(HType type = HType::Tagged())
     999             :       : HValue(type),
    1000             :         next_(NULL),
    1001             :         previous_(NULL),
    1002    32490157 :         position_(SourcePosition::Unknown()) {
    1003             :     SetDependsOnFlag(kOsrEntries);
    1004             :   }
    1005             : 
    1006     6726099 :   void DeleteFromGraph() override { Unlink(); }
    1007             : 
    1008             :  private:
    1009             :   void InitializeAsFirst(HBasicBlock* block) {
    1010             :     DCHECK(!IsLinked());
    1011     4620854 :     SetBlock(block);
    1012             :   }
    1013             : 
    1014             :   HInstruction* next_;
    1015             :   HInstruction* previous_;
    1016             :   SourcePosition position_;
    1017             : 
    1018             :   friend class HBasicBlock;
    1019             : };
    1020             : 
    1021             : 
    1022             : template<int V>
    1023           0 : class HTemplateInstruction : public HInstruction {
    1024             :  public:
    1025    44306591 :   int OperandCount() const final { return V; }
    1026    48596619 :   HValue* OperandAt(int i) const final { return inputs_[i]; }
    1027             : 
    1028             :  protected:
    1029             :   explicit HTemplateInstruction(HType type = HType::Tagged())
    1030    20835952 :       : HInstruction(type) {}
    1031             : 
    1032    11070455 :   void InternalSetOperandAt(int i, HValue* value) final { inputs_[i] = value; }
    1033             : 
    1034             :  private:
    1035             :   EmbeddedContainer<HValue*, V> inputs_;
    1036             : };
    1037             : 
    1038             : 
    1039     4617298 : class HControlInstruction : public HInstruction {
    1040             :  public:
    1041             :   virtual HBasicBlock* SuccessorAt(int i) const = 0;
    1042             :   virtual int SuccessorCount() const = 0;
    1043             :   virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
    1044             : 
    1045             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1046             : 
    1047      586739 :   virtual bool KnownSuccessorBlock(HBasicBlock** block) {
    1048      586739 :     *block = NULL;
    1049      586739 :     return false;
    1050             :   }
    1051             : 
    1052     9628907 :   HBasicBlock* FirstSuccessor() {
    1053     9628907 :     return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
    1054             :   }
    1055     5560236 :   HBasicBlock* SecondSuccessor() {
    1056     5560236 :     return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
    1057             :   }
    1058             : 
    1059        1787 :   void Not() {
    1060        1787 :     HBasicBlock* swap = SuccessorAt(0);
    1061        1787 :     SetSuccessorAt(0, SuccessorAt(1));
    1062        1787 :     SetSuccessorAt(1, swap);
    1063        1787 :   }
    1064             : 
    1065     8706634 :   DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
    1066             : };
    1067             : 
    1068             : 
    1069             : class HSuccessorIterator final BASE_EMBEDDED {
    1070             :  public:
    1071             :   explicit HSuccessorIterator(const HControlInstruction* instr)
    1072     1951557 :       : instr_(instr), current_(0) {}
    1073             : 
    1074    62038849 :   bool Done() { return current_ >= instr_->SuccessorCount(); }
    1075    33092250 :   HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
    1076    33092246 :   void Advance() { current_++; }
    1077             : 
    1078             :  private:
    1079             :   const HControlInstruction* instr_;
    1080             :   int current_;
    1081             : };
    1082             : 
    1083             : 
    1084             : template<int S, int V>
    1085    13820296 : class HTemplateControlInstruction : public HControlInstruction {
    1086             :  public:
    1087    90964797 :   int SuccessorCount() const override { return S; }
    1088    64832630 :   HBasicBlock* SuccessorAt(int i) const override { return successors_[i]; }
    1089     1927168 :   void SetSuccessorAt(int i, HBasicBlock* block) override {
    1090     6147112 :     successors_[i] = block;
    1091     1927168 :   }
    1092             : 
    1093        5488 :   int OperandCount() const override { return V; }
    1094    13071632 :   HValue* OperandAt(int i) const override { return inputs_[i]; }
    1095             : 
    1096             : 
    1097             :  protected:
    1098     3079314 :   void InternalSetOperandAt(int i, HValue* value) override {
    1099     3079314 :     inputs_[i] = value;
    1100     3079314 :   }
    1101             : 
    1102             :  private:
    1103             :   EmbeddedContainer<HBasicBlock*, S> successors_;
    1104             :   EmbeddedContainer<HValue*, V> inputs_;
    1105             : };
    1106             : 
    1107             : 
    1108     4620854 : class HBlockEntry final : public HTemplateInstruction<0> {
    1109             :  public:
    1110           0 :   Representation RequiredInputRepresentation(int index) override {
    1111           0 :     return Representation::None();
    1112             :   }
    1113             : 
    1114    50013999 :   DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
    1115             : };
    1116             : 
    1117             : 
    1118           0 : class HDummyUse final : public HTemplateInstruction<1> {
    1119             :  public:
    1120             :   explicit HDummyUse(HValue* value)
    1121             :       : HTemplateInstruction<1>(HType::Smi()) {
    1122             :     SetOperandAt(0, value);
    1123             :     // Pretend to be a Smi so that the HChange instructions inserted
    1124             :     // before any use generate as little code as possible.
    1125             :     set_representation(Representation::Tagged());
    1126             :   }
    1127             : 
    1128             :   HValue* value() const { return OperandAt(0); }
    1129             : 
    1130           0 :   bool HasEscapingOperandAt(int index) override { return false; }
    1131           0 :   Representation RequiredInputRepresentation(int index) override {
    1132           0 :     return Representation::None();
    1133             :   }
    1134             : 
    1135             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1136             : 
    1137           0 :   DECLARE_CONCRETE_INSTRUCTION(DummyUse);
    1138             : };
    1139             : 
    1140             : 
    1141             : // Inserts an int3/stop break instruction for debugging purposes.
    1142           0 : class HDebugBreak final : public HTemplateInstruction<0> {
    1143             :  public:
    1144           0 :   DECLARE_INSTRUCTION_FACTORY_P0(HDebugBreak);
    1145             : 
    1146           0 :   Representation RequiredInputRepresentation(int index) override {
    1147           0 :     return Representation::None();
    1148             :   }
    1149             : 
    1150           0 :   DECLARE_CONCRETE_INSTRUCTION(DebugBreak)
    1151             : };
    1152             : 
    1153             : 
    1154      263913 : class HPrologue final : public HTemplateInstruction<0> {
    1155             :  public:
    1156      791739 :   static HPrologue* New(Zone* zone) { return new (zone) HPrologue(); }
    1157             : 
    1158           0 :   Representation RequiredInputRepresentation(int index) override {
    1159           0 :     return Representation::None();
    1160             :   }
    1161             : 
    1162     3116608 :   DECLARE_CONCRETE_INSTRUCTION(Prologue)
    1163             : };
    1164             : 
    1165             : 
    1166           0 : class HGoto final : public HTemplateControlInstruction<1, 0> {
    1167             :  public:
    1168     3033443 :   explicit HGoto(HBasicBlock* target) {
    1169             :     SetSuccessorAt(0, target);
    1170             :   }
    1171             : 
    1172     7469536 :   bool KnownSuccessorBlock(HBasicBlock** block) override {
    1173     7469536 :     *block = FirstSuccessor();
    1174     7469520 :     return true;
    1175             :   }
    1176             : 
    1177           0 :   Representation RequiredInputRepresentation(int index) override {
    1178           0 :     return Representation::None();
    1179             :   }
    1180             : 
    1181             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1182             : 
    1183    37817204 :   DECLARE_CONCRETE_INSTRUCTION(Goto)
    1184             : };
    1185             : 
    1186             : 
    1187           0 : class HDeoptimize final : public HTemplateControlInstruction<1, 0> {
    1188             :  public:
    1189      189474 :   static HDeoptimize* New(Isolate* isolate, Zone* zone, HValue* context,
    1190             :                           DeoptimizeReason reason,
    1191             :                           Deoptimizer::BailoutType type,
    1192             :                           HBasicBlock* unreachable_continuation) {
    1193      189474 :     return new(zone) HDeoptimize(reason, type, unreachable_continuation);
    1194             :   }
    1195             : 
    1196      188914 :   bool KnownSuccessorBlock(HBasicBlock** block) override {
    1197      188914 :     *block = NULL;
    1198      188914 :     return true;
    1199             :   }
    1200             : 
    1201           0 :   Representation RequiredInputRepresentation(int index) override {
    1202           0 :     return Representation::None();
    1203             :   }
    1204             : 
    1205             :   DeoptimizeReason reason() const { return reason_; }
    1206             :   Deoptimizer::BailoutType type() { return type_; }
    1207             : 
    1208     2264042 :   DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
    1209             : 
    1210             :  private:
    1211             :   explicit HDeoptimize(DeoptimizeReason reason, Deoptimizer::BailoutType type,
    1212             :                        HBasicBlock* unreachable_continuation)
    1213      189474 :       : reason_(reason), type_(type) {
    1214             :     SetSuccessorAt(0, unreachable_continuation);
    1215             :   }
    1216             : 
    1217             :   DeoptimizeReason reason_;
    1218             :   Deoptimizer::BailoutType type_;
    1219             : };
    1220             : 
    1221             : 
    1222           0 : class HUnaryControlInstruction : public HTemplateControlInstruction<2, 1> {
    1223             :  public:
    1224             :   HUnaryControlInstruction(HValue* value,
    1225             :                            HBasicBlock* true_target,
    1226      763018 :                            HBasicBlock* false_target) {
    1227      763018 :     SetOperandAt(0, value);
    1228             :     SetSuccessorAt(0, true_target);
    1229             :     SetSuccessorAt(1, false_target);
    1230             :   }
    1231             : 
    1232             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1233             : 
    1234     4516976 :   HValue* value() const { return OperandAt(0); }
    1235             : };
    1236             : 
    1237             : 
    1238           0 : class HBranch final : public HUnaryControlInstruction {
    1239             :  public:
    1240      657588 :   DECLARE_INSTRUCTION_FACTORY_P1(HBranch, HValue*);
    1241      622218 :   DECLARE_INSTRUCTION_FACTORY_P2(HBranch, HValue*, ToBooleanHints);
    1242       26998 :   DECLARE_INSTRUCTION_FACTORY_P4(HBranch, HValue*, ToBooleanHints, HBasicBlock*,
    1243             :                                  HBasicBlock*);
    1244             : 
    1245      654015 :   Representation RequiredInputRepresentation(int index) override {
    1246      654015 :     return Representation::None();
    1247             :   }
    1248             :   Representation observed_input_representation(int index) override;
    1249             : 
    1250             :   bool KnownSuccessorBlock(HBasicBlock** block) override;
    1251             : 
    1252             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1253             : 
    1254             :   ToBooleanHints expected_input_types() const { return expected_input_types_; }
    1255             : 
    1256    14179944 :   DECLARE_CONCRETE_INSTRUCTION(Branch)
    1257             : 
    1258             :  private:
    1259             :   HBranch(HValue* value,
    1260             :           ToBooleanHints expected_input_types = ToBooleanHint::kNone,
    1261             :           HBasicBlock* true_target = NULL, HBasicBlock* false_target = NULL)
    1262             :       : HUnaryControlInstruction(value, true_target, false_target),
    1263      653402 :         expected_input_types_(expected_input_types) {}
    1264             : 
    1265             :   ToBooleanHints expected_input_types_;
    1266             : };
    1267             : 
    1268             : 
    1269           0 : class HCompareMap final : public HUnaryControlInstruction {
    1270             :  public:
    1271        3654 :   DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>);
    1272       41120 :   DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>,
    1273             :                                  HBasicBlock*, HBasicBlock*);
    1274             : 
    1275      154261 :   bool KnownSuccessorBlock(HBasicBlock** block) override {
    1276      154261 :     if (known_successor_index() != kNoKnownSuccessorIndex) {
    1277       13068 :       *block = SuccessorAt(known_successor_index());
    1278        6534 :       return true;
    1279             :     }
    1280      147727 :     *block = NULL;
    1281      147727 :     return false;
    1282             :   }
    1283             : 
    1284             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1285             : 
    1286             :   static const int kNoKnownSuccessorIndex = -1;
    1287             :   int known_successor_index() const {
    1288             :     return KnownSuccessorIndexField::decode(bit_field_) -
    1289        6534 :            kInternalKnownSuccessorOffset;
    1290             :   }
    1291             :   void set_known_successor_index(int index) {
    1292             :     DCHECK(index >= 0 - kInternalKnownSuccessorOffset);
    1293             :     bit_field_ = KnownSuccessorIndexField::update(
    1294        6534 :         bit_field_, index + kInternalKnownSuccessorOffset);
    1295             :   }
    1296             : 
    1297             :   Unique<Map> map() const { return map_; }
    1298             :   bool map_is_stable() const { return MapIsStableField::decode(bit_field_); }
    1299             : 
    1300       31093 :   Representation RequiredInputRepresentation(int index) override {
    1301       31093 :     return Representation::Tagged();
    1302             :   }
    1303             : 
    1304      634588 :   DECLARE_CONCRETE_INSTRUCTION(CompareMap)
    1305             : 
    1306             :  protected:
    1307       70432 :   int RedefinedOperandIndex() override { return 0; }
    1308             : 
    1309             :  private:
    1310       22387 :   HCompareMap(HValue* value, Handle<Map> map, HBasicBlock* true_target = NULL,
    1311             :               HBasicBlock* false_target = NULL)
    1312             :       : HUnaryControlInstruction(value, true_target, false_target),
    1313             :         bit_field_(KnownSuccessorIndexField::encode(
    1314             :                        kNoKnownSuccessorIndex + kInternalKnownSuccessorOffset) |
    1315             :                    MapIsStableField::encode(map->is_stable())),
    1316       44774 :         map_(Unique<Map>::CreateImmovable(map)) {
    1317             :     set_representation(Representation::Tagged());
    1318       22387 :   }
    1319             : 
    1320             :   // BitFields can only store unsigned values, so use an offset.
    1321             :   // Adding kInternalKnownSuccessorOffset must yield an unsigned value.
    1322             :   static const int kInternalKnownSuccessorOffset = 1;
    1323             :   STATIC_ASSERT(kNoKnownSuccessorIndex + kInternalKnownSuccessorOffset >= 0);
    1324             : 
    1325             :   class KnownSuccessorIndexField : public BitField<int, 0, 31> {};
    1326             :   class MapIsStableField : public BitField<bool, 31, 1> {};
    1327             : 
    1328             :   uint32_t bit_field_;
    1329             :   Unique<Map> map_;
    1330             : };
    1331             : 
    1332             : 
    1333           0 : class HContext final : public HTemplateInstruction<0> {
    1334             :  public:
    1335      289883 :   static HContext* New(Zone* zone) {
    1336      289884 :     return new(zone) HContext();
    1337             :   }
    1338             : 
    1339           0 :   Representation RequiredInputRepresentation(int index) override {
    1340           0 :     return Representation::None();
    1341             :   }
    1342             : 
    1343    17467869 :   DECLARE_CONCRETE_INSTRUCTION(Context)
    1344             : 
    1345             :  protected:
    1346           0 :   bool DataEquals(HValue* other) override { return true; }
    1347             : 
    1348             :  private:
    1349      289884 :   HContext() {
    1350             :     set_representation(Representation::Tagged());
    1351             :     SetFlag(kUseGVN);
    1352             :   }
    1353             : 
    1354         358 :   bool IsDeletable() const override { return true; }
    1355             : };
    1356             : 
    1357             : 
    1358           0 : class HReturn final : public HTemplateControlInstruction<0, 3> {
    1359             :  public:
    1360      365938 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HReturn, HValue*, HValue*);
    1361             :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HReturn, HValue*);
    1362             : 
    1363     1312352 :   Representation RequiredInputRepresentation(int index) override {
    1364             :     // TODO(titzer): require an Int32 input for faster returns.
    1365     1312352 :     if (index == 2) return Representation::Smi();
    1366             :     return Representation::Tagged();
    1367             :   }
    1368             : 
    1369             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1370             : 
    1371      365865 :   HValue* value() const { return OperandAt(0); }
    1372       37289 :   HValue* context() const { return OperandAt(1); }
    1373      365862 :   HValue* parameter_count() const { return OperandAt(2); }
    1374             : 
    1375     4980882 :   DECLARE_CONCRETE_INSTRUCTION(Return)
    1376             : 
    1377             :  private:
    1378      365938 :   HReturn(HValue* context, HValue* value, HValue* parameter_count = 0) {
    1379      365938 :     SetOperandAt(0, value);
    1380      365938 :     SetOperandAt(1, context);
    1381      365938 :     SetOperandAt(2, parameter_count);
    1382      365938 :   }
    1383             : };
    1384             : 
    1385             : 
    1386           0 : class HAbnormalExit final : public HTemplateControlInstruction<0, 0> {
    1387             :  public:
    1388       31598 :   DECLARE_INSTRUCTION_FACTORY_P0(HAbnormalExit);
    1389             : 
    1390           0 :   Representation RequiredInputRepresentation(int index) override {
    1391           0 :     return Representation::None();
    1392             :   }
    1393             : 
    1394      155597 :   DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
    1395             :  private:
    1396       15799 :   HAbnormalExit() {}
    1397             : };
    1398             : 
    1399             : 
    1400           0 : class HUnaryOperation : public HTemplateInstruction<1> {
    1401             :  public:
    1402     1407881 :   explicit HUnaryOperation(HValue* value, HType type = HType::Tagged())
    1403     1407881 :       : HTemplateInstruction<1>(type) {
    1404     1407881 :     SetOperandAt(0, value);
    1405     1407882 :   }
    1406             : 
    1407             :   static HUnaryOperation* cast(HValue* value) {
    1408             :     return reinterpret_cast<HUnaryOperation*>(value);
    1409             :   }
    1410             : 
    1411             :   HValue* value() const { return OperandAt(0); }
    1412             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1413             : };
    1414             : 
    1415             : 
    1416           0 : class HUseConst final : public HUnaryOperation {
    1417             :  public:
    1418             :   DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*);
    1419             : 
    1420           0 :   Representation RequiredInputRepresentation(int index) override {
    1421           0 :     return Representation::None();
    1422             :   }
    1423             : 
    1424           0 :   DECLARE_CONCRETE_INSTRUCTION(UseConst)
    1425             : 
    1426             :  private:
    1427             :     explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
    1428             : };
    1429             : 
    1430             : 
    1431           0 : class HForceRepresentation final : public HTemplateInstruction<1> {
    1432             :  public:
    1433             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    1434             :                            HValue* value,
    1435             :                            Representation required_representation);
    1436             : 
    1437             :   HValue* value() const { return OperandAt(0); }
    1438             : 
    1439       83705 :   Representation observed_input_representation(int index) override {
    1440             :     // We haven't actually *observed* this, but it's closer to the truth
    1441             :     // than 'None'.
    1442       83705 :     return representation();  // Same as the output representation.
    1443             :   }
    1444      136215 :   Representation RequiredInputRepresentation(int index) override {
    1445      136215 :     return representation();  // Same as the output representation.
    1446             :   }
    1447             : 
    1448             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1449             : 
    1450      899218 :   DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
    1451             : 
    1452             :  private:
    1453      123028 :   HForceRepresentation(HValue* value, Representation required_representation) {
    1454       61514 :     SetOperandAt(0, value);
    1455             :     set_representation(required_representation);
    1456       61514 :   }
    1457             : };
    1458             : 
    1459           0 : class HChange final : public HUnaryOperation {
    1460             :  public:
    1461      510920 :   HChange(HValue* value, Representation to, bool is_truncating_to_smi,
    1462             :           bool is_truncating_to_int32, bool is_truncating_to_number)
    1463      510920 :       : HUnaryOperation(value) {
    1464             :     DCHECK(!value->representation().IsNone());
    1465             :     DCHECK(!to.IsNone());
    1466             :     DCHECK(!value->representation().Equals(to));
    1467             :     set_representation(to);
    1468             :     SetFlag(kUseGVN);
    1469             :     SetFlag(kCanOverflow);
    1470      510917 :     if (is_truncating_to_smi && to.IsSmi()) {
    1471             :       SetFlag(kTruncatingToSmi);
    1472             :       SetFlag(kTruncatingToInt32);
    1473             :       SetFlag(kTruncatingToNumber);
    1474      510917 :     } else if (is_truncating_to_int32) {
    1475             :       SetFlag(kTruncatingToInt32);
    1476             :       SetFlag(kTruncatingToNumber);
    1477      474758 :     } else if (is_truncating_to_number) {
    1478             :       SetFlag(kTruncatingToNumber);
    1479             :     }
    1480     1008903 :     if (value->representation().IsSmi() || value->type().IsSmi()) {
    1481             :       set_type(HType::Smi());
    1482             :     } else {
    1483             :       set_type(HType::TaggedNumber());
    1484      454929 :       if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
    1485             :     }
    1486      510917 :   }
    1487             : 
    1488             :   HType CalculateInferredType() override;
    1489             :   HValue* Canonicalize() override;
    1490             : 
    1491             :   Representation from() const { return value()->representation(); }
    1492             :   Representation to() const { return representation(); }
    1493             :   bool deoptimize_on_minus_zero() const {
    1494             :     return CheckFlag(kBailoutOnMinusZero);
    1495             :   }
    1496           0 :   Representation RequiredInputRepresentation(int index) override {
    1497           0 :     return from();
    1498             :   }
    1499             : 
    1500             :   Range* InferRange(Zone* zone) override;
    1501             : 
    1502             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1503             : 
    1504     6264845 :   DECLARE_CONCRETE_INSTRUCTION(Change)
    1505             : 
    1506             :  protected:
    1507      140930 :   bool DataEquals(HValue* other) override { return true; }
    1508             : 
    1509             :  private:
    1510         490 :   bool IsDeletable() const override {
    1511         733 :     return !from().IsTagged() || value()->type().IsSmi();
    1512             :   }
    1513             : };
    1514             : 
    1515             : 
    1516           0 : class HClampToUint8 final : public HUnaryOperation {
    1517             :  public:
    1518         335 :   DECLARE_INSTRUCTION_FACTORY_P1(HClampToUint8, HValue*);
    1519             : 
    1520         335 :   Representation RequiredInputRepresentation(int index) override {
    1521         335 :     return Representation::None();
    1522             :   }
    1523             : 
    1524        8234 :   DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
    1525             : 
    1526             :  protected:
    1527           7 :   bool DataEquals(HValue* other) override { return true; }
    1528             : 
    1529             :  private:
    1530         335 :   explicit HClampToUint8(HValue* value)
    1531         335 :       : HUnaryOperation(value) {
    1532             :     set_representation(Representation::Integer32());
    1533             :     SetFlag(kTruncatingToNumber);
    1534             :     SetFlag(kUseGVN);
    1535         335 :   }
    1536             : 
    1537           0 :   bool IsDeletable() const override { return true; }
    1538             : };
    1539             : 
    1540             : 
    1541             : enum RemovableSimulate {
    1542             :   REMOVABLE_SIMULATE,
    1543             :   FIXED_SIMULATE
    1544             : };
    1545             : 
    1546             : 
    1547             : class HSimulate final : public HInstruction {
    1548             :  public:
    1549     4964890 :   HSimulate(BailoutId ast_id, int pop_count, Zone* zone,
    1550             :             RemovableSimulate removable)
    1551             :       : ast_id_(ast_id),
    1552             :         pop_count_(pop_count),
    1553             :         values_(2, zone),
    1554             :         assigned_indexes_(2, zone),
    1555             :         zone_(zone),
    1556             :         bit_field_(RemovableField::encode(removable) |
    1557     4964890 :                    DoneWithReplayField::encode(false)) {}
    1558           0 :   ~HSimulate() {}
    1559             : 
    1560             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1561             : 
    1562             :   bool HasAstId() const { return !ast_id_.IsNone(); }
    1563             :   BailoutId ast_id() const { return ast_id_; }
    1564             :   void set_ast_id(BailoutId id) {
    1565             :     DCHECK(!HasAstId());
    1566     2505644 :     ast_id_ = id;
    1567             :   }
    1568             : 
    1569             :   int pop_count() const { return pop_count_; }
    1570             :   const ZoneList<HValue*>* values() const { return &values_; }
    1571             :   int GetAssignedIndexAt(int index) const {
    1572             :     DCHECK(HasAssignedIndexAt(index));
    1573             :     return assigned_indexes_[index];
    1574             :   }
    1575             :   bool HasAssignedIndexAt(int index) const {
    1576     8041736 :     return assigned_indexes_[index] != kNoIndex;
    1577             :   }
    1578             :   void AddAssignedValue(int index, HValue* value) {
    1579     1340905 :     AddValue(index, value);
    1580             :   }
    1581             :   void AddPushedValue(HValue* value) {
    1582     2885753 :     AddValue(kNoIndex, value);
    1583             :   }
    1584             :   int ToOperandIndex(int environment_index) {
    1585     3440826 :     for (int i = 0; i < assigned_indexes_.length(); ++i) {
    1586     5160078 :       if (assigned_indexes_[i] == environment_index) return i;
    1587             :     }
    1588             :     return -1;
    1589             :   }
    1590      659118 :   int OperandCount() const override { return values_.length(); }
    1591     9537062 :   HValue* OperandAt(int index) const override { return values_[index]; }
    1592             : 
    1593        1864 :   bool HasEscapingOperandAt(int index) override { return false; }
    1594     3936486 :   Representation RequiredInputRepresentation(int index) override {
    1595     3936486 :     return Representation::None();
    1596             :   }
    1597             : 
    1598             :   void MergeWith(ZoneList<HSimulate*>* list);
    1599             :   bool is_candidate_for_removal() {
    1600             :     return RemovableField::decode(bit_field_) == REMOVABLE_SIMULATE;
    1601             :   }
    1602             : 
    1603             :   // Replay effects of this instruction on the given environment.
    1604             :   void ReplayEnvironment(HEnvironment* env);
    1605             : 
    1606    58398582 :   DECLARE_CONCRETE_INSTRUCTION(Simulate)
    1607             : 
    1608             : #ifdef DEBUG
    1609             :   void Verify() override;
    1610             :   void set_closure(Handle<JSFunction> closure) { closure_ = closure; }
    1611             :   Handle<JSFunction> closure() const { return closure_; }
    1612             : #endif
    1613             : 
    1614             :  protected:
    1615     4818478 :   void InternalSetOperandAt(int index, HValue* value) override {
    1616     9636956 :     values_[index] = value;
    1617     4818478 :   }
    1618             : 
    1619             :  private:
    1620             :   static const int kNoIndex = -1;
    1621     4226657 :   void AddValue(int index, HValue* value) {
    1622     4226657 :     assigned_indexes_.Add(index, zone_);
    1623             :     // Resize the list of pushed values.
    1624     4226657 :     values_.Add(NULL, zone_);
    1625             :     // Set the operand through the base method in HValue to make sure that the
    1626             :     // use lists are correctly updated.
    1627     4226656 :     SetOperandAt(values_.length() - 1, value);
    1628     4226657 :   }
    1629             :   bool HasValueForIndex(int index) {
    1630      155442 :     for (int i = 0; i < assigned_indexes_.length(); ++i) {
    1631      239734 :       if (assigned_indexes_[i] == index) return true;
    1632             :     }
    1633             :     return false;
    1634             :   }
    1635             :   bool is_done_with_replay() const {
    1636             :     return DoneWithReplayField::decode(bit_field_);
    1637             :   }
    1638             :   void set_done_with_replay() {
    1639     9479974 :     bit_field_ = DoneWithReplayField::update(bit_field_, true);
    1640             :   }
    1641             : 
    1642             :   class RemovableField : public BitField<RemovableSimulate, 0, 1> {};
    1643             :   class DoneWithReplayField : public BitField<bool, 1, 1> {};
    1644             : 
    1645             :   BailoutId ast_id_;
    1646             :   int pop_count_;
    1647             :   ZoneList<HValue*> values_;
    1648             :   ZoneList<int> assigned_indexes_;
    1649             :   Zone* zone_;
    1650             :   uint32_t bit_field_;
    1651             : 
    1652             : #ifdef DEBUG
    1653             :   Handle<JSFunction> closure_;
    1654             : #endif
    1655             : };
    1656             : 
    1657             : 
    1658           0 : class HEnvironmentMarker final : public HTemplateInstruction<1> {
    1659             :  public:
    1660             :   enum Kind { BIND, LOOKUP };
    1661             : 
    1662     2562564 :   DECLARE_INSTRUCTION_FACTORY_P2(HEnvironmentMarker, Kind, int);
    1663             : 
    1664             :   Kind kind() const { return kind_; }
    1665             :   int index() const { return index_; }
    1666             :   HSimulate* next_simulate() { return next_simulate_; }
    1667             :   void set_next_simulate(HSimulate* simulate) {
    1668     1493781 :     next_simulate_ = simulate;
    1669             :   }
    1670             : 
    1671           0 :   Representation RequiredInputRepresentation(int index) override {
    1672           0 :     return Representation::None();
    1673             :   }
    1674             : 
    1675             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1676             : 
    1677             : #ifdef DEBUG
    1678             :   void set_closure(Handle<JSFunction> closure) {
    1679             :     DCHECK(closure_.is_null());
    1680             :     DCHECK(!closure.is_null());
    1681             :     closure_ = closure;
    1682             :   }
    1683             :   Handle<JSFunction> closure() const { return closure_; }
    1684             : #endif
    1685             : 
    1686     1571170 :   DECLARE_CONCRETE_INSTRUCTION(EnvironmentMarker);
    1687             : 
    1688             :  private:
    1689             :   HEnvironmentMarker(Kind kind, int index)
    1690     1281282 :       : kind_(kind), index_(index), next_simulate_(NULL) { }
    1691             : 
    1692             :   Kind kind_;
    1693             :   int index_;
    1694             :   HSimulate* next_simulate_;
    1695             : 
    1696             : #ifdef DEBUG
    1697             :   Handle<JSFunction> closure_;
    1698             : #endif
    1699             : };
    1700             : 
    1701             : 
    1702           0 : class HStackCheck final : public HTemplateInstruction<1> {
    1703             :  public:
    1704             :   enum Type {
    1705             :     kFunctionEntry,
    1706             :     kBackwardsBranch
    1707             :   };
    1708             : 
    1709      309501 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HStackCheck, Type);
    1710             : 
    1711             :   HValue* context() { return OperandAt(0); }
    1712             : 
    1713      309082 :   Representation RequiredInputRepresentation(int index) override {
    1714      309082 :     return Representation::Tagged();
    1715             :   }
    1716             : 
    1717             :   void Eliminate() {
    1718             :     // The stack check eliminator might try to eliminate the same stack
    1719             :     // check instruction multiple times.
    1720        4170 :     if (IsLinked()) {
    1721        4010 :       DeleteAndReplaceWith(NULL);
    1722             :     }
    1723             :   }
    1724             : 
    1725             :   bool is_function_entry() { return type_ == kFunctionEntry; }
    1726             :   bool is_backwards_branch() { return type_ == kBackwardsBranch; }
    1727             : 
    1728     3802275 :   DECLARE_CONCRETE_INSTRUCTION(StackCheck)
    1729             : 
    1730             :  private:
    1731      619002 :   HStackCheck(HValue* context, Type type) : type_(type) {
    1732      309501 :     SetOperandAt(0, context);
    1733             :     SetChangesFlag(kNewSpacePromotion);
    1734      309501 :   }
    1735             : 
    1736             :   Type type_;
    1737             : };
    1738             : 
    1739             : 
    1740             : enum InliningKind {
    1741             :   NORMAL_RETURN,          // Drop the function from the environment on return.
    1742             :   CONSTRUCT_CALL_RETURN,  // Either use allocated receiver or return value.
    1743             :   GETTER_CALL_RETURN,     // Returning from a getter, need to restore context.
    1744             :   SETTER_CALL_RETURN      // Use the RHS of the assignment as the return value.
    1745             : };
    1746             : 
    1747             : 
    1748             : class HArgumentsObject;
    1749             : class HConstant;
    1750             : 
    1751             : 
    1752           0 : class HEnterInlined final : public HTemplateInstruction<0> {
    1753             :  public:
    1754      107398 :   static HEnterInlined* New(Isolate* isolate, Zone* zone, HValue* context,
    1755             :                             BailoutId return_id, Handle<JSFunction> closure,
    1756             :                             HConstant* closure_context, int arguments_count,
    1757             :                             FunctionLiteral* function,
    1758             :                             InliningKind inlining_kind, Variable* arguments_var,
    1759             :                             HArgumentsObject* arguments_object,
    1760             :                             TailCallMode syntactic_tail_call_mode) {
    1761             :     return new (zone)
    1762             :         HEnterInlined(return_id, closure, closure_context, arguments_count,
    1763             :                       function, inlining_kind, arguments_var, arguments_object,
    1764      214796 :                       syntactic_tail_call_mode, zone);
    1765             :   }
    1766             : 
    1767             :   void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone);
    1768             :   ZoneList<HBasicBlock*>* return_targets() { return &return_targets_; }
    1769             : 
    1770             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    1771             : 
    1772             :   Handle<SharedFunctionInfo> shared() const { return shared_; }
    1773             :   Handle<JSFunction> closure() const { return closure_; }
    1774             :   HConstant* closure_context() const { return closure_context_; }
    1775             :   int arguments_count() const { return arguments_count_; }
    1776             :   bool arguments_pushed() const { return arguments_pushed_; }
    1777         232 :   void set_arguments_pushed() { arguments_pushed_ = true; }
    1778             :   FunctionLiteral* function() const { return function_; }
    1779             :   InliningKind inlining_kind() const { return inlining_kind_; }
    1780             :   TailCallMode syntactic_tail_call_mode() const {
    1781             :     return syntactic_tail_call_mode_;
    1782             :   }
    1783             :   BailoutId ReturnId() const { return return_id_; }
    1784             :   int inlining_id() const { return inlining_id_; }
    1785           3 :   void set_inlining_id(int inlining_id) { inlining_id_ = inlining_id; }
    1786             : 
    1787           0 :   Representation RequiredInputRepresentation(int index) override {
    1788           0 :     return Representation::None();
    1789             :   }
    1790             : 
    1791             :   Variable* arguments_var() { return arguments_var_; }
    1792             :   HArgumentsObject* arguments_object() { return arguments_object_; }
    1793             : 
    1794     1300678 :   DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
    1795             : 
    1796             :  private:
    1797      107398 :   HEnterInlined(BailoutId return_id, Handle<JSFunction> closure,
    1798             :                 HConstant* closure_context, int arguments_count,
    1799             :                 FunctionLiteral* function, InliningKind inlining_kind,
    1800             :                 Variable* arguments_var, HArgumentsObject* arguments_object,
    1801             :                 TailCallMode syntactic_tail_call_mode, Zone* zone)
    1802             :       : return_id_(return_id),
    1803             :         shared_(handle(closure->shared())),
    1804             :         closure_(closure),
    1805             :         closure_context_(closure_context),
    1806             :         arguments_count_(arguments_count),
    1807             :         arguments_pushed_(false),
    1808             :         function_(function),
    1809             :         inlining_kind_(inlining_kind),
    1810             :         syntactic_tail_call_mode_(syntactic_tail_call_mode),
    1811             :         inlining_id_(-1),
    1812             :         arguments_var_(arguments_var),
    1813             :         arguments_object_(arguments_object),
    1814      214796 :         return_targets_(2, zone) {}
    1815             : 
    1816             :   BailoutId return_id_;
    1817             :   Handle<SharedFunctionInfo> shared_;
    1818             :   Handle<JSFunction> closure_;
    1819             :   HConstant* closure_context_;
    1820             :   int arguments_count_;
    1821             :   bool arguments_pushed_;
    1822             :   FunctionLiteral* function_;
    1823             :   InliningKind inlining_kind_;
    1824             :   TailCallMode syntactic_tail_call_mode_;
    1825             :   int inlining_id_;
    1826             :   Variable* arguments_var_;
    1827             :   HArgumentsObject* arguments_object_;
    1828             :   ZoneList<HBasicBlock*> return_targets_;
    1829             : };
    1830             : 
    1831             : 
    1832           0 : class HLeaveInlined final : public HTemplateInstruction<0> {
    1833             :  public:
    1834             :   HLeaveInlined(HEnterInlined* entry,
    1835             :                 int drop_count)
    1836             :       : entry_(entry),
    1837      562667 :         drop_count_(drop_count) { }
    1838             : 
    1839           0 :   Representation RequiredInputRepresentation(int index) override {
    1840           0 :     return Representation::None();
    1841             :   }
    1842             : 
    1843      558631 :   int argument_delta() const override {
    1844      558631 :     return entry_->arguments_pushed() ? -drop_count_ : 0;
    1845             :   }
    1846             : 
    1847     5951523 :   DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
    1848             : 
    1849             :  private:
    1850             :   HEnterInlined* entry_;
    1851             :   int drop_count_;
    1852             : };
    1853             : 
    1854             : 
    1855           0 : class HPushArguments final : public HInstruction {
    1856             :  public:
    1857      597064 :   static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context) {
    1858      597064 :     return new(zone) HPushArguments(zone);
    1859             :   }
    1860       35747 :   static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context,
    1861             :                              HValue* arg1) {
    1862       35747 :     HPushArguments* instr = new(zone) HPushArguments(zone);
    1863       35747 :     instr->AddInput(arg1);
    1864       35747 :     return instr;
    1865             :   }
    1866        8061 :   static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context,
    1867             :                              HValue* arg1, HValue* arg2) {
    1868        8061 :     HPushArguments* instr = new(zone) HPushArguments(zone);
    1869        8061 :     instr->AddInput(arg1);
    1870        8061 :     instr->AddInput(arg2);
    1871        8061 :     return instr;
    1872             :   }
    1873        1165 :   static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context,
    1874             :                              HValue* arg1, HValue* arg2, HValue* arg3) {
    1875        1165 :     HPushArguments* instr = new(zone) HPushArguments(zone);
    1876        1165 :     instr->AddInput(arg1);
    1877        1165 :     instr->AddInput(arg2);
    1878        1165 :     instr->AddInput(arg3);
    1879        1165 :     return instr;
    1880             :   }
    1881       33528 :   static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context,
    1882             :                              HValue* arg1, HValue* arg2, HValue* arg3,
    1883             :                              HValue* arg4) {
    1884       33528 :     HPushArguments* instr = new(zone) HPushArguments(zone);
    1885       33528 :     instr->AddInput(arg1);
    1886       33528 :     instr->AddInput(arg2);
    1887       33528 :     instr->AddInput(arg3);
    1888       33528 :     instr->AddInput(arg4);
    1889       33528 :     return instr;
    1890             :   }
    1891             : 
    1892     1903758 :   Representation RequiredInputRepresentation(int index) override {
    1893     1903758 :     return Representation::Tagged();
    1894             :   }
    1895             : 
    1896      670750 :   int argument_delta() const override { return inputs_.length(); }
    1897             :   HValue* argument(int i) { return OperandAt(i); }
    1898             : 
    1899     2497670 :   int OperandCount() const final { return inputs_.length(); }
    1900     7241664 :   HValue* OperandAt(int i) const final { return inputs_[i]; }
    1901             : 
    1902             :   void AddInput(HValue* value);
    1903             : 
    1904    10052242 :   DECLARE_CONCRETE_INSTRUCTION(PushArguments)
    1905             : 
    1906             :  protected:
    1907     4338868 :   void InternalSetOperandAt(int i, HValue* value) final { inputs_[i] = value; }
    1908             : 
    1909             :  private:
    1910      675565 :   explicit HPushArguments(Zone* zone)
    1911      675565 :       : HInstruction(HType::Tagged()), inputs_(4, zone) {
    1912             :     set_representation(Representation::Tagged());
    1913      675565 :   }
    1914             : 
    1915             :   ZoneList<HValue*> inputs_;
    1916             : };
    1917             : 
    1918             : 
    1919           0 : class HThisFunction final : public HTemplateInstruction<0> {
    1920             :  public:
    1921       89072 :   DECLARE_INSTRUCTION_FACTORY_P0(HThisFunction);
    1922             : 
    1923           0 :   Representation RequiredInputRepresentation(int index) override {
    1924           0 :     return Representation::None();
    1925             :   }
    1926             : 
    1927      819435 :   DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
    1928             : 
    1929             :  protected:
    1930       16579 :   bool DataEquals(HValue* other) override { return true; }
    1931             : 
    1932             :  private:
    1933       44536 :   HThisFunction() {
    1934             :     set_representation(Representation::Tagged());
    1935             :     SetFlag(kUseGVN);
    1936             :   }
    1937             : 
    1938          32 :   bool IsDeletable() const override { return true; }
    1939             : };
    1940             : 
    1941             : 
    1942           0 : class HDeclareGlobals final : public HUnaryOperation {
    1943             :  public:
    1944       24860 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HDeclareGlobals,
    1945             :                                               Handle<FixedArray>, int,
    1946             :                                               Handle<FeedbackVector>);
    1947             : 
    1948             :   HValue* context() { return OperandAt(0); }
    1949             :   Handle<FixedArray> declarations() const { return declarations_; }
    1950             :   int flags() const { return flags_; }
    1951             :   Handle<FeedbackVector> feedback_vector() const { return feedback_vector_; }
    1952             : 
    1953      197584 :   DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals)
    1954             : 
    1955       12333 :   Representation RequiredInputRepresentation(int index) override {
    1956       12333 :     return Representation::Tagged();
    1957             :   }
    1958             : 
    1959             :  private:
    1960             :   HDeclareGlobals(HValue* context, Handle<FixedArray> declarations, int flags,
    1961             :                   Handle<FeedbackVector> feedback_vector)
    1962             :       : HUnaryOperation(context),
    1963             :         declarations_(declarations),
    1964             :         feedback_vector_(feedback_vector),
    1965       12430 :         flags_(flags) {
    1966             :     set_representation(Representation::Tagged());
    1967             :     SetAllSideEffects();
    1968             :   }
    1969             : 
    1970             :   Handle<FixedArray> declarations_;
    1971             :   Handle<FeedbackVector> feedback_vector_;
    1972             :   int flags_;
    1973             : };
    1974             : 
    1975             : 
    1976             : template <int V>
    1977           0 : class HCall : public HTemplateInstruction<V> {
    1978             :  public:
    1979             :   // The argument count includes the receiver.
    1980      506416 :   explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
    1981             :     this->set_representation(Representation::Tagged());
    1982             :     this->SetAllSideEffects();
    1983      253208 :   }
    1984             : 
    1985      482145 :   virtual int argument_count() const {
    1986      482145 :     return argument_count_;
    1987             :   }
    1988             : 
    1989      251194 :   int argument_delta() const override { return -argument_count(); }
    1990             : 
    1991             :  private:
    1992             :   int argument_count_;
    1993             : };
    1994             : 
    1995             : 
    1996           0 : class HUnaryCall : public HCall<1> {
    1997             :  public:
    1998             :   HUnaryCall(HValue* value, int argument_count)
    1999             :       : HCall<1>(argument_count) {
    2000             :     SetOperandAt(0, value);
    2001             :   }
    2002             : 
    2003           0 :   Representation RequiredInputRepresentation(int index) final {
    2004           0 :     return Representation::Tagged();
    2005             :   }
    2006             : 
    2007             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2008             : 
    2009             :   HValue* value() const { return OperandAt(0); }
    2010             : };
    2011             : 
    2012             : 
    2013           0 : class HBinaryCall : public HCall<2> {
    2014             :  public:
    2015      146006 :   HBinaryCall(HValue* first, HValue* second, int argument_count)
    2016      146006 :       : HCall<2>(argument_count) {
    2017      146006 :     SetOperandAt(0, first);
    2018      146006 :     SetOperandAt(1, second);
    2019      146006 :   }
    2020             : 
    2021             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2022             : 
    2023      291961 :   Representation RequiredInputRepresentation(int index) final {
    2024      291961 :     return Representation::Tagged();
    2025             :   }
    2026             : 
    2027             :   HValue* first() const { return OperandAt(0); }
    2028             :   HValue* second() const { return OperandAt(1); }
    2029             : };
    2030             : 
    2031             : 
    2032           0 : class HCallWithDescriptor final : public HInstruction {
    2033             :  public:
    2034      530164 :   static HCallWithDescriptor* New(
    2035             :       Isolate* isolate, Zone* zone, HValue* context, HValue* target,
    2036             :       int argument_count, CallInterfaceDescriptor descriptor,
    2037             :       const Vector<HValue*>& operands,
    2038             :       TailCallMode syntactic_tail_call_mode = TailCallMode::kDisallow,
    2039             :       TailCallMode tail_call_mode = TailCallMode::kDisallow) {
    2040             :     HCallWithDescriptor* res = new (zone) HCallWithDescriptor(
    2041             :         Code::STUB, context, target, argument_count, descriptor, operands,
    2042      530164 :         syntactic_tail_call_mode, tail_call_mode, zone);
    2043      530164 :     return res;
    2044             :   }
    2045             : 
    2046      484017 :   static HCallWithDescriptor* New(
    2047             :       Isolate* isolate, Zone* zone, HValue* context, Code::Kind kind,
    2048             :       HValue* target, int argument_count, CallInterfaceDescriptor descriptor,
    2049             :       const Vector<HValue*>& operands,
    2050             :       TailCallMode syntactic_tail_call_mode = TailCallMode::kDisallow,
    2051             :       TailCallMode tail_call_mode = TailCallMode::kDisallow) {
    2052             :     HCallWithDescriptor* res = new (zone) HCallWithDescriptor(
    2053             :         kind, context, target, argument_count, descriptor, operands,
    2054      484017 :         syntactic_tail_call_mode, tail_call_mode, zone);
    2055      484017 :     return res;
    2056             :   }
    2057             : 
    2058     1905054 :   int OperandCount() const final { return values_.length(); }
    2059    24518520 :   HValue* OperandAt(int index) const final { return values_[index]; }
    2060             : 
    2061     6367375 :   Representation RequiredInputRepresentation(int index) final {
    2062     6367375 :     if (index == 0 || index == 1) {
    2063             :       // Target + context
    2064             :       return Representation::Tagged();
    2065             :     } else {
    2066     4350032 :       int par_index = index - 2;
    2067             :       DCHECK(par_index < GetParameterCount());
    2068             :       return RepresentationFromMachineType(
    2069     4350032 :           descriptor_.GetParameterType(par_index));
    2070             :     }
    2071             :   }
    2072             : 
    2073    45310784 :   DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor)
    2074             : 
    2075             :   // Defines whether this instruction corresponds to a JS call at tail position.
    2076             :   TailCallMode syntactic_tail_call_mode() const {
    2077             :     return SyntacticTailCallModeField::decode(bit_field_);
    2078             :   }
    2079             : 
    2080             :   // Defines whether this call should be generated as a tail call.
    2081             :   TailCallMode tail_call_mode() const {
    2082             :     return TailCallModeField::decode(bit_field_);
    2083             :   }
    2084      848446 :   bool IsTailCall() const { return tail_call_mode() == TailCallMode::kAllow; }
    2085             : 
    2086             :   Code::Kind kind() const { return KindField::decode(bit_field_); }
    2087             : 
    2088           0 :   virtual int argument_count() const {
    2089           0 :     return argument_count_;
    2090             :   }
    2091             : 
    2092     1007170 :   int argument_delta() const override { return -argument_count_; }
    2093             : 
    2094             :   CallInterfaceDescriptor descriptor() const { return descriptor_; }
    2095             : 
    2096             :   HValue* target() { return OperandAt(0); }
    2097             :   HValue* context() { return OperandAt(1); }
    2098             :   HValue* parameter(int index) {
    2099             :     DCHECK_LT(index, GetParameterCount());
    2100             :     return OperandAt(index + 2);
    2101             :   }
    2102             : 
    2103             :   HValue* Canonicalize() override;
    2104             : 
    2105             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2106             : 
    2107             :  private:
    2108             :   // The argument count includes the receiver.
    2109     1014181 :   HCallWithDescriptor(Code::Kind kind, HValue* context, HValue* target,
    2110             :                       int argument_count, CallInterfaceDescriptor descriptor,
    2111     8385457 :                       const Vector<HValue*>& operands,
    2112             :                       TailCallMode syntactic_tail_call_mode,
    2113             :                       TailCallMode tail_call_mode, Zone* zone)
    2114             :       : descriptor_(descriptor),
    2115             :         values_(GetParameterCount() + 2, zone),  // +2 for context and target.
    2116             :         argument_count_(argument_count),
    2117             :         bit_field_(
    2118     1014181 :             TailCallModeField::encode(tail_call_mode) |
    2119     1014181 :             SyntacticTailCallModeField::encode(syntactic_tail_call_mode) |
    2120     3042543 :             KindField::encode(kind)) {
    2121             :     DCHECK_EQ(operands.length(), GetParameterCount());
    2122             :     // We can only tail call without any stack arguments.
    2123             :     DCHECK(tail_call_mode != TailCallMode::kAllow || argument_count == 0);
    2124     1014181 :     AddOperand(target, zone);
    2125     1014181 :     AddOperand(context, zone);
    2126     9399638 :     for (int i = 0; i < operands.length(); i++) {
    2127     3685638 :       AddOperand(operands[i], zone);
    2128             :     }
    2129             :     this->set_representation(Representation::Tagged());
    2130             :     this->SetAllSideEffects();
    2131     1014181 :   }
    2132             : 
    2133     5713998 :   void AddOperand(HValue* v, Zone* zone) {
    2134             :     values_.Add(NULL, zone);
    2135     5713998 :     SetOperandAt(values_.length() - 1, v);
    2136     5713999 :   }
    2137             : 
    2138             :   int GetParameterCount() const { return descriptor_.GetParameterCount(); }
    2139             : 
    2140     8921803 :   void InternalSetOperandAt(int index, HValue* value) final {
    2141    17843606 :     values_[index] = value;
    2142     8921803 :   }
    2143             : 
    2144             :   CallInterfaceDescriptor descriptor_;
    2145             :   ZoneList<HValue*> values_;
    2146             :   int argument_count_;
    2147             :   class TailCallModeField : public BitField<TailCallMode, 0, 1> {};
    2148             :   class SyntacticTailCallModeField
    2149             :       : public BitField<TailCallMode, TailCallModeField::kNext, 1> {};
    2150             :   class KindField
    2151             :       : public BitField<Code::Kind, SyntacticTailCallModeField::kNext, 5> {};
    2152             :   uint32_t bit_field_;
    2153             : };
    2154             : 
    2155             : 
    2156           0 : class HInvokeFunction final : public HBinaryCall {
    2157             :  public:
    2158      291200 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(HInvokeFunction, HValue*,
    2159             :                                               Handle<JSFunction>, int,
    2160             :                                               TailCallMode, TailCallMode);
    2161             : 
    2162             :   HValue* context() { return first(); }
    2163             :   HValue* function() { return second(); }
    2164             :   Handle<JSFunction> known_function() { return known_function_; }
    2165             :   int formal_parameter_count() const { return formal_parameter_count_; }
    2166             : 
    2167       16448 :   bool HasStackCheck() final { return HasStackCheckField::decode(bit_field_); }
    2168             : 
    2169             :   // Defines whether this instruction corresponds to a JS call at tail position.
    2170             :   TailCallMode syntactic_tail_call_mode() const {
    2171             :     return SyntacticTailCallModeField::decode(bit_field_);
    2172             :   }
    2173             : 
    2174             :   // Defines whether this call should be generated as a tail call.
    2175             :   TailCallMode tail_call_mode() const {
    2176             :     return TailCallModeField::decode(bit_field_);
    2177             :   }
    2178             : 
    2179     9231437 :   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
    2180             : 
    2181             :   std::ostream& PrintTo(std::ostream& os) const override;      // NOLINT
    2182             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2183             : 
    2184             :  private:
    2185             :   void set_has_stack_check(bool has_stack_check) {
    2186      145600 :     bit_field_ = HasStackCheckField::update(bit_field_, has_stack_check);
    2187             :   }
    2188             : 
    2189      145600 :   HInvokeFunction(HValue* context, HValue* function,
    2190             :                   Handle<JSFunction> known_function, int argument_count,
    2191             :                   TailCallMode syntactic_tail_call_mode,
    2192             :                   TailCallMode tail_call_mode)
    2193             :       : HBinaryCall(context, function, argument_count),
    2194             :         known_function_(known_function),
    2195             :         bit_field_(
    2196      145600 :             TailCallModeField::encode(tail_call_mode) |
    2197      291200 :             SyntacticTailCallModeField::encode(syntactic_tail_call_mode)) {
    2198             :     DCHECK(tail_call_mode != TailCallMode::kAllow ||
    2199             :            syntactic_tail_call_mode == TailCallMode::kAllow);
    2200             :     formal_parameter_count_ =
    2201             :         known_function.is_null()
    2202             :             ? 0
    2203      291200 :             : known_function->shared()->internal_formal_parameter_count();
    2204             :     set_has_stack_check(
    2205      286207 :         !known_function.is_null() &&
    2206      128794 :         (known_function->code()->kind() == Code::FUNCTION ||
    2207             :          known_function->code()->kind() == Code::OPTIMIZED_FUNCTION));
    2208      145600 :   }
    2209             : 
    2210             :   Handle<JSFunction> known_function_;
    2211             :   int formal_parameter_count_;
    2212             : 
    2213             :   class HasStackCheckField : public BitField<bool, 0, 1> {};
    2214             :   class TailCallModeField
    2215             :       : public BitField<TailCallMode, HasStackCheckField::kNext, 1> {};
    2216             :   class SyntacticTailCallModeField
    2217             :       : public BitField<TailCallMode, TailCallModeField::kNext, 1> {};
    2218             :   uint32_t bit_field_;
    2219             : };
    2220             : 
    2221             : 
    2222           0 : class HCallNewArray final : public HBinaryCall {
    2223             :  public:
    2224         812 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HCallNewArray, HValue*, int,
    2225             :                                               ElementsKind,
    2226             :                                               Handle<AllocationSite>);
    2227             : 
    2228             :   HValue* context() { return first(); }
    2229             :   HValue* constructor() { return second(); }
    2230             : 
    2231             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2232             : 
    2233             :   ElementsKind elements_kind() const { return elements_kind_; }
    2234             :   Handle<AllocationSite> site() const { return site_; }
    2235             : 
    2236       60113 :   DECLARE_CONCRETE_INSTRUCTION(CallNewArray)
    2237             : 
    2238             :  private:
    2239             :   HCallNewArray(HValue* context, HValue* constructor, int argument_count,
    2240             :                 ElementsKind elements_kind, Handle<AllocationSite> site)
    2241             :       : HBinaryCall(context, constructor, argument_count),
    2242             :         elements_kind_(elements_kind),
    2243         406 :         site_(site) {}
    2244             : 
    2245             :   ElementsKind elements_kind_;
    2246             :   Handle<AllocationSite> site_;
    2247             : };
    2248             : 
    2249             : 
    2250           0 : class HCallRuntime final : public HCall<1> {
    2251             :  public:
    2252      107202 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallRuntime,
    2253             :                                               const Runtime::Function*, int);
    2254             : 
    2255             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2256             : 
    2257             :   HValue* context() { return OperandAt(0); }
    2258             :   const Runtime::Function* function() const { return c_function_; }
    2259             :   SaveFPRegsMode save_doubles() const { return save_doubles_; }
    2260             :   void set_save_doubles(SaveFPRegsMode save_doubles) {
    2261       12546 :     save_doubles_ = save_doubles;
    2262             :   }
    2263             : 
    2264      108161 :   Representation RequiredInputRepresentation(int index) override {
    2265      108161 :     return Representation::Tagged();
    2266             :   }
    2267             : 
    2268     5218089 :   DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
    2269             : 
    2270             :  private:
    2271      107202 :   HCallRuntime(HValue* context, const Runtime::Function* c_function,
    2272             :                int argument_count)
    2273             :       : HCall<1>(argument_count),
    2274             :         c_function_(c_function),
    2275      107202 :         save_doubles_(kDontSaveFPRegs) {
    2276      107202 :     SetOperandAt(0, context);
    2277      107202 :   }
    2278             : 
    2279             :   const Runtime::Function* c_function_;
    2280             :   SaveFPRegsMode save_doubles_;
    2281             : };
    2282             : 
    2283             : 
    2284           0 : class HUnaryMathOperation final : public HTemplateInstruction<2> {
    2285             :  public:
    2286             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    2287             :                            HValue* value, BuiltinFunctionId op);
    2288             : 
    2289             :   HValue* context() const { return OperandAt(0); }
    2290             :   HValue* value() const { return OperandAt(1); }
    2291             : 
    2292             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2293             : 
    2294      102909 :   Representation RequiredInputRepresentation(int index) override {
    2295      102909 :     if (index == 0) {
    2296             :       return Representation::Tagged();
    2297             :     } else {
    2298       53257 :       switch (op_) {
    2299             :         case kMathCos:
    2300             :         case kMathFloor:
    2301             :         case kMathRound:
    2302             :         case kMathFround:
    2303             :         case kMathSin:
    2304             :         case kMathSqrt:
    2305             :         case kMathPowHalf:
    2306             :         case kMathLog:
    2307             :         case kMathExp:
    2308             :           return Representation::Double();
    2309             :         case kMathAbs:
    2310             :           return representation();
    2311             :         case kMathClz32:
    2312             :           return Representation::Integer32();
    2313             :         default:
    2314           0 :           UNREACHABLE();
    2315             :           return Representation::None();
    2316             :       }
    2317             :     }
    2318             :   }
    2319             : 
    2320             :   Range* InferRange(Zone* zone) override;
    2321             : 
    2322             :   HValue* Canonicalize() override;
    2323             :   Representation RepresentationFromUses() override;
    2324             :   Representation RepresentationFromInputs() override;
    2325             : 
    2326             :   BuiltinFunctionId op() const { return op_; }
    2327             :   const char* OpName() const;
    2328             : 
    2329      730367 :   DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
    2330             : 
    2331             :  protected:
    2332         164 :   bool DataEquals(HValue* other) override {
    2333         164 :     HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
    2334         328 :     return op_ == b->op();
    2335             :   }
    2336             : 
    2337             :  private:
    2338             :   // Indicates if we support a double (and int32) output for Math.floor and
    2339             :   // Math.round.
    2340             :   bool SupportsFlexibleFloorAndRound() const {
    2341             : #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_PPC
    2342             :     return true;
    2343             : #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
    2344             :     return CpuFeatures::IsSupported(SSE4_1);
    2345             : #else
    2346             :     return false;
    2347             : #endif
    2348             :   }
    2349       29288 :   HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
    2350       29288 :       : HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) {
    2351       29288 :     SetOperandAt(0, context);
    2352       29288 :     SetOperandAt(1, value);
    2353       29288 :     switch (op) {
    2354             :       case kMathFloor:
    2355             :       case kMathRound:
    2356       27563 :         if (SupportsFlexibleFloorAndRound()) {
    2357             :           SetFlag(kFlexibleRepresentation);
    2358             :         } else {
    2359             :           set_representation(Representation::Integer32());
    2360             :         }
    2361             :         break;
    2362             :       case kMathClz32:
    2363             :         set_representation(Representation::Integer32());
    2364             :         break;
    2365             :       case kMathAbs:
    2366             :         // Not setting representation here: it is None intentionally.
    2367             :         SetFlag(kFlexibleRepresentation);
    2368             :         // TODO(svenpanne) This flag is actually only needed if representation()
    2369             :         // is tagged, and not when it is an unboxed double or unboxed integer.
    2370             :         SetChangesFlag(kNewSpacePromotion);
    2371             :         break;
    2372             :       case kMathCos:
    2373             :       case kMathFround:
    2374             :       case kMathLog:
    2375             :       case kMathExp:
    2376             :       case kMathSin:
    2377             :       case kMathSqrt:
    2378             :       case kMathPowHalf:
    2379             :         set_representation(Representation::Double());
    2380             :         break;
    2381             :       default:
    2382           0 :         UNREACHABLE();
    2383             :     }
    2384             :     SetFlag(kUseGVN);
    2385             :     SetFlag(kTruncatingToNumber);
    2386       29288 :   }
    2387             : 
    2388          72 :   bool IsDeletable() const override {
    2389             :     // TODO(crankshaft): This should be true, however the semantics of this
    2390             :     // instruction also include the ToNumber conversion that is mentioned in the
    2391             :     // spec, which is of course observable.
    2392          72 :     return false;
    2393             :   }
    2394             : 
    2395             :   HValue* SimplifiedDividendForMathFloorOfDiv(HDiv* hdiv);
    2396             :   HValue* SimplifiedDivisorForMathFloorOfDiv(HDiv* hdiv);
    2397             : 
    2398             :   BuiltinFunctionId op_;
    2399             : };
    2400             : 
    2401             : 
    2402           0 : class HLoadRoot final : public HTemplateInstruction<0> {
    2403             :  public:
    2404       10878 :   DECLARE_INSTRUCTION_FACTORY_P1(HLoadRoot, Heap::RootListIndex);
    2405             :   DECLARE_INSTRUCTION_FACTORY_P2(HLoadRoot, Heap::RootListIndex, HType);
    2406             : 
    2407           0 :   Representation RequiredInputRepresentation(int index) override {
    2408           0 :     return Representation::None();
    2409             :   }
    2410             : 
    2411             :   Heap::RootListIndex index() const { return index_; }
    2412             : 
    2413      104746 :   DECLARE_CONCRETE_INSTRUCTION(LoadRoot)
    2414             : 
    2415             :  protected:
    2416          19 :   bool DataEquals(HValue* other) override {
    2417             :     HLoadRoot* b = HLoadRoot::cast(other);
    2418          19 :     return index_ == b->index_;
    2419             :   }
    2420             : 
    2421             :  private:
    2422             :   explicit HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged())
    2423        5439 :       : HTemplateInstruction<0>(type), index_(index) {
    2424             :     SetFlag(kUseGVN);
    2425             :     // TODO(bmeurer): We'll need kDependsOnRoots once we add the
    2426             :     // corresponding HStoreRoot instruction.
    2427             :     SetDependsOnFlag(kCalls);
    2428             :     set_representation(Representation::Tagged());
    2429             :   }
    2430             : 
    2431           0 :   bool IsDeletable() const override { return true; }
    2432             : 
    2433             :   const Heap::RootListIndex index_;
    2434             : };
    2435             : 
    2436             : 
    2437           0 : class HCheckMaps final : public HTemplateInstruction<2> {
    2438             :  public:
    2439      144038 :   static HCheckMaps* New(Isolate* isolate, Zone* zone, HValue* context,
    2440             :                          HValue* value, Handle<Map> map,
    2441             :                          HValue* typecheck = NULL) {
    2442             :     return new(zone) HCheckMaps(value, new(zone) UniqueSet<Map>(
    2443      144038 :             Unique<Map>::CreateImmovable(map), zone), typecheck);
    2444             :   }
    2445      180420 :   static HCheckMaps* New(Isolate* isolate, Zone* zone, HValue* context,
    2446             :                          HValue* value, SmallMapList* map_list,
    2447             :                          HValue* typecheck = NULL) {
    2448             :     UniqueSet<Map>* maps = new(zone) UniqueSet<Map>(map_list->length(), zone);
    2449      735246 :     for (int i = 0; i < map_list->length(); ++i) {
    2450      187203 :       maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone);
    2451             :     }
    2452      180420 :     return new(zone) HCheckMaps(value, maps, typecheck);
    2453             :   }
    2454             : 
    2455             :   bool IsStabilityCheck() const {
    2456             :     return IsStabilityCheckField::decode(bit_field_);
    2457             :   }
    2458             :   void MarkAsStabilityCheck() {
    2459             :     bit_field_ = MapsAreStableField::encode(true) |
    2460             :                  HasMigrationTargetField::encode(false) |
    2461      199880 :                  IsStabilityCheckField::encode(true);
    2462             :     ClearChangesFlag(kNewSpacePromotion);
    2463             :     ClearDependsOnFlag(kElementsKind);
    2464             :     ClearDependsOnFlag(kMaps);
    2465             :   }
    2466             : 
    2467        6490 :   bool HasEscapingOperandAt(int index) override { return false; }
    2468      648055 :   Representation RequiredInputRepresentation(int index) override {
    2469      648055 :     return Representation::Tagged();
    2470             :   }
    2471             : 
    2472      319301 :   HType CalculateInferredType() override {
    2473      319301 :     if (value()->type().IsHeapObject()) return value()->type();
    2474             :     return HType::HeapObject();
    2475             :   }
    2476             : 
    2477             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2478             : 
    2479             :   HValue* value() const { return OperandAt(0); }
    2480             :   HValue* typecheck() const { return OperandAt(1); }
    2481             : 
    2482             :   const UniqueSet<Map>* maps() const { return maps_; }
    2483       14898 :   void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; }
    2484             : 
    2485             :   bool maps_are_stable() const {
    2486             :     return MapsAreStableField::decode(bit_field_);
    2487             :   }
    2488             : 
    2489             :   bool HasMigrationTarget() const {
    2490             :     return HasMigrationTargetField::decode(bit_field_);
    2491             :   }
    2492             : 
    2493             :   HValue* Canonicalize() override;
    2494             : 
    2495           0 :   static HCheckMaps* CreateAndInsertAfter(Zone* zone,
    2496             :                                           HValue* value,
    2497             :                                           Unique<Map> map,
    2498             :                                           bool map_is_stable,
    2499             :                                           HInstruction* instr) {
    2500             :     return instr->Append(new(zone) HCheckMaps(
    2501           0 :             value, new(zone) UniqueSet<Map>(map, zone), map_is_stable));
    2502             :   }
    2503             : 
    2504         722 :   static HCheckMaps* CreateAndInsertBefore(Zone* zone,
    2505             :                                            HValue* value,
    2506             :                                            const UniqueSet<Map>* maps,
    2507             :                                            bool maps_are_stable,
    2508             :                                            HInstruction* instr) {
    2509        1444 :     return instr->Prepend(new(zone) HCheckMaps(value, maps, maps_are_stable));
    2510             :   }
    2511             : 
    2512     5081189 :   DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
    2513             : 
    2514             :  protected:
    2515      225510 :   bool DataEquals(HValue* other) override {
    2516      338265 :     return this->maps()->Equals(HCheckMaps::cast(other)->maps());
    2517             :   }
    2518             : 
    2519      592952 :   int RedefinedOperandIndex() override { return 0; }
    2520             : 
    2521             :  private:
    2522         722 :   HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable)
    2523             :       : HTemplateInstruction<2>(HType::HeapObject()),
    2524             :         maps_(maps),
    2525             :         bit_field_(HasMigrationTargetField::encode(false) |
    2526             :                    IsStabilityCheckField::encode(false) |
    2527        1444 :                    MapsAreStableField::encode(maps_are_stable)) {
    2528             :     DCHECK_NE(0, maps->size());
    2529         722 :     SetOperandAt(0, value);
    2530             :     // Use the object value for the dependency.
    2531         722 :     SetOperandAt(1, value);
    2532             :     set_representation(Representation::Tagged());
    2533             :     SetFlag(kUseGVN);
    2534             :     SetDependsOnFlag(kMaps);
    2535             :     SetDependsOnFlag(kElementsKind);
    2536         722 :   }
    2537             : 
    2538     1635856 :   HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck)
    2539             :       : HTemplateInstruction<2>(HType::HeapObject()),
    2540             :         maps_(maps),
    2541             :         bit_field_(HasMigrationTargetField::encode(false) |
    2542             :                    IsStabilityCheckField::encode(false) |
    2543      324458 :                    MapsAreStableField::encode(true)) {
    2544             :     DCHECK_NE(0, maps->size());
    2545      324458 :     SetOperandAt(0, value);
    2546             :     // Use the object value for the dependency if NULL is passed.
    2547      324458 :     SetOperandAt(1, typecheck ? typecheck : value);
    2548             :     set_representation(Representation::Tagged());
    2549             :     SetFlag(kUseGVN);
    2550             :     SetDependsOnFlag(kMaps);
    2551             :     SetDependsOnFlag(kElementsKind);
    2552     1311398 :     for (int i = 0; i < maps->size(); ++i) {
    2553             :       Handle<Map> map = maps->at(i).handle();
    2554      331241 :       if (map->is_migration_target()) {
    2555        7898 :         bit_field_ = HasMigrationTargetField::update(bit_field_, true);
    2556             :       }
    2557      331241 :       if (!map->is_stable()) {
    2558      127362 :         bit_field_ = MapsAreStableField::update(bit_field_, false);
    2559             :       }
    2560             :     }
    2561      324458 :     if (HasMigrationTarget()) SetChangesFlag(kNewSpacePromotion);
    2562      324458 :   }
    2563             : 
    2564             :   class HasMigrationTargetField : public BitField<bool, 0, 1> {};
    2565             :   class IsStabilityCheckField : public BitField<bool, 1, 1> {};
    2566             :   class MapsAreStableField : public BitField<bool, 2, 1> {};
    2567             : 
    2568             :   const UniqueSet<Map>* maps_;
    2569             :   uint32_t bit_field_;
    2570             : };
    2571             : 
    2572             : 
    2573           0 : class HCheckValue final : public HUnaryOperation {
    2574             :  public:
    2575      203106 :   static HCheckValue* New(Isolate* isolate, Zone* zone, HValue* context,
    2576             :                           HValue* value, Handle<JSFunction> func) {
    2577             :     bool in_new_space = isolate->heap()->InNewSpace(*func);
    2578             :     // NOTE: We create an uninitialized Unique and initialize it later.
    2579             :     // This is because a JSFunction can move due to GC during graph creation.
    2580             :     Unique<JSFunction> target = Unique<JSFunction>::CreateUninitialized(func);
    2581             :     HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space);
    2582      203106 :     return check;
    2583             :   }
    2584        1824 :   static HCheckValue* New(Isolate* isolate, Zone* zone, HValue* context,
    2585             :                           HValue* value, Unique<HeapObject> target,
    2586             :                           bool object_in_new_space) {
    2587        3648 :     return new(zone) HCheckValue(value, target, object_in_new_space);
    2588             :   }
    2589             : 
    2590      202617 :   void FinalizeUniqueness() override {
    2591      202617 :     object_ = Unique<HeapObject>(object_.handle());
    2592      202617 :   }
    2593             : 
    2594      204282 :   Representation RequiredInputRepresentation(int index) override {
    2595      204282 :     return Representation::Tagged();
    2596             :   }
    2597             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2598             : 
    2599             :   HValue* Canonicalize() override;
    2600             : 
    2601             : #ifdef DEBUG
    2602             :   void Verify() override;
    2603             : #endif
    2604             : 
    2605             :   Unique<HeapObject> object() const { return object_; }
    2606             :   bool object_in_new_space() const { return object_in_new_space_; }
    2607             : 
    2608     2189117 :   DECLARE_CONCRETE_INSTRUCTION(CheckValue)
    2609             : 
    2610             :  protected:
    2611        1204 :   bool DataEquals(HValue* other) override {
    2612             :     HCheckValue* b = HCheckValue::cast(other);
    2613        2408 :     return object_ == b->object_;
    2614             :   }
    2615             : 
    2616             :  private:
    2617             :   HCheckValue(HValue* value, Unique<HeapObject> object,
    2618             :                bool object_in_new_space)
    2619             :       : HUnaryOperation(value, value->type()),
    2620             :         object_(object),
    2621      204930 :         object_in_new_space_(object_in_new_space) {
    2622             :     set_representation(Representation::Tagged());
    2623             :     SetFlag(kUseGVN);
    2624             :   }
    2625             : 
    2626             :   Unique<HeapObject> object_;
    2627             :   bool object_in_new_space_;
    2628             : };
    2629             : 
    2630             : 
    2631           0 : class HCheckInstanceType final : public HUnaryOperation {
    2632             :  public:
    2633             :   enum Check {
    2634             :     IS_JS_RECEIVER,
    2635             :     IS_JS_ARRAY,
    2636             :     IS_JS_FUNCTION,
    2637             :     IS_JS_DATE,
    2638             :     IS_STRING,
    2639             :     IS_INTERNALIZED_STRING,
    2640             :     LAST_INTERVAL_CHECK = IS_JS_DATE
    2641             :   };
    2642             : 
    2643      190696 :   DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check);
    2644             : 
    2645             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2646             : 
    2647       97171 :   Representation RequiredInputRepresentation(int index) override {
    2648       97171 :     return Representation::Tagged();
    2649             :   }
    2650             : 
    2651       89311 :   HType CalculateInferredType() override {
    2652       89311 :     switch (check_) {
    2653             :       case IS_JS_RECEIVER: return HType::JSReceiver();
    2654             :       case IS_JS_ARRAY: return HType::JSArray();
    2655             :       case IS_JS_FUNCTION:
    2656             :         return HType::JSObject();
    2657             :       case IS_JS_DATE: return HType::JSObject();
    2658             :       case IS_STRING: return HType::String();
    2659             :       case IS_INTERNALIZED_STRING: return HType::String();
    2660             :     }
    2661           0 :     UNREACHABLE();
    2662             :     return HType::Tagged();
    2663             :   }
    2664             : 
    2665             :   HValue* Canonicalize() override;
    2666             : 
    2667       50117 :   bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
    2668             :   void GetCheckInterval(InstanceType* first, InstanceType* last);
    2669             :   void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
    2670             : 
    2671             :   Check check() const { return check_; }
    2672             : 
    2673     1470316 :   DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
    2674             : 
    2675             :  protected:
    2676             :   // TODO(ager): It could be nice to allow the ommision of instance
    2677             :   // type checks if we have already performed an instance type check
    2678             :   // with a larger range.
    2679       19517 :   bool DataEquals(HValue* other) override {
    2680             :     HCheckInstanceType* b = HCheckInstanceType::cast(other);
    2681       19517 :     return check_ == b->check_;
    2682             :   }
    2683             : 
    2684      134690 :   int RedefinedOperandIndex() override { return 0; }
    2685             : 
    2686             :  private:
    2687             :   const char* GetCheckName() const;
    2688             : 
    2689             :   HCheckInstanceType(HValue* value, Check check)
    2690       95348 :       : HUnaryOperation(value, HType::HeapObject()), check_(check) {
    2691             :     set_representation(Representation::Tagged());
    2692             :     SetFlag(kUseGVN);
    2693             :   }
    2694             : 
    2695             :   const Check check_;
    2696             : };
    2697             : 
    2698             : 
    2699           0 : class HCheckSmi final : public HUnaryOperation {
    2700             :  public:
    2701             :   DECLARE_INSTRUCTION_FACTORY_P1(HCheckSmi, HValue*);
    2702             : 
    2703           0 :   Representation RequiredInputRepresentation(int index) override {
    2704           0 :     return Representation::Tagged();
    2705             :   }
    2706             : 
    2707           0 :   HValue* Canonicalize() override {
    2708             :     HType value_type = value()->type();
    2709           0 :     if (value_type.IsSmi()) {
    2710             :       return NULL;
    2711             :     }
    2712           0 :     return this;
    2713             :   }
    2714             : 
    2715           0 :   DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
    2716             : 
    2717             :  protected:
    2718           0 :   bool DataEquals(HValue* other) override { return true; }
    2719             : 
    2720             :  private:
    2721             :   explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) {
    2722             :     set_representation(Representation::Smi());
    2723             :     SetFlag(kUseGVN);
    2724             :   }
    2725             : };
    2726             : 
    2727             : 
    2728           0 : class HCheckArrayBufferNotNeutered final : public HUnaryOperation {
    2729             :  public:
    2730        4032 :   DECLARE_INSTRUCTION_FACTORY_P1(HCheckArrayBufferNotNeutered, HValue*);
    2731             : 
    2732           0 :   bool HasEscapingOperandAt(int index) override { return false; }
    2733        4032 :   Representation RequiredInputRepresentation(int index) override {
    2734        4032 :     return Representation::Tagged();
    2735             :   }
    2736             : 
    2737        4032 :   HType CalculateInferredType() override {
    2738        4032 :     if (value()->type().IsHeapObject()) return value()->type();
    2739             :     return HType::HeapObject();
    2740             :   }
    2741             : 
    2742       63548 :   DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered)
    2743             : 
    2744             :  protected:
    2745        1599 :   bool DataEquals(HValue* other) override { return true; }
    2746        8763 :   int RedefinedOperandIndex() override { return 0; }
    2747             : 
    2748             :  private:
    2749        4032 :   explicit HCheckArrayBufferNotNeutered(HValue* value)
    2750        4032 :       : HUnaryOperation(value) {
    2751             :     set_representation(Representation::Tagged());
    2752             :     SetFlag(kUseGVN);
    2753             :     SetDependsOnFlag(kCalls);
    2754        4032 :   }
    2755             : };
    2756             : 
    2757             : 
    2758           0 : class HCheckHeapObject final : public HUnaryOperation {
    2759             :  public:
    2760      367018 :   DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*);
    2761             : 
    2762         875 :   bool HasEscapingOperandAt(int index) override { return false; }
    2763      197461 :   Representation RequiredInputRepresentation(int index) override {
    2764      197461 :     return Representation::Tagged();
    2765             :   }
    2766             : 
    2767      181291 :   HType CalculateInferredType() override {
    2768      181291 :     if (value()->type().IsHeapObject()) return value()->type();
    2769             :     return HType::HeapObject();
    2770             :   }
    2771             : 
    2772             : #ifdef DEBUG
    2773             :   void Verify() override;
    2774             : #endif
    2775             : 
    2776      177200 :   HValue* Canonicalize() override {
    2777      177200 :     return value()->type().IsHeapObject() ? NULL : this;
    2778             :   }
    2779             : 
    2780     2902695 :   DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject)
    2781             : 
    2782             :  protected:
    2783       65383 :   bool DataEquals(HValue* other) override { return true; }
    2784             : 
    2785             :  private:
    2786      183509 :   explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) {
    2787             :     set_representation(Representation::Tagged());
    2788             :     SetFlag(kUseGVN);
    2789             :   }
    2790             : };
    2791             : 
    2792             : 
    2793           0 : class HPhi final : public HValue {
    2794             :  public:
    2795      696556 :   HPhi(int merged_index, Zone* zone)
    2796      696556 :       : inputs_(2, zone), merged_index_(merged_index) {
    2797             :     DCHECK(merged_index >= 0 || merged_index == kInvalidMergedIndex);
    2798             :     SetFlag(kFlexibleRepresentation);
    2799      696556 :   }
    2800             : 
    2801             :   Representation RepresentationFromInputs() override;
    2802             : 
    2803             :   Range* InferRange(Zone* zone) override;
    2804             :   void InferRepresentation(HInferRepresentationPhase* h_infer) override;
    2805     1276382 :   Representation RequiredInputRepresentation(int index) override {
    2806     1276382 :     return representation();
    2807             :   }
    2808      541302 :   Representation KnownOptimalRepresentation() override {
    2809      541302 :     return representation();
    2810             :   }
    2811             :   HType CalculateInferredType() override;
    2812    11417658 :   int OperandCount() const override { return inputs_.length(); }
    2813    25650671 :   HValue* OperandAt(int index) const override { return inputs_[index]; }
    2814             :   HValue* GetRedundantReplacement();
    2815             :   void AddInput(HValue* value);
    2816             :   bool HasRealUses();
    2817             : 
    2818             :   bool IsReceiver() const { return merged_index_ == 0; }
    2819             :   bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; }
    2820             : 
    2821             :   SourcePosition position() const override;
    2822             : 
    2823             :   int merged_index() const { return merged_index_; }
    2824             : 
    2825             :   std::ostream& PrintTo(std::ostream& os) const override;  // NOLINT
    2826             : 
    2827             : #ifdef DEBUG
    2828             :   void Verify() override;
    2829             : #endif
    2830             : 
    2831             :   void InitRealUses(int id);
    2832             :   void AddNonPhiUsesFrom(HPhi* other);
    2833             : 
    2834             :   Representation representation_from_indirect_uses() const {
    2835             :     return representation_from_indirect_uses_;
    2836             :   }
    2837             : 
    2838             :   bool has_type_feedback_from_uses() const {
    2839             :     return has_type_feedback_from_uses_;
    2840             :   }
    2841             : 
    2842             :   int phi_id() { return phi_id_; }
    2843             : 
    2844         155 :   static HPhi* cast(HValue* value) {
    2845             :     DCHECK(value->IsPhi());
    2846         155 :     return reinterpret_cast<HPhi*>(value);
    2847             :   }
    2848    23374135 :   Opcode opcode() const override { return HValue::kPhi; }
    2849             : 
    2850             :   void SimplifyConstantInputs();
    2851             : 
    2852             :   // Marker value representing an invalid merge index.
    2853             :   static const int kInvalidMergedIndex = -1;
    2854             : 
    2855             :  protected:
    2856             :   void DeleteFromGraph() override;
    2857     2055364 :   void InternalSetOperandAt(int index, HValue* value) override {
    2858     4110728 :     inputs_[index] = value;
    2859     2055364 :   }
    2860             : 
    2861             :  private:
    2862             :   Representation representation_from_non_phi_uses() const {
    2863             :     return representation_from_non_phi_uses_;
    2864             :   }
    2865             : 
    2866             :   ZoneList<HValue*> inputs_;
    2867             :   int merged_index_ = 0;
    2868             : 
    2869             :   int phi_id_ = -1;
    2870             : 
    2871             :   Representation representation_from_indirect_uses_ = Representation::None();
    2872             :   Representation representation_from_non_phi_uses_ = Representation::None();
    2873             :   bool has_type_feedback_from_uses_ = false;
    2874             : 
    2875         224 :   bool IsDeletable() const override { return !IsReceiver(); }
    2876             : };
    2877             : 
    2878             : 
    2879             : // Common base class for HArgumentsObject and HCapturedObject.
    2880           0 : class HDematerializedObject : public HInstruction {
    2881             :  public:
    2882      764542 :   HDematerializedObject(int count, Zone* zone) : values_(count, zone) {}
    2883             : 
    2884       86150 :   int OperandCount() const final { return values_.length(); }
    2885     2599541 :   HValue* OperandAt(int index) const final { return values_[index]; }
    2886             : 
    2887         394 :   bool HasEscapingOperandAt(int index) final { return false; }
    2888      811050 :   Representation RequiredInputRepresentation(int index) final {
    2889      811050 :     return Representation::None();
    2890             :   }
    2891             : 
    2892             :  protected:
    2893      960181 :   void InternalSetOperandAt(int index, HValue* value) final {
    2894     1920362 :     values_[index] = value;
    2895      960181 :   }
    2896             : 
    2897             :   // List of values tracked by this marker.
    2898             :   ZoneList<HValue*> values_;
    2899             : };
    2900             : 
    2901             : 
    2902           0 : class HArgumentsObject final : public HDematerializedObject {
    2903             :  public:
    2904      371310 :   static HArgumentsObject* New(Isolate* isolate, Zone* zone, HValue* context,
    2905             :                                int count) {
    2906      371311 :     return new(zone) HArgumentsObject(count, zone);
    2907             :   }
    2908             : 
    2909             :   // The values contain a list of all elements in the arguments object
    2910             :   // including the receiver object, which is skipped when materializing.
    2911             :   const ZoneList<HValue*>* arguments_values() const { return &values_; }
    2912             :   int arguments_count() const { return values_.length(); }
    2913             : 
    2914      726799 :   void AddArgument(HValue* argument, Zone* zone) {
    2915             :     values_.Add(NULL, zone);  // Resize list.
    2916      726800 :     SetOperandAt(values_.length() - 1, argument);
    2917      726800 :   }
    2918             : 
    2919     5233886 :   DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
    2920             : 
    2921             :  private:
    2922             :   HArgumentsObject(int count, Zone* zone)
    2923      371310 :       : HDematerializedObject(count, zone) {
    2924             :     set_representation(Representation::Tagged());
    2925             :     SetFlag(kIsArguments);
    2926             :   }
    2927             : };
    2928             : 
    2929             : 
    2930           0 : class HCapturedObject final : public HDematerializedObject {
    2931             :  public:
    2932       10961 :   HCapturedObject(int length, int id, Zone* zone)
    2933       10961 :       : HDematerializedObject(length, zone), capture_id_(id) {
    2934             :     set_representation(Representation::Tagged());
    2935       10961 :     values_.AddBlock(NULL, length, zone);  // Resize list.
    2936       10961 :   }
    2937             : 
    2938             :   // The values contain a list of all in-object properties inside the
    2939             :   // captured object and is index by field index. Properties in the
    2940             :   // properties or elements backing store are not tracked here.
    2941             :   const ZoneList<HValue*>* values() const { return &values_; }
    2942             :   int length() const { return values_.length(); }
    2943             :   int capture_id() const { return capture_id_; }
    2944             : 
    2945             :   // Shortcut for the map value of this captured object.
    2946        1390 :   HValue* map_value() const { return values()->first(); }
    2947             : 
    2948             :   void ReuseSideEffectsFromStore(HInstruction* store) {
    2949             :     DCHECK(store->HasObservableSideEffects());
    2950             :     DCHECK(store->IsStoreNamedField());
    2951             :     changes_flags_.Add(store->ChangesFlags());
    2952             :   }
    2953             : 
    2954             :   // Replay effects of this instruction on the given environment.
    2955             :   void ReplayEnvironment(HEnvironment* env);
    2956             : 
    2957             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    2958             : 
    2959      387528 :   DECLARE_CONCRETE_INSTRUCTION(CapturedObject)
    2960             : 
    2961             :  private:
    2962             :   int capture_id_;
    2963             : 
    2964             :   // Note that we cannot DCE captured objects as they are used to replay
    2965             :   // the environment. This method is here as an explicit reminder.
    2966             :   // TODO(mstarzinger): Turn HSimulates into full snapshots maybe?
    2967          59 :   bool IsDeletable() const final { return false; }
    2968             : };
    2969             : 
    2970             : 
    2971           0 : class HConstant final : public HTemplateInstruction<0> {
    2972             :  public:
    2973             :   enum Special { kHoleNaN };
    2974             : 
    2975         128 :   DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Special);
    2976     4428199 :   DECLARE_INSTRUCTION_FACTORY_P1(HConstant, int32_t);
    2977        7988 :   DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation);
    2978         974 :   DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double);
    2979     9240594 :   DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>);
    2980       22410 :   DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference);
    2981             : 
    2982             :   static HConstant* CreateAndInsertAfter(Isolate* isolate, Zone* zone,
    2983             :                                          HValue* context, int32_t value,
    2984             :                                          Representation representation,
    2985             :                                          HInstruction* instruction) {
    2986             :     return instruction->Append(
    2987             :         HConstant::New(isolate, zone, context, value, representation));
    2988             :   }
    2989             : 
    2990      338104 :   Handle<Map> GetMonomorphicJSObjectMap() override {
    2991             :     Handle<Object> object = object_.handle();
    2992      676208 :     if (!object.is_null() && object->IsHeapObject()) {
    2993             :       return v8::internal::handle(HeapObject::cast(*object)->map());
    2994             :     }
    2995        4804 :     return Handle<Map>();
    2996             :   }
    2997             : 
    2998             :   static HConstant* CreateAndInsertBefore(Isolate* isolate, Zone* zone,
    2999             :                                           HValue* context, int32_t value,
    3000             :                                           Representation representation,
    3001             :                                           HInstruction* instruction) {
    3002             :     return instruction->Prepend(
    3003        2829 :         HConstant::New(isolate, zone, context, value, representation));
    3004             :   }
    3005             : 
    3006          14 :   static HConstant* CreateAndInsertBefore(Zone* zone,
    3007             :                                           Unique<Map> map,
    3008             :                                           bool map_is_stable,
    3009             :                                           HInstruction* instruction) {
    3010             :     return instruction->Prepend(new(zone) HConstant(
    3011             :         map, Unique<Map>(Handle<Map>::null()), map_is_stable,
    3012             :         Representation::Tagged(), HType::HeapObject(), true,
    3013          42 :         false, false, MAP_TYPE));
    3014             :   }
    3015             : 
    3016             :   static HConstant* CreateAndInsertAfter(Zone* zone,
    3017             :                                          Unique<Map> map,
    3018             :                                          bool map_is_stable,
    3019             :                                          HInstruction* instruction) {
    3020             :     return instruction->Append(new(zone) HConstant(
    3021             :             map, Unique<Map>(Handle<Map>::null()), map_is_stable,
    3022             :             Representation::Tagged(), HType::HeapObject(), true,
    3023             :             false, false, MAP_TYPE));
    3024             :   }
    3025             : 
    3026    18781481 :   Handle<Object> handle(Isolate* isolate) {
    3027    18781481 :     if (object_.handle().is_null()) {
    3028             :       // Default arguments to is_not_in_new_space depend on this heap number
    3029             :       // to be tenured so that it's guaranteed not to be located in new space.
    3030             :       object_ = Unique<Object>::CreateUninitialized(
    3031      175420 :           isolate->factory()->NewNumber(double_value_, TENURED));
    3032             :     }
    3033             :     AllowDeferredHandleDereference smi_check;
    3034             :     DCHECK(HasInteger32Value() || !object_.handle()->IsSmi());
    3035    18781481 :     return object_.handle();
    3036             :   }
    3037             : 
    3038         556 :   bool IsSpecialDouble() const {
    3039        1112 :     return HasDoubleValue() &&
    3040        1100 :            (bit_cast<int64_t>(double_value_) == bit_cast<int64_t>(-0.0) ||
    3041        1100 :             std::isnan(double_value_));
    3042             :   }
    3043             : 
    3044             :   bool NotInNewSpace() const {
    3045             :     return IsNotInNewSpaceField::decode(bit_field_);
    3046             :   }
    3047             : 
    3048             :   bool ImmortalImmovable() const;
    3049             : 
    3050     8008276 :   bool IsCell() const {
    3051             :     InstanceType instance_type = GetInstanceType();
    3052             :     return instance_type == CELL_TYPE;
    3053             :   }
    3054             : 
    3055           0 :   Representation RequiredInputRepresentation(int index) override {
    3056           0 :     return Representation::None();
    3057             :   }
    3058             : 
    3059      206460 :   Representation KnownOptimalRepresentation() override {
    3060             :     if (HasSmiValue() && SmiValuesAre31Bits()) return Representation::Smi();
    3061      206460 :     if (HasInteger32Value()) return Representation::Integer32();
    3062      124558 :     if (HasNumberValue()) return Representation::Double();
    3063      116953 :     if (HasExternalReferenceValue()) return Representation::External();
    3064             :     return Representation::Tagged();
    3065             :   }
    3066             : 
    3067             :   bool EmitAtUses() override;
    3068             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    3069             :   HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
    3070             :   Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
    3071             :   Maybe<HConstant*> CopyToTruncatedNumber(Isolate* isolate, Zone* zone);
    3072             :   bool HasInteger32Value() const {
    3073             :     return HasInt32ValueField::decode(bit_field_);
    3074             :   }
    3075             :   int32_t Integer32Value() const {
    3076             :     DCHECK(HasInteger32Value());
    3077             :     return int32_value_;
    3078             :   }
    3079             :   bool HasSmiValue() const { return HasSmiValueField::decode(bit_field_); }
    3080             :   bool HasDoubleValue() const {
    3081             :     return HasDoubleValueField::decode(bit_field_);
    3082             :   }
    3083             :   double DoubleValue() const {
    3084             :     DCHECK(HasDoubleValue());
    3085             :     return double_value_;
    3086             :   }
    3087             :   uint64_t DoubleValueAsBits() const {
    3088             :     DCHECK(HasDoubleValue());
    3089      213489 :     return bit_cast<uint64_t>(double_value_);
    3090             :   }
    3091             :   bool IsTheHole() const {
    3092             :     if (HasDoubleValue() && DoubleValueAsBits() == kHoleNanInt64) {
    3093             :       return true;
    3094             :     }
    3095             :     return object_.IsInitialized() &&
    3096             :            object_.IsKnownGlobal(isolate()->heap()->the_hole_value());
    3097             :   }
    3098      138066 :   bool HasNumberValue() const { return HasDoubleValue(); }
    3099             :   int32_t NumberValueAsInteger32() const {
    3100             :     DCHECK(HasNumberValue());
    3101             :     // Irrespective of whether a numeric HConstant can be safely
    3102             :     // represented as an int32, we store the (in some cases lossy)
    3103             :     // representation of the number in int32_value_.
    3104             :     return int32_value_;
    3105             :   }
    3106             :   bool HasStringValue() const {
    3107      136715 :     if (HasNumberValue()) return false;
    3108             :     DCHECK(!object_.handle().is_null());
    3109      130573 :     return GetInstanceType() < FIRST_NONSTRING_TYPE;
    3110             :   }
    3111             :   Handle<String> StringValue() const {
    3112             :     DCHECK(HasStringValue());
    3113             :     return Handle<String>::cast(object_.handle());
    3114             :   }
    3115        8522 :   bool HasInternalizedStringValue() const {
    3116       17042 :     return HasStringValue() && StringShape(GetInstanceType()).IsInternalized();
    3117             :   }
    3118             : 
    3119             :   bool HasExternalReferenceValue() const {
    3120             :     return HasExternalReferenceValueField::decode(bit_field_);
    3121             :   }
    3122             :   ExternalReference ExternalReferenceValue() const {
    3123             :     return external_reference_value_;
    3124             :   }
    3125             : 
    3126             :   bool HasBooleanValue() const { return type_.IsBoolean(); }
    3127             :   bool BooleanValue() const { return BooleanValueField::decode(bit_field_); }
    3128             :   bool IsCallable() const { return IsCallableField::decode(bit_field_); }
    3129             :   bool IsUndetectable() const {
    3130             :     return IsUndetectableField::decode(bit_field_);
    3131             :   }
    3132             :   InstanceType GetInstanceType() const {
    3133             :     return InstanceTypeField::decode(bit_field_);
    3134             :   }
    3135             : 
    3136             :   bool HasMapValue() const { return GetInstanceType() == MAP_TYPE; }
    3137             :   Unique<Map> MapValue() const {
    3138             :     DCHECK(HasMapValue());
    3139             :     return Unique<Map>::cast(GetUnique());
    3140             :   }
    3141             :   bool HasStableMapValue() const {
    3142             :     DCHECK(HasMapValue() || !HasStableMapValueField::decode(bit_field_));
    3143             :     return HasStableMapValueField::decode(bit_field_);
    3144             :   }
    3145             : 
    3146      184373 :   bool HasObjectMap() const { return !object_map_.IsNull(); }
    3147             :   Unique<Map> ObjectMap() const {
    3148             :     DCHECK(HasObjectMap());
    3149             :     return object_map_;
    3150             :   }
    3151             : 
    3152    18304577 :   intptr_t Hashcode() override {
    3153    18304577 :     if (HasInteger32Value()) {
    3154     7413576 :       return static_cast<intptr_t>(int32_value_);
    3155    10891001 :     } else if (HasDoubleValue()) {
    3156             :       uint64_t bits = DoubleValueAsBits();
    3157             :       if (sizeof(bits) > sizeof(intptr_t)) {
    3158             :         bits ^= (bits >> 32);
    3159             :       }
    3160      170493 :       return static_cast<intptr_t>(bits);
    3161    10720508 :     } else if (HasExternalReferenceValue()) {
    3162       29105 :       return reinterpret_cast<intptr_t>(external_reference_value_.address());
    3163             :     } else {
    3164             :       DCHECK(!object_.handle().is_null());
    3165    21382806 :       return object_.Hashcode();
    3166             :     }
    3167             :   }
    3168             : 
    3169     7056340 :   void FinalizeUniqueness() override {
    3170    11610327 :     if (!HasDoubleValue() && !HasExternalReferenceValue()) {
    3171             :       DCHECK(!object_.handle().is_null());
    3172     4542833 :       object_ = Unique<Object>(object_.handle());
    3173             :     }
    3174     7056340 :   }
    3175             : 
    3176             :   Unique<Object> GetUnique() const {
    3177             :     return object_;
    3178             :   }
    3179             : 
    3180             :   bool EqualsUnique(Unique<Object> other) const {
    3181      164491 :     return object_.IsInitialized() && object_ == other;
    3182             :   }
    3183             : 
    3184     5716156 :   bool DataEquals(HValue* other) override {
    3185     5716156 :     HConstant* other_constant = HConstant::cast(other);
    3186     5716156 :     if (HasInteger32Value()) {
    3187     2062343 :       return other_constant->HasInteger32Value() &&
    3188     2062343 :              int32_value_ == other_constant->int32_value_;
    3189     4647148 :     } else if (HasDoubleValue()) {
    3190     1240132 :       return other_constant->HasDoubleValue() &&
    3191             :              std::memcmp(&double_value_, &other_constant->double_value_,
    3192     1240132 :                          sizeof(double_value_)) == 0;
    3193     4027082 :     } else if (HasExternalReferenceValue()) {
    3194        5020 :       return other_constant->HasExternalReferenceValue() &&
    3195        2510 :              external_reference_value_ ==
    3196        2510 :                  other_constant->external_reference_value_;
    3197             :     } else {
    3198     8049142 :       if (other_constant->HasInteger32Value() ||
    3199     8049142 :           other_constant->HasDoubleValue() ||
    3200             :           other_constant->HasExternalReferenceValue()) {
    3201             :         return false;
    3202             :       }
    3203             :       DCHECK(!object_.handle().is_null());
    3204     8049140 :       return other_constant->object_ == object_;
    3205             :     }
    3206             :   }
    3207             : 
    3208             : #ifdef DEBUG
    3209             :   void Verify() override {}
    3210             : #endif
    3211             : 
    3212   229068921 :   DECLARE_CONCRETE_INSTRUCTION(Constant)
    3213             : 
    3214             :  protected:
    3215             :   Range* InferRange(Zone* zone) override;
    3216             : 
    3217             :  private:
    3218             :   friend class HGraph;
    3219             :   explicit HConstant(Special special);
    3220             :   explicit HConstant(Handle<Object> handle,
    3221             :                      Representation r = Representation::None());
    3222             :   HConstant(int32_t value,
    3223             :             Representation r = Representation::None(),
    3224             :             bool is_not_in_new_space = true,
    3225             :             Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
    3226             :   HConstant(double value,
    3227             :             Representation r = Representation::None(),
    3228             :             bool is_not_in_new_space = true,
    3229             :             Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
    3230             :   HConstant(Unique<Object> object,
    3231             :             Unique<Map> object_map,
    3232             :             bool has_stable_map_value,
    3233             :             Representation r,
    3234             :             HType type,
    3235             :             bool is_not_in_new_space,
    3236             :             bool boolean_value,
    3237             :             bool is_undetectable,
    3238             :             InstanceType instance_type);
    3239             : 
    3240             :   explicit HConstant(ExternalReference reference);
    3241             : 
    3242             :   void Initialize(Representation r);
    3243             : 
    3244        3967 :   bool IsDeletable() const override { return true; }
    3245             : 
    3246             :   // If object_ is a map, this indicates whether the map is stable.
    3247             :   class HasStableMapValueField : public BitField<bool, 0, 1> {};
    3248             : 
    3249             :   // We store the HConstant in the most specific form safely possible.
    3250             :   // These flags tell us if the respective member fields hold valid, safe
    3251             :   // representations of the constant. More specific flags imply more general
    3252             :   // flags, but not the converse (i.e. smi => int32 => double).
    3253             :   class HasSmiValueField : public BitField<bool, 1, 1> {};
    3254             :   class HasInt32ValueField : public BitField<bool, 2, 1> {};
    3255             :   class HasDoubleValueField : public BitField<bool, 3, 1> {};
    3256             : 
    3257             :   class HasExternalReferenceValueField : public BitField<bool, 4, 1> {};
    3258             :   class IsNotInNewSpaceField : public BitField<bool, 5, 1> {};
    3259             :   class BooleanValueField : public BitField<bool, 6, 1> {};
    3260             :   class IsUndetectableField : public BitField<bool, 7, 1> {};
    3261             :   class IsCallableField : public BitField<bool, 8, 1> {};
    3262             : 
    3263             :   static const InstanceType kUnknownInstanceType = FILLER_TYPE;
    3264             :   class InstanceTypeField : public BitField<InstanceType, 16, 8> {};
    3265             : 
    3266             :   // If this is a numerical constant, object_ either points to the
    3267             :   // HeapObject the constant originated from or is null.  If the
    3268             :   // constant is non-numeric, object_ always points to a valid
    3269             :   // constant HeapObject.
    3270             :   Unique<Object> object_;
    3271             : 
    3272             :   // If object_ is a heap object, this points to the stable map of the object.
    3273             :   Unique<Map> object_map_;
    3274             : 
    3275             :   uint32_t bit_field_;
    3276             : 
    3277             :   int32_t int32_value_;
    3278             :   double double_value_;
    3279             :   ExternalReference external_reference_value_;
    3280             : };
    3281             : 
    3282             : 
    3283           0 : class HBinaryOperation : public HTemplateInstruction<3> {
    3284             :  public:
    3285      944089 :   HBinaryOperation(HValue* context, HValue* left, HValue* right,
    3286             :                    HType type = HType::Tagged())
    3287             :       : HTemplateInstruction<3>(type),
    3288     2832267 :         observed_output_representation_(Representation::None()) {
    3289             :     DCHECK(left != NULL && right != NULL);
    3290      944089 :     SetOperandAt(0, context);
    3291      944089 :     SetOperandAt(1, left);
    3292      944089 :     SetOperandAt(2, right);
    3293      944089 :     observed_input_representation_[0] = Representation::None();
    3294      944089 :     observed_input_representation_[1] = Representation::None();
    3295      944089 :   }
    3296             : 
    3297             :   HValue* context() const { return OperandAt(0); }
    3298             :   HValue* left() const { return OperandAt(1); }
    3299             :   HValue* right() const { return OperandAt(2); }
    3300             : 
    3301             :   // True if switching left and right operands likely generates better code.
    3302      826163 :   bool AreOperandsBetterSwitched() {
    3303      826163 :     if (!IsCommutative()) return false;
    3304             : 
    3305             :     // Constant operands are better off on the right, they can be inlined in
    3306             :     // many situations on most platforms.
    3307      772707 :     if (left()->IsConstant()) return true;
    3308      714300 :     if (right()->IsConstant()) return false;
    3309             : 
    3310             :     // Otherwise, if there is only one use of the right operand, it would be
    3311             :     // better off on the left for platforms that only have 2-arg arithmetic
    3312             :     // ops (e.g ia32, x64) that clobber the left operand.
    3313      400504 :     return right()->HasOneUse();
    3314             :   }
    3315             : 
    3316             :   HValue* BetterLeftOperand() {
    3317      498399 :     return AreOperandsBetterSwitched() ? right() : left();
    3318             :   }
    3319             : 
    3320             :   HValue* BetterRightOperand() {
    3321      327767 :     return AreOperandsBetterSwitched() ? left() : right();
    3322             :   }
    3323             : 
    3324             :   void set_observed_input_representation(int index, Representation rep) {
    3325             :     DCHECK(index >= 1 && index <= 2);
    3326      709224 :     observed_input_representation_[index - 1] = rep;
    3327             :   }
    3328             : 
    3329      260976 :   virtual void initialize_output_representation(Representation observed) {
    3330      336379 :     observed_output_representation_ = observed;
    3331      260976 :   }
    3332             : 
    3333     1911676 :   Representation observed_input_representation(int index) override {
    3334     2555912 :     if (index == 0) return Representation::Tagged();
    3335     2532644 :     return observed_input_representation_[index - 1];
    3336             :   }
    3337             : 
    3338     2036939 :   void UpdateRepresentation(Representation new_rep,
    3339             :                             HInferRepresentationPhase* h_infer,
    3340             :                             const char* reason) override {
    3341     2036939 :     Representation rep = !FLAG_smi_binop && new_rep.IsSmi()
    3342     2036939 :         ? Representation::Integer32() : new_rep;
    3343     2036939 :     HValue::UpdateRepresentation(rep, h_infer, reason);
    3344     2036947 :   }
    3345             : 
    3346             :   void InferRepresentation(HInferRepresentationPhase* h_infer) override;
    3347             :   Representation RepresentationFromInputs() override;
    3348             :   Representation RepresentationFromOutput();
    3349             :   void AssumeRepresentation(Representation r) override;
    3350             : 
    3351       48902 :   virtual bool IsCommutative() const { return false; }
    3352             : 
    3353             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    3354             : 
    3355      990717 :   Representation RequiredInputRepresentation(int index) override {
    3356     2136466 :     if (index == 0) return Representation::Tagged();
    3357             :     return representation();
    3358             :   }
    3359             : 
    3360        8223 :   bool RightIsPowerOf2() {
    3361        8223 :     if (!right()->IsInteger32Constant()) return false;
    3362        7296 :     int32_t value = right()->GetInteger32Constant();
    3363        7296 :     if (value < 0) {
    3364        6540 :       return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(-value));
    3365             :     }
    3366        8052 :     return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value));
    3367             :   }
    3368             : 
    3369      336862 :   DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
    3370             : 
    3371             :  private:
    3372             :   bool IgnoreObservedOutputRepresentation(Representation current_rep);
    3373             : 
    3374             :   Representation observed_input_representation_[2];
    3375             :   Representation observed_output_representation_;
    3376             : };
    3377             : 
    3378             : 
    3379           0 : class HWrapReceiver final : public HTemplateInstruction<2> {
    3380             :  public:
    3381        4956 :   DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*);
    3382             : 
    3383           0 :   bool DataEquals(HValue* other) override { return true; }
    3384             : 
    3385       10886 :   Representation RequiredInputRepresentation(int index) override {
    3386       10886 :     return Representation::Tagged();
    3387             :   }
    3388             : 
    3389             :   HValue* receiver() const { return OperandAt(0); }
    3390             :   HValue* function() const { return OperandAt(1); }
    3391             : 
    3392             :   HValue* Canonicalize() override;
    3393             : 
    3394             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    3395             :   bool known_function() const { return known_function_; }
    3396             : 
    3397      125500 :   DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
    3398             : 
    3399             :  private:
    3400        9912 :   HWrapReceiver(HValue* receiver, HValue* function) {
    3401        4956 :     known_function_ = function->IsConstant() &&
    3402        4956 :         HConstant::cast(function)->handle(function->isolate())->IsJSFunction();
    3403             :     set_representation(Representation::Tagged());
    3404        4956 :     SetOperandAt(0, receiver);
    3405        4956 :     SetOperandAt(1, function);
    3406             :     SetFlag(kUseGVN);
    3407        4956 :   }
    3408             : 
    3409             :   bool known_function_;
    3410             : };
    3411             : 
    3412             : 
    3413           0 : class HApplyArguments final : public HTemplateInstruction<4> {
    3414             :  public:
    3415         136 :   DECLARE_INSTRUCTION_FACTORY_P5(HApplyArguments, HValue*, HValue*, HValue*,
    3416             :                                  HValue*, TailCallMode);
    3417             : 
    3418         550 :   Representation RequiredInputRepresentation(int index) override {
    3419             :     // The length is untagged, all other inputs are tagged.
    3420             :     return (index == 2)
    3421             :         ? Representation::Integer32()
    3422         550 :         : Representation::Tagged();
    3423             :   }
    3424             : 
    3425             :   HValue* function() { return OperandAt(0); }
    3426             :   HValue* receiver() { return OperandAt(1); }
    3427             :   HValue* length() { return OperandAt(2); }
    3428             :   HValue* elements() { return OperandAt(3); }
    3429             : 
    3430             :   TailCallMode tail_call_mode() const {
    3431             :     return TailCallModeField::decode(bit_field_);
    3432             :   }
    3433             : 
    3434       10985 :   DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
    3435             : 
    3436             :  private:
    3437         136 :   HApplyArguments(HValue* function, HValue* receiver, HValue* length,
    3438             :                   HValue* elements, TailCallMode tail_call_mode)
    3439         136 :       : bit_field_(TailCallModeField::encode(tail_call_mode)) {
    3440             :     set_representation(Representation::Tagged());
    3441         136 :     SetOperandAt(0, function);
    3442         136 :     SetOperandAt(1, receiver);
    3443         136 :     SetOperandAt(2, length);
    3444         136 :     SetOperandAt(3, elements);
    3445             :     SetAllSideEffects();
    3446         136 :   }
    3447             : 
    3448             :   class TailCallModeField : public BitField<TailCallMode, 0, 1> {};
    3449             :   uint32_t bit_field_;
    3450             : };
    3451             : 
    3452             : 
    3453           0 : class HArgumentsElements final : public HTemplateInstruction<0> {
    3454             :  public:
    3455        2376 :   DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsElements, bool);
    3456             :   DECLARE_INSTRUCTION_FACTORY_P2(HArgumentsElements, bool, bool);
    3457             : 
    3458       19318 :   DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
    3459             : 
    3460           0 :   Representation RequiredInputRepresentation(int index) override {
    3461           0 :     return Representation::None();
    3462             :   }
    3463             : 
    3464             :   bool from_inlined() const { return from_inlined_; }
    3465             :   bool arguments_adaptor() const { return arguments_adaptor_; }
    3466             : 
    3467             :  protected:
    3468         336 :   bool DataEquals(HValue* other) override { return true; }
    3469             : 
    3470             :  private:
    3471             :   explicit HArgumentsElements(bool from_inlined, bool arguments_adaptor = true)
    3472        1188 :       : from_inlined_(from_inlined), arguments_adaptor_(arguments_adaptor) {
    3473             :     // The value produced by this instruction is a pointer into the stack
    3474             :     // that looks as if it was a smi because of alignment.
    3475             :     set_representation(Representation::Tagged());
    3476             :     SetFlag(kUseGVN);
    3477             :   }
    3478             : 
    3479           0 :   bool IsDeletable() const override { return true; }
    3480             : 
    3481             :   bool from_inlined_;
    3482             :   bool arguments_adaptor_;
    3483             : };
    3484             : 
    3485             : 
    3486           0 : class HArgumentsLength final : public HUnaryOperation {
    3487             :  public:
    3488        1912 :   DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsLength, HValue*);
    3489             : 
    3490         919 :   Representation RequiredInputRepresentation(int index) override {
    3491         919 :     return Representation::Tagged();
    3492             :   }
    3493             : 
    3494       31386 :   DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
    3495             : 
    3496             :  protected:
    3497         336 :   bool DataEquals(HValue* other) override { return true; }
    3498             : 
    3499             :  private:
    3500         956 :   explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
    3501             :     set_representation(Representation::Integer32());
    3502             :     SetFlag(kUseGVN);
    3503             :   }
    3504             : 
    3505           0 :   bool IsDeletable() const override { return true; }
    3506             : };
    3507             : 
    3508             : 
    3509           0 : class HAccessArgumentsAt final : public HTemplateInstruction<3> {
    3510             :  public:
    3511         715 :   DECLARE_INSTRUCTION_FACTORY_P3(HAccessArgumentsAt, HValue*, HValue*, HValue*);
    3512             : 
    3513             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    3514             : 
    3515        2124 :   Representation RequiredInputRepresentation(int index) override {
    3516             :     // The arguments elements is considered tagged.
    3517             :     return index == 0
    3518             :         ? Representation::Tagged()
    3519        2124 :         : Representation::Integer32();
    3520             :   }
    3521             : 
    3522             :   HValue* arguments() const { return OperandAt(0); }
    3523             :   HValue* length() const { return OperandAt(1); }
    3524             :   HValue* index() const { return OperandAt(2); }
    3525             : 
    3526       40405 :   DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
    3527             : 
    3528             :  private:
    3529        1430 :   HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
    3530             :     set_representation(Representation::Tagged());
    3531             :     SetFlag(kUseGVN);
    3532         715 :     SetOperandAt(0, arguments);
    3533         715 :     SetOperandAt(1, length);
    3534         715 :     SetOperandAt(2, index);
    3535         715 :   }
    3536             : 
    3537          18 :   bool DataEquals(HValue* other) override { return true; }
    3538             : };
    3539             : 
    3540             : 
    3541           0 : class HBoundsCheck final : public HTemplateInstruction<2> {
    3542             :  public:
    3543       41190 :   DECLARE_INSTRUCTION_FACTORY_P2(HBoundsCheck, HValue*, HValue*);
    3544             : 
    3545             :   bool skip_check() const { return skip_check_; }
    3546             :   void set_skip_check() { skip_check_ = true; }
    3547             : 
    3548             :   HValue* base() const { return base_; }
    3549             :   int offset() const { return offset_; }
    3550             :   int scale() const { return scale_; }
    3551             : 
    3552       93386 :   Representation RequiredInputRepresentation(int index) override {
    3553       93386 :     return representation();
    3554             :   }
    3555             : 
    3556             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    3557             :   void InferRepresentation(HInferRepresentationPhase* h_infer) override;
    3558             : 
    3559             :   HValue* index() const { return OperandAt(0); }
    3560             :   HValue* length() const { return OperandAt(1); }
    3561             :   bool allow_equality() const { return allow_equality_; }
    3562             :   void set_allow_equality(bool v) { allow_equality_ = v; }
    3563             : 
    3564       90940 :   int RedefinedOperandIndex() override { return 0; }
    3565       33118 :   bool IsPurelyInformativeDefinition() override { return skip_check(); }
    3566             : 
    3567      746752 :   DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
    3568             : 
    3569             :  protected:
    3570             :   Range* InferRange(Zone* zone) override;
    3571             : 
    3572        1264 :   bool DataEquals(HValue* other) override { return true; }
    3573             :   bool skip_check_;
    3574             :   HValue* base_;
    3575             :   int offset_;
    3576             :   int scale_;
    3577             :   bool allow_equality_;
    3578             : 
    3579             :  private:
    3580             :   // Normally HBoundsCheck should be created using the
    3581             :   // HGraphBuilder::AddBoundsCheck() helper.
    3582             :   // However when building stubs, where we know that the arguments are Int32,
    3583             :   // it makes sense to invoke this constructor directly.
    3584       41190 :   HBoundsCheck(HValue* index, HValue* length)
    3585             :     : skip_check_(false),
    3586             :       base_(NULL), offset_(0), scale_(0),
    3587       41190 :       allow_equality_(false) {
    3588       41190 :     SetOperandAt(0, index);
    3589       41190 :     SetOperandAt(1, length);
    3590             :     SetFlag(kFlexibleRepresentation);
    3591             :     SetFlag(kUseGVN);
    3592       41190 :   }
    3593             : 
    3594          12 :   bool IsDeletable() const override { return skip_check() && !FLAG_debug_code; }
    3595             : };
    3596             : 
    3597             : 
    3598           0 : class HBitwiseBinaryOperation : public HBinaryOperation {
    3599             :  public:
    3600      180784 :   HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
    3601             :                           HType type = HType::TaggedNumber())
    3602      180784 :       : HBinaryOperation(context, left, right, type) {
    3603             :     SetFlag(kFlexibleRepresentation);
    3604             :     SetFlag(kTruncatingToInt32);
    3605             :     SetFlag(kTruncatingToNumber);
    3606             :     SetAllSideEffects();
    3607      180784 :   }
    3608             : 
    3609      167654 :   void RepresentationChanged(Representation to) override {
    3610      342762 :     if (to.IsTagged() &&
    3611        1628 :         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
    3612             :       SetAllSideEffects();
    3613             :       ClearFlag(kUseGVN);
    3614             :     } else {
    3615             :       ClearAllSideEffects();
    3616             :       SetFlag(kUseGVN);
    3617             :     }
    3618      167654 :     if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
    3619      167654 :   }
    3620             : 
    3621      416826 :   void UpdateRepresentation(Representation new_rep,
    3622             :                             HInferRepresentationPhase* h_infer,
    3623             :                             const char* reason) override {
    3624             :     // We only generate either int32 or generic tagged bitwise operations.
    3625      564270 :     if (new_rep.IsDouble()) new_rep = Representation::Integer32();
    3626      564270 :     HBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
    3627      416826 :   }
    3628             : 
    3629      644236 :   Representation observed_input_representation(int index) override {
    3630             :     Representation r = HBinaryOperation::observed_input_representation(index);
    3631      644236 :     if (r.IsDouble()) return Representation::Integer32();
    3632      601850 :     return r;
    3633             :   }
    3634             : 
    3635       75403 :   void initialize_output_representation(Representation observed) override {
    3636       75403 :     if (observed.IsDouble()) observed = Representation::Integer32();
    3637             :     HBinaryOperation::initialize_output_representation(observed);
    3638       75403 :   }
    3639             : 
    3640           0 :   DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
    3641             : 
    3642             :  private:
    3643         160 :   bool IsDeletable() const override { return true; }
    3644             : };
    3645             : 
    3646             : 
    3647           0 : class HMathFloorOfDiv final : public HBinaryOperation {
    3648             :  public:
    3649        2600 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HMathFloorOfDiv,
    3650             :                                               HValue*,
    3651             :                                               HValue*);
    3652             : 
    3653       48925 :   DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv)
    3654             : 
    3655             :  protected:
    3656           0 :   bool DataEquals(HValue* other) override { return true; }
    3657             : 
    3658             :  private:
    3659        2600 :   HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
    3660        2600 :       : HBinaryOperation(context, left, right) {
    3661             :     set_representation(Representation::Integer32());
    3662             :     SetFlag(kUseGVN);
    3663             :     SetFlag(kCanOverflow);
    3664             :     SetFlag(kCanBeDivByZero);
    3665             :     SetFlag(kLeftCanBeMinInt);
    3666             :     SetFlag(kLeftCanBeNegative);
    3667             :     SetFlag(kLeftCanBePositive);
    3668             :     SetFlag(kTruncatingToNumber);
    3669        2600 :   }
    3670             : 
    3671             :   Range* InferRange(Zone* zone) override;
    3672             : 
    3673           0 :   bool IsDeletable() const override { return true; }
    3674             : };
    3675             : 
    3676             : 
    3677           0 : class HArithmeticBinaryOperation : public HBinaryOperation {
    3678             :  public:
    3679      406012 :   HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right,
    3680             :                              HType type = HType::TaggedNumber())
    3681      406012 :       : HBinaryOperation(context, left, right, type) {
    3682             :     SetAllSideEffects();
    3683             :     SetFlag(kFlexibleRepresentation);
    3684             :     SetFlag(kTruncatingToNumber);
    3685      406012 :   }
    3686             : 
    3687      133448 :   void RepresentationChanged(Representation to) override {
    3688      305306 :     if (to.IsTagged() &&
    3689       31797 :         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
    3690             :       SetAllSideEffects();
    3691             :       ClearFlag(kUseGVN);
    3692             :     } else {
    3693             :       ClearAllSideEffects();
    3694             :       SetFlag(kUseGVN);
    3695             :     }
    3696      133448 :     if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
    3697      133448 :   }
    3698             : 
    3699      399046 :   DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation)
    3700             : 
    3701             :  private:
    3702         149 :   bool IsDeletable() const override { return true; }
    3703             : };
    3704             : 
    3705             : 
    3706           0 : class HCompareGeneric final : public HBinaryOperation {
    3707             :  public:
    3708      327836 :   static HCompareGeneric* New(Isolate* isolate, Zone* zone, HValue* context,
    3709             :                               HValue* left, HValue* right, Token::Value token) {
    3710      327836 :     return new (zone) HCompareGeneric(context, left, right, token);
    3711             :   }
    3712             : 
    3713      996826 :   Representation RequiredInputRepresentation(int index) override {
    3714             :     return index == 0
    3715             :         ? Representation::Tagged()
    3716      996826 :         : representation();
    3717             :   }
    3718             : 
    3719             :   Token::Value token() const { return token_; }
    3720             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    3721             : 
    3722     6989920 :   DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
    3723             : 
    3724             :  private:
    3725             :   HCompareGeneric(HValue* context, HValue* left, HValue* right,
    3726             :                   Token::Value token)
    3727             :       : HBinaryOperation(context, left, right, HType::Boolean()),
    3728      327836 :         token_(token) {
    3729             :     DCHECK(Token::IsCompareOp(token));
    3730             :     set_representation(Representation::Tagged());
    3731             :     SetAllSideEffects();
    3732             :   }
    3733             : 
    3734             :   Token::Value token_;
    3735             : };
    3736             : 
    3737             : 
    3738           0 : class HCompareNumericAndBranch : public HTemplateControlInstruction<2, 2> {
    3739             :  public:
    3740             :   static HCompareNumericAndBranch* New(Isolate* isolate, Zone* zone,
    3741             :                                        HValue* context, HValue* left,
    3742             :                                        HValue* right, Token::Value token,
    3743             :                                        HBasicBlock* true_target = NULL,
    3744             :                                        HBasicBlock* false_target = NULL) {
    3745             :     return new (zone)
    3746      190259 :         HCompareNumericAndBranch(left, right, token, true_target, false_target);
    3747             :   }
    3748             : 
    3749     2281150 :   HValue* left() const { return OperandAt(0); }
    3750     2255659 :   HValue* right() const { return OperandAt(1); }
    3751             :   Token::Value token() const { return token_; }
    3752             : 
    3753             :   void set_observed_input_representation(Representation left,
    3754             :                                          Representation right) {
    3755       80894 :       observed_input_representation_[0] = left;
    3756       80894 :       observed_input_representation_[1] = right;
    3757             :   }
    3758             : 
    3759             :   void InferRepresentation(HInferRepresentationPhase* h_infer) override;
    3760             : 
    3761      429902 :   Representation RequiredInputRepresentation(int index) override {
    3762      429902 :     return representation();
    3763             :   }
    3764      852888 :   Representation observed_input_representation(int index) override {
    3765      852888 :     return observed_input_representation_[index];
    3766             :   }
    3767             : 
    3768             :   bool KnownSuccessorBlock(HBasicBlock** block) override;
    3769             : 
    3770             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    3771             : 
    3772     5330966 :   DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch)
    3773             : 
    3774             :  private:
    3775      190259 :   HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token,
    3776             :                            HBasicBlock* true_target, HBasicBlock* false_target)
    3777      570777 :       : token_(token) {
    3778             :     SetFlag(kFlexibleRepresentation);
    3779             :     DCHECK(Token::IsCompareOp(token));
    3780      190259 :     SetOperandAt(0, left);
    3781      190259 :     SetOperandAt(1, right);
    3782             :     SetSuccessorAt(0, true_target);
    3783             :     SetSuccessorAt(1, false_target);
    3784      190259 :   }
    3785             : 
    3786             :   Representation observed_input_representation_[2];
    3787             :   Token::Value token_;
    3788             : };
    3789             : 
    3790             : 
    3791           0 : class HCompareHoleAndBranch final : public HUnaryControlInstruction {
    3792             :  public:
    3793          66 :   DECLARE_INSTRUCTION_FACTORY_P1(HCompareHoleAndBranch, HValue*);
    3794             :   DECLARE_INSTRUCTION_FACTORY_P3(HCompareHoleAndBranch, HValue*,
    3795             :                                  HBasicBlock*, HBasicBlock*);
    3796             : 
    3797             :   void InferRepresentation(HInferRepresentationPhase* h_infer) override;
    3798             : 
    3799          33 :   Representation RequiredInputRepresentation(int index) override {
    3800          33 :     return representation();
    3801             :   }
    3802             : 
    3803         942 :   DECLARE_CONCRETE_INSTRUCTION(CompareHoleAndBranch)
    3804             : 
    3805             :  private:
    3806          33 :   HCompareHoleAndBranch(HValue* value,
    3807             :                         HBasicBlock* true_target = NULL,
    3808             :                         HBasicBlock* false_target = NULL)
    3809          33 :       : HUnaryControlInstruction(value, true_target, false_target) {
    3810             :     SetFlag(kFlexibleRepresentation);
    3811          33 :   }
    3812             : };
    3813             : 
    3814             : 
    3815           0 : class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> {
    3816             :  public:
    3817       86580 :   DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*);
    3818         460 :   DECLARE_INSTRUCTION_FACTORY_P4(HCompareObjectEqAndBranch, HValue*, HValue*,
    3819             :                                  HBasicBlock*, HBasicBlock*);
    3820             : 
    3821             :   bool KnownSuccessorBlock(HBasicBlock** block) override;
    3822             : 
    3823             :   static const int kNoKnownSuccessorIndex = -1;
    3824             :   int known_successor_index() const { return known_successor_index_; }
    3825             :   void set_known_successor_index(int known_successor_index) {
    3826           0 :     known_successor_index_ = known_successor_index;
    3827             :   }
    3828             : 
    3829      130051 :   HValue* left() const { return OperandAt(0); }
    3830       88351 :   HValue* right() const { return OperandAt(1); }
    3831             : 
    3832             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    3833             : 
    3834       96159 :   Representation RequiredInputRepresentation(int index) override {
    3835       96159 :     return Representation::Tagged();
    3836             :   }
    3837             : 
    3838       17665 :   Representation observed_input_representation(int index) override {
    3839       17665 :     return Representation::Tagged();
    3840             :   }
    3841             : 
    3842     1136064 :   DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
    3843             : 
    3844             :  private:
    3845       43750 :   HCompareObjectEqAndBranch(HValue* left,
    3846             :                             HValue* right,
    3847             :                             HBasicBlock* true_target = NULL,
    3848             :                             HBasicBlock* false_target = NULL)
    3849       43750 :       : known_successor_index_(kNoKnownSuccessorIndex) {
    3850       43750 :     SetOperandAt(0, left);
    3851       43750 :     SetOperandAt(1, right);
    3852             :     SetSuccessorAt(0, true_target);
    3853             :     SetSuccessorAt(1, false_target);
    3854       43750 :   }
    3855             : 
    3856             :   int known_successor_index_;
    3857             : };
    3858             : 
    3859             : 
    3860           0 : class HIsStringAndBranch final : public HUnaryControlInstruction {
    3861             :  public:
    3862         902 :   DECLARE_INSTRUCTION_FACTORY_P1(HIsStringAndBranch, HValue*);
    3863          23 :   DECLARE_INSTRUCTION_FACTORY_P3(HIsStringAndBranch, HValue*,
    3864             :                                  HBasicBlock*, HBasicBlock*);
    3865             : 
    3866         499 :   Representation RequiredInputRepresentation(int index) override {
    3867         499 :     return Representation::Tagged();
    3868             :   }
    3869             : 
    3870             :   bool KnownSuccessorBlock(HBasicBlock** block) override;
    3871             : 
    3872             :   static const int kNoKnownSuccessorIndex = -1;
    3873             :   int known_successor_index() const { return known_successor_index_; }
    3874             :   void set_known_successor_index(int known_successor_index) {
    3875           6 :     known_successor_index_ = known_successor_index;
    3876             :   }
    3877             : 
    3878       13391 :   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
    3879             : 
    3880             :  protected:
    3881         948 :   int RedefinedOperandIndex() override { return 0; }
    3882             : 
    3883             :  private:
    3884         474 :   HIsStringAndBranch(HValue* value, HBasicBlock* true_target = NULL,
    3885             :                      HBasicBlock* false_target = NULL)
    3886             :       : HUnaryControlInstruction(value, true_target, false_target),
    3887         474 :         known_successor_index_(kNoKnownSuccessorIndex) {
    3888             :     set_representation(Representation::Tagged());
    3889         474 :   }
    3890             : 
    3891             :   int known_successor_index_;
    3892             : };
    3893             : 
    3894             : 
    3895           0 : class HIsSmiAndBranch final : public HUnaryControlInstruction {
    3896             :  public:
    3897       16990 :   DECLARE_INSTRUCTION_FACTORY_P1(HIsSmiAndBranch, HValue*);
    3898         705 :   DECLARE_INSTRUCTION_FACTORY_P3(HIsSmiAndBranch, HValue*,
    3899             :                                  HBasicBlock*, HBasicBlock*);
    3900             : 
    3901      273315 :   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
    3902             : 
    3903       10571 :   Representation RequiredInputRepresentation(int index) override {
    3904       10571 :     return Representation::Tagged();
    3905             :   }
    3906             : 
    3907             :  protected:
    3908           0 :   bool DataEquals(HValue* other) override { return true; }
    3909       18388 :   int RedefinedOperandIndex() override { return 0; }
    3910             : 
    3911             :  private:
    3912        9200 :   HIsSmiAndBranch(HValue* value,
    3913             :                   HBasicBlock* true_target = NULL,
    3914             :                   HBasicBlock* false_target = NULL)
    3915        9200 :       : HUnaryControlInstruction(value, true_target, false_target) {
    3916             :     set_representation(Representation::Tagged());
    3917        9200 :   }
    3918             : };
    3919             : 
    3920             : 
    3921           0 : class HIsUndetectableAndBranch final : public HUnaryControlInstruction {
    3922             :  public:
    3923        2976 :   DECLARE_INSTRUCTION_FACTORY_P1(HIsUndetectableAndBranch, HValue*);
    3924             :   DECLARE_INSTRUCTION_FACTORY_P3(HIsUndetectableAndBranch, HValue*,
    3925             :                                  HBasicBlock*, HBasicBlock*);
    3926             : 
    3927        1594 :   Representation RequiredInputRepresentation(int index) override {
    3928        1594 :     return Representation::Tagged();
    3929             :   }
    3930             : 
    3931             :   bool KnownSuccessorBlock(HBasicBlock** block) override;
    3932             : 
    3933       36909 :   DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
    3934             : 
    3935             :  private:
    3936             :   HIsUndetectableAndBranch(HValue* value,
    3937             :                            HBasicBlock* true_target = NULL,
    3938             :                            HBasicBlock* false_target = NULL)
    3939        1488 :       : HUnaryControlInstruction(value, true_target, false_target) {}
    3940             : };
    3941             : 
    3942             : 
    3943           0 : class HStringCompareAndBranch final : public HTemplateControlInstruction<2, 3> {
    3944             :  public:
    3945       15294 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HStringCompareAndBranch,
    3946             :                                               HValue*,
    3947             :                                               HValue*,
    3948             :                                               Token::Value);
    3949             : 
    3950       15235 :   HValue* context() const { return OperandAt(0); }
    3951       15235 :   HValue* left() const { return OperandAt(1); }
    3952       15235 :   HValue* right() const { return OperandAt(2); }
    3953             :   Token::Value token() const { return token_; }
    3954             : 
    3955             :   std::ostream& PrintDataTo(std::ostream& os) const final;  // NOLINT
    3956             : 
    3957       45846 :   Representation RequiredInputRepresentation(int index) final {
    3958       45846 :     return Representation::Tagged();
    3959             :   }
    3960             : 
    3961      417959 :   DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch)
    3962             : 
    3963             :  private:
    3964       15294 :   HStringCompareAndBranch(HValue* context, HValue* left, HValue* right,
    3965             :                           Token::Value token)
    3966       15294 :       : token_(token) {
    3967             :     DCHECK(Token::IsCompareOp(token));
    3968       15294 :     SetOperandAt(0, context);
    3969       15294 :     SetOperandAt(1, left);
    3970       15294 :     SetOperandAt(2, right);
    3971             :     set_representation(Representation::Tagged());
    3972             :     SetChangesFlag(kNewSpacePromotion);
    3973             :     SetDependsOnFlag(kStringChars);
    3974             :     SetDependsOnFlag(kStringLengths);
    3975       15294 :   }
    3976             : 
    3977             :   Token::Value const token_;
    3978             : };
    3979             : 
    3980             : 
    3981           0 : class HHasInstanceTypeAndBranch final : public HUnaryControlInstruction {
    3982             :  public:
    3983         882 :   DECLARE_INSTRUCTION_FACTORY_P2(
    3984             :       HHasInstanceTypeAndBranch, HValue*, InstanceType);
    3985        1090 :   DECLARE_INSTRUCTION_FACTORY_P3(
    3986             :       HHasInstanceTypeAndBranch, HValue*, InstanceType, InstanceType);
    3987             : 
    3988             :   InstanceType from() { return from_; }
    3989             :   InstanceType to() { return to_; }
    3990             : 
    3991             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    3992             : 
    3993        2084 :   Representation RequiredInputRepresentation(int index) override {
    3994        2084 :     return Representation::Tagged();
    3995             :   }
    3996             : 
    3997             :   bool KnownSuccessorBlock(HBasicBlock** block) override;
    3998             : 
    3999       50912 :   DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
    4000             : 
    4001             :  private:
    4002         882 :   HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
    4003         882 :       : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
    4004        1090 :   HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
    4005        1090 :       : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
    4006             :     DCHECK(to == LAST_TYPE);  // Others not implemented yet in backend.
    4007        1090 :   }
    4008             : 
    4009             :   InstanceType from_;
    4010             :   InstanceType to_;  // Inclusive range, not all combinations work.
    4011             : };
    4012             : 
    4013           0 : class HClassOfTestAndBranch final : public HUnaryControlInstruction {
    4014             :  public:
    4015       15394 :   DECLARE_INSTRUCTION_FACTORY_P2(HClassOfTestAndBranch, HValue*,
    4016             :                                  Handle<String>);
    4017             : 
    4018      189512 :   DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
    4019             : 
    4020        7790 :   Representation RequiredInputRepresentation(int index) override {
    4021        7790 :     return Representation::Tagged();
    4022             :   }
    4023             : 
    4024             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    4025             : 
    4026             :   Handle<String> class_name() const { return class_name_; }
    4027             : 
    4028             :  private:
    4029        7697 :   HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
    4030        7697 :       : HUnaryControlInstruction(value, NULL, NULL), class_name_(class_name) {}
    4031             : 
    4032             :   Handle<String> class_name_;
    4033             : };
    4034             : 
    4035           0 : class HTypeofIsAndBranch final : public HUnaryControlInstruction {
    4036             :  public:
    4037      132730 :   DECLARE_INSTRUCTION_FACTORY_P2(HTypeofIsAndBranch, HValue*, Handle<String>);
    4038             : 
    4039             :   Handle<String> type_literal() const { return type_literal_.handle(); }
    4040             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    4041             : 
    4042     1446272 :   DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
    4043             : 
    4044       70403 :   Representation RequiredInputRepresentation(int index) override {
    4045       70403 :     return Representation::None();
    4046             :   }
    4047             : 
    4048             :   bool KnownSuccessorBlock(HBasicBlock** block) override;
    4049             : 
    4050       66201 :   void FinalizeUniqueness() override {
    4051       66201 :     type_literal_ = Unique<String>(type_literal_.handle());
    4052       66201 :   }
    4053             : 
    4054             :  private:
    4055       66365 :   HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
    4056             :       : HUnaryControlInstruction(value, NULL, NULL),
    4057       66365 :         type_literal_(Unique<String>::CreateUninitialized(type_literal)) { }
    4058             : 
    4059             :   Unique<String> type_literal_;
    4060             : };
    4061             : 
    4062             : 
    4063           0 : class HHasInPrototypeChainAndBranch final
    4064             :     : public HTemplateControlInstruction<2, 2> {
    4065             :  public:
    4066         323 :   DECLARE_INSTRUCTION_FACTORY_P2(HHasInPrototypeChainAndBranch, HValue*,
    4067             :                                  HValue*);
    4068             : 
    4069         932 :   HValue* object() const { return OperandAt(0); }
    4070         319 :   HValue* prototype() const { return OperandAt(1); }
    4071             : 
    4072         643 :   Representation RequiredInputRepresentation(int index) override {
    4073         643 :     return Representation::Tagged();
    4074             :   }
    4075             : 
    4076         319 :   bool ObjectNeedsSmiCheck() const {
    4077         613 :     return !object()->type().IsHeapObject() &&
    4078         319 :            !object()->representation().IsHeapObject();
    4079             :   }
    4080             : 
    4081        8022 :   DECLARE_CONCRETE_INSTRUCTION(HasInPrototypeChainAndBranch)
    4082             : 
    4083             :  private:
    4084         323 :   HHasInPrototypeChainAndBranch(HValue* object, HValue* prototype) {
    4085         323 :     SetOperandAt(0, object);
    4086         323 :     SetOperandAt(1, prototype);
    4087             :     SetDependsOnFlag(kCalls);
    4088         323 :   }
    4089             : };
    4090             : 
    4091             : 
    4092           0 : class HPower final : public HTemplateInstruction<2> {
    4093             :  public:
    4094             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4095             :                            HValue* left, HValue* right);
    4096             : 
    4097             :   HValue* left() { return OperandAt(0); }
    4098             :   HValue* right() const { return OperandAt(1); }
    4099             : 
    4100        2466 :   Representation RequiredInputRepresentation(int index) override {
    4101             :     return index == 0
    4102             :       ? Representation::Double()
    4103        2510 :       : Representation::None();
    4104             :   }
    4105          44 :   Representation observed_input_representation(int index) override {
    4106          44 :     return RequiredInputRepresentation(index);
    4107             :   }
    4108             : 
    4109      185765 :   DECLARE_CONCRETE_INSTRUCTION(Power)
    4110             : 
    4111             :  protected:
    4112         119 :   bool DataEquals(HValue* other) override { return true; }
    4113             : 
    4114             :  private:
    4115        1942 :   HPower(HValue* left, HValue* right) {
    4116         971 :     SetOperandAt(0, left);
    4117         971 :     SetOperandAt(1, right);
    4118             :     set_representation(Representation::Double());
    4119             :     SetFlag(kUseGVN);
    4120             :     SetChangesFlag(kNewSpacePromotion);
    4121         971 :   }
    4122             : 
    4123           0 :   bool IsDeletable() const override {
    4124           0 :     return !right()->representation().IsTagged();
    4125             :   }
    4126             : };
    4127             : 
    4128             : 
    4129             : enum ExternalAddType {
    4130             :   AddOfExternalAndTagged,
    4131             :   AddOfExternalAndInt32,
    4132             :   NoExternalAdd
    4133             : };
    4134             : 
    4135             : 
    4136           0 : class HAdd final : public HArithmeticBinaryOperation {
    4137             :  public:
    4138             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4139             :                            HValue* left, HValue* right);
    4140             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4141             :                            HValue* left, HValue* right,
    4142             :                            ExternalAddType external_add_type);
    4143             : 
    4144             :   // Add is only commutative if two integer values are added and not if two
    4145             :   // tagged values are added (because it might be a String concatenation).
    4146             :   // We also do not commute (pointer + offset).
    4147      555504 :   bool IsCommutative() const override {
    4148      555504 :     return !representation().IsTagged() && !representation().IsExternal();
    4149             :   }
    4150             : 
    4151             :   HValue* Canonicalize() override;
    4152             : 
    4153      324071 :   void RepresentationChanged(Representation to) override {
    4154      663588 :     if (to.IsTagged() &&
    4155        5094 :         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() ||
    4156         458 :          left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) {
    4157             :       SetAllSideEffects();
    4158             :       ClearFlag(kUseGVN);
    4159             :     } else {
    4160             :       ClearAllSideEffects();
    4161             :       SetFlag(kUseGVN);
    4162             :     }
    4163      324071 :     if (to.IsTagged()) {
    4164             :       SetChangesFlag(kNewSpacePromotion);
    4165             :       ClearFlag(kTruncatingToNumber);
    4166             :     }
    4167      445638 :     if (!right()->type().IsTaggedNumber() &&
    4168      445198 :         !right()->representation().IsDouble() &&
    4169             :         !right()->representation().IsSmiOrInteger32()) {
    4170             :       ClearFlag(kTruncatingToNumber);
    4171             :     }
    4172      324071 :   }
    4173             : 
    4174             :   Representation RepresentationFromInputs() override;
    4175             : 
    4176             :   Representation RequiredInputRepresentation(int index) override;
    4177             : 
    4178             :   bool IsConsistentExternalRepresentation() {
    4179             :     return left()->representation().IsExternal() &&
    4180             :            ((external_add_type_ == AddOfExternalAndInt32 &&
    4181             :              right()->representation().IsInteger32()) ||
    4182             :             (external_add_type_ == AddOfExternalAndTagged &&
    4183             :              right()->representation().IsTagged()));
    4184             :   }
    4185             : 
    4186             :   ExternalAddType external_add_type() const { return external_add_type_; }
    4187             : 
    4188     9262775 :   DECLARE_CONCRETE_INSTRUCTION(Add)
    4189             : 
    4190             :  protected:
    4191       28888 :   bool DataEquals(HValue* other) override { return true; }
    4192             : 
    4193             :   Range* InferRange(Zone* zone) override;
    4194             : 
    4195             :  private:
    4196      292654 :   HAdd(HValue* context, HValue* left, HValue* right,
    4197             :        ExternalAddType external_add_type = NoExternalAdd)
    4198             :       : HArithmeticBinaryOperation(context, left, right, HType::Tagged()),
    4199      292654 :         external_add_type_(external_add_type) {
    4200             :     SetFlag(kCanOverflow);
    4201      292654 :     switch (external_add_type_) {
    4202             :       case AddOfExternalAndTagged:
    4203             :         DCHECK(left->representation().IsExternal());
    4204             :         DCHECK(right->representation().IsTagged());
    4205             :         SetDependsOnFlag(kNewSpacePromotion);
    4206             :         ClearFlag(HValue::kCanOverflow);
    4207             :         SetFlag(kHasNoObservableSideEffects);
    4208             :         break;
    4209             : 
    4210             :       case NoExternalAdd:
    4211             :         // This is a bit of a hack: The call to this constructor is generated
    4212             :         // by a macro that also supports sub and mul, so it doesn't pass in
    4213             :         // a value for external_add_type but uses the default.
    4214      288757 :         if (left->representation().IsExternal()) {
    4215           0 :           external_add_type_ = AddOfExternalAndInt32;
    4216             :         }
    4217             :         break;
    4218             : 
    4219             :       case AddOfExternalAndInt32:
    4220             :         // See comment above.
    4221           0 :         UNREACHABLE();
    4222             :         break;
    4223             :     }
    4224      292654 :   }
    4225             : 
    4226             :   ExternalAddType external_add_type_;
    4227             : };
    4228             : 
    4229             : 
    4230           0 : class HSub final : public HArithmeticBinaryOperation {
    4231             :  public:
    4232             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4233             :                            HValue* left, HValue* right);
    4234             : 
    4235             :   HValue* Canonicalize() override;
    4236             : 
    4237     1012103 :   DECLARE_CONCRETE_INSTRUCTION(Sub)
    4238             : 
    4239             :  protected:
    4240        2010 :   bool DataEquals(HValue* other) override { return true; }
    4241             : 
    4242             :   Range* InferRange(Zone* zone) override;
    4243             : 
    4244             :  private:
    4245             :   HSub(HValue* context, HValue* left, HValue* right)
    4246       26374 :       : HArithmeticBinaryOperation(context, left, right) {
    4247             :     SetFlag(kCanOverflow);
    4248             :   }
    4249             : };
    4250             : 
    4251             : 
    4252           0 : class HMul final : public HArithmeticBinaryOperation {
    4253             :  public:
    4254             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4255             :                            HValue* left, HValue* right);
    4256             : 
    4257         607 :   static HInstruction* NewImul(Isolate* isolate, Zone* zone, HValue* context,
    4258             :                                HValue* left, HValue* right) {
    4259         607 :     HInstruction* instr = HMul::New(isolate, zone, context, left, right);
    4260        1214 :     if (!instr->IsMul()) return instr;
    4261             :     HMul* mul = HMul::cast(instr);
    4262             :     // TODO(mstarzinger): Prevent bailout on minus zero for imul.
    4263         607 :     mul->AssumeRepresentation(Representation::Integer32());
    4264             :     mul->ClearFlag(HValue::kCanOverflow);
    4265         607 :     return mul;
    4266             :   }
    4267             : 
    4268             :   HValue* Canonicalize() override;
    4269             : 
    4270             :   // Only commutative if it is certain that not two objects are multiplicated.
    4271       41604 :   bool IsCommutative() const override { return !representation().IsTagged(); }
    4272             : 
    4273       74563 :   void UpdateRepresentation(Representation new_rep,
    4274             :                             HInferRepresentationPhase* h_infer,
    4275             :                             const char* reason) override {
    4276       74563 :     HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
    4277       74563 :   }
    4278             : 
    4279             :   bool MulMinusOne();
    4280             : 
    4281      985963 :   DECLARE_CONCRETE_INSTRUCTION(Mul)
    4282             : 
    4283             :  protected:
    4284        3881 :   bool DataEquals(HValue* other) override { return true; }
    4285             : 
    4286             :   Range* InferRange(Zone* zone) override;
    4287             : 
    4288             :  private:
    4289             :   HMul(HValue* context, HValue* left, HValue* right)
    4290       27279 :       : HArithmeticBinaryOperation(context, left, right) {
    4291             :     SetFlag(kCanOverflow);
    4292             :   }
    4293             : };
    4294             : 
    4295             : 
    4296           0 : class HMod final : public HArithmeticBinaryOperation {
    4297             :  public:
    4298             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4299             :                            HValue* left, HValue* right);
    4300             : 
    4301             :   HValue* Canonicalize() override;
    4302             : 
    4303       20530 :   void UpdateRepresentation(Representation new_rep,
    4304             :                             HInferRepresentationPhase* h_infer,
    4305             :                             const char* reason) override {
    4306       20530 :     if (new_rep.IsSmi()) new_rep = Representation::Integer32();
    4307       20530 :     HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
    4308       20530 :   }
    4309             : 
    4310      406551 :   DECLARE_CONCRETE_INSTRUCTION(Mod)
    4311             : 
    4312             :  protected:
    4313         227 :   bool DataEquals(HValue* other) override { return true; }
    4314             : 
    4315             :   Range* InferRange(Zone* zone) override;
    4316             : 
    4317             :  private:
    4318        5635 :   HMod(HValue* context, HValue* left, HValue* right)
    4319        5635 :       : HArithmeticBinaryOperation(context, left, right) {
    4320             :     SetFlag(kCanBeDivByZero);
    4321             :     SetFlag(kCanOverflow);
    4322             :     SetFlag(kLeftCanBeNegative);
    4323        5635 :   }
    4324             : };
    4325             : 
    4326             : 
    4327           0 : class HDiv final : public HArithmeticBinaryOperation {
    4328             :  public:
    4329             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4330             :                            HValue* left, HValue* right);
    4331             : 
    4332             :   HValue* Canonicalize() override;
    4333             : 
    4334      120326 :   void UpdateRepresentation(Representation new_rep,
    4335             :                             HInferRepresentationPhase* h_infer,
    4336             :                             const char* reason) override {
    4337      120326 :     if (new_rep.IsSmi()) new_rep = Representation::Integer32();
    4338      120326 :     HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
    4339      120326 :   }
    4340             : 
    4341     1560305 :   DECLARE_CONCRETE_INSTRUCTION(Div)
    4342             : 
    4343             :  protected:
    4344        1189 :   bool DataEquals(HValue* other) override { return true; }
    4345             : 
    4346             :   Range* InferRange(Zone* zone) override;
    4347             : 
    4348             :  private:
    4349       52355 :   HDiv(HValue* context, HValue* left, HValue* right)
    4350       52355 :       : HArithmeticBinaryOperation(context, left, right) {
    4351             :     SetFlag(kCanBeDivByZero);
    4352             :     SetFlag(kCanOverflow);
    4353       52355 :   }
    4354             : };
    4355             : 
    4356             : 
    4357           0 : class HMathMinMax final : public HArithmeticBinaryOperation {
    4358             :  public:
    4359             :   enum Operation { kMathMin, kMathMax };
    4360             : 
    4361             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4362             :                            HValue* left, HValue* right, Operation op);
    4363             : 
    4364         459 :   Representation observed_input_representation(int index) override {
    4365         459 :     return RequiredInputRepresentation(index);
    4366             :   }
    4367             : 
    4368             :   void InferRepresentation(HInferRepresentationPhase* h_infer) override;
    4369             : 
    4370        2203 :   Representation RepresentationFromInputs() override {
    4371        2203 :     Representation left_rep = left()->representation();
    4372        2203 :     Representation right_rep = right()->representation();
    4373        2203 :     Representation result = Representation::Smi();
    4374        2203 :     result = result.generalize(left_rep);
    4375        2203 :     result = result.generalize(right_rep);
    4376        2203 :     if (result.IsTagged()) return Representation::Double();
    4377        1263 :     return result;
    4378             :   }
    4379             : 
    4380         426 :   bool IsCommutative() const override { return true; }
    4381             : 
    4382             :   Operation operation() { return operation_; }
    4383             : 
    4384      125497 :   DECLARE_CONCRETE_INSTRUCTION(MathMinMax)
    4385             : 
    4386             :  protected:
    4387         181 :   bool DataEquals(HValue* other) override {
    4388         362 :     return other->IsMathMinMax() &&
    4389         362 :         HMathMinMax::cast(other)->operation_ == operation_;
    4390             :   }
    4391             : 
    4392             :   Range* InferRange(Zone* zone) override;
    4393             : 
    4394             :  private:
    4395             :   HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
    4396        1715 :       : HArithmeticBinaryOperation(context, left, right), operation_(op) {}
    4397             : 
    4398             :   Operation operation_;
    4399             : };
    4400             : 
    4401             : 
    4402           0 : class HBitwise final : public HBitwiseBinaryOperation {
    4403             :  public:
    4404             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4405             :                            Token::Value op, HValue* left, HValue* right);
    4406             : 
    4407             :   Token::Value op() const { return op_; }
    4408             : 
    4409      179728 :   bool IsCommutative() const override { return true; }
    4410             : 
    4411             :   HValue* Canonicalize() override;
    4412             : 
    4413             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    4414             : 
    4415     3110727 :   DECLARE_CONCRETE_INSTRUCTION(Bitwise)
    4416             : 
    4417             :  protected:
    4418       15881 :   bool DataEquals(HValue* other) override {
    4419       15881 :     return op() == HBitwise::cast(other)->op();
    4420             :   }
    4421             : 
    4422             :   Range* InferRange(Zone* zone) override;
    4423             : 
    4424             :  private:
    4425      139726 :   HBitwise(HValue* context, Token::Value op, HValue* left, HValue* right)
    4426      139726 :       : HBitwiseBinaryOperation(context, left, right), op_(op) {
    4427             :     DCHECK(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
    4428             :     // BIT_AND with a smi-range positive value will always unset the
    4429             :     // entire sign-extension of the smi-sign.
    4430      360021 :     if (op == Token::BIT_AND &&
    4431        2754 :         ((left->IsConstant() &&
    4432           0 :           left->representation().IsSmi() &&
    4433       80569 :           HConstant::cast(left)->Integer32Value() >= 0) ||
    4434       64705 :          (right->IsConstant() &&
    4435           0 :           right->representation().IsSmi() &&
    4436           0 :           HConstant::cast(right)->Integer32Value() >= 0))) {
    4437             :       SetFlag(kTruncatingToSmi);
    4438             :       SetFlag(kTruncatingToInt32);
    4439             :     // BIT_OR with a smi-range negative value will always set the entire
    4440             :     // sign-extension of the smi-sign.
    4441      310103 :     } else if (op == Token::BIT_OR &&
    4442         643 :         ((left->IsConstant() &&
    4443           0 :           left->representation().IsSmi() &&
    4444       30651 :           HConstant::cast(left)->Integer32Value() < 0) ||
    4445       23005 :          (right->IsConstant() &&
    4446           0 :           right->representation().IsSmi() &&
    4447           0 :           HConstant::cast(right)->Integer32Value() < 0))) {
    4448             :       SetFlag(kTruncatingToSmi);
    4449             :       SetFlag(kTruncatingToInt32);
    4450             :     }
    4451      139726 :   }
    4452             : 
    4453             :   Token::Value op_;
    4454             : };
    4455             : 
    4456             : 
    4457           0 : class HShl final : public HBitwiseBinaryOperation {
    4458             :  public:
    4459             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4460             :                            HValue* left, HValue* right);
    4461             : 
    4462             :   Range* InferRange(Zone* zone) override;
    4463             : 
    4464       64956 :   void UpdateRepresentation(Representation new_rep,
    4465             :                             HInferRepresentationPhase* h_infer,
    4466             :                             const char* reason) override {
    4467      130474 :     if (new_rep.IsSmi() &&
    4468             :         !(right()->IsInteger32Constant() &&
    4469           0 :           right()->GetInteger32Constant() >= 0)) {
    4470             :       new_rep = Representation::Integer32();
    4471             :     }
    4472             :     HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
    4473       64956 :   }
    4474             : 
    4475      531329 :   DECLARE_CONCRETE_INSTRUCTION(Shl)
    4476             : 
    4477             :  protected:
    4478          96 :   bool DataEquals(HValue* other) override { return true; }
    4479             : 
    4480             :  private:
    4481             :   HShl(HValue* context, HValue* left, HValue* right)
    4482       16562 :       : HBitwiseBinaryOperation(context, left, right) {}
    4483             : };
    4484             : 
    4485             : 
    4486           0 : class HShr final : public HBitwiseBinaryOperation {
    4487             :  public:
    4488             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4489             :                            HValue* left, HValue* right);
    4490             : 
    4491             :   Range* InferRange(Zone* zone) override;
    4492             : 
    4493       34654 :   void UpdateRepresentation(Representation new_rep,
    4494             :                             HInferRepresentationPhase* h_infer,
    4495             :                             const char* reason) override {
    4496       34654 :     if (new_rep.IsSmi()) new_rep = Representation::Integer32();
    4497             :     HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
    4498       34654 :   }
    4499             : 
    4500      578760 :   DECLARE_CONCRETE_INSTRUCTION(Shr)
    4501             : 
    4502             :  protected:
    4503         171 :   bool DataEquals(HValue* other) override { return true; }
    4504             : 
    4505             :  private:
    4506             :   HShr(HValue* context, HValue* left, HValue* right)
    4507        9359 :       : HBitwiseBinaryOperation(context, left, right) {}
    4508             : };
    4509             : 
    4510             : 
    4511           0 : class HSar final : public HBitwiseBinaryOperation {
    4512             :  public:
    4513             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4514             :                            HValue* left, HValue* right);
    4515             : 
    4516             :   Range* InferRange(Zone* zone) override;
    4517             : 
    4518       45134 :   void UpdateRepresentation(Representation new_rep,
    4519             :                             HInferRepresentationPhase* h_infer,
    4520             :                             const char* reason) override {
    4521       45134 :     if (new_rep.IsSmi()) new_rep = Representation::Integer32();
    4522             :     HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
    4523       45134 :   }
    4524             : 
    4525      520305 :   DECLARE_CONCRETE_INSTRUCTION(Sar)
    4526             : 
    4527             :  protected:
    4528         842 :   bool DataEquals(HValue* other) override { return true; }
    4529             : 
    4530             :  private:
    4531             :   HSar(HValue* context, HValue* left, HValue* right)
    4532       14637 :       : HBitwiseBinaryOperation(context, left, right) {}
    4533             : };
    4534             : 
    4535             : 
    4536           0 : class HRor final : public HBitwiseBinaryOperation {
    4537             :  public:
    4538             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    4539             :                            HValue* left, HValue* right) {
    4540         500 :     return new (zone) HRor(context, left, right);
    4541             :   }
    4542             : 
    4543        2700 :   void UpdateRepresentation(Representation new_rep,
    4544             :                             HInferRepresentationPhase* h_infer,
    4545             :                             const char* reason) override {
    4546        2700 :     if (new_rep.IsSmi()) new_rep = Representation::Integer32();
    4547             :     HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
    4548        2700 :   }
    4549             : 
    4550       16089 :   DECLARE_CONCRETE_INSTRUCTION(Ror)
    4551             : 
    4552             :  protected:
    4553           0 :   bool DataEquals(HValue* other) override { return true; }
    4554             : 
    4555             :  private:
    4556         500 :   HRor(HValue* context, HValue* left, HValue* right)
    4557         500 :       : HBitwiseBinaryOperation(context, left, right) {
    4558         500 :     ChangeRepresentation(Representation::Integer32());
    4559         500 :   }
    4560             : };
    4561             : 
    4562             : 
    4563           0 : class HOsrEntry final : public HTemplateInstruction<0> {
    4564             :  public:
    4565        4876 :   DECLARE_INSTRUCTION_FACTORY_P1(HOsrEntry, BailoutId);
    4566             : 
    4567             :   BailoutId ast_id() const { return ast_id_; }
    4568             : 
    4569           0 :   Representation RequiredInputRepresentation(int index) override {
    4570           0 :     return Representation::None();
    4571             :   }
    4572             : 
    4573       26852 :   DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
    4574             : 
    4575             :  private:
    4576        2438 :   explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
    4577             :     SetChangesFlag(kOsrEntries);
    4578             :     SetChangesFlag(kNewSpacePromotion);
    4579             :   }
    4580             : 
    4581             :   BailoutId ast_id_;
    4582             : };
    4583             : 
    4584             : 
    4585           0 : class HParameter final : public HTemplateInstruction<0> {
    4586             :  public:
    4587             :   enum ParameterKind {
    4588             :     STACK_PARAMETER,
    4589             :     REGISTER_PARAMETER
    4590             :   };
    4591             : 
    4592      855582 :   DECLARE_INSTRUCTION_FACTORY_P1(HParameter, unsigned);
    4593             :   DECLARE_INSTRUCTION_FACTORY_P2(HParameter, unsigned, ParameterKind);
    4594       74354 :   DECLARE_INSTRUCTION_FACTORY_P3(HParameter, unsigned, ParameterKind,
    4595             :                                  Representation);
    4596             : 
    4597             :   unsigned index() const { return index_; }
    4598             :   ParameterKind kind() const { return kind_; }
    4599             : 
    4600             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    4601             : 
    4602           0 :   Representation RequiredInputRepresentation(int index) override {
    4603           0 :     return Representation::None();
    4604             :   }
    4605             : 
    4606        9630 :   Representation KnownOptimalRepresentation() override {
    4607             :     // If a parameter is an input to a phi, that phi should not
    4608             :     // choose any more optimistic representation than Tagged.
    4609        9630 :     return Representation::Tagged();
    4610             :   }
    4611             : 
    4612    50160204 :   DECLARE_CONCRETE_INSTRUCTION(Parameter)
    4613             : 
    4614             :  private:
    4615             :   explicit HParameter(unsigned index,
    4616             :                       ParameterKind kind = STACK_PARAMETER)
    4617             :       : index_(index),
    4618      427791 :         kind_(kind) {
    4619             :     set_representation(Representation::Tagged());
    4620             :   }
    4621             : 
    4622             :   explicit HParameter(unsigned index,
    4623             :                       ParameterKind kind,
    4624             :                       Representation r)
    4625             :       : index_(index),
    4626       37177 :         kind_(kind) {
    4627             :     set_representation(r);
    4628             :   }
    4629             : 
    4630             :   unsigned index_;
    4631             :   ParameterKind kind_;
    4632             : };
    4633             : 
    4634             : 
    4635           0 : class HUnknownOSRValue final : public HTemplateInstruction<0> {
    4636             :  public:
    4637       29078 :   DECLARE_INSTRUCTION_FACTORY_P2(HUnknownOSRValue, HEnvironment*, int);
    4638             : 
    4639             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    4640             : 
    4641           0 :   Representation RequiredInputRepresentation(int index) override {
    4642           0 :     return Representation::None();
    4643             :   }
    4644             : 
    4645        3835 :   void set_incoming_value(HPhi* value) { incoming_value_ = value; }
    4646             :   HPhi* incoming_value() { return incoming_value_; }
    4647             :   HEnvironment *environment() { return environment_; }
    4648             :   int index() { return index_; }
    4649             : 
    4650       13826 :   Representation KnownOptimalRepresentation() override {
    4651       13826 :     if (incoming_value_ == NULL) return Representation::None();
    4652             :     return incoming_value_->KnownOptimalRepresentation();
    4653             :   }
    4654             : 
    4655      429726 :   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
    4656             : 
    4657             :  private:
    4658             :   HUnknownOSRValue(HEnvironment* environment, int index)
    4659             :       : environment_(environment),
    4660             :         index_(index),
    4661       14539 :         incoming_value_(NULL) {
    4662             :     set_representation(Representation::Tagged());
    4663             :   }
    4664             : 
    4665             :   HEnvironment* environment_;
    4666             :   int index_;
    4667             :   HPhi* incoming_value_;
    4668             : };
    4669             : 
    4670           0 : class HAllocate final : public HTemplateInstruction<3> {
    4671             :  public:
    4672             :   static bool CompatibleInstanceTypes(InstanceType type1,
    4673             :                                       InstanceType type2) {
    4674             :     return ComputeFlags(TENURED, type1) == ComputeFlags(TENURED, type2) &&
    4675             :         ComputeFlags(NOT_TENURED, type1) == ComputeFlags(NOT_TENURED, type2);
    4676             :   }
    4677             : 
    4678       36045 :   static HAllocate* New(
    4679             :       Isolate* isolate, Zone* zone, HValue* context, HValue* size, HType type,
    4680             :       PretenureFlag pretenure_flag, InstanceType instance_type,
    4681             :       HValue* dominator,
    4682             :       Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()) {
    4683             :     return new (zone) HAllocate(context, size, type, pretenure_flag,
    4684       72090 :                                 instance_type, dominator, allocation_site);
    4685             :   }
    4686             : 
    4687             :   // Maximum instance size for which allocations will be inlined.
    4688             :   static const int kMaxInlineSize = 64 * kPointerSize;
    4689             : 
    4690             :   HValue* context() const { return OperandAt(0); }
    4691             :   HValue* size() const { return OperandAt(1); }
    4692             :   HValue* allocation_folding_dominator() const { return OperandAt(2); }
    4693             : 
    4694       72526 :   Representation RequiredInputRepresentation(int index) override {
    4695       72526 :     if (index == 0) {
    4696             :       return Representation::Tagged();
    4697             :     } else {
    4698             :       return Representation::Integer32();
    4699             :     }
    4700             :   }
    4701             : 
    4702        8884 :   Handle<Map> GetMonomorphicJSObjectMap() override {
    4703        8884 :     return known_initial_map_;
    4704             :   }
    4705             : 
    4706             :   void set_known_initial_map(Handle<Map> known_initial_map) {
    4707        4599 :     known_initial_map_ = known_initial_map;
    4708             :   }
    4709             : 
    4710             :   bool IsNewSpaceAllocation() const {
    4711      118839 :     return (flags_ & ALLOCATE_IN_NEW_SPACE) != 0;
    4712             :   }
    4713             : 
    4714             :   bool IsOldSpaceAllocation() const {
    4715       47986 :     return (flags_ & ALLOCATE_IN_OLD_SPACE) != 0;
    4716             :   }
    4717             : 
    4718             :   bool MustAllocateDoubleAligned() const {
    4719       31414 :     return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0;
    4720             :   }
    4721             : 
    4722             :   bool MustPrefillWithFiller() const {
    4723       20528 :     return (flags_ & PREFILL_WITH_FILLER) != 0;
    4724             :   }
    4725             : 
    4726             :   void MakePrefillWithFiller() {
    4727             :     flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER);
    4728             :   }
    4729             : 
    4730             :   void MakeDoubleAligned() {
    4731         378 :     flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED);
    4732             :   }
    4733             : 
    4734             :   void MakeAllocationFoldingDominator() {
    4735             :     flags_ =
    4736        2074 :         static_cast<HAllocate::Flags>(flags_ | ALLOCATION_FOLDING_DOMINATOR);
    4737             :   }
    4738             : 
    4739             :   bool IsAllocationFoldingDominator() const {
    4740       69694 :     return (flags_ & ALLOCATION_FOLDING_DOMINATOR) != 0;
    4741             :   }
    4742             : 
    4743        4903 :   void MakeFoldedAllocation(HAllocate* dominator) {
    4744        4903 :     flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATION_FOLDED);
    4745             :     ClearFlag(kTrackSideEffectDominators);
    4746             :     ClearChangesFlag(kNewSpacePromotion);
    4747        4903 :     SetOperandAt(2, dominator);
    4748        4903 :   }
    4749             : 
    4750      145353 :   bool IsAllocationFolded() const { return (flags_ & ALLOCATION_FOLDED) != 0; }
    4751             : 
    4752             :   bool HandleSideEffectDominator(GVNFlag side_effect,
    4753             :                                  HValue* dominator) override;
    4754             : 
    4755             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    4756             : 
    4757     2462721 :   DECLARE_CONCRETE_INSTRUCTION(Allocate)
    4758             : 
    4759             :  private:
    4760             :   enum Flags {
    4761             :     ALLOCATE_IN_NEW_SPACE = 1 << 0,
    4762             :     ALLOCATE_IN_OLD_SPACE = 1 << 2,
    4763             :     ALLOCATE_DOUBLE_ALIGNED = 1 << 3,
    4764             :     PREFILL_WITH_FILLER = 1 << 4,
    4765             :     ALLOCATION_FOLDING_DOMINATOR = 1 << 5,
    4766             :     ALLOCATION_FOLDED = 1 << 6
    4767             :   };
    4768             : 
    4769       36045 :   HAllocate(
    4770             :       HValue* context, HValue* size, HType type, PretenureFlag pretenure_flag,
    4771             :       InstanceType instance_type, HValue* dominator,
    4772             :       Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null())
    4773             :       : HTemplateInstruction<3>(type),
    4774       72090 :         flags_(ComputeFlags(pretenure_flag, instance_type)) {
    4775       36045 :     SetOperandAt(0, context);
    4776             :     UpdateSize(size);
    4777       36045 :     SetOperandAt(2, dominator);
    4778             :     set_representation(Representation::Tagged());
    4779             :     SetFlag(kTrackSideEffectDominators);
    4780             :     SetChangesFlag(kNewSpacePromotion);
    4781             :     SetDependsOnFlag(kNewSpacePromotion);
    4782             : 
    4783       36045 :     if (FLAG_trace_pretenuring) {
    4784             :       PrintF("HAllocate with AllocationSite %p %s\n",
    4785             :              allocation_site.is_null()
    4786             :                  ? static_cast<void*>(NULL)
    4787             :                  : static_cast<void*>(*allocation_site),
    4788           0 :              pretenure_flag == TENURED ? "tenured" : "not tenured");
    4789             :     }
    4790       36045 :   }
    4791             : 
    4792             :   static Flags ComputeFlags(PretenureFlag pretenure_flag,
    4793             :                             InstanceType instance_type) {
    4794             :     Flags flags = pretenure_flag == TENURED ? ALLOCATE_IN_OLD_SPACE
    4795       36045 :                                             : ALLOCATE_IN_NEW_SPACE;
    4796       36045 :     if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
    4797         505 :       flags = static_cast<Flags>(flags | ALLOCATE_DOUBLE_ALIGNED);
    4798             :     }
    4799             :     // We have to fill the allocated object with one word fillers if we do
    4800             :     // not use allocation folding since some allocations may depend on each
    4801             :     // other, i.e., have a pointer to each other. A GC in between these
    4802             :     // allocations may leave such objects behind in a not completely initialized
    4803             :     // state.
    4804       36045 :     if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
    4805         129 :       flags = static_cast<Flags>(flags | PREFILL_WITH_FILLER);
    4806             :     }
    4807             :     return flags;
    4808             :   }
    4809             : 
    4810             :   void UpdateSize(HValue* size) {
    4811       38874 :     SetOperandAt(1, size);
    4812             :   }
    4813             : 
    4814        2829 :   bool IsFoldable(HAllocate* allocate) {
    4815        5658 :     return (IsNewSpaceAllocation() && allocate->IsNewSpaceAllocation()) ||
    4816          37 :            (IsOldSpaceAllocation() && allocate->IsOldSpaceAllocation());
    4817             :   }
    4818             : 
    4819             :   Flags flags_;
    4820             :   Handle<Map> known_initial_map_;
    4821             : };
    4822             : 
    4823             : 
    4824           0 : class HStoreCodeEntry final : public HTemplateInstruction<2> {
    4825             :  public:
    4826             :   static HStoreCodeEntry* New(Isolate* isolate, Zone* zone, HValue* context,
    4827             :                               HValue* function, HValue* code) {
    4828             :     return new(zone) HStoreCodeEntry(function, code);
    4829             :   }
    4830             : 
    4831           0 :   Representation RequiredInputRepresentation(int index) override {
    4832           0 :     return Representation::Tagged();
    4833             :   }
    4834             : 
    4835             :   HValue* function() { return OperandAt(0); }
    4836             :   HValue* code_object() { return OperandAt(1); }
    4837             : 
    4838           0 :   DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry)
    4839             : 
    4840             :  private:
    4841             :   HStoreCodeEntry(HValue* function, HValue* code) {
    4842             :     SetOperandAt(0, function);
    4843             :     SetOperandAt(1, code);
    4844             :   }
    4845             : };
    4846             : 
    4847             : 
    4848           0 : class HInnerAllocatedObject final : public HTemplateInstruction<2> {
    4849             :  public:
    4850        7160 :   static HInnerAllocatedObject* New(Isolate* isolate, Zone* zone,
    4851             :                                     HValue* context, HValue* value,
    4852             :                                     HValue* offset, HType type) {
    4853       14320 :     return new(zone) HInnerAllocatedObject(value, offset, type);
    4854             :   }
    4855             : 
    4856             :   HValue* base_object() const { return OperandAt(0); }
    4857             :   HValue* offset() const { return OperandAt(1); }
    4858             : 
    4859       14320 :   Representation RequiredInputRepresentation(int index) override {
    4860       14320 :     return index == 0 ? Representation::Tagged() : Representation::Integer32();
    4861             :   }
    4862             : 
    4863             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    4864             : 
    4865      211147 :   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
    4866             : 
    4867             :  private:
    4868        7160 :   HInnerAllocatedObject(HValue* value,
    4869             :                         HValue* offset,
    4870        7160 :                         HType type) : HTemplateInstruction<2>(type) {
    4871             :     DCHECK(value->IsAllocate());
    4872             :     DCHECK(type.IsHeapObject());
    4873        7160 :     SetOperandAt(0, value);
    4874        7160 :     SetOperandAt(1, offset);
    4875             :     set_representation(Representation::Tagged());
    4876        7160 :   }
    4877             : };
    4878             : 
    4879             : 
    4880      416959 : inline bool StoringValueNeedsWriteBarrier(HValue* value) {
    4881             :   return !value->type().IsSmi()
    4882      354378 :       && !value->type().IsNull()
    4883      351001 :       && !value->type().IsBoolean()
    4884      348255 :       && !value->type().IsUndefined()
    4885      738085 :       && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
    4886             : }
    4887             : 
    4888             : 
    4889      178516 : inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
    4890             :                                             HValue* value,
    4891             :                                             HValue* dominator) {
    4892             :   // There may be multiple inner allocates dominated by one allocate.
    4893      385672 :   while (object->IsInnerAllocatedObject()) {
    4894             :     object = HInnerAllocatedObject::cast(object)->base_object();
    4895             :   }
    4896             : 
    4897      178516 :   if (object->IsAllocate()) {
    4898      119605 :     HAllocate* allocate = HAllocate::cast(object);
    4899      119605 :     if (allocate->IsAllocationFolded()) {
    4900             :       HValue* dominator = allocate->allocation_folding_dominator();
    4901             :       // There is no guarantee that all allocations are folded together because
    4902             :       // GVN performs a fixpoint.
    4903       45950 :       if (HAllocate::cast(dominator)->IsAllocationFoldingDominator()) {
    4904             :         object = dominator;
    4905             :       }
    4906             :     }
    4907             :   }
    4908             : 
    4909      186794 :   if (object->IsConstant() &&
    4910        8278 :       HConstant::cast(object)->HasExternalReferenceValue()) {
    4911             :     // Stores to external references require no write barriers
    4912             :     return false;
    4913             :   }
    4914             :   // We definitely need a write barrier unless the object is the allocation
    4915             :   // dominator.
    4916      289859 :   if (object == dominator && object->IsAllocate()) {
    4917             :     // Stores to new space allocations require no write barriers.
    4918      220970 :     if (HAllocate::cast(object)->IsNewSpaceAllocation()) {
    4919             :       return false;
    4920             :     }
    4921             :   }
    4922       68167 :   return true;
    4923             : }
    4924             : 
    4925             : 
    4926       21332 : inline PointersToHereCheck PointersToHereCheckForObject(HValue* object,
    4927             :                                                         HValue* dominator) {
    4928       42664 :   while (object->IsInnerAllocatedObject()) {
    4929             :     object = HInnerAllocatedObject::cast(object)->base_object();
    4930             :   }
    4931       28556 :   if (object == dominator &&
    4932       21991 :       object->IsAllocate() &&
    4933         659 :       HAllocate::cast(object)->IsNewSpaceAllocation()) {
    4934             :     return kPointersToHereAreAlwaysInteresting;
    4935             :   }
    4936       20674 :   return kPointersToHereMaybeInteresting;
    4937             : }
    4938             : 
    4939             : 
    4940           0 : class HLoadContextSlot final : public HUnaryOperation {
    4941             :  public:
    4942             :   enum Mode {
    4943             :     // Perform a normal load of the context slot without checking its value.
    4944             :     kNoCheck,
    4945             :     // Load and check the value of the context slot. Deoptimize if it's the
    4946             :     // hole value. This is used for checking for loading of uninitialized
    4947             :     // harmony bindings where we deoptimize into full-codegen generated code
    4948             :     // which will subsequently throw a reference error.
    4949             :     kCheckDeoptimize
    4950             :   };
    4951             : 
    4952      389339 :   HLoadContextSlot(HValue* context, int slot_index, Mode mode)
    4953      389339 :       : HUnaryOperation(context), slot_index_(slot_index), mode_(mode) {
    4954             :     set_representation(Representation::Tagged());
    4955             :     SetFlag(kUseGVN);
    4956             :     SetDependsOnFlag(kContextSlots);
    4957      389339 :   }
    4958             : 
    4959             :   int slot_index() const { return slot_index_; }
    4960             :   Mode mode() const { return mode_; }
    4961             : 
    4962             :   bool DeoptimizesOnHole() {
    4963             :     return mode_ == kCheckDeoptimize;
    4964             :   }
    4965             : 
    4966             :   bool RequiresHoleCheck() const {
    4967             :     return mode_ != kNoCheck;
    4968             :   }
    4969             : 
    4970      387812 :   Representation RequiredInputRepresentation(int index) override {
    4971      387812 :     return Representation::Tagged();
    4972             :   }
    4973             : 
    4974             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    4975             : 
    4976    13334291 :   DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
    4977             : 
    4978             :  protected:
    4979       92572 :   bool DataEquals(HValue* other) override {
    4980       92572 :     HLoadContextSlot* b = HLoadContextSlot::cast(other);
    4981       92572 :     return (slot_index() == b->slot_index());
    4982             :   }
    4983             : 
    4984             :  private:
    4985         172 :   bool IsDeletable() const override { return !RequiresHoleCheck(); }
    4986             : 
    4987             :   int slot_index_;
    4988             :   Mode mode_;
    4989             : };
    4990             : 
    4991             : 
    4992           0 : class HStoreContextSlot final : public HTemplateInstruction<2> {
    4993             :  public:
    4994             :   enum Mode {
    4995             :     // Perform a normal store to the context slot without checking its previous
    4996             :     // value.
    4997             :     kNoCheck,
    4998             :     // Check the previous value of the context slot and deoptimize if it's the
    4999             :     // hole value. This is used for checking for assignments to uninitialized
    5000             :     // harmony bindings where we deoptimize into full-codegen generated code
    5001             :     // which will subsequently throw a reference error.
    5002             :     kCheckDeoptimize
    5003             :   };
    5004             : 
    5005       70842 :   DECLARE_INSTRUCTION_FACTORY_P4(HStoreContextSlot, HValue*, int,
    5006             :                                  Mode, HValue*);
    5007             : 
    5008             :   HValue* context() const { return OperandAt(0); }
    5009             :   HValue* value() const { return OperandAt(1); }
    5010             :   int slot_index() const { return slot_index_; }
    5011             :   Mode mode() const { return mode_; }
    5012             : 
    5013             :   bool NeedsWriteBarrier() {
    5014      140055 :     return StoringValueNeedsWriteBarrier(value());
    5015             :   }
    5016             : 
    5017             :   bool DeoptimizesOnHole() {
    5018             :     return mode_ == kCheckDeoptimize;
    5019             :   }
    5020             : 
    5021             :   bool RequiresHoleCheck() {
    5022             :     return mode_ != kNoCheck;
    5023             :   }
    5024             : 
    5025      142467 :   Representation RequiredInputRepresentation(int index) override {
    5026      142467 :     return Representation::Tagged();
    5027             :   }
    5028             : 
    5029             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    5030             : 
    5031      912171 :   DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
    5032             : 
    5033             :  private:
    5034       70842 :   HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
    5035       70842 :       : slot_index_(slot_index), mode_(mode) {
    5036       70842 :     SetOperandAt(0, context);
    5037       70842 :     SetOperandAt(1, value);
    5038             :     SetChangesFlag(kContextSlots);
    5039       70842 :   }
    5040             : 
    5041             :   int slot_index_;
    5042             :   Mode mode_;
    5043             : };
    5044             : 
    5045             : 
    5046             : // Represents an access to a portion of an object, such as the map pointer,
    5047             : // array elements pointer, etc, but not accesses to array elements themselves.
    5048             : class HObjectAccess final {
    5049             :  public:
    5050             :   inline bool IsInobject() const {
    5051     1282739 :     return portion() != kBackingStore && portion() != kExternalMemory;
    5052             :   }
    5053             : 
    5054             :   inline bool IsExternalMemory() const {
    5055             :     return portion() == kExternalMemory;
    5056             :   }
    5057             : 
    5058             :   inline bool IsStringLength() const {
    5059             :     return portion() == kStringLengths;
    5060             :   }
    5061             : 
    5062             :   inline bool IsMap() const {
    5063             :     return portion() == kMaps;
    5064             :   }
    5065             : 
    5066             :   inline int offset() const {
    5067             :     return OffsetField::decode(value_);
    5068             :   }
    5069             : 
    5070             :   inline Representation representation() const {
    5071             :     return Representation::FromKind(RepresentationField::decode(value_));
    5072             :   }
    5073             : 
    5074             :   inline Handle<Name> name() const { return name_; }
    5075             : 
    5076             :   inline bool immutable() const {
    5077             :     return ImmutableField::decode(value_);
    5078             :   }
    5079             : 
    5080             :   // Returns true if access is being made to an in-object property that
    5081             :   // was already added to the object.
    5082             :   inline bool existing_inobject_property() const {
    5083             :     return ExistingInobjectPropertyField::decode(value_);
    5084             :   }
    5085             : 
    5086       19359 :   inline HObjectAccess WithRepresentation(Representation representation) {
    5087             :     return HObjectAccess(portion(), offset(), representation, name(),
    5088       19359 :                          immutable(), existing_inobject_property());
    5089             :   }
    5090             : 
    5091             :   static HObjectAccess ForHeapNumberValue() {
    5092             :     return HObjectAccess(
    5093             :         kDouble, HeapNumber::kValueOffset, Representation::Double());
    5094             :   }
    5095             : 
    5096             :   static HObjectAccess ForHeapNumberValueLowestBits() {
    5097             :     return HObjectAccess(kDouble,
    5098             :                          HeapNumber::kValueOffset,
    5099             :                          Representation::Integer32());
    5100             :   }
    5101             : 
    5102             :   static HObjectAccess ForHeapNumberValueHighestBits() {
    5103             :     return HObjectAccess(kDouble,
    5104             :                          HeapNumber::kValueOffset + kIntSize,
    5105             :                          Representation::Integer32());
    5106             :   }
    5107             : 
    5108             :   static HObjectAccess ForOddballToNumber(
    5109             :       Representation representation = Representation::Tagged()) {
    5110             :     return HObjectAccess(kInobject, Oddball::kToNumberOffset, representation);
    5111             :   }
    5112             : 
    5113             :   static HObjectAccess ForOddballTypeOf() {
    5114             :     return HObjectAccess(kInobject, Oddball::kTypeOfOffset,
    5115             :                          Representation::HeapObject());
    5116             :   }
    5117             : 
    5118             :   static HObjectAccess ForElementsPointer() {
    5119             :     return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
    5120             :   }
    5121             : 
    5122             :   static HObjectAccess ForNextFunctionLinkPointer() {
    5123             :     return HObjectAccess(kInobject, JSFunction::kNextFunctionLinkOffset);
    5124             :   }
    5125             : 
    5126             :   static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
    5127             :     return HObjectAccess(
    5128             :         kArrayLengths,
    5129             :         JSArray::kLengthOffset,
    5130             :         IsFastElementsKind(elements_kind)
    5131       57298 :             ? Representation::Smi() : Representation::Tagged());
    5132             :   }
    5133             : 
    5134             :   static HObjectAccess ForAllocationSiteOffset(int offset);
    5135             : 
    5136             :   static HObjectAccess ForAllocationSiteList() {
    5137             :     return HObjectAccess(kExternalMemory, 0, Representation::Tagged(),
    5138             :                          Handle<Name>::null(), false, false);
    5139             :   }
    5140             : 
    5141             :   static HObjectAccess ForFixedArrayLength() {
    5142             :     return HObjectAccess(
    5143             :         kArrayLengths,
    5144             :         FixedArray::kLengthOffset,
    5145             :         Representation::Smi());
    5146             :   }
    5147             : 
    5148             :   static HObjectAccess ForFixedTypedArrayBaseBasePointer() {
    5149             :     return HObjectAccess(kInobject, FixedTypedArrayBase::kBasePointerOffset,
    5150             :                          Representation::Tagged());
    5151             :   }
    5152             : 
    5153        3897 :   static HObjectAccess ForFixedTypedArrayBaseExternalPointer() {
    5154             :     return HObjectAccess::ForObservableJSObjectOffset(
    5155             :         FixedTypedArrayBase::kExternalPointerOffset,
    5156        3897 :         Representation::External());
    5157             :   }
    5158             : 
    5159             :   static HObjectAccess ForStringHashField() {
    5160             :     return HObjectAccess(kInobject,
    5161             :                          String::kHashFieldOffset,
    5162             :                          Representation::Integer32());
    5163             :   }
    5164             : 
    5165             :   static HObjectAccess ForStringLength() {
    5166             :     STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
    5167             :     return HObjectAccess(
    5168             :         kStringLengths,
    5169             :         String::kLengthOffset,
    5170             :         Representation::Smi());
    5171             :   }
    5172             : 
    5173             :   static HObjectAccess ForConsStringFirst() {
    5174             :     return HObjectAccess(kInobject, ConsString::kFirstOffset);
    5175             :   }
    5176             : 
    5177             :   static HObjectAccess ForConsStringSecond() {
    5178             :     return HObjectAccess(kInobject, ConsString::kSecondOffset);
    5179             :   }
    5180             : 
    5181             :   static HObjectAccess ForPropertiesPointer() {
    5182             :     return HObjectAccess(kInobject, JSObject::kPropertiesOffset);
    5183             :   }
    5184             : 
    5185             :   static HObjectAccess ForPrototypeOrInitialMap() {
    5186             :     return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset);
    5187             :   }
    5188             : 
    5189             :   static HObjectAccess ForSharedFunctionInfoPointer() {
    5190             :     return HObjectAccess(kInobject, JSFunction::kSharedFunctionInfoOffset);
    5191             :   }
    5192             : 
    5193             :   static HObjectAccess ForCodeEntryPointer() {
    5194             :     return HObjectAccess(kInobject, JSFunction::kCodeEntryOffset);
    5195             :   }
    5196             : 
    5197             :   static HObjectAccess ForCodeOffset() {
    5198             :     return HObjectAccess(kInobject, SharedFunctionInfo::kCodeOffset);
    5199             :   }
    5200             : 
    5201             :   static HObjectAccess ForOptimizedCodeMap() {
    5202             :     return HObjectAccess(kInobject,
    5203             :                          SharedFunctionInfo::kOptimizedCodeMapOffset);
    5204             :   }
    5205             : 
    5206             :   static HObjectAccess ForFunctionContextPointer() {
    5207             :     return HObjectAccess(kInobject, JSFunction::kContextOffset);
    5208             :   }
    5209             : 
    5210             :   static HObjectAccess ForMap() {
    5211             :     return HObjectAccess(kMaps, JSObject::kMapOffset);
    5212             :   }
    5213             : 
    5214             :   static HObjectAccess ForPrototype() {
    5215             :     return HObjectAccess(kMaps, Map::kPrototypeOffset);
    5216             :   }
    5217             : 
    5218             :   static HObjectAccess ForMapAsInteger32() {
    5219             :     return HObjectAccess(kMaps, JSObject::kMapOffset,
    5220             :                          Representation::Integer32());
    5221             :   }
    5222             : 
    5223             :   static HObjectAccess ForMapInObjectPropertiesOrConstructorFunctionIndex() {
    5224             :     return HObjectAccess(
    5225             :         kInobject, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset,
    5226             :         Representation::UInteger8());
    5227             :   }
    5228             : 
    5229             :   static HObjectAccess ForMapInstanceType() {
    5230             :     return HObjectAccess(kInobject,
    5231             :                          Map::kInstanceTypeOffset,
    5232             :                          Representation::UInteger8());
    5233             :   }
    5234             : 
    5235             :   static HObjectAccess ForMapInstanceSize() {
    5236             :     return HObjectAccess(kInobject,
    5237             :                          Map::kInstanceSizeOffset,
    5238             :                          Representation::UInteger8());
    5239             :   }
    5240             : 
    5241             :   static HObjectAccess ForMapBitField() {
    5242             :     return HObjectAccess(kInobject,
    5243             :                          Map::kBitFieldOffset,
    5244             :                          Representation::UInteger8());
    5245             :   }
    5246             : 
    5247             :   static HObjectAccess ForMapBitField2() {
    5248             :     return HObjectAccess(kInobject,
    5249             :                          Map::kBitField2Offset,
    5250             :                          Representation::UInteger8());
    5251             :   }
    5252             : 
    5253             :   static HObjectAccess ForMapBitField3() {
    5254             :     return HObjectAccess(kInobject, Map::kBitField3Offset,
    5255             :                          Representation::Integer32());
    5256             :   }
    5257             : 
    5258             :   static HObjectAccess ForMapDescriptors() {
    5259             :     return HObjectAccess(kInobject, Map::kDescriptorsOffset);
    5260             :   }
    5261             : 
    5262             :   static HObjectAccess ForNameHashField() {
    5263             :     return HObjectAccess(kInobject,
    5264             :                          Name::kHashFieldOffset,
    5265             :                          Representation::Integer32());
    5266             :   }
    5267             : 
    5268             :   static HObjectAccess ForMapInstanceTypeAndBitField() {
    5269             :     STATIC_ASSERT((Map::kInstanceTypeAndBitFieldOffset & 1) == 0);
    5270             :     // Ensure the two fields share one 16-bit word, endian-independent.
    5271             :     STATIC_ASSERT((Map::kBitFieldOffset & ~1) ==
    5272             :                   (Map::kInstanceTypeOffset & ~1));
    5273             :     return HObjectAccess(kInobject,
    5274             :                          Map::kInstanceTypeAndBitFieldOffset,
    5275             :                          Representation::UInteger16());
    5276             :   }
    5277             : 
    5278             :   static HObjectAccess ForPropertyCellValue() {
    5279             :     return HObjectAccess(kInobject, PropertyCell::kValueOffset);
    5280             :   }
    5281             : 
    5282             :   static HObjectAccess ForPropertyCellDetails() {
    5283             :     return HObjectAccess(kInobject, PropertyCell::kDetailsOffset,
    5284             :                          Representation::Smi());
    5285             :   }
    5286             : 
    5287             :   static HObjectAccess ForCellValue() {
    5288             :     return HObjectAccess(kInobject, Cell::kValueOffset);
    5289             :   }
    5290             : 
    5291             :   static HObjectAccess ForWeakCellValue() {
    5292             :     return HObjectAccess(kInobject, WeakCell::kValueOffset);
    5293             :   }
    5294             : 
    5295             :   static HObjectAccess ForWeakCellNext() {
    5296             :     return HObjectAccess(kInobject, WeakCell::kNextOffset);
    5297             :   }
    5298             : 
    5299             :   static HObjectAccess ForAllocationMementoSite() {
    5300             :     return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
    5301             :   }
    5302             : 
    5303             :   static HObjectAccess ForCounter() {
    5304             :     return HObjectAccess(kExternalMemory, 0, Representation::Integer32(),
    5305             :                          Handle<Name>::null(), false, false);
    5306             :   }
    5307             : 
    5308             :   static HObjectAccess ForExternalUInteger8() {
    5309             :     return HObjectAccess(kExternalMemory, 0, Representation::UInteger8(),
    5310             :                          Handle<Name>::null(), false, false);
    5311             :   }
    5312             : 
    5313             :   static HObjectAccess ForBoundTargetFunction() {
    5314             :     return HObjectAccess(kInobject,
    5315             :                          JSBoundFunction::kBoundTargetFunctionOffset);
    5316             :   }
    5317             : 
    5318             :   static HObjectAccess ForBoundThis() {
    5319             :     return HObjectAccess(kInobject, JSBoundFunction::kBoundThisOffset);
    5320             :   }
    5321             : 
    5322             :   static HObjectAccess ForBoundArguments() {
    5323             :     return HObjectAccess(kInobject, JSBoundFunction::kBoundArgumentsOffset);
    5324             :   }
    5325             : 
    5326             :   // Create an access to an offset in a fixed array header.
    5327             :   static HObjectAccess ForFixedArrayHeader(int offset);
    5328             : 
    5329             :   // Create an access to an in-object property in a JSObject.
    5330             :   // This kind of access must be used when the object |map| is known and
    5331             :   // in-object properties are being accessed. Accesses of the in-object
    5332             :   // properties can have different semantics depending on whether corresponding
    5333             :   // property was added to the map or not.
    5334             :   static HObjectAccess ForMapAndOffset(Handle<Map> map, int offset,
    5335             :       Representation representation = Representation::Tagged());
    5336             : 
    5337             :   // Create an access to an in-object property in a JSObject.
    5338             :   // This kind of access can be used for accessing object header fields or
    5339             :   // in-object properties if the map of the object is not known.
    5340             :   static HObjectAccess ForObservableJSObjectOffset(int offset,
    5341             :       Representation representation = Representation::Tagged()) {
    5342        6364 :     return ForMapAndOffset(Handle<Map>::null(), offset, representation);
    5343             :   }
    5344             : 
    5345             :   // Create an access to an in-object property in a JSArray.
    5346             :   static HObjectAccess ForJSArrayOffset(int offset);
    5347             : 
    5348             :   static HObjectAccess ForContextSlot(int index);
    5349             : 
    5350             :   static HObjectAccess ForScriptContext(int index);
    5351             : 
    5352             :   // Create an access to the backing store of an object.
    5353             :   static HObjectAccess ForBackingStoreOffset(int offset,
    5354             :       Representation representation = Representation::Tagged());
    5355             : 
    5356             :   // Create an access to a resolved field (in-object or backing store).
    5357             :   static HObjectAccess ForField(Handle<Map> map, int index,
    5358             :                                 Representation representation,
    5359             :                                 Handle<Name> name);
    5360             : 
    5361             :   static HObjectAccess ForJSTypedArrayLength() {
    5362             :     return HObjectAccess::ForObservableJSObjectOffset(
    5363             :         JSTypedArray::kLengthOffset);
    5364             :   }
    5365             : 
    5366             :   static HObjectAccess ForJSArrayBufferBackingStore() {
    5367             :     return HObjectAccess::ForObservableJSObjectOffset(
    5368             :         JSArrayBuffer::kBackingStoreOffset, Representation::External());
    5369             :   }
    5370             : 
    5371           0 :   static HObjectAccess ForJSArrayBufferByteLength() {
    5372             :     return HObjectAccess::ForObservableJSObjectOffset(
    5373           0 :         JSArrayBuffer::kByteLengthOffset, Representation::Tagged());
    5374             :   }
    5375             : 
    5376         189 :   static HObjectAccess ForJSArrayBufferBitField() {
    5377             :     return HObjectAccess::ForObservableJSObjectOffset(
    5378         189 :         JSArrayBuffer::kBitFieldOffset, Representation::Integer32());
    5379             :   }
    5380             : 
    5381             :   static HObjectAccess ForJSArrayBufferBitFieldSlot() {
    5382             :     return HObjectAccess::ForObservableJSObjectOffset(
    5383             :         JSArrayBuffer::kBitFieldSlot, Representation::Smi());
    5384             :   }
    5385             : 
    5386         189 :   static HObjectAccess ForJSArrayBufferViewBuffer() {
    5387             :     return HObjectAccess::ForObservableJSObjectOffset(
    5388         189 :         JSArrayBufferView::kBufferOffset);
    5389             :   }
    5390             : 
    5391             :   static HObjectAccess ForJSArrayBufferViewByteOffset() {
    5392             :     return HObjectAccess::ForObservableJSObjectOffset(
    5393             :         JSArrayBufferView::kByteOffsetOffset);
    5394             :   }
    5395             : 
    5396             :   static HObjectAccess ForJSArrayBufferViewByteLength() {
    5397             :     return HObjectAccess::ForObservableJSObjectOffset(
    5398             :         JSArrayBufferView::kByteLengthOffset);
    5399             :   }
    5400             : 
    5401             :   static HObjectAccess ForJSGlobalObjectNativeContext() {
    5402             :     return HObjectAccess(kInobject, JSGlobalObject::kNativeContextOffset);
    5403             :   }
    5404             : 
    5405             :   static HObjectAccess ForJSRegExpFlags() {
    5406             :     return HObjectAccess(kInobject, JSRegExp::kFlagsOffset);
    5407             :   }
    5408             : 
    5409             :   static HObjectAccess ForJSRegExpSource() {
    5410             :     return HObjectAccess(kInobject, JSRegExp::kSourceOffset);
    5411             :   }
    5412             : 
    5413        1553 :   static HObjectAccess ForJSCollectionTable() {
    5414             :     return HObjectAccess::ForObservableJSObjectOffset(
    5415        1553 :         JSCollection::kTableOffset);
    5416             :   }
    5417             : 
    5418             :   template <typename CollectionType>
    5419             :   static HObjectAccess ForOrderedHashTableNumberOfBuckets() {
    5420             :     return HObjectAccess(kInobject, CollectionType::kNumberOfBucketsOffset,
    5421             :                          Representation::Smi());
    5422             :   }
    5423             : 
    5424             :   template <typename CollectionType>
    5425             :   static HObjectAccess ForOrderedHashTableNumberOfElements() {
    5426             :     return HObjectAccess(kInobject, CollectionType::kNumberOfElementsOffset,
    5427             :                          Representation::Smi());
    5428             :   }
    5429             : 
    5430             :   template <typename CollectionType>
    5431             :   static HObjectAccess ForOrderedHashTableNumberOfDeletedElements() {
    5432             :     return HObjectAccess(kInobject,
    5433             :                          CollectionType::kNumberOfDeletedElementsOffset,
    5434             :                          Representation::Smi());
    5435             :   }
    5436             : 
    5437             :   template <typename CollectionType>
    5438             :   static HObjectAccess ForOrderedHashTableNextTable() {
    5439             :     return HObjectAccess(kInobject, CollectionType::kNextTableOffset);
    5440             :   }
    5441             : 
    5442             :   template <typename CollectionType>
    5443             :   static HObjectAccess ForOrderedHashTableBucket(int bucket) {
    5444             :     return HObjectAccess(kInobject, CollectionType::kHashTableStartOffset +
    5445             :                                         (bucket * kPointerSize),
    5446           6 :                          Representation::Smi());
    5447             :   }
    5448             : 
    5449             :   // Access into the data table of an OrderedHashTable with a
    5450             :   // known-at-compile-time bucket count.
    5451             :   template <typename CollectionType, int kBucketCount>
    5452             :   static HObjectAccess ForOrderedHashTableDataTableIndex(int index) {
    5453             :     return HObjectAccess(kInobject, CollectionType::kHashTableStartOffset +
    5454             :                                         (kBucketCount * kPointerSize) +
    5455          28 :                                         (index * kPointerSize));
    5456             :   }
    5457             : 
    5458             :   inline bool Equals(HObjectAccess that) const {
    5459             :     return value_ == that.value_;  // portion and offset must match
    5460             :   }
    5461             : 
    5462             :  protected:
    5463             :   void SetGVNFlags(HValue *instr, PropertyAccessType access_type);
    5464             : 
    5465             :  private:
    5466             :   // internal use only; different parts of an object or array
    5467             :   enum Portion {
    5468             :     kMaps,             // map of an object
    5469             :     kArrayLengths,     // the length of an array
    5470             :     kStringLengths,    // the length of a string
    5471             :     kElementsPointer,  // elements pointer
    5472             :     kBackingStore,     // some field in the backing store
    5473             :     kDouble,           // some double field
    5474             :     kInobject,         // some other in-object field
    5475             :     kExternalMemory    // some field in external memory
    5476             :   };
    5477             : 
    5478    11913090 :   HObjectAccess() : value_(0) {}
    5479             : 
    5480             :   HObjectAccess(Portion portion, int offset,
    5481             :                 Representation representation = Representation::Tagged(),
    5482             :                 Handle<Name> name = Handle<Name>::null(),
    5483             :                 bool immutable = false, bool existing_inobject_property = true)
    5484      189551 :       : value_(PortionField::encode(portion) |
    5485       19359 :                RepresentationField::encode(representation.kind()) |
    5486      183446 :                ImmutableField::encode(immutable ? 1 : 0) |
    5487             :                ExistingInobjectPropertyField::encode(
    5488      293743 :                    existing_inobject_property ? 1 : 0) |
    5489             :                OffsetField::encode(offset)),
    5490             :         name_(name) {
    5491             :     // assert that the fields decode correctly
    5492             :     DCHECK(this->offset() == offset);
    5493             :     DCHECK(this->portion() == portion);
    5494             :     DCHECK(this->immutable() == immutable);
    5495             :     DCHECK(this->existing_inobject_property() == existing_inobject_property);
    5496             :     DCHECK(RepresentationField::decode(value_) == representation.kind());
    5497             :     DCHECK(!this->existing_inobject_property() || IsInobject());
    5498             :   }
    5499             : 
    5500             :   class PortionField : public BitField<Portion, 0, 3> {};
    5501             :   class RepresentationField : public BitField<Representation::Kind, 3, 4> {};
    5502             :   class ImmutableField : public BitField<bool, 7, 1> {};
    5503             :   class ExistingInobjectPropertyField : public BitField<bool, 8, 1> {};
    5504             :   class OffsetField : public BitField<int, 9, 23> {};
    5505             : 
    5506             :   uint32_t value_;  // encodes portion, representation, immutable, and offset
    5507             :   Handle<Name> name_;
    5508             : 
    5509             :   friend class HLoadNamedField;
    5510             :   friend class HStoreNamedField;
    5511             :   friend class SideEffectsTracker;
    5512             :   friend std::ostream& operator<<(std::ostream& os,
    5513             :                                   const HObjectAccess& access);
    5514             : 
    5515             :   inline Portion portion() const {
    5516             :     return PortionField::decode(value_);
    5517             :   }
    5518             : };
    5519             : 
    5520             : 
    5521             : std::ostream& operator<<(std::ostream& os, const HObjectAccess& access);
    5522             : 
    5523             : 
    5524           0 : class HLoadNamedField final : public HTemplateInstruction<2> {
    5525             :  public:
    5526      614238 :   DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*,
    5527             :                                  HValue*, HObjectAccess);
    5528       21266 :   DECLARE_INSTRUCTION_FACTORY_P5(HLoadNamedField, HValue*, HValue*,
    5529             :                                  HObjectAccess, const UniqueSet<Map>*, HType);
    5530             : 
    5531             :   HValue* object() const { return OperandAt(0); }
    5532             :   HValue* dependency() const {
    5533             :     DCHECK(HasDependency());
    5534             :     return OperandAt(1);
    5535             :   }
    5536             :   bool HasDependency() const { return OperandAt(0) != OperandAt(1); }
    5537             :   HObjectAccess access() const { return access_; }
    5538             :   Representation field_representation() const {
    5539             :       return access_.representation();
    5540             :   }
    5541             : 
    5542             :   const UniqueSet<Map>* maps() const { return maps_; }
    5543             : 
    5544        4118 :   bool HasEscapingOperandAt(int index) override { return false; }
    5545        4118 :   bool HasOutOfBoundsAccess(int size) override {
    5546        8236 :     return !access().IsInobject() || access().offset() >= size;
    5547             :   }
    5548      599472 :   Representation RequiredInputRepresentation(int index) override {
    5549      599472 :     if (index == 0) {
    5550             :       // object must be external in case of external memory access
    5551             :       return access().IsExternalMemory() ? Representation::External()
    5552      301749 :                                          : Representation::Tagged();
    5553             :     }
    5554             :     DCHECK(index == 1);
    5555             :     return Representation::None();
    5556             :   }
    5557             :   Range* InferRange(Zone* zone) override;
    5558             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    5559             : 
    5560       30206 :   bool CanBeReplacedWith(HValue* other) const {
    5561       60412 :     if (!CheckFlag(HValue::kCantBeReplaced)) return false;
    5562           0 :     if (!type().Equals(other->type())) return false;
    5563           0 :     if (!representation().Equals(other->representation())) return false;
    5564           0 :     if (!other->IsLoadNamedField()) return true;
    5565             :     HLoadNamedField* that = HLoadNamedField::cast(other);
    5566           0 :     if (this->maps_ == that->maps_) return true;
    5567           0 :     if (this->maps_ == NULL || that->maps_ == NULL) return false;
    5568           0 :     return this->maps_->IsSubset(that->maps_);
    5569             :   }
    5570             : 
    5571    13481291 :   DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
    5572             : 
    5573             :  protected:
    5574       42816 :   bool DataEquals(HValue* other) override {
    5575             :     HLoadNamedField* that = HLoadNamedField::cast(other);
    5576       42816 :     if (!this->access_.Equals(that->access_)) return false;
    5577       35770 :     if (this->maps_ == that->maps_) return true;
    5578         307 :     return (this->maps_ != NULL &&
    5579         614 :             that->maps_ != NULL &&
    5580         307 :             this->maps_->Equals(that->maps_));
    5581             :   }
    5582             : 
    5583             :  private:
    5584      307119 :   HLoadNamedField(HValue* object,
    5585             :                   HValue* dependency,
    5586             :                   HObjectAccess access)
    5587      307119 :       : access_(access), maps_(NULL) {
    5588             :     DCHECK_NOT_NULL(object);
    5589      307119 :     SetOperandAt(0, object);
    5590      307119 :     SetOperandAt(1, dependency ? dependency : object);
    5591             : 
    5592      307119 :     Representation representation = access.representation();
    5593      614238 :     if (representation.IsInteger8() ||
    5594      279209 :         representation.IsUInteger8() ||
    5595      586328 :         representation.IsInteger16() ||
    5596             :         representation.IsUInteger16()) {
    5597             :       set_representation(Representation::Integer32());
    5598      279209 :     } else if (representation.IsSmi()) {
    5599             :       set_type(HType::Smi());
    5600             :       if (SmiValuesAre32Bits()) {
    5601             :         set_representation(Representation::Integer32());
    5602             :       } else {
    5603             :         set_representation(representation);
    5604             :       }
    5605      320101 :     } else if (representation.IsDouble() ||
    5606      316204 :                representation.IsExternal() ||
    5607             :                representation.IsInteger32()) {
    5608             :       set_representation(representation);
    5609      152205 :     } else if (representation.IsHeapObject()) {
    5610             :       set_type(HType::HeapObject());
    5611             :       set_representation(Representation::Tagged());
    5612             :     } else {
    5613             :       set_representation(Representation::Tagged());
    5614             :     }
    5615      307119 :     access.SetGVNFlags(this, LOAD);
    5616      307119 :   }
    5617             : 
    5618       10633 :   HLoadNamedField(HValue* object,
    5619             :                   HValue* dependency,
    5620             :                   HObjectAccess access,
    5621             :                   const UniqueSet<Map>* maps,
    5622             :                   HType type)
    5623       10633 :       : HTemplateInstruction<2>(type), access_(access), maps_(maps) {
    5624             :     DCHECK_NOT_NULL(maps);
    5625             :     DCHECK_NE(0, maps->size());
    5626             : 
    5627             :     DCHECK_NOT_NULL(object);
    5628       10633 :     SetOperandAt(0, object);
    5629       10633 :     SetOperandAt(1, dependency ? dependency : object);
    5630             : 
    5631             :     DCHECK(access.representation().IsHeapObject());
    5632             :     DCHECK(type.IsHeapObject());
    5633             :     set_representation(Representation::Tagged());
    5634             : 
    5635       10633 :     access.SetGVNFlags(this, LOAD);
    5636       10633 :   }
    5637             : 
    5638          91 :   bool IsDeletable() const override { return true; }
    5639             : 
    5640             :   HObjectAccess access_;
    5641             :   const UniqueSet<Map>* maps_;
    5642             : };
    5643             : 
    5644             : 
    5645           0 : class HLoadFunctionPrototype final : public HUnaryOperation {
    5646             :  public:
    5647        6085 :   DECLARE_INSTRUCTION_FACTORY_P1(HLoadFunctionPrototype, HValue*);
    5648             : 
    5649             :   HValue* function() { return OperandAt(0); }
    5650             : 
    5651        6051 :   Representation RequiredInputRepresentation(int index) override {
    5652        6051 :     return Representation::Tagged();
    5653             :   }
    5654             : 
    5655      150740 :   DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
    5656             : 
    5657             :  protected:
    5658           8 :   bool DataEquals(HValue* other) override { return true; }
    5659             : 
    5660             :  private:
    5661        6085 :   explicit HLoadFunctionPrototype(HValue* function)
    5662        6085 :       : HUnaryOperation(function) {
    5663             :     set_representation(Representation::Tagged());
    5664             :     SetFlag(kUseGVN);
    5665             :     SetDependsOnFlag(kCalls);
    5666        6085 :   }
    5667             : };
    5668             : 
    5669       80309 : class ArrayInstructionInterface {
    5670             :  public:
    5671             :   virtual HValue* GetKey() = 0;
    5672             :   virtual void SetKey(HValue* key) = 0;
    5673             :   virtual ElementsKind elements_kind() const = 0;
    5674             :   // TryIncreaseBaseOffset returns false if overflow would result.
    5675             :   virtual bool TryIncreaseBaseOffset(uint32_t increase_by_value) = 0;
    5676             :   virtual bool IsDehoisted() const = 0;
    5677             :   virtual void SetDehoisted(bool is_dehoisted) = 0;
    5678           0 :   virtual ~ArrayInstructionInterface() { }
    5679             : 
    5680             :   static Representation KeyedAccessIndexRequirement(Representation r) {
    5681             :     return r.IsInteger32() || SmiValuesAre32Bits()
    5682             :         ? Representation::Integer32() : Representation::Smi();
    5683             :   }
    5684             : };
    5685             : 
    5686             : 
    5687             : static const int kDefaultKeyedHeaderOffsetSentinel = -1;
    5688             : 
    5689             : enum LoadKeyedHoleMode {
    5690             :   NEVER_RETURN_HOLE,
    5691             :   ALLOW_RETURN_HOLE,
    5692             :   CONVERT_HOLE_TO_UNDEFINED
    5693             : };
    5694             : 
    5695             : 
    5696           0 : class HLoadKeyed final : public HTemplateInstruction<4>,
    5697             :                          public ArrayInstructionInterface {
    5698             :  public:
    5699        4076 :   DECLARE_INSTRUCTION_FACTORY_P5(HLoadKeyed, HValue*, HValue*, HValue*, HValue*,
    5700             :                                  ElementsKind);
    5701      100026 :   DECLARE_INSTRUCTION_FACTORY_P6(HLoadKeyed, HValue*, HValue*, HValue*, HValue*,
    5702             :                                  ElementsKind, LoadKeyedHoleMode);
    5703             :   DECLARE_INSTRUCTION_FACTORY_P7(HLoadKeyed, HValue*, HValue*, HValue*, HValue*,
    5704             :                                  ElementsKind, LoadKeyedHoleMode, int);
    5705             : 
    5706             :   bool is_fixed_typed_array() const {
    5707             :     return IsFixedTypedArrayElementsKind(elements_kind());
    5708             :   }
    5709             :   HValue* elements() const { return OperandAt(0); }
    5710             :   HValue* key() const { return OperandAt(1); }
    5711             :   HValue* dependency() const {
    5712             :     DCHECK(HasDependency());
    5713             :     return OperandAt(2);
    5714             :   }
    5715             :   bool HasDependency() const { return OperandAt(0) != OperandAt(2); }
    5716             :   HValue* backing_store_owner() const {
    5717             :     DCHECK(HasBackingStoreOwner());
    5718             :     return OperandAt(3);
    5719             :   }
    5720             :   bool HasBackingStoreOwner() const { return OperandAt(0) != OperandAt(3); }
    5721             :   uint32_t base_offset() const { return BaseOffsetField::decode(bit_field_); }
    5722             :   bool TryIncreaseBaseOffset(uint32_t increase_by_value) override;
    5723      103240 :   HValue* GetKey() override { return key(); }
    5724        8050 :   void SetKey(HValue* key) override { SetOperandAt(1, key); }
    5725           0 :   bool IsDehoisted() const override {
    5726       50531 :     return IsDehoistedField::decode(bit_field_);
    5727             :   }
    5728        8050 :   void SetDehoisted(bool is_dehoisted) override {
    5729       16100 :     bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
    5730        8050 :   }
    5731        9246 :   ElementsKind elements_kind() const override {
    5732      263701 :     return ElementsKindField::decode(bit_field_);
    5733             :   }
    5734             :   LoadKeyedHoleMode hole_mode() const {
    5735             :     return HoleModeField::decode(bit_field_);
    5736             :   }
    5737             : 
    5738      299252 :   Representation RequiredInputRepresentation(int index) override {
    5739             :     // kind_fast:                 tagged[int32] (none)
    5740             :     // kind_double:               tagged[int32] (none)
    5741             :     // kind_fixed_typed_array:    external[int32] (none)
    5742             :     // kind_external:             external[int32] (none)
    5743      243601 :     if (index == 0) {
    5744             :       return is_fixed_typed_array() ? Representation::External()
    5745       55651 :                                     : Representation::Tagged();
    5746             :     }
    5747      187950 :     if (index == 1) {
    5748             :       return ArrayInstructionInterface::KeyedAccessIndexRequirement(
    5749             :           OperandAt(1)->representation());
    5750             :     }
    5751      108966 :     if (index == 2) {
    5752             :       return Representation::None();
    5753             :     }
    5754             :     DCHECK_EQ(3, index);
    5755             :     return HasBackingStoreOwner() ? Representation::Tagged()
    5756       53701 :                                   : Representation::None();
    5757             :   }
    5758             : 
    5759       32892 :   Representation observed_input_representation(int index) override {
    5760       32892 :     return RequiredInputRepresentation(index);
    5761             :   }
    5762             : 
    5763             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    5764             : 
    5765             :   bool UsesMustHandleHole() const;
    5766             :   bool AllUsesCanTreatHoleAsNaN() const;
    5767             :   bool RequiresHoleCheck() const;
    5768             : 
    5769             :   Range* InferRange(Zone* zone) override;
    5770             : 
    5771     3786641 :   DECLARE_CONCRETE_INSTRUCTION(LoadKeyed)
    5772             : 
    5773             :  protected:
    5774         462 :   bool DataEquals(HValue* other) override {
    5775         231 :     if (!other->IsLoadKeyed()) return false;
    5776         231 :     HLoadKeyed* other_load = HLoadKeyed::cast(other);
    5777             : 
    5778         231 :     if (base_offset() != other_load->base_offset()) return false;
    5779         231 :     return elements_kind() == other_load->elements_kind();
    5780             :   }
    5781             : 
    5782             :  private:
    5783       52051 :   HLoadKeyed(HValue* obj, HValue* key, HValue* dependency,
    5784             :              HValue* backing_store_owner, ElementsKind elements_kind,
    5785             :              LoadKeyedHoleMode mode = NEVER_RETURN_HOLE,
    5786       52051 :              int offset = kDefaultKeyedHeaderOffsetSentinel)
    5787       52051 :       : bit_field_(0) {
    5788             :     offset = offset == kDefaultKeyedHeaderOffsetSentinel
    5789             :         ? GetDefaultHeaderSizeForElementsKind(elements_kind)
    5790       52051 :         : offset;
    5791       52051 :     bit_field_ = ElementsKindField::encode(elements_kind) |
    5792       52051 :         HoleModeField::encode(mode) |
    5793      104102 :         BaseOffsetField::encode(offset);
    5794             : 
    5795       52051 :     SetOperandAt(0, obj);
    5796       52051 :     SetOperandAt(1, key);
    5797       52051 :     SetOperandAt(2, dependency != nullptr ? dependency : obj);
    5798       52051 :     SetOperandAt(3, backing_store_owner != nullptr ? backing_store_owner : obj);
    5799             :     DCHECK_EQ(HasBackingStoreOwner(), is_fixed_typed_array());
    5800             : 
    5801       52051 :     if (!is_fixed_typed_array()) {
    5802             :       // I can detect the case between storing double (holey and fast) and
    5803             :       // smi/object by looking at elements_kind_.
    5804             :       DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
    5805             :              IsFastDoubleElementsKind(elements_kind));
    5806             : 
    5807       49949 :       if (IsFastSmiOrObjectElementsKind(elements_kind)) {
    5808       96155 :         if (IsFastSmiElementsKind(elements_kind) &&
    5809         578 :             (!IsHoleyElementsKind(elements_kind) ||
    5810             :              mode == NEVER_RETURN_HOLE)) {
    5811             :           set_type(HType::Smi());
    5812        7800 :           if (SmiValuesAre32Bits() && !RequiresHoleCheck()) {
    5813             :             set_representation(Representation::Integer32());
    5814             :           } else {
    5815             :             set_representation(Representation::Smi());
    5816             :           }
    5817             :         } else {
    5818             :           set_representation(Representation::Tagged());
    5819             :         }
    5820             : 
    5821             :         SetDependsOnFlag(kArrayElements);
    5822             :       } else {
    5823             :         set_representation(Representation::Double());
    5824             :         SetDependsOnFlag(kDoubleArrayElements);
    5825             :       }
    5826             :     } else {
    5827        2102 :       if (elements_kind == FLOAT32_ELEMENTS ||
    5828             :           elements_kind == FLOAT64_ELEMENTS) {
    5829             :         set_representation(Representation::Double());
    5830             :       } else {
    5831             :         set_representation(Representation::Integer32());
    5832             :       }
    5833             : 
    5834        2102 :       if (is_fixed_typed_array()) {
    5835             :         SetDependsOnFlag(kExternalMemory);
    5836             :         SetDependsOnFlag(kTypedArrayElements);
    5837             :       } else {
    5838           0 :         UNREACHABLE();
    5839             :       }
    5840             :       // Native code could change the specialized array.
    5841             :       SetDependsOnFlag(kCalls);
    5842             :     }
    5843             : 
    5844             :     SetFlag(kUseGVN);
    5845       52051 :   }
    5846             : 
    5847          15 :   bool IsDeletable() const override { return !RequiresHoleCheck(); }
    5848             : 
    5849             :   // Establish some checks around our packed fields
    5850             :   enum LoadKeyedBits {
    5851             :     kBitsForElementsKind = 5,
    5852             :     kBitsForHoleMode = 2,
    5853             :     kBitsForBaseOffset = 24,
    5854             :     kBitsForIsDehoisted = 1,
    5855             : 
    5856             :     kStartElementsKind = 0,
    5857             :     kStartHoleMode = kStartElementsKind + kBitsForElementsKind,
    5858             :     kStartBaseOffset = kStartHoleMode + kBitsForHoleMode,
    5859             :     kStartIsDehoisted = kStartBaseOffset + kBitsForBaseOffset
    5860             :   };
    5861             : 
    5862             :   STATIC_ASSERT((kBitsForElementsKind + kBitsForHoleMode + kBitsForBaseOffset +
    5863             :                  kBitsForIsDehoisted) <= sizeof(uint32_t) * 8);
    5864             :   STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind));
    5865             :   class ElementsKindField:
    5866             :     public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind>
    5867             :     {};  // NOLINT
    5868             :   class HoleModeField:
    5869             :     public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode>
    5870             :     {};  // NOLINT
    5871             :   class BaseOffsetField:
    5872             :     public BitField<uint32_t, kStartBaseOffset, kBitsForBaseOffset>
    5873             :     {};  // NOLINT
    5874             :   class IsDehoistedField:
    5875             :     public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted>
    5876             :     {};  // NOLINT
    5877             :   uint32_t bit_field_;
    5878             : };
    5879             : 
    5880             : 
    5881             : // Indicates whether the store is a store to an entry that was previously
    5882             : // initialized or not.
    5883             : enum StoreFieldOrKeyedMode {
    5884             :   // The entry could be either previously initialized or not.
    5885             :   INITIALIZING_STORE,
    5886             :   // At the time of this store it is guaranteed that the entry is already
    5887             :   // initialized.
    5888             :   STORE_TO_INITIALIZED_ENTRY
    5889             : };
    5890             : 
    5891             : 
    5892           0 : class HStoreNamedField final : public HTemplateInstruction<3> {
    5893             :  public:
    5894      458194 :   DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
    5895             :                                  HObjectAccess, HValue*);
    5896       44968 :   DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*,
    5897             :                                  HObjectAccess, HValue*, StoreFieldOrKeyedMode);
    5898             : 
    5899     2667699 :   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
    5900             : 
    5901       11314 :   bool HasEscapingOperandAt(int index) override { return index == 1; }
    5902        9325 :   bool HasOutOfBoundsAccess(int size) override {
    5903       18650 :     return !access().IsInobject() || access().offset() >= size;
    5904             :   }
    5905      671873 :   Representation RequiredInputRepresentation(int index) override {
    5906      789861 :     if (index == 0 && access().IsExternalMemory()) {
    5907             :       // object must be external in case of external memory access
    5908             :       return Representation::External();
    5909      601012 :     } else if (index == 1) {
    5910      449178 :       if (field_representation().IsInteger8() ||
    5911      224589 :           field_representation().IsUInteger8() ||
    5912      224589 :           field_representation().IsInteger16() ||
    5913      449178 :           field_representation().IsUInteger16() ||
    5914             :           field_representation().IsInteger32()) {
    5915             :         return Representation::Integer32();
    5916      211170 :       } else if (field_representation().IsDouble()) {
    5917             :         return field_representation();
    5918      210821 :       } else if (field_representation().IsSmi()) {
    5919       70861 :         if (SmiValuesAre32Bits() &&
    5920             :             store_mode() == STORE_TO_INITIALIZED_ENTRY) {
    5921             :           return Representation::Integer32();
    5922             :         }
    5923             :         return field_representation();
    5924      139960 :       } else if (field_representation().IsExternal()) {
    5925             :         return Representation::External();
    5926             :       }
    5927             :     }
    5928             :     return Representation::Tagged();
    5929             :   }
    5930      237985 :   bool HandleSideEffectDominator(GVNFlag side_effect,
    5931             :                                  HValue* dominator) override {
    5932             :     DCHECK(side_effect == kNewSpacePromotion);
    5933      237985 :     if (!FLAG_use_write_barrier_elimination) return false;
    5934      237985 :     dominator_ = dominator;
    5935      237985 :     return false;
    5936             :   }
    5937             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    5938             : 
    5939             :   HValue* object() const { return OperandAt(0); }
    5940             :   HValue* value() const { return OperandAt(1); }
    5941             :   HValue* transition() const { return OperandAt(2); }
    5942             : 
    5943             :   HObjectAccess access() const { return access_; }
    5944             :   HValue* dominator() const { return dominator_; }
    5945             :   bool has_transition() const { return HasTransitionField::decode(bit_field_); }
    5946             :   StoreFieldOrKeyedMode store_mode() const {
    5947             :     return StoreModeField::decode(bit_field_);
    5948             :   }
    5949             : 
    5950        9704 :   Handle<Map> transition_map() const {
    5951        9704 :     if (has_transition()) {
    5952             :       return Handle<Map>::cast(
    5953       19408 :           HConstant::cast(transition())->handle(isolate()));
    5954             :     } else {
    5955           0 :       return Handle<Map>();
    5956             :     }
    5957             :   }
    5958             : 
    5959       11394 :   void SetTransition(HConstant* transition) {
    5960             :     DCHECK(!has_transition());  // Only set once.
    5961       11394 :     SetOperandAt(2, transition);
    5962       22788 :     bit_field_ = HasTransitionField::update(bit_field_, true);
    5963             :     SetChangesFlag(kMaps);
    5964       11394 :   }
    5965             : 
    5966      490814 :   bool NeedsWriteBarrier() const {
    5967             :     DCHECK(!field_representation().IsDouble() ||
    5968             :            (FLAG_unbox_double_fields && access_.IsInobject()) ||
    5969             :            !has_transition());
    5970      357703 :     if (field_representation().IsDouble()) return false;
    5971      357157 :     if (field_representation().IsSmi()) return false;
    5972      273890 :     if (field_representation().IsInteger32()) return false;
    5973      247923 :     if (field_representation().IsExternal()) return false;
    5974      381034 :     return StoringValueNeedsWriteBarrier(value()) &&
    5975      381034 :         ReceiverObjectNeedsWriteBarrier(object(), value(), dominator());
    5976             :   }
    5977             : 
    5978       20809 :   bool NeedsWriteBarrierForMap() {
    5979             :     return ReceiverObjectNeedsWriteBarrier(object(), transition(),
    5980       20809 :                                            dominator());
    5981             :   }
    5982             : 
    5983             :   SmiCheck SmiCheckForWriteBarrier() const {
    5984       14802 :     if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK;
    5985        5084 :     if (value()->type().IsHeapObject()) return OMIT_SMI_CHECK;
    5986             :     return INLINE_SMI_CHECK;
    5987             :   }
    5988             : 
    5989       14802 :   PointersToHereCheck PointersToHereCheckForValue() const {
    5990       14802 :     return PointersToHereCheckForObject(value(), dominator());
    5991             :   }
    5992             : 
    5993             :   Representation field_representation() const {
    5994      939410 :     return access_.representation();
    5995             :   }
    5996             : 
    5997             :   void UpdateValue(HValue* value) {
    5998             :     SetOperandAt(1, value);
    5999             :   }
    6000             : 
    6001         290 :   bool CanBeReplacedWith(HStoreNamedField* that) const {
    6002         290 :     if (!this->access().Equals(that->access())) return false;
    6003           0 :     if (SmiValuesAre32Bits() &&
    6004           0 :         this->field_representation().IsSmi() &&
    6005           0 :         this->store_mode() == INITIALIZING_STORE &&
    6006             :         that->store_mode() == STORE_TO_INITIALIZED_ENTRY) {
    6007             :       // We cannot replace an initializing store to a smi field with a store to
    6008             :       // an initialized entry on 64-bit architectures (with 32-bit smis).
    6009             :       return false;
    6010             :     }
    6011           0 :     return true;
    6012             :   }
    6013             : 
    6014             :  private:
    6015      251581 :   HStoreNamedField(HValue* obj, HObjectAccess access, HValue* val,
    6016             :                    StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
    6017             :       : access_(access),
    6018             :         dominator_(NULL),
    6019             :         bit_field_(HasTransitionField::encode(false) |
    6020      503162 :                    StoreModeField::encode(store_mode)) {
    6021             :     // Stores to a non existing in-object property are allowed only to the
    6022             :     // newly allocated objects (via HAllocate or HInnerAllocatedObject).
    6023             :     DCHECK(!access.IsInobject() || access.existing_inobject_property() ||
    6024             :            obj->IsAllocate() || obj->IsInnerAllocatedObject());
    6025      251581 :     SetOperandAt(0, obj);
    6026      251581 :     SetOperandAt(1, val);
    6027      251581 :     SetOperandAt(2, obj);
    6028      251581 :     access.SetGVNFlags(this, STORE);
    6029      251581 :   }
    6030             : 
    6031             :   class HasTransitionField : public BitField<bool, 0, 1> {};
    6032             :   class StoreModeField : public BitField<StoreFieldOrKeyedMode, 1, 1> {};
    6033             : 
    6034             :   HObjectAccess access_;
    6035             :   HValue* dominator_;
    6036             :   uint32_t bit_field_;
    6037             : };
    6038             : 
    6039           0 : class HStoreKeyed final : public HTemplateInstruction<4>,
    6040             :                           public ArrayInstructionInterface {
    6041             :  public:
    6042       39370 :   DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*,
    6043             :                                  HValue*, ElementsKind);
    6044       17146 :   DECLARE_INSTRUCTION_FACTORY_P6(HStoreKeyed, HValue*, HValue*, HValue*,
    6045             :                                  HValue*, ElementsKind, StoreFieldOrKeyedMode);
    6046             :   DECLARE_INSTRUCTION_FACTORY_P7(HStoreKeyed, HValue*, HValue*, HValue*,
    6047             :                                  HValue*, ElementsKind, StoreFieldOrKeyedMode,
    6048             :                                  int);
    6049             : 
    6050      229454 :   Representation RequiredInputRepresentation(int index) override {
    6051             :     // kind_fast:               tagged[int32] = tagged
    6052             :     // kind_double:             tagged[int32] = double
    6053             :     // kind_smi   :             tagged[int32] = smi
    6054             :     // kind_fixed_typed_array:  tagged[int32] = (double | int32)
    6055             :     // kind_external:           external[int32] = (double | int32)
    6056      151721 :     if (index == 0) {
    6057             :       return is_fixed_typed_array() ? Representation::External()
    6058       43669 :                                     : Representation::Tagged();
    6059      108052 :     } else if (index == 1) {
    6060             :       return ArrayInstructionInterface::KeyedAccessIndexRequirement(
    6061             :           OperandAt(1)->representation());
    6062       76032 :     } else if (index == 2) {
    6063       34064 :       return RequiredValueRepresentation(elements_kind(), store_mode());
    6064             :     }
    6065             : 
    6066             :     DCHECK_EQ(3, index);
    6067             :     return HasBackingStoreOwner() ? Representation::Tagged()
    6068       41968 :                                   : Representation::None();
    6069             :   }
    6070             : 
    6071       40026 :   static Representation RequiredValueRepresentation(
    6072             :       ElementsKind kind, StoreFieldOrKeyedMode mode) {
    6073       40026 :     if (IsDoubleOrFloatElementsKind(kind)) {
    6074             :       return Representation::Double();
    6075             :     }
    6076             : 
    6077       32698 :     if (kind == FAST_SMI_ELEMENTS && SmiValuesAre32Bits() &&
    6078             :         mode == STORE_TO_INITIALIZED_ENTRY) {
    6079             :       return Representation::Integer32();
    6080             :     }
    6081             : 
    6082       30201 :     if (IsFastSmiElementsKind(kind)) {
    6083             :       return Representation::Smi();
    6084             :     }
    6085             : 
    6086       20296 :     if (IsFixedTypedArrayElementsKind(kind)) {
    6087             :       return Representation::Integer32();
    6088             :     }
    6089             :     return Representation::Tagged();
    6090             :   }
    6091             : 
    6092          13 :   bool is_fixed_typed_array() const {
    6093          13 :     return IsFixedTypedArrayElementsKind(elements_kind());
    6094             :   }
    6095             : 
    6096       29332 :   Representation observed_input_representation(int index) override {
    6097       25976 :     if (index != 2) return RequiredInputRepresentation(index);
    6098        3356 :     if (IsUninitialized()) {
    6099             :       return Representation::None();
    6100             :     }
    6101             :     Representation r =
    6102        3356 :         RequiredValueRepresentation(elements_kind(), store_mode());
    6103             :     // For fast object elements kinds, don't assume anything.
    6104        3356 :     if (r.IsTagged()) return Representation::None();
    6105         603 :     return r;
    6106             :   }
    6107             : 
    6108             :   HValue* elements() const { return OperandAt(0); }
    6109             :   HValue* key() const { return OperandAt(1); }
    6110          12 :   HValue* value() const { return OperandAt(2); }
    6111             :   HValue* backing_store_owner() const {
    6112             :     DCHECK(HasBackingStoreOwner());
    6113             :     return OperandAt(3);
    6114             :   }
    6115             :   bool HasBackingStoreOwner() const { return OperandAt(0) != OperandAt(3); }
    6116             :   bool value_is_smi() const { return IsFastSmiElementsKind(elements_kind()); }
    6117             :   StoreFieldOrKeyedMode store_mode() const {
    6118             :     return StoreModeField::decode(bit_field_);
    6119             :   }
    6120        2870 :   ElementsKind elements_kind() const override {
    6121       35501 :     return ElementsKindField::decode(bit_field_);
    6122             :   }
    6123             :   uint32_t base_offset() const { return base_offset_; }
    6124             :   bool TryIncreaseBaseOffset(uint32_t increase_by_value) override;
    6125       56228 :   HValue* GetKey() override { return key(); }
    6126        1199 :   void SetKey(HValue* key) override { SetOperandAt(1, key); }
    6127           0 :   bool IsDehoisted() const override {
    6128           0 :     return IsDehoistedField::decode(bit_field_);
    6129             :   }
    6130        1199 :   void SetDehoisted(bool is_dehoisted) override {
    6131        2398 :     bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
    6132        1199 :   }
    6133             :   bool IsUninitialized() { return IsUninitializedField::decode(bit_field_); }
    6134             :   void SetUninitialized(bool is_uninitialized) {
    6135             :     bit_field_ = IsUninitializedField::update(bit_field_, is_uninitialized);
    6136             :   }
    6137             : 
    6138             :   bool IsConstantHoleStore() {
    6139             :     return value()->IsConstant() && HConstant::cast(value())->IsTheHole();
    6140             :   }
    6141             : 
    6142       13771 :   bool HandleSideEffectDominator(GVNFlag side_effect,
    6143             :                                  HValue* dominator) override {
    6144             :     DCHECK(side_effect == kNewSpacePromotion);
    6145       13771 :     dominator_ = dominator;
    6146       13771 :     return false;
    6147             :   }
    6148             : 
    6149             :   HValue* dominator() const { return dominator_; }
    6150             : 
    6151       70748 :   bool NeedsWriteBarrier() {
    6152       46152 :     if (value_is_smi()) {
    6153             :       return false;
    6154             :     } else {
    6155       53578 :       return StoringValueNeedsWriteBarrier(value()) &&
    6156       53578 :           ReceiverObjectNeedsWriteBarrier(elements(), value(), dominator());
    6157             :     }
    6158             :   }
    6159             : 
    6160        6530 :   PointersToHereCheck PointersToHereCheckForValue() const {
    6161        6530 :     return PointersToHereCheckForObject(value(), dominator());
    6162             :   }
    6163             : 
    6164             :   bool NeedsCanonicalization();
    6165             : 
    6166             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    6167             : 
    6168      403648 :   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
    6169             : 
    6170             :  private:
    6171       28258 :   HStoreKeyed(HValue* obj, HValue* key, HValue* val,
    6172             :               HValue* backing_store_owner, ElementsKind elements_kind,
    6173             :               StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE,
    6174       13640 :               int offset = kDefaultKeyedHeaderOffsetSentinel)
    6175             :       : base_offset_(offset == kDefaultKeyedHeaderOffsetSentinel
    6176       28258 :                          ? GetDefaultHeaderSizeForElementsKind(elements_kind)
    6177             :                          : offset),
    6178             :         bit_field_(IsDehoistedField::encode(false) |
    6179             :                    IsUninitializedField::encode(false) |
    6180       28258 :                    StoreModeField::encode(store_mode) |
    6181             :                    ElementsKindField::encode(elements_kind)),
    6182       84774 :         dominator_(NULL) {
    6183       28258 :     SetOperandAt(0, obj);
    6184       28258 :     SetOperandAt(1, key);
    6185       28258 :     SetOperandAt(2, val);
    6186       28258 :     SetOperandAt(3, backing_store_owner != nullptr ? backing_store_owner : obj);
    6187             :     DCHECK_EQ(HasBackingStoreOwner(), is_fixed_typed_array());
    6188             : 
    6189       28258 :     if (IsFastObjectElementsKind(elements_kind)) {
    6190             :       SetFlag(kTrackSideEffectDominators);
    6191             :       SetDependsOnFlag(kNewSpacePromotion);
    6192             :     }
    6193       28258 :     if (IsFastDoubleElementsKind(elements_kind)) {
    6194             :       SetChangesFlag(kDoubleArrayElements);
    6195       22287 :     } else if (IsFastSmiElementsKind(elements_kind)) {
    6196             :       SetChangesFlag(kArrayElements);
    6197       13640 :     } else if (is_fixed_typed_array()) {
    6198             :       SetChangesFlag(kTypedArrayElements);
    6199             :       SetChangesFlag(kExternalMemory);
    6200             :       SetFlag(kTruncatingToNumber);
    6201             :     } else {
    6202             :       SetChangesFlag(kArrayElements);
    6203             :     }
    6204             : 
    6205             :     // {UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
    6206       28258 :     if (elements_kind >= UINT8_ELEMENTS && elements_kind <= INT32_ELEMENTS) {
    6207             :       SetFlag(kTruncatingToInt32);
    6208             :     }
    6209       28258 :   }
    6210             : 
    6211             :   class IsDehoistedField : public BitField<bool, 0, 1> {};
    6212             :   class IsUninitializedField : public BitField<bool, 1, 1> {};
    6213             :   class StoreModeField : public BitField<StoreFieldOrKeyedMode, 2, 1> {};
    6214             :   class ElementsKindField : public BitField<ElementsKind, 3, 5> {};
    6215             : 
    6216             :   uint32_t base_offset_;
    6217             :   uint32_t bit_field_;
    6218             :   HValue* dominator_;
    6219             : };
    6220             : 
    6221           0 : class HTransitionElementsKind final : public HTemplateInstruction<2> {
    6222             :  public:
    6223         806 :   inline static HTransitionElementsKind* New(Isolate* isolate, Zone* zone,
    6224             :                                              HValue* context, HValue* object,
    6225             :                                              Handle<Map> original_map,
    6226             :                                              Handle<Map> transitioned_map) {
    6227             :     return new(zone) HTransitionElementsKind(context, object,
    6228        1612 :                                              original_map, transitioned_map);
    6229             :   }
    6230             : 
    6231        1687 :   Representation RequiredInputRepresentation(int index) override {
    6232        1687 :     return Representation::Tagged();
    6233             :   }
    6234             : 
    6235             :   HValue* object() const { return OperandAt(0); }
    6236             :   HValue* context() const { return OperandAt(1); }
    6237             :   Unique<Map> original_map() const { return original_map_; }
    6238             :   Unique<Map> transitioned_map() const { return transitioned_map_; }
    6239             :   ElementsKind from_kind() const {
    6240             :     return FromElementsKindField::decode(bit_field_);
    6241             :   }
    6242             :   ElementsKind to_kind() const {
    6243             :     return ToElementsKindField::decode(bit_field_);
    6244             :   }
    6245             :   bool map_is_stable() const { return MapIsStableField::decode(bit_field_); }
    6246             : 
    6247             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    6248             : 
    6249       19258 :   DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
    6250             : 
    6251             :  protected:
    6252         610 :   bool DataEquals(HValue* other) override {
    6253             :     HTransitionElementsKind* instr = HTransitionElementsKind::cast(other);
    6254         647 :     return original_map_ == instr->original_map_ &&
    6255         647 :            transitioned_map_ == instr->transitioned_map_;
    6256             :   }
    6257             : 
    6258        1508 :   int RedefinedOperandIndex() override { return 0; }
    6259             : 
    6260             :  private:
    6261         806 :   HTransitionElementsKind(HValue* context, HValue* object,
    6262             :                           Handle<Map> original_map,
    6263         806 :                           Handle<Map> transitioned_map)
    6264             :       : original_map_(Unique<Map>(original_map)),
    6265             :         transitioned_map_(Unique<Map>(transitioned_map)),
    6266             :         bit_field_(
    6267         806 :             FromElementsKindField::encode(original_map->elements_kind()) |
    6268         806 :             ToElementsKindField::encode(transitioned_map->elements_kind()) |
    6269        1612 :             MapIsStableField::encode(transitioned_map->is_stable())) {
    6270         806 :     SetOperandAt(0, object);
    6271         806 :     SetOperandAt(1, context);
    6272             :     SetFlag(kUseGVN);
    6273             :     SetChangesFlag(kElementsKind);
    6274         806 :     if (!IsSimpleMapChangeTransition(from_kind(), to_kind())) {
    6275             :       SetChangesFlag(kElementsPointer);
    6276             :       SetChangesFlag(kNewSpacePromotion);
    6277             :     }
    6278             :     set_representation(Representation::Tagged());
    6279         806 :   }
    6280             : 
    6281             :   class FromElementsKindField : public BitField<ElementsKind, 0, 5> {};
    6282             :   class ToElementsKindField : public BitField<ElementsKind, 5, 5> {};
    6283             :   class MapIsStableField : public BitField<bool, 10, 1> {};
    6284             : 
    6285             :   Unique<Map> original_map_;
    6286             :   Unique<Map> transitioned_map_;
    6287             :   uint32_t bit_field_;
    6288             : };
    6289             : 
    6290             : 
    6291           0 : class HStringAdd final : public HBinaryOperation {
    6292             :  public:
    6293             :   static HInstruction* New(
    6294             :       Isolate* isolate, Zone* zone, HValue* context, HValue* left,
    6295             :       HValue* right, PretenureFlag pretenure_flag = NOT_TENURED,
    6296             :       StringAddFlags flags = STRING_ADD_CHECK_BOTH,
    6297             :       Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());
    6298             : 
    6299             :   StringAddFlags flags() const { return flags_; }
    6300             :   PretenureFlag pretenure_flag() const { return pretenure_flag_; }
    6301             : 
    6302       73453 :   Representation RequiredInputRepresentation(int index) override {
    6303       73453 :     return Representation::Tagged();
    6304             :   }
    6305             : 
    6306             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    6307             : 
    6308     1115981 :   DECLARE_CONCRETE_INSTRUCTION(StringAdd)
    6309             : 
    6310             :  protected:
    6311          30 :   bool DataEquals(HValue* other) override {
    6312          60 :     return flags_ == HStringAdd::cast(other)->flags_ &&
    6313          60 :         pretenure_flag_ == HStringAdd::cast(other)->pretenure_flag_;
    6314             :   }
    6315             : 
    6316             :  private:
    6317       26857 :   HStringAdd(HValue* context, HValue* left, HValue* right,
    6318             :              PretenureFlag pretenure_flag, StringAddFlags flags,
    6319             :              Handle<AllocationSite> allocation_site)
    6320             :       : HBinaryOperation(context, left, right, HType::String()),
    6321             :         flags_(flags),
    6322       26857 :         pretenure_flag_(pretenure_flag) {
    6323             :     set_representation(Representation::Tagged());
    6324       26857 :     if ((flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT) {
    6325             :       SetAllSideEffects();
    6326             :       ClearFlag(kUseGVN);
    6327             :     } else {
    6328             :       SetChangesFlag(kNewSpacePromotion);
    6329             :       SetFlag(kUseGVN);
    6330             :     }
    6331             :     SetDependsOnFlag(kMaps);
    6332       26857 :     if (FLAG_trace_pretenuring) {
    6333             :       PrintF("HStringAdd with AllocationSite %p %s\n",
    6334             :              allocation_site.is_null()
    6335             :                  ? static_cast<void*>(NULL)
    6336             :                  : static_cast<void*>(*allocation_site),
    6337           0 :              pretenure_flag == TENURED ? "tenured" : "not tenured");
    6338             :     }
    6339       26857 :   }
    6340             : 
    6341          48 :   bool IsDeletable() const final {
    6342          48 :     return (flags_ & STRING_ADD_CONVERT) != STRING_ADD_CONVERT;
    6343             :   }
    6344             : 
    6345             :   const StringAddFlags flags_;
    6346             :   const PretenureFlag pretenure_flag_;
    6347             : };
    6348             : 
    6349             : 
    6350           0 : class HStringCharCodeAt final : public HTemplateInstruction<3> {
    6351             :  public:
    6352         377 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HStringCharCodeAt,
    6353             :                                               HValue*,
    6354             :                                               HValue*);
    6355             : 
    6356        1179 :   Representation RequiredInputRepresentation(int index) override {
    6357             :     // The index is supposed to be Integer32.
    6358             :     return index == 2
    6359             :         ? Representation::Integer32()
    6360        1179 :         : Representation::Tagged();
    6361             :   }
    6362             : 
    6363             :   HValue* context() const { return OperandAt(0); }
    6364             :   HValue* string() const { return OperandAt(1); }
    6365             :   HValue* index() const { return OperandAt(2); }
    6366             : 
    6367       14715 :   DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
    6368             : 
    6369             :  protected:
    6370           0 :   bool DataEquals(HValue* other) override { return true; }
    6371             : 
    6372         377 :   Range* InferRange(Zone* zone) override {
    6373         377 :     return new(zone) Range(0, String::kMaxUtf16CodeUnit);
    6374             :   }
    6375             : 
    6376             :  private:
    6377         754 :   HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
    6378         377 :     SetOperandAt(0, context);
    6379         377 :     SetOperandAt(1, string);
    6380         377 :     SetOperandAt(2, index);
    6381             :     set_representation(Representation::Integer32());
    6382             :     SetFlag(kUseGVN);
    6383             :     SetDependsOnFlag(kMaps);
    6384             :     SetDependsOnFlag(kStringChars);
    6385             :     SetChangesFlag(kNewSpacePromotion);
    6386         377 :   }
    6387             : 
    6388             :   // No side effects: runtime function assumes string + number inputs.
    6389           0 :   bool IsDeletable() const override { return true; }
    6390             : };
    6391             : 
    6392             : 
    6393           0 : class HStringCharFromCode final : public HTemplateInstruction<2> {
    6394             :  public:
    6395             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    6396             :                            HValue* char_code);
    6397             : 
    6398        1084 :   Representation RequiredInputRepresentation(int index) override {
    6399             :     return index == 0
    6400             :         ? Representation::Tagged()
    6401        1084 :         : Representation::Integer32();
    6402             :   }
    6403             : 
    6404             :   HValue* context() const { return OperandAt(0); }
    6405             :   HValue* value() const { return OperandAt(1); }
    6406             : 
    6407          18 :   bool DataEquals(HValue* other) override { return true; }
    6408             : 
    6409      119995 :   DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
    6410             : 
    6411             :  private:
    6412         506 :   HStringCharFromCode(HValue* context, HValue* char_code)
    6413         506 :       : HTemplateInstruction<2>(HType::String()) {
    6414         506 :     SetOperandAt(0, context);
    6415         506 :     SetOperandAt(1, char_code);
    6416             :     set_representation(Representation::Tagged());
    6417             :     SetFlag(kUseGVN);
    6418             :     SetChangesFlag(kNewSpacePromotion);
    6419         506 :   }
    6420             : 
    6421           0 :   bool IsDeletable() const override {
    6422           0 :     return !value()->ToNumberCanBeObserved();
    6423             :   }
    6424             : };
    6425             : 
    6426             : 
    6427           0 : class HTypeof final : public HTemplateInstruction<2> {
    6428             :  public:
    6429       40359 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HTypeof, HValue*);
    6430             : 
    6431             :   HValue* context() const { return OperandAt(0); }
    6432             :   HValue* value() const { return OperandAt(1); }
    6433             : 
    6434             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    6435             : 
    6436       91503 :   Representation RequiredInputRepresentation(int index) override {
    6437       91503 :     return Representation::Tagged();
    6438             :   }
    6439             : 
    6440      982565 :   DECLARE_CONCRETE_INSTRUCTION(Typeof)
    6441             : 
    6442             :  private:
    6443       80718 :   explicit HTypeof(HValue* context, HValue* value) {
    6444       40359 :     SetOperandAt(0, context);
    6445       40359 :     SetOperandAt(1, value);
    6446             :     set_representation(Representation::Tagged());
    6447       40359 :   }
    6448             : 
    6449          28 :   bool IsDeletable() const override { return true; }
    6450             : };
    6451             : 
    6452             : 
    6453           0 : class HTrapAllocationMemento final : public HTemplateInstruction<1> {
    6454             :  public:
    6455          37 :   DECLARE_INSTRUCTION_FACTORY_P1(HTrapAllocationMemento, HValue*);
    6456             : 
    6457          37 :   Representation RequiredInputRepresentation(int index) override {
    6458          37 :     return Representation::Tagged();
    6459             :   }
    6460             : 
    6461             :   HValue* object() { return OperandAt(0); }
    6462             : 
    6463         444 :   DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento)
    6464             : 
    6465             :  private:
    6466          74 :   explicit HTrapAllocationMemento(HValue* obj) {
    6467          37 :     SetOperandAt(0, obj);
    6468          37 :   }
    6469             : };
    6470             : 
    6471             : 
    6472           0 : class HMaybeGrowElements final : public HTemplateInstruction<5> {
    6473             :  public:
    6474        2606 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P6(HMaybeGrowElements, HValue*,
    6475             :                                               HValue*, HValue*, HValue*, bool,
    6476             :                                               ElementsKind);
    6477             : 
    6478       13380 :   Representation RequiredInputRepresentation(int index) override {
    6479       13380 :     if (index < 3) {
    6480             :       return Representation::Tagged();
    6481             :     }
    6482             :     DCHECK(index == 3 || index == 4);
    6483             :     return Representation::Integer32();
    6484             :   }
    6485             : 
    6486             :   HValue* context() const { return OperandAt(0); }
    6487             :   HValue* object() const { return OperandAt(1); }
    6488             :   HValue* elements() const { return OperandAt(2); }
    6489             :   HValue* key() const { return OperandAt(3); }
    6490             :   HValue* current_capacity() const { return OperandAt(4); }
    6491             : 
    6492             :   bool is_js_array() const { return is_js_array_; }
    6493             :   ElementsKind kind() const { return kind_; }
    6494             : 
    6495      107999 :   DECLARE_CONCRETE_INSTRUCTION(MaybeGrowElements)
    6496             : 
    6497             :  protected:
    6498           0 :   bool DataEquals(HValue* other) override { return true; }
    6499             : 
    6500             :  private:
    6501        2606 :   explicit HMaybeGrowElements(HValue* context, HValue* object, HValue* elements,
    6502             :                               HValue* key, HValue* current_capacity,
    6503        2606 :                               bool is_js_array, ElementsKind kind) {
    6504        2606 :     is_js_array_ = is_js_array;
    6505        2606 :     kind_ = kind;
    6506             : 
    6507        2606 :     SetOperandAt(0, context);
    6508        2606 :     SetOperandAt(1, object);
    6509        2606 :     SetOperandAt(2, elements);
    6510        2606 :     SetOperandAt(3, key);
    6511        2606 :     SetOperandAt(4, current_capacity);
    6512             : 
    6513             :     SetFlag(kUseGVN);
    6514             :     SetChangesFlag(kElementsPointer);
    6515             :     SetChangesFlag(kNewSpacePromotion);
    6516             :     set_representation(Representation::Tagged());
    6517        2606 :   }
    6518             : 
    6519             :   bool is_js_array_;
    6520             :   ElementsKind kind_;
    6521             : };
    6522             : 
    6523             : 
    6524           0 : class HSeqStringGetChar final : public HTemplateInstruction<2> {
    6525             :  public:
    6526             :   static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
    6527             :                            String::Encoding encoding, HValue* string,
    6528             :                            HValue* index);
    6529             : 
    6530       31788 :   Representation RequiredInputRepresentation(int index) override {
    6531             :     return (index == 0) ? Representation::Tagged()
    6532       31788 :                         : Representation::Integer32();
    6533             :   }
    6534             : 
    6535             :   String::Encoding encoding() const { return encoding_; }
    6536             :   HValue* string() const { return OperandAt(0); }
    6537             :   HValue* index() const { return OperandAt(1); }
    6538             : 
    6539      306064 :   DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar)
    6540             : 
    6541             :  protected:
    6542           0 :   bool DataEquals(HValue* other) override {
    6543           0 :     return encoding() == HSeqStringGetChar::cast(other)->encoding();
    6544             :   }
    6545             : 
    6546       14320 :   Range* InferRange(Zone* zone) override {
    6547       14320 :     if (encoding() == String::ONE_BYTE_ENCODING) {
    6548        7160 :       return new(zone) Range(0, String::kMaxOneByteCharCode);
    6549             :     } else {
    6550             :       DCHECK_EQ(String::TWO_BYTE_ENCODING, encoding());
    6551        7160 :       return  new(zone) Range(0, String::kMaxUtf16CodeUnit);
    6552             :     }
    6553             :   }
    6554             : 
    6555             :  private:
    6556       14320 :   HSeqStringGetChar(String::Encoding encoding,
    6557             :                     HValue* string,
    6558       14320 :                     HValue* index) : encoding_(encoding) {
    6559       14320 :     SetOperandAt(0, string);
    6560       14320 :     SetOperandAt(1, index);
    6561             :     set_representation(Representation::Integer32());
    6562             :     SetFlag(kUseGVN);
    6563             :     SetDependsOnFlag(kStringChars);
    6564       14320 :   }
    6565             : 
    6566           0 :   bool IsDeletable() const override { return true; }
    6567             : 
    6568             :   String::Encoding encoding_;
    6569             : };
    6570             : 
    6571             : 
    6572           0 : class HSeqStringSetChar final : public HTemplateInstruction<4> {
    6573             :  public:
    6574       14320 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(
    6575             :       HSeqStringSetChar, String::Encoding,
    6576             :       HValue*, HValue*, HValue*);
    6577             : 
    6578             :   String::Encoding encoding() { return encoding_; }
    6579             :   HValue* context() { return OperandAt(0); }
    6580             :   HValue* string() { return OperandAt(1); }
    6581             :   HValue* index() { return OperandAt(2); }
    6582             :   HValue* value() { return OperandAt(3); }
    6583             : 
    6584       57280 :   Representation RequiredInputRepresentation(int index) override {
    6585             :     return (index <= 1) ? Representation::Tagged()
    6586       57280 :                         : Representation::Integer32();
    6587             :   }
    6588             : 
    6589      243232 :   DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar)
    6590             : 
    6591             :  private:
    6592       14320 :   HSeqStringSetChar(HValue* context,
    6593             :                     String::Encoding encoding,
    6594             :                     HValue* string,
    6595             :                     HValue* index,
    6596       14320 :                     HValue* value) : encoding_(encoding) {
    6597       14320 :     SetOperandAt(0, context);
    6598       14320 :     SetOperandAt(1, string);
    6599       14320 :     SetOperandAt(2, index);
    6600       14320 :     SetOperandAt(3, value);
    6601             :     set_representation(Representation::Tagged());
    6602             :     SetChangesFlag(kStringChars);
    6603       14320 :   }
    6604             : 
    6605             :   String::Encoding encoding_;
    6606             : };
    6607             : 
    6608             : 
    6609           0 : class HCheckMapValue final : public HTemplateInstruction<2> {
    6610             :  public:
    6611        1436 :   DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*);
    6612             : 
    6613        1583 :   Representation RequiredInputRepresentation(int index) override {
    6614        1583 :     return Representation::Tagged();
    6615             :   }
    6616             : 
    6617             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    6618             : 
    6619         757 :   HType CalculateInferredType() override {
    6620         757 :     if (value()->type().IsHeapObject()) return value()->type();
    6621             :     return HType::HeapObject();
    6622             :   }
    6623             : 
    6624             :   HValue* value() const { return OperandAt(0); }
    6625             :   HValue* map() const { return OperandAt(1); }
    6626             : 
    6627             :   HValue* Canonicalize() override;
    6628             : 
    6629       22256 :   DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
    6630             : 
    6631             :  protected:
    6632        2424 :   int RedefinedOperandIndex() override { return 0; }
    6633             : 
    6634         139 :   bool DataEquals(HValue* other) override { return true; }
    6635             : 
    6636             :  private:
    6637        1436 :   HCheckMapValue(HValue* value, HValue* map)
    6638        1436 :       : HTemplateInstruction<2>(HType::HeapObject()) {
    6639        1436 :     SetOperandAt(0, value);
    6640        1436 :     SetOperandAt(1, map);
    6641             :     set_representation(Representation::Tagged());
    6642             :     SetFlag(kUseGVN);
    6643             :     SetDependsOnFlag(kMaps);
    6644             :     SetDependsOnFlag(kElementsKind);
    6645        1436 :   }
    6646             : };
    6647             : 
    6648             : 
    6649           0 : class HForInPrepareMap final : public HTemplateInstruction<2> {
    6650             :  public:
    6651         842 :   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HForInPrepareMap, HValue*);
    6652             : 
    6653        1525 :   Representation RequiredInputRepresentation(int index) override {
    6654        1525 :     return Representation::Tagged();
    6655             :   }
    6656             : 
    6657             :   HValue* context() const { return OperandAt(0); }
    6658             :   HValue* enumerable() const { return OperandAt(1); }
    6659             : 
    6660             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    6661             : 
    6662         757 :   HType CalculateInferredType() override { return HType::Tagged(); }
    6663             : 
    6664      450986 :   DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
    6665             : 
    6666             :  private:
    6667         842 :   HForInPrepareMap(HValue* context,
    6668         842 :                    HValue* object) {
    6669         842 :     SetOperandAt(0, context);
    6670         842 :     SetOperandAt(1, object);
    6671             :     set_representation(Representation::Tagged());
    6672             :     SetAllSideEffects();
    6673         842 :   }
    6674             : };
    6675             : 
    6676             : 
    6677           0 : class HForInCacheArray final : public HTemplateInstruction<2> {
    6678             :  public:
    6679        1914 :   DECLARE_INSTRUCTION_FACTORY_P3(HForInCacheArray, HValue*, HValue*, int);
    6680             : 
    6681        3505 :   Representation RequiredInputRepresentation(int index) override {
    6682        3505 :     return Representation::Tagged();
    6683             :   }
    6684             : 
    6685             :   HValue* enumerable() const { return OperandAt(0); }
    6686             :   HValue* map() const { return OperandAt(1); }
    6687             :   int idx() const { return idx_; }
    6688             : 
    6689             :   HForInCacheArray* index_cache() {
    6690             :     return index_cache_;
    6691             :   }
    6692             : 
    6693             :   void set_index_cache(HForInCacheArray* index_cache) {
    6694         842 :     index_cache_ = index_cache;
    6695             :   }
    6696             : 
    6697             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    6698             : 
    6699        1738 :   HType CalculateInferredType() override { return HType::Tagged(); }
    6700             : 
    6701      285721 :   DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
    6702             : 
    6703             :  private:
    6704        1914 :   HForInCacheArray(HValue* enumerable,
    6705             :                    HValue* keys,
    6706        1914 :                    int idx) : idx_(idx) {
    6707        1914 :     SetOperandAt(0, enumerable);
    6708        1914 :     SetOperandAt(1, keys);
    6709             :     set_representation(Representation::Tagged());
    6710        1914 :   }
    6711             : 
    6712             :   int idx_;
    6713             :   HForInCacheArray* index_cache_;
    6714             : };
    6715             : 
    6716             : 
    6717           0 : class HLoadFieldByIndex final : public HTemplateInstruction<2> {
    6718             :  public:
    6719             :   DECLARE_INSTRUCTION_FACTORY_P2(HLoadFieldByIndex, HValue*, HValue*);
    6720             : 
    6721         594 :   HLoadFieldByIndex(HValue* object,
    6722         594 :                     HValue* index) {
    6723         594 :     SetOperandAt(0, object);
    6724         594 :     SetOperandAt(1, index);
    6725             :     SetChangesFlag(kNewSpacePromotion);
    6726             :     set_representation(Representation::Tagged());
    6727         594 :   }
    6728             : 
    6729           0 :   Representation RequiredInputRepresentation(int index) override {
    6730           0 :     if (index == 1) {
    6731             :       return Representation::Smi();
    6732             :     } else {
    6733             :       return Representation::Tagged();
    6734             :     }
    6735             :   }
    6736             : 
    6737             :   HValue* object() const { return OperandAt(0); }
    6738             :   HValue* index() const { return OperandAt(1); }
    6739             : 
    6740             :   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
    6741             : 
    6742           0 :   HType CalculateInferredType() override { return HType::Tagged(); }
    6743             : 
    6744      171528 :   DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
    6745             : 
    6746             :  private:
    6747           1 :   bool IsDeletable() const override { return true; }
    6748             : };
    6749             : 
    6750             : #undef DECLARE_INSTRUCTION
    6751             : #undef DECLARE_CONCRETE_INSTRUCTION
    6752             : 
    6753             : }  // namespace internal
    6754             : }  // namespace v8
    6755             : 
    6756             : #endif  // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_

Generated by: LCOV version 1.10