LCOV - code coverage report
Current view: top level - src/crankshaft - hydrogen-instructions.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1250 1730 72.3 %
Date: 2017-04-26 Functions: 253 339 74.6 %

          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             : #include "src/crankshaft/hydrogen-instructions.h"
       6             : 
       7             : #include "src/base/bits.h"
       8             : #include "src/base/ieee754.h"
       9             : #include "src/base/safe_math.h"
      10             : #include "src/codegen.h"
      11             : #include "src/crankshaft/hydrogen-infer-representation.h"
      12             : #include "src/double.h"
      13             : #include "src/elements.h"
      14             : #include "src/factory.h"
      15             : #include "src/objects-inl.h"
      16             : 
      17             : #if V8_TARGET_ARCH_IA32
      18             : #include "src/crankshaft/ia32/lithium-ia32.h"  // NOLINT
      19             : #elif V8_TARGET_ARCH_X64
      20             : #include "src/crankshaft/x64/lithium-x64.h"  // NOLINT
      21             : #elif V8_TARGET_ARCH_ARM64
      22             : #include "src/crankshaft/arm64/lithium-arm64.h"  // NOLINT
      23             : #elif V8_TARGET_ARCH_ARM
      24             : #include "src/crankshaft/arm/lithium-arm.h"  // NOLINT
      25             : #elif V8_TARGET_ARCH_PPC
      26             : #include "src/crankshaft/ppc/lithium-ppc.h"  // NOLINT
      27             : #elif V8_TARGET_ARCH_MIPS
      28             : #include "src/crankshaft/mips/lithium-mips.h"  // NOLINT
      29             : #elif V8_TARGET_ARCH_MIPS64
      30             : #include "src/crankshaft/mips64/lithium-mips64.h"  // NOLINT
      31             : #elif V8_TARGET_ARCH_S390
      32             : #include "src/crankshaft/s390/lithium-s390.h"  // NOLINT
      33             : #elif V8_TARGET_ARCH_X87
      34             : #include "src/crankshaft/x87/lithium-x87.h"  // NOLINT
      35             : #else
      36             : #error Unsupported target architecture.
      37             : #endif
      38             : 
      39             : namespace v8 {
      40             : namespace internal {
      41             : 
      42             : #define DEFINE_COMPILE(type)                                         \
      43             :   LInstruction* H##type::CompileToLithium(LChunkBuilder* builder) {  \
      44             :     return builder->Do##type(this);                                  \
      45             :   }
      46    20717578 : HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE)
      47             : #undef DEFINE_COMPILE
      48             : 
      49     4387218 : Representation RepresentationFromMachineType(MachineType type) {
      50     4387218 :   if (type == MachineType::Int32()) {
      51             :     return Representation::Integer32();
      52             :   }
      53             : 
      54     3748778 :   if (type == MachineType::TaggedSigned()) {
      55             :     return Representation::Smi();
      56             :   }
      57             : 
      58     2769853 :   if (type == MachineType::Pointer()) {
      59             :     return Representation::External();
      60             :   }
      61             : 
      62             :   return Representation::Tagged();
      63             : }
      64             : 
      65      160351 : Isolate* HValue::isolate() const {
      66             :   DCHECK(block() != NULL);
      67      160351 :   return block()->isolate();
      68             : }
      69             : 
      70             : 
      71         607 : void HValue::AssumeRepresentation(Representation r) {
      72         607 :   if (CheckFlag(kFlexibleRepresentation)) {
      73             :     ChangeRepresentation(r);
      74             :     // The representation of the value is dictated by type feedback and
      75             :     // will not be changed later.
      76             :     ClearFlag(kFlexibleRepresentation);
      77             :   }
      78         607 : }
      79             : 
      80             : 
      81      114774 : void HValue::InferRepresentation(HInferRepresentationPhase* h_infer) {
      82             :   DCHECK(CheckFlag(kFlexibleRepresentation));
      83      114774 :   Representation new_rep = RepresentationFromInputs();
      84      114774 :   UpdateRepresentation(new_rep, h_infer, "inputs");
      85      114774 :   new_rep = RepresentationFromUses();
      86      114774 :   UpdateRepresentation(new_rep, h_infer, "uses");
      87      114774 :   if (representation().IsSmi() && HasNonSmiUse()) {
      88             :     UpdateRepresentation(
      89       43549 :         Representation::Integer32(), h_infer, "use requirements");
      90             :   }
      91      114774 : }
      92             : 
      93             : 
      94      998853 : Representation HValue::RepresentationFromUses() {
      95      998853 :   if (HasNoUses()) return Representation::None();
      96      966091 :   Representation result = Representation::None();
      97             : 
      98     2089865 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
      99     2089865 :     HValue* use = it.value();
     100     2089865 :     Representation rep = use->observed_input_representation(it.index());
     101     2089863 :     result = result.generalize(rep);
     102             : 
     103     2089865 :     if (FLAG_trace_representation) {
     104             :       PrintF("#%d %s is used by #%d %s as %s%s\n",
     105             :              id(), Mnemonic(), use->id(), use->Mnemonic(), rep.Mnemonic(),
     106           0 :              (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : ""));
     107             :     }
     108             :   }
     109      966094 :   if (IsPhi()) {
     110             :     result = result.generalize(
     111      445427 :         HPhi::cast(this)->representation_from_indirect_uses());
     112             :   }
     113             : 
     114             :   // External representations are dealt with separately.
     115      966091 :   return result.IsExternal() ? Representation::None() : result;
     116             : }
     117             : 
     118             : 
     119     3795996 : void HValue::UpdateRepresentation(Representation new_rep,
     120             :                                   HInferRepresentationPhase* h_infer,
     121     1079684 :                                   const char* reason) {
     122     3795996 :   Representation r = representation();
     123     3795996 :   if (new_rep.is_more_general_than(r)) {
     124     1177072 :     if (CheckFlag(kCannotBeTagged) && new_rep.IsTagged()) return;
     125     1077724 :     if (FLAG_trace_representation) {
     126             :       PrintF("Changing #%d %s representation %s -> %s based on %s\n",
     127           0 :              id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason);
     128             :     }
     129             :     ChangeRepresentation(new_rep);
     130     1077725 :     AddDependantsToWorklist(h_infer);
     131             :   }
     132             : }
     133             : 
     134             : 
     135     1077726 : void HValue::AddDependantsToWorklist(HInferRepresentationPhase* h_infer) {
     136     2512320 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     137     2512316 :     h_infer->AddToWorklist(it.value());
     138             :   }
     139     3915172 :   for (int i = 0; i < OperandCount(); ++i) {
     140     2837456 :     h_infer->AddToWorklist(OperandAt(i));
     141             :   }
     142     1077720 : }
     143             : 
     144             : 
     145             : static int32_t ConvertAndSetOverflow(Representation r,
     146             :                                      int64_t result,
     147             :                                      bool* overflow) {
     148      384638 :   if (r.IsSmi()) {
     149        3104 :     if (result > Smi::kMaxValue) {
     150             :       *overflow = true;
     151             :       return Smi::kMaxValue;
     152             :     }
     153        1552 :     if (result < Smi::kMinValue) {
     154             :       *overflow = true;
     155             :       return Smi::kMinValue;
     156             :     }
     157             :   } else {
     158      680090 :     if (result > kMaxInt) {
     159             :       *overflow = true;
     160             :       return kMaxInt;
     161             :     }
     162      501080 :     if (result < kMinInt) {
     163             :       *overflow = true;
     164             :       return kMinInt;
     165             :     }
     166             :   }
     167      402546 :   return static_cast<int32_t>(result);
     168             : }
     169             : 
     170             : 
     171             : static int32_t AddWithoutOverflow(Representation r,
     172             :                                   int32_t a,
     173             :                                   int32_t b,
     174             :                                   bool* overflow) {
     175      624906 :   int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b);
     176             :   return ConvertAndSetOverflow(r, result, overflow);
     177             : }
     178             : 
     179             : 
     180             : static int32_t SubWithoutOverflow(Representation r,
     181             :                                   int32_t a,
     182             :                                   int32_t b,
     183             :                                   bool* overflow) {
     184       27728 :   int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b);
     185             :   return ConvertAndSetOverflow(r, result, overflow);
     186             : }
     187             : 
     188             : 
     189             : static int32_t MulWithoutOverflow(const Representation& r,
     190             :                                   int32_t a,
     191             :                                   int32_t b,
     192             :                                   bool* overflow) {
     193       30560 :   int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b);
     194             :   return ConvertAndSetOverflow(r, result, overflow);
     195             : }
     196             : 
     197             : 
     198           0 : int32_t Range::Mask() const {
     199      149440 :   if (lower_ == upper_) return lower_;
     200       94426 :   if (lower_ >= 0) {
     201             :     int32_t res = 1;
     202      556030 :     while (res < upper_) {
     203      497358 :       res = (res << 1) | 1;
     204             :     }
     205             :     return res;
     206             :   }
     207             :   return 0xffffffff;
     208             : }
     209             : 
     210             : 
     211      149278 : void Range::AddConstant(int32_t value) {
     212      298556 :   if (value == 0) return;
     213             :   bool may_overflow = false;  // Overflow is ignored here.
     214             :   Representation r = Representation::Integer32();
     215      298556 :   lower_ = AddWithoutOverflow(r, lower_, value, &may_overflow);
     216      298556 :   upper_ = AddWithoutOverflow(r, upper_, value, &may_overflow);
     217             : #ifdef DEBUG
     218             :   Verify();
     219             : #endif
     220             : }
     221             : 
     222             : 
     223      473153 : void Range::Intersect(Range* other) {
     224      946306 :   upper_ = Min(upper_, other->upper_);
     225      946306 :   lower_ = Max(lower_, other->lower_);
     226      473159 :   bool b = CanBeMinusZero() && other->CanBeMinusZero();
     227             :   set_can_be_minus_zero(b);
     228      473153 : }
     229             : 
     230             : 
     231       19017 : void Range::Union(Range* other) {
     232       38034 :   upper_ = Max(upper_, other->upper_);
     233       38034 :   lower_ = Min(lower_, other->lower_);
     234       34263 :   bool b = CanBeMinusZero() || other->CanBeMinusZero();
     235             :   set_can_be_minus_zero(b);
     236       19017 : }
     237             : 
     238             : 
     239         115 : void Range::CombinedMax(Range* other) {
     240         230 :   upper_ = Max(upper_, other->upper_);
     241         230 :   lower_ = Max(lower_, other->lower_);
     242         190 :   set_can_be_minus_zero(CanBeMinusZero() || other->CanBeMinusZero());
     243         115 : }
     244             : 
     245             : 
     246          98 : void Range::CombinedMin(Range* other) {
     247         196 :   upper_ = Min(upper_, other->upper_);
     248         196 :   lower_ = Min(lower_, other->lower_);
     249         172 :   set_can_be_minus_zero(CanBeMinusZero() || other->CanBeMinusZero());
     250          98 : }
     251             : 
     252             : 
     253           0 : void Range::Sar(int32_t value) {
     254       13667 :   int32_t bits = value & 0x1F;
     255       13667 :   lower_ = lower_ >> bits;
     256       13667 :   upper_ = upper_ >> bits;
     257             :   set_can_be_minus_zero(false);
     258           0 : }
     259             : 
     260             : 
     261           0 : void Range::Shl(int32_t value) {
     262       15020 :   int32_t bits = value & 0x1F;
     263       15020 :   int old_lower = lower_;
     264       15020 :   int old_upper = upper_;
     265       15020 :   lower_ = lower_ << bits;
     266       15020 :   upper_ = upper_ << bits;
     267       15020 :   if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) {
     268       10724 :     upper_ = kMaxInt;
     269       10724 :     lower_ = kMinInt;
     270             :   }
     271             :   set_can_be_minus_zero(false);
     272           0 : }
     273             : 
     274             : 
     275      326350 : bool Range::AddAndCheckOverflow(const Representation& r, Range* other) {
     276             :   bool may_overflow = false;
     277      326350 :   lower_ = AddWithoutOverflow(r, lower_, other->lower(), &may_overflow);
     278      326350 :   upper_ = AddWithoutOverflow(r, upper_, other->upper(), &may_overflow);
     279      163175 :   if (may_overflow) {
     280             :     Clear();
     281             :   } else {
     282             :     KeepOrder();
     283             :   }
     284             : #ifdef DEBUG
     285             :   Verify();
     286             : #endif
     287      163175 :   return may_overflow;
     288             : }
     289             : 
     290             : 
     291       27728 : bool Range::SubAndCheckOverflow(const Representation& r, Range* other) {
     292             :   bool may_overflow = false;
     293       27728 :   lower_ = SubWithoutOverflow(r, lower_, other->upper(), &may_overflow);
     294       27728 :   upper_ = SubWithoutOverflow(r, upper_, other->lower(), &may_overflow);
     295       13864 :   if (may_overflow) {
     296             :     Clear();
     297             :   } else {
     298             :     KeepOrder();
     299             :   }
     300             : #ifdef DEBUG
     301             :   Verify();
     302             : #endif
     303       13864 :   return may_overflow;
     304             : }
     305             : 
     306           0 : void Range::Clear() {
     307      105054 :   lower_ = kMinInt;
     308      105054 :   upper_ = kMaxInt;
     309           0 : }
     310             : 
     311           0 : void Range::KeepOrder() {
     312       79216 :   if (lower_ > upper_) {
     313             :     int32_t tmp = lower_;
     314           0 :     lower_ = upper_;
     315           0 :     upper_ = tmp;
     316             :   }
     317           0 : }
     318             : 
     319             : 
     320             : #ifdef DEBUG
     321             : void Range::Verify() const {
     322             :   DCHECK(lower_ <= upper_);
     323             : }
     324             : #endif
     325             : 
     326             : 
     327       15280 : bool Range::MulAndCheckOverflow(const Representation& r, Range* other) {
     328             :   bool may_overflow = false;
     329        7640 :   int v1 = MulWithoutOverflow(r, lower_, other->lower(), &may_overflow);
     330             :   int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow);
     331        7640 :   int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow);
     332             :   int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow);
     333        7640 :   if (may_overflow) {
     334             :     Clear();
     335             :   } else {
     336         409 :     lower_ = Min(Min(v1, v2), Min(v3, v4));
     337         409 :     upper_ = Max(Max(v1, v2), Max(v3, v4));
     338             :   }
     339             : #ifdef DEBUG
     340             :   Verify();
     341             : #endif
     342        7640 :   return may_overflow;
     343             : }
     344             : 
     345             : 
     346     2747328 : bool HValue::IsDefinedAfter(HBasicBlock* other) const {
     347     2747328 :   return block()->block_id() > other->block_id();
     348             : }
     349             : 
     350             : 
     351      200252 : HUseListNode* HUseListNode::tail() {
     352             :   // Skip and remove dead items in the use list.
     353   105929658 :   while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) {
     354    29052457 :     tail_ = tail_->tail_;
     355             :   }
     356      200252 :   return tail_;
     357             : }
     358             : 
     359             : 
     360      341370 : bool HValue::CheckUsesForFlag(Flag f) const {
     361       34778 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     362      654278 :     if (it.value()->IsSimulate()) continue;
     363      636510 :     if (!it.value()->CheckFlag(f)) return false;
     364             :   }
     365       49009 :   return true;
     366             : }
     367             : 
     368             : 
     369      328587 : bool HValue::CheckUsesForFlag(Flag f, HValue** value) const {
     370      291367 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     371     1013142 :     if (it.value()->IsSimulate()) continue;
     372      965270 :     if (!it.value()->CheckFlag(f)) {
     373      215204 :       *value = it.value();
     374      215204 :       return false;
     375             :     }
     376             :   }
     377      113383 :   return true;
     378             : }
     379             : 
     380             : 
     381      251236 : bool HValue::HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const {
     382             :   bool return_value = false;
     383       32821 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     384      512824 :     if (it.value()->IsSimulate()) continue;
     385      509540 :     if (!it.value()->CheckFlag(f)) return false;
     386             :     return_value = true;
     387             :   }
     388       27645 :   return return_value;
     389             : }
     390             : 
     391             : 
     392    17309204 : HUseIterator::HUseIterator(HUseListNode* head) : next_(head) {
     393    17309204 :   Advance();
     394    13247792 : }
     395             : 
     396             : 
     397    52684608 : void HUseIterator::Advance() {
     398    52684608 :   current_ = next_;
     399   125200388 :   if (current_ != NULL) {
     400    36257890 :     next_ = current_->tail();
     401    36257890 :     value_ = current_->value();
     402    36257890 :     index_ = current_->index();
     403             :   }
     404    52684608 : }
     405             : 
     406             : 
     407      170632 : int HValue::UseCount() const {
     408             :   int count = 0;
     409     1158581 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) ++count;
     410      170632 :   return count;
     411             : }
     412             : 
     413             : 
     414     3468474 : HUseListNode* HValue::RemoveUse(HValue* value, int index) {
     415             :   HUseListNode* previous = NULL;
     416    13352942 :   HUseListNode* current = use_list_;
     417     9849246 :   while (current != NULL) {
     418     9884468 :     if (current->value() == value && current->index() == index) {
     419     3468460 :       if (previous == NULL) {
     420     2808392 :         use_list_ = current->tail();
     421             :       } else {
     422             :         previous->set_tail(current->tail());
     423             :       }
     424             :       break;
     425             :     }
     426             : 
     427             :     previous = current;
     428             :     current = current->tail();
     429             :   }
     430             : 
     431             : #ifdef DEBUG
     432             :   // Do not reuse use list nodes in debug mode, zap them.
     433             :   if (current != NULL) {
     434             :     HUseListNode* temp =
     435             :         new(block()->zone())
     436             :         HUseListNode(current->value(), current->index(), NULL);
     437             :     current->Zap();
     438             :     current = temp;
     439             :   }
     440             : #endif
     441     3468474 :   return current;
     442             : }
     443             : 
     444             : 
     445    22303089 : bool HValue::Equals(HValue* other) {
     446    15857814 :   if (other->opcode() != opcode()) return false;
     447    12943534 :   if (!other->representation().Equals(representation())) return false;
     448    10417329 :   if (!other->type_.Equals(type_)) return false;
     449     6445275 :   if (other->flags() != flags()) return false;
     450     6289610 :   if (OperandCount() != other->OperandCount()) return false;
     451      805026 :   for (int i = 0; i < OperandCount(); ++i) {
     452      828497 :     if (OperandAt(i)->id() != other->OperandAt(i)->id()) return false;
     453             :   }
     454     6266135 :   bool result = DataEquals(other);
     455             :   DCHECK(!result || Hashcode() == other->Hashcode());
     456     6266134 :   return result;
     457             : }
     458             : 
     459             : 
     460     8573482 : intptr_t HValue::Hashcode() {
     461     8573482 :   intptr_t result = opcode();
     462     8573494 :   int count = OperandCount();
     463    21786165 :   for (int i = 0; i < count; ++i) {
     464    13212759 :     result = result * 19 + OperandAt(i)->id() + (result >> 7);
     465             :   }
     466     8573406 :   return result;
     467             : }
     468             : 
     469             : 
     470    10451073 : const char* HValue::Mnemonic() const {
     471    10451073 :   switch (opcode()) {
     472             : #define MAKE_CASE(type) case k##type: return #type;
     473             :     HYDROGEN_CONCRETE_INSTRUCTION_LIST(MAKE_CASE)
     474             : #undef MAKE_CASE
     475             :     case kPhi: return "Phi";
     476             :     default: return "";
     477             :   }
     478             : }
     479             : 
     480             : 
     481    48844346 : bool HValue::CanReplaceWithDummyUses() {
     482    48844346 :   return FLAG_unreachable_code_elimination &&
     483     4013980 :       !(block()->IsReachable() ||
     484     2932739 :         IsBlockEntry() ||
     485     4784196 :         IsControlInstruction() ||
     486     1846023 :         IsArgumentsObject() ||
     487     1842814 :         IsCapturedObject() ||
     488      865802 :         IsSimulate() ||
     489             :         IsEnterInlined() ||
     490      860388 :         IsLeaveInlined());
     491             : }
     492             : 
     493             : 
     494       30939 : bool HValue::IsInteger32Constant() {
     495     1414902 :   return IsConstant() && HConstant::cast(this)->HasInteger32Value();
     496             : }
     497             : 
     498             : 
     499       29507 : int32_t HValue::GetInteger32Constant() {
     500      377978 :   return HConstant::cast(this)->Integer32Value();
     501             : }
     502             : 
     503             : 
     504      962821 : bool HValue::EqualsInteger32Constant(int32_t value) {
     505     1305634 :   return IsInteger32Constant() && GetInteger32Constant() == value;
     506             : }
     507             : 
     508             : 
     509    27674147 : void HValue::SetOperandAt(int index, HValue* value) {
     510    27674147 :   RegisterUse(index, value);
     511    27674006 :   InternalSetOperandAt(index, value);
     512    27674068 : }
     513             : 
     514             : 
     515     6726132 : void HValue::DeleteAndReplaceWith(HValue* other) {
     516             :   // We replace all uses first, so Delete can assert that there are none.
     517     6726132 :   if (other != NULL) ReplaceAllUsesWith(other);
     518     6726134 :   Kill();
     519     6726124 :   DeleteFromGraph();
     520     6726119 : }
     521             : 
     522             : 
     523     4049466 : void HValue::ReplaceAllUsesWith(HValue* other) {
     524    13499338 :   while (use_list_ != NULL) {
     525    10800820 :     HUseListNode* list_node = use_list_;
     526             :     HValue* value = list_node->value();
     527             :     DCHECK(!value->block()->IsStartBlock());
     528    10800820 :     value->InternalSetOperandAt(list_node->index(), other);
     529     5400406 :     use_list_ = list_node->tail();
     530     5400406 :     list_node->set_tail(other->use_list_);
     531     5400406 :     other->use_list_ = list_node;
     532             :   }
     533     4049462 : }
     534             : 
     535             : 
     536     7105171 : void HValue::Kill() {
     537             :   // Instead of going through the entire use list of each operand, we only
     538             :   // check the first item in each use list and rely on the tail() method to
     539             :   // skip dead items, removing them lazily next time we traverse the list.
     540             :   SetFlag(kIsDead);
     541    10782861 :   for (int i = 0; i < OperandCount(); ++i) {
     542     3677687 :     HValue* operand = OperandAt(i);
     543     3677690 :     if (operand == NULL) continue;
     544     4707189 :     HUseListNode* first = operand->use_list_;
     545     7012320 :     if (first != NULL && first->value()->CheckFlag(kIsDead)) {
     546      576838 :       operand->use_list_ = first->tail();
     547             :     }
     548             :   }
     549     7105163 : }
     550             : 
     551             : 
     552    67715526 : void HValue::SetBlock(HBasicBlock* block) {
     553             :   DCHECK(block_ == NULL || block == NULL);
     554    34529321 :   block_ = block;
     555    34529321 :   if (id_ == kNoNumber && block != NULL) {
     556    33186153 :     id_ = block->graph()->GetNextValueID(this);
     557             :   }
     558    34529269 : }
     559             : 
     560             : 
     561           0 : std::ostream& operator<<(std::ostream& os, const HValue& v) {
     562           0 :   return v.PrintTo(os);
     563             : }
     564             : 
     565             : 
     566           0 : std::ostream& operator<<(std::ostream& os, const TypeOf& t) {
     567           0 :   if (t.value->representation().IsTagged() &&
     568             :       !t.value->type().Equals(HType::Tagged()))
     569             :     return os;
     570           0 :   return os << " type:" << t.value->type();
     571             : }
     572             : 
     573             : 
     574           0 : std::ostream& operator<<(std::ostream& os, const ChangesOf& c) {
     575           0 :   GVNFlagSet changes_flags = c.value->ChangesFlags();
     576           0 :   if (changes_flags.IsEmpty()) return os;
     577           0 :   os << " changes[";
     578           0 :   if (changes_flags == c.value->AllSideEffectsFlagSet()) {
     579           0 :     os << "*";
     580             :   } else {
     581             :     bool add_comma = false;
     582             : #define PRINT_DO(Type)                   \
     583             :   if (changes_flags.Contains(k##Type)) { \
     584             :     if (add_comma) os << ",";            \
     585             :     add_comma = true;                    \
     586             :     os << #Type;                         \
     587             :   }
     588           0 :     GVN_TRACKED_FLAG_LIST(PRINT_DO);
     589           0 :     GVN_UNTRACKED_FLAG_LIST(PRINT_DO);
     590             : #undef PRINT_DO
     591             :   }
     592           0 :   return os << "]";
     593             : }
     594             : 
     595             : 
     596      805234 : bool HValue::HasMonomorphicJSObjectType() {
     597     1610468 :   return !GetMonomorphicJSObjectMap().is_null();
     598             : }
     599             : 
     600             : 
     601    29475715 : bool HValue::UpdateInferredType() {
     602    29475715 :   HType type = CalculateInferredType();
     603    29475759 :   bool result = (!type.Equals(type_));
     604    29475759 :   type_ = type;
     605    29475759 :   return result;
     606             : }
     607             : 
     608             : 
     609    51839311 : void HValue::RegisterUse(int index, HValue* new_value) {
     610    27674152 :   HValue* old_value = OperandAt(index);
     611    55348712 :   if (old_value == new_value) return;
     612             : 
     613             :   HUseListNode* removed = NULL;
     614    27633063 :   if (old_value != NULL) {
     615     3468475 :     removed = old_value->RemoveUse(this, index);
     616             :   }
     617             : 
     618    27633629 :   if (new_value != NULL) {
     619    27633629 :     if (removed == NULL) {
     620    24165159 :       new_value->use_list_ = new(new_value->block()->zone()) HUseListNode(
     621    48330202 :           this, index, new_value->use_list_);
     622             :     } else {
     623     3468470 :       removed->set_tail(new_value->use_list_);
     624     3468470 :       new_value->use_list_ = removed;
     625             :     }
     626             :   }
     627             : }
     628             : 
     629             : 
     630      877718 : void HValue::AddNewRange(Range* r, Zone* zone) {
     631      438859 :   if (!HasRange()) ComputeInitialRange(zone);
     632      438859 :   if (!HasRange()) range_ = new(zone) Range();
     633             :   DCHECK(HasRange());
     634      438859 :   r->StackUpon(range_);
     635      438859 :   range_ = r;
     636      438859 : }
     637             : 
     638             : 
     639      418101 : void HValue::RemoveLastAddedRange() {
     640             :   DCHECK(HasRange());
     641             :   DCHECK(range_->next() != NULL);
     642      418101 :   range_ = range_->next();
     643      418101 : }
     644             : 
     645             : 
     646    10450933 : void HValue::ComputeInitialRange(Zone* zone) {
     647             :   DCHECK(!HasRange());
     648    10450933 :   range_ = InferRange(zone);
     649             :   DCHECK(HasRange());
     650    10451127 : }
     651             : 
     652             : 
     653           0 : std::ostream& HInstruction::PrintTo(std::ostream& os) const {  // NOLINT
     654           0 :   os << Mnemonic() << " ";
     655           0 :   PrintDataTo(os) << ChangesOf(this) << TypeOf(this);
     656           0 :   if (CheckFlag(HValue::kHasNoObservableSideEffects)) os << " [noOSE]";
     657           0 :   if (CheckFlag(HValue::kIsDead)) os << " [dead]";
     658           0 :   return os;
     659             : }
     660             : 
     661             : 
     662           0 : std::ostream& HInstruction::PrintDataTo(std::ostream& os) const {  // NOLINT
     663           0 :   for (int i = 0; i < OperandCount(); ++i) {
     664           0 :     if (i > 0) os << " ";
     665           0 :     os << NameOf(OperandAt(i));
     666             :   }
     667           0 :   return os;
     668             : }
     669             : 
     670             : 
     671     7690492 : void HInstruction::Unlink() {
     672             :   DCHECK(IsLinked());
     673             :   DCHECK(!IsControlInstruction());  // Must never move control instructions.
     674             :   DCHECK(!IsBlockEntry());  // Doesn't make sense to delete these.
     675             :   DCHECK(previous_ != NULL);
     676     7690492 :   previous_->next_ = next_;
     677     7690492 :   if (next_ == NULL) {
     678             :     DCHECK(block()->last() == this);
     679       37391 :     block()->set_last(previous_);
     680             :   } else {
     681     7653101 :     next_->previous_ = previous_;
     682             :   }
     683             :   clear_block();
     684     7690492 : }
     685             : 
     686             : 
     687     2959003 : void HInstruction::InsertBefore(HInstruction* next) {
     688             :   DCHECK(!IsLinked());
     689             :   DCHECK(!next->IsBlockEntry());
     690             :   DCHECK(!IsControlInstruction());
     691             :   DCHECK(!next->block()->IsStartBlock());
     692             :   DCHECK(next->previous_ != NULL);
     693             :   HInstruction* prev = next->previous();
     694     2959003 :   prev->next_ = this;
     695     2959003 :   next->previous_ = this;
     696     2959003 :   next_ = next;
     697     2959003 :   previous_ = prev;
     698     2959003 :   SetBlock(next->block());
     699     4958225 :   if (!has_position() && next->has_position()) {
     700     1559490 :     set_position(next->position());
     701             :   }
     702     2959003 : }
     703             : 
     704             : 
     705    25874648 : void HInstruction::InsertAfter(HInstruction* previous) {
     706             :   DCHECK(!IsLinked());
     707             :   DCHECK(!previous->IsControlInstruction());
     708             :   DCHECK(!IsControlInstruction() || previous->next_ == NULL);
     709    53702247 :   HBasicBlock* block = previous->block();
     710             :   // Never insert anything except constants into the start block after finishing
     711             :   // it.
     712    28513959 :   if (block->IsStartBlock() && block->IsFinished() && !IsConstant()) {
     713             :     DCHECK(block->end()->SecondSuccessor() == NULL);
     714           0 :     InsertAfter(block->end()->FirstSuccessor()->first());
     715    25874646 :     return;
     716             :   }
     717             : 
     718             :   // If we're inserting after an instruction with side-effects that is
     719             :   // followed by a simulate instruction, we need to insert after the
     720             :   // simulate instruction instead.
     721    25874647 :   HInstruction* next = previous->next_;
     722    25874647 :   if (previous->HasObservableSideEffects() && next != NULL) {
     723             :     DCHECK(next->IsSimulate());
     724             :     previous = next;
     725           0 :     next = previous->next_;
     726             :   }
     727             : 
     728    25874647 :   previous_ = previous;
     729    25874647 :   next_ = next;
     730    25874647 :   SetBlock(block);
     731    25874646 :   previous->next_ = this;
     732    25874646 :   if (next != NULL) next->previous_ = this;
     733    25874646 :   if (block->last() == previous) {
     734             :     block->set_last(this);
     735             :   }
     736    32446319 :   if (!has_position() && previous->has_position()) {
     737       12787 :     set_position(previous->position());
     738             :   }
     739             : }
     740             : 
     741             : 
     742           0 : bool HInstruction::Dominates(HInstruction* other) {
     743           0 :   if (block() != other->block()) {
     744           0 :     return block()->Dominates(other->block());
     745             :   }
     746             :   // Both instructions are in the same basic block. This instruction
     747             :   // should precede the other one in order to dominate it.
     748           0 :   for (HInstruction* instr = next(); instr != NULL; instr = instr->next()) {
     749           0 :     if (instr == other) {
     750             :       return true;
     751             :     }
     752             :   }
     753             :   return false;
     754             : }
     755             : 
     756             : 
     757             : #ifdef DEBUG
     758             : void HInstruction::Verify() {
     759             :   // Verify that input operands are defined before use.
     760             :   HBasicBlock* cur_block = block();
     761             :   for (int i = 0; i < OperandCount(); ++i) {
     762             :     HValue* other_operand = OperandAt(i);
     763             :     if (other_operand == NULL) continue;
     764             :     HBasicBlock* other_block = other_operand->block();
     765             :     if (cur_block == other_block) {
     766             :       if (!other_operand->IsPhi()) {
     767             :         HInstruction* cur = this->previous();
     768             :         while (cur != NULL) {
     769             :           if (cur == other_operand) break;
     770             :           cur = cur->previous();
     771             :         }
     772             :         // Must reach other operand in the same block!
     773             :         DCHECK(cur == other_operand);
     774             :       }
     775             :     } else {
     776             :       // If the following assert fires, you may have forgotten an
     777             :       // AddInstruction.
     778             :       DCHECK(other_block->Dominates(cur_block));
     779             :     }
     780             :   }
     781             : 
     782             :   // Verify that instructions that may have side-effects are followed
     783             :   // by a simulate instruction.
     784             :   if (HasObservableSideEffects() && !IsOsrEntry()) {
     785             :     DCHECK(next()->IsSimulate());
     786             :   }
     787             : 
     788             :   // Verify that instructions that can be eliminated by GVN have overridden
     789             :   // HValue::DataEquals.  The default implementation is UNREACHABLE.  We
     790             :   // don't actually care whether DataEquals returns true or false here.
     791             :   if (CheckFlag(kUseGVN)) DataEquals(this);
     792             : 
     793             :   // Verify that all uses are in the graph.
     794             :   for (HUseIterator use = uses(); !use.Done(); use.Advance()) {
     795             :     if (use.value()->IsInstruction()) {
     796             :       DCHECK(HInstruction::cast(use.value())->IsLinked());
     797             :     }
     798             :   }
     799             : }
     800             : #endif
     801             : 
     802             : 
     803         166 : bool HInstruction::CanDeoptimize() {
     804         166 :   switch (opcode()) {
     805             :     case HValue::kAbnormalExit:
     806             :     case HValue::kAccessArgumentsAt:
     807             :     case HValue::kAllocate:
     808             :     case HValue::kArgumentsElements:
     809             :     case HValue::kArgumentsLength:
     810             :     case HValue::kArgumentsObject:
     811             :     case HValue::kBlockEntry:
     812             :     case HValue::kCallNewArray:
     813             :     case HValue::kCapturedObject:
     814             :     case HValue::kClassOfTestAndBranch:
     815             :     case HValue::kCompareGeneric:
     816             :     case HValue::kCompareHoleAndBranch:
     817             :     case HValue::kCompareMap:
     818             :     case HValue::kCompareNumericAndBranch:
     819             :     case HValue::kCompareObjectEqAndBranch:
     820             :     case HValue::kConstant:
     821             :     case HValue::kContext:
     822             :     case HValue::kDebugBreak:
     823             :     case HValue::kDeclareGlobals:
     824             :     case HValue::kDummyUse:
     825             :     case HValue::kEnterInlined:
     826             :     case HValue::kEnvironmentMarker:
     827             :     case HValue::kForceRepresentation:
     828             :     case HValue::kGoto:
     829             :     case HValue::kHasInstanceTypeAndBranch:
     830             :     case HValue::kInnerAllocatedObject:
     831             :     case HValue::kIsSmiAndBranch:
     832             :     case HValue::kIsStringAndBranch:
     833             :     case HValue::kIsUndetectableAndBranch:
     834             :     case HValue::kLeaveInlined:
     835             :     case HValue::kLoadFieldByIndex:
     836             :     case HValue::kLoadNamedField:
     837             :     case HValue::kLoadRoot:
     838             :     case HValue::kMathMinMax:
     839             :     case HValue::kParameter:
     840             :     case HValue::kPhi:
     841             :     case HValue::kPushArguments:
     842             :     case HValue::kReturn:
     843             :     case HValue::kSeqStringGetChar:
     844             :     case HValue::kStoreCodeEntry:
     845             :     case HValue::kStoreKeyed:
     846             :     case HValue::kStoreNamedField:
     847             :     case HValue::kStringCharCodeAt:
     848             :     case HValue::kStringCharFromCode:
     849             :     case HValue::kThisFunction:
     850             :     case HValue::kTypeofIsAndBranch:
     851             :     case HValue::kUnknownOSRValue:
     852             :     case HValue::kUseConst:
     853             :       return false;
     854             : 
     855             :     case HValue::kAdd:
     856             :     case HValue::kApplyArguments:
     857             :     case HValue::kBitwise:
     858             :     case HValue::kBoundsCheck:
     859             :     case HValue::kBranch:
     860             :     case HValue::kCallRuntime:
     861             :     case HValue::kCallWithDescriptor:
     862             :     case HValue::kChange:
     863             :     case HValue::kCheckArrayBufferNotNeutered:
     864             :     case HValue::kCheckHeapObject:
     865             :     case HValue::kCheckInstanceType:
     866             :     case HValue::kCheckMapValue:
     867             :     case HValue::kCheckMaps:
     868             :     case HValue::kCheckSmi:
     869             :     case HValue::kCheckValue:
     870             :     case HValue::kClampToUint8:
     871             :     case HValue::kDeoptimize:
     872             :     case HValue::kDiv:
     873             :     case HValue::kForInCacheArray:
     874             :     case HValue::kForInPrepareMap:
     875             :     case HValue::kHasInPrototypeChainAndBranch:
     876             :     case HValue::kInvokeFunction:
     877             :     case HValue::kLoadContextSlot:
     878             :     case HValue::kLoadFunctionPrototype:
     879             :     case HValue::kLoadKeyed:
     880             :     case HValue::kMathFloorOfDiv:
     881             :     case HValue::kMaybeGrowElements:
     882             :     case HValue::kMod:
     883             :     case HValue::kMul:
     884             :     case HValue::kOsrEntry:
     885             :     case HValue::kPower:
     886             :     case HValue::kPrologue:
     887             :     case HValue::kRor:
     888             :     case HValue::kSar:
     889             :     case HValue::kSeqStringSetChar:
     890             :     case HValue::kShl:
     891             :     case HValue::kShr:
     892             :     case HValue::kSimulate:
     893             :     case HValue::kStackCheck:
     894             :     case HValue::kStoreContextSlot:
     895             :     case HValue::kStringAdd:
     896             :     case HValue::kStringCompareAndBranch:
     897             :     case HValue::kSub:
     898             :     case HValue::kTransitionElementsKind:
     899             :     case HValue::kTrapAllocationMemento:
     900             :     case HValue::kTypeof:
     901             :     case HValue::kUnaryMathOperation:
     902             :     case HValue::kWrapReceiver:
     903          79 :       return true;
     904             :   }
     905           0 :   UNREACHABLE();
     906             :   return true;
     907             : }
     908             : 
     909             : 
     910           0 : std::ostream& operator<<(std::ostream& os, const NameOf& v) {
     911           0 :   return os << v.value->representation().Mnemonic() << v.value->id();
     912             : }
     913             : 
     914           0 : std::ostream& HDummyUse::PrintDataTo(std::ostream& os) const {  // NOLINT
     915           0 :   return os << NameOf(value());
     916             : }
     917             : 
     918             : 
     919           0 : std::ostream& HEnvironmentMarker::PrintDataTo(
     920           0 :     std::ostream& os) const {  // NOLINT
     921           0 :   return os << (kind() == BIND ? "bind" : "lookup") << " var[" << index()
     922           0 :             << "]";
     923             : }
     924             : 
     925             : 
     926           0 : std::ostream& HUnaryCall::PrintDataTo(std::ostream& os) const {  // NOLINT
     927           0 :   return os << NameOf(value()) << " #" << argument_count();
     928             : }
     929             : 
     930             : 
     931           0 : std::ostream& HBinaryCall::PrintDataTo(std::ostream& os) const {  // NOLINT
     932           0 :   return os << NameOf(first()) << " " << NameOf(second()) << " #"
     933           0 :             << argument_count();
     934             : }
     935             : 
     936           0 : std::ostream& HInvokeFunction::PrintTo(std::ostream& os) const {  // NOLINT
     937           0 :   if (tail_call_mode() == TailCallMode::kAllow) os << "Tail";
     938           0 :   return HBinaryCall::PrintTo(os);
     939             : }
     940             : 
     941           0 : std::ostream& HInvokeFunction::PrintDataTo(std::ostream& os) const {  // NOLINT
     942           0 :   HBinaryCall::PrintDataTo(os);
     943           0 :   if (syntactic_tail_call_mode() == TailCallMode::kAllow) {
     944           0 :     os << ", JSTailCall";
     945             :   }
     946           0 :   return os;
     947             : }
     948             : 
     949           0 : std::ostream& HBoundsCheck::PrintDataTo(std::ostream& os) const {  // NOLINT
     950           0 :   os << NameOf(index()) << " " << NameOf(length());
     951           0 :   if (base() != NULL && (offset() != 0 || scale() != 0)) {
     952           0 :     os << " base: ((";
     953           0 :     if (base() != index()) {
     954           0 :       os << NameOf(index());
     955             :     } else {
     956           0 :       os << "index";
     957             :     }
     958           0 :     os << " + " << offset() << ") >> " << scale() << ")";
     959             :   }
     960           0 :   if (skip_check()) os << " [DISABLED]";
     961           0 :   return os;
     962             : }
     963             : 
     964             : 
     965       58568 : void HBoundsCheck::InferRepresentation(HInferRepresentationPhase* h_infer) {
     966             :   DCHECK(CheckFlag(kFlexibleRepresentation));
     967       58568 :   HValue* actual_index = index()->ActualValue();
     968       58568 :   HValue* actual_length = length()->ActualValue();
     969       58569 :   Representation index_rep = actual_index->representation();
     970             :   Representation length_rep = actual_length->representation();
     971       67075 :   if (index_rep.IsTagged() && actual_index->type().IsSmi()) {
     972           0 :     index_rep = Representation::Smi();
     973             :   }
     974       58569 :   if (length_rep.IsTagged() && actual_length->type().IsSmi()) {
     975             :     length_rep = Representation::Smi();
     976             :   }
     977       58569 :   Representation r = index_rep.generalize(length_rep);
     978       58568 :   if (r.is_more_general_than(Representation::Integer32())) {
     979        8592 :     r = Representation::Integer32();
     980             :   }
     981       58569 :   UpdateRepresentation(r, h_infer, "boundscheck");
     982       58568 : }
     983             : 
     984             : 
     985       68592 : Range* HBoundsCheck::InferRange(Zone* zone) {
     986             :   Representation r = representation();
     987       68593 :   if (r.IsSmiOrInteger32() && length()->HasRange()) {
     988       68592 :     int upper = length()->range()->upper() - (allow_equality() ? 0 : 1);
     989             :     int lower = 0;
     990             : 
     991             :     Range* result = new(zone) Range(lower, upper);
     992       34297 :     if (index()->HasRange()) {
     993       34297 :       result->Intersect(index()->range());
     994             :     }
     995             : 
     996             :     // In case of Smi representation, clamp result to Smi::kMaxValue.
     997       34297 :     if (r.IsSmi()) result->ClampToSmi();
     998       34297 :     return result;
     999             :   }
    1000           0 :   return HValue::InferRange(zone);
    1001             : }
    1002             : 
    1003             : 
    1004           0 : std::ostream& HCallWithDescriptor::PrintDataTo(
    1005           0 :     std::ostream& os) const {  // NOLINT
    1006           0 :   for (int i = 0; i < OperandCount(); i++) {
    1007           0 :     os << NameOf(OperandAt(i)) << " ";
    1008             :   }
    1009           0 :   os << "#" << argument_count();
    1010           0 :   if (syntactic_tail_call_mode() == TailCallMode::kAllow) {
    1011           0 :     os << ", JSTailCall";
    1012             :   }
    1013           0 :   return os;
    1014             : }
    1015             : 
    1016             : 
    1017           0 : std::ostream& HCallNewArray::PrintDataTo(std::ostream& os) const {  // NOLINT
    1018           0 :   os << ElementsKindToString(elements_kind()) << " ";
    1019           0 :   return HBinaryCall::PrintDataTo(os);
    1020             : }
    1021             : 
    1022             : 
    1023           0 : std::ostream& HCallRuntime::PrintDataTo(std::ostream& os) const {  // NOLINT
    1024           0 :   os << function()->name << " ";
    1025           0 :   if (save_doubles() == kSaveFPRegs) os << "[save doubles] ";
    1026           0 :   return os << "#" << argument_count();
    1027             : }
    1028             : 
    1029           0 : std::ostream& HClassOfTestAndBranch::PrintDataTo(
    1030             :     std::ostream& os) const {  // NOLINT
    1031           0 :   return os << "class_of_test(" << NameOf(value()) << ", \""
    1032           0 :             << class_name()->ToCString().get() << "\")";
    1033             : }
    1034             : 
    1035           0 : std::ostream& HWrapReceiver::PrintDataTo(std::ostream& os) const {  // NOLINT
    1036           0 :   return os << NameOf(receiver()) << " " << NameOf(function());
    1037             : }
    1038             : 
    1039             : 
    1040           0 : std::ostream& HAccessArgumentsAt::PrintDataTo(
    1041             :     std::ostream& os) const {  // NOLINT
    1042           0 :   return os << NameOf(arguments()) << "[" << NameOf(index()) << "], length "
    1043           0 :             << NameOf(length());
    1044             : }
    1045             : 
    1046             : 
    1047           0 : std::ostream& HControlInstruction::PrintDataTo(
    1048             :     std::ostream& os) const {  // NOLINT
    1049           0 :   os << " goto (";
    1050             :   bool first_block = true;
    1051           0 :   for (HSuccessorIterator it(this); !it.Done(); it.Advance()) {
    1052           0 :     if (!first_block) os << ", ";
    1053           0 :     os << *it.Current();
    1054             :     first_block = false;
    1055             :   }
    1056           0 :   return os << ")";
    1057             : }
    1058             : 
    1059             : 
    1060           0 : std::ostream& HUnaryControlInstruction::PrintDataTo(
    1061             :     std::ostream& os) const {  // NOLINT
    1062           0 :   os << NameOf(value());
    1063           0 :   return HControlInstruction::PrintDataTo(os);
    1064             : }
    1065             : 
    1066             : 
    1067           0 : std::ostream& HReturn::PrintDataTo(std::ostream& os) const {  // NOLINT
    1068           0 :   return os << NameOf(value()) << " (pop " << NameOf(parameter_count())
    1069           0 :             << " values)";
    1070             : }
    1071             : 
    1072             : 
    1073       18077 : Representation HBranch::observed_input_representation(int index) {
    1074       18077 :   if (expected_input_types_ &
    1075             :       (ToBooleanHint::kNull | ToBooleanHint::kReceiver |
    1076             :        ToBooleanHint::kString | ToBooleanHint::kSymbol)) {
    1077             :     return Representation::Tagged();
    1078             :   }
    1079       15007 :   if (expected_input_types_ & ToBooleanHint::kUndefined) {
    1080          52 :     if (expected_input_types_ & ToBooleanHint::kHeapNumber) {
    1081             :       return Representation::Double();
    1082             :     }
    1083             :     return Representation::Tagged();
    1084             :   }
    1085       14955 :   if (expected_input_types_ & ToBooleanHint::kHeapNumber) {
    1086             :     return Representation::Double();
    1087             :   }
    1088       14955 :   if (expected_input_types_ & ToBooleanHint::kSmallInteger) {
    1089             :     return Representation::Smi();
    1090             :   }
    1091             :   return Representation::None();
    1092             : }
    1093             : 
    1094             : 
    1095     2827351 : bool HBranch::KnownSuccessorBlock(HBasicBlock** block) {
    1096             :   HValue* value = this->value();
    1097     2827348 :   if (value->EmitAtUses()) {
    1098             :     DCHECK(value->IsConstant());
    1099             :     DCHECK(!value->representation().IsDouble());
    1100      584754 :     *block = HConstant::cast(value)->BooleanValue()
    1101      183478 :         ? FirstSuccessor()
    1102      768232 :         : SecondSuccessor();
    1103      584754 :     return true;
    1104             :   }
    1105     2242602 :   *block = NULL;
    1106     2242602 :   return false;
    1107             : }
    1108             : 
    1109             : 
    1110           0 : std::ostream& HBranch::PrintDataTo(std::ostream& os) const {  // NOLINT
    1111           0 :   return HUnaryControlInstruction::PrintDataTo(os) << " "
    1112           0 :                                                    << expected_input_types();
    1113             : }
    1114             : 
    1115             : 
    1116           0 : std::ostream& HCompareMap::PrintDataTo(std::ostream& os) const {  // NOLINT
    1117           0 :   os << NameOf(value()) << " (" << *map().handle() << ")";
    1118           0 :   HControlInstruction::PrintDataTo(os);
    1119           0 :   if (known_successor_index() == 0) {
    1120           0 :     os << " [true]";
    1121           0 :   } else if (known_successor_index() == 1) {
    1122           0 :     os << " [false]";
    1123             :   }
    1124           0 :   return os;
    1125             : }
    1126             : 
    1127             : 
    1128           0 : const char* HUnaryMathOperation::OpName() const {
    1129           0 :   switch (op()) {
    1130             :     case kMathFloor:
    1131             :       return "floor";
    1132             :     case kMathFround:
    1133           0 :       return "fround";
    1134             :     case kMathRound:
    1135           0 :       return "round";
    1136             :     case kMathAbs:
    1137           0 :       return "abs";
    1138             :     case kMathCos:
    1139           0 :       return "cos";
    1140             :     case kMathLog:
    1141           0 :       return "log";
    1142             :     case kMathExp:
    1143           0 :       return "exp";
    1144             :     case kMathSin:
    1145           0 :       return "sin";
    1146             :     case kMathSqrt:
    1147           0 :       return "sqrt";
    1148             :     case kMathPowHalf:
    1149           0 :       return "pow-half";
    1150             :     case kMathClz32:
    1151           0 :       return "clz32";
    1152             :     default:
    1153           0 :       UNREACHABLE();
    1154             :       return NULL;
    1155             :   }
    1156             : }
    1157             : 
    1158             : 
    1159       26495 : Range* HUnaryMathOperation::InferRange(Zone* zone) {
    1160             :   Representation r = representation();
    1161       26537 :   if (op() == kMathClz32) return new(zone) Range(0, 32);
    1162       46022 :   if (r.IsSmiOrInteger32() && value()->HasRange()) {
    1163       19569 :     if (op() == kMathAbs) {
    1164          61 :       int upper = value()->range()->upper();
    1165          61 :       int lower = value()->range()->lower();
    1166             :       bool spans_zero = value()->range()->CanBeZero();
    1167             :       // Math.abs(kMinInt) overflows its representation, on which the
    1168             :       // instruction deopts. Hence clamp it to kMaxInt.
    1169          61 :       int abs_upper = upper == kMinInt ? kMaxInt : abs(upper);
    1170          61 :       int abs_lower = lower == kMinInt ? kMaxInt : abs(lower);
    1171             :       Range* result =
    1172             :           new(zone) Range(spans_zero ? 0 : Min(abs_lower, abs_upper),
    1173          61 :                           Max(abs_lower, abs_upper));
    1174             :       // In case of Smi representation, clamp Math.abs(Smi::kMinValue) to
    1175             :       // Smi::kMaxValue.
    1176          61 :       if (r.IsSmi()) result->ClampToSmi();
    1177          61 :       return result;
    1178             :     }
    1179             :   }
    1180       26392 :   return HValue::InferRange(zone);
    1181             : }
    1182             : 
    1183             : 
    1184           0 : std::ostream& HUnaryMathOperation::PrintDataTo(
    1185             :     std::ostream& os) const {  // NOLINT
    1186           0 :   return os << OpName() << " " << NameOf(value());
    1187             : }
    1188             : 
    1189             : 
    1190           0 : std::ostream& HUnaryOperation::PrintDataTo(std::ostream& os) const {  // NOLINT
    1191           0 :   return os << NameOf(value());
    1192             : }
    1193             : 
    1194             : 
    1195           0 : std::ostream& HHasInstanceTypeAndBranch::PrintDataTo(
    1196             :     std::ostream& os) const {  // NOLINT
    1197           0 :   os << NameOf(value());
    1198           0 :   switch (from_) {
    1199             :     case FIRST_JS_RECEIVER_TYPE:
    1200           0 :       if (to_ == LAST_TYPE) os << " spec_object";
    1201             :       break;
    1202             :     case JS_REGEXP_TYPE:
    1203           0 :       if (to_ == JS_REGEXP_TYPE) os << " reg_exp";
    1204             :       break;
    1205             :     case JS_ARRAY_TYPE:
    1206           0 :       if (to_ == JS_ARRAY_TYPE) os << " array";
    1207             :       break;
    1208             :     case JS_FUNCTION_TYPE:
    1209           0 :       if (to_ == JS_FUNCTION_TYPE) os << " function";
    1210             :       break;
    1211             :     default:
    1212             :       break;
    1213             :   }
    1214           0 :   return os;
    1215             : }
    1216             : 
    1217             : 
    1218           0 : std::ostream& HTypeofIsAndBranch::PrintDataTo(
    1219             :     std::ostream& os) const {  // NOLINT
    1220           0 :   os << NameOf(value()) << " == " << type_literal()->ToCString().get();
    1221           0 :   return HControlInstruction::PrintDataTo(os);
    1222             : }
    1223             : 
    1224             : 
    1225             : namespace {
    1226             : 
    1227           0 : String* TypeOfString(HConstant* constant, Isolate* isolate) {
    1228           0 :   Heap* heap = isolate->heap();
    1229           0 :   if (constant->HasNumberValue()) return heap->number_string();
    1230           0 :   if (constant->HasStringValue()) return heap->string_string();
    1231           0 :   switch (constant->GetInstanceType()) {
    1232             :     case ODDBALL_TYPE: {
    1233             :       Unique<Object> unique = constant->GetUnique();
    1234           0 :       if (unique.IsKnownGlobal(heap->true_value()) ||
    1235             :           unique.IsKnownGlobal(heap->false_value())) {
    1236           0 :         return heap->boolean_string();
    1237             :       }
    1238           0 :       if (unique.IsKnownGlobal(heap->null_value())) {
    1239           0 :         return heap->object_string();
    1240             :       }
    1241             :       DCHECK(unique.IsKnownGlobal(heap->undefined_value()));
    1242           0 :       return heap->undefined_string();
    1243             :     }
    1244             :     case SYMBOL_TYPE:
    1245           0 :       return heap->symbol_string();
    1246             :     default:
    1247           0 :       if (constant->IsUndetectable()) return heap->undefined_string();
    1248           0 :       if (constant->IsCallable()) return heap->function_string();
    1249           0 :       return heap->object_string();
    1250             :   }
    1251             : }
    1252             : 
    1253             : }  // namespace
    1254             : 
    1255             : 
    1256      320992 : bool HTypeofIsAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    1257      321271 :   if (FLAG_fold_constants && value()->IsConstant()) {
    1258             :     HConstant* constant = HConstant::cast(value());
    1259           0 :     String* type_string = TypeOfString(constant, isolate());
    1260       17074 :     bool same_type = type_literal_.IsKnownGlobal(type_string);
    1261           0 :     *block = same_type ? FirstSuccessor() : SecondSuccessor();
    1262           0 :     return true;
    1263      320992 :   } else if (value()->representation().IsSpecialization()) {
    1264             :     bool number_type =
    1265       17074 :         type_literal_.IsKnownGlobal(isolate()->heap()->number_string());
    1266       17074 :     *block = number_type ? FirstSuccessor() : SecondSuccessor();
    1267       17074 :     return true;
    1268             :   }
    1269      303918 :   *block = NULL;
    1270      303918 :   return false;
    1271             : }
    1272             : 
    1273             : 
    1274           0 : std::ostream& HCheckMapValue::PrintDataTo(std::ostream& os) const {  // NOLINT
    1275           0 :   return os << NameOf(value()) << " " << NameOf(map());
    1276             : }
    1277             : 
    1278             : 
    1279         757 : HValue* HCheckMapValue::Canonicalize() {
    1280         757 :   if (map()->IsConstant()) {
    1281           0 :     HConstant* c_map = HConstant::cast(map());
    1282             :     return HCheckMaps::CreateAndInsertAfter(
    1283             :         block()->graph()->zone(), value(), c_map->MapValue(),
    1284           0 :         c_map->HasStableMapValue(), this);
    1285             :   }
    1286         757 :   return this;
    1287             : }
    1288             : 
    1289             : 
    1290           0 : std::ostream& HForInPrepareMap::PrintDataTo(std::ostream& os) const {  // NOLINT
    1291           0 :   return os << NameOf(enumerable());
    1292             : }
    1293             : 
    1294             : 
    1295           0 : std::ostream& HForInCacheArray::PrintDataTo(std::ostream& os) const {  // NOLINT
    1296           0 :   return os << NameOf(enumerable()) << " " << NameOf(map()) << "[" << idx_
    1297           0 :             << "]";
    1298             : }
    1299             : 
    1300             : 
    1301           0 : std::ostream& HLoadFieldByIndex::PrintDataTo(
    1302             :     std::ostream& os) const {  // NOLINT
    1303           0 :   return os << NameOf(object()) << " " << NameOf(index());
    1304             : }
    1305             : 
    1306             : 
    1307             : static bool MatchLeftIsOnes(HValue* l, HValue* r, HValue** negated) {
    1308       44484 :   if (!l->EqualsInteger32Constant(~0)) return false;
    1309        1622 :   *negated = r;
    1310             :   return true;
    1311             : }
    1312             : 
    1313             : 
    1314       93804 : static bool MatchNegationViaXor(HValue* instr, HValue** negated) {
    1315       93804 :   if (!instr->IsBitwise()) return false;
    1316       92853 :   HBitwise* b = HBitwise::cast(instr);
    1317      115095 :   return (b->op() == Token::BIT_XOR) &&
    1318       22242 :       (MatchLeftIsOnes(b->left(), b->right(), negated) ||
    1319       92853 :        MatchLeftIsOnes(b->right(), b->left(), negated));
    1320             : }
    1321             : 
    1322             : 
    1323       92221 : static bool MatchDoubleNegation(HValue* instr, HValue** arg) {
    1324             :   HValue* negated;
    1325       93804 :   return MatchNegationViaXor(instr, &negated) &&
    1326       93806 :       MatchNegationViaXor(negated, arg);
    1327             : }
    1328             : 
    1329             : 
    1330      229280 : HValue* HBitwise::Canonicalize() {
    1331      117186 :   if (!representation().IsSmiOrInteger32()) return this;
    1332             :   // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x.
    1333      112094 :   int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0;
    1334      112299 :   if (left()->EqualsInteger32Constant(nop_constant) &&
    1335         205 :       !right()->CheckFlag(kUint32)) {
    1336         204 :     return right();
    1337             :   }
    1338      131688 :   if (right()->EqualsInteger32Constant(nop_constant) &&
    1339       19799 :       !left()->CheckFlag(kUint32)) {
    1340       19667 :     return left();
    1341             :   }
    1342             :   // Optimize double negation, a common pattern used for ToInt32(x).
    1343             :   HValue* arg;
    1344       92260 :   if (MatchDoubleNegation(this, &arg) && !arg->CheckFlag(kUint32)) {
    1345          39 :     return arg;
    1346             :   }
    1347             :   return this;
    1348             : }
    1349             : 
    1350             : 
    1351             : // static
    1352        3897 : HInstruction* HAdd::New(Isolate* isolate, Zone* zone, HValue* context,
    1353             :                         HValue* left, HValue* right,
    1354             :                         ExternalAddType external_add_type) {
    1355             :   // For everything else, you should use the other factory method without
    1356             :   // ExternalAddType.
    1357             :   DCHECK_EQ(external_add_type, AddOfExternalAndTagged);
    1358        3897 :   return new (zone) HAdd(context, left, right, external_add_type);
    1359             : }
    1360             : 
    1361             : 
    1362      564241 : Representation HAdd::RepresentationFromInputs() {
    1363             :   Representation left_rep = left()->representation();
    1364      564241 :   if (left_rep.IsExternal()) {
    1365             :     return Representation::External();
    1366             :   }
    1367      560224 :   return HArithmeticBinaryOperation::RepresentationFromInputs();
    1368             : }
    1369             : 
    1370             : 
    1371     1149646 : Representation HAdd::RequiredInputRepresentation(int index) {
    1372     1149646 :   if (index == 2) {
    1373             :     Representation left_rep = left()->representation();
    1374      368917 :     if (left_rep.IsExternal()) {
    1375        3897 :       if (external_add_type_ == AddOfExternalAndTagged) {
    1376             :         return Representation::Tagged();
    1377             :       } else {
    1378             :         return Representation::Integer32();
    1379             :       }
    1380             :     }
    1381             :   }
    1382             :   return HArithmeticBinaryOperation::RequiredInputRepresentation(index);
    1383             : }
    1384             : 
    1385             : 
    1386      697311 : static bool IsIdentityOperation(HValue* arg1, HValue* arg2, int32_t identity) {
    1387     1315080 :   return arg1->representation().IsSpecialization() &&
    1388     1315080 :     arg2->EqualsInteger32Constant(identity);
    1389             : }
    1390             : 
    1391             : 
    1392      286187 : HValue* HAdd::Canonicalize() {
    1393             :   // Adding 0 is an identity operation except in case of -0: -0 + 0 = +0
    1394      294063 :   if (IsIdentityOperation(left(), right(), 0) &&
    1395             :       !left()->representation().IsDouble()) {  // Left could be -0.
    1396        7812 :     return left();
    1397             :   }
    1398      300638 :   if (IsIdentityOperation(right(), left(), 0) &&
    1399             :       !left()->representation().IsDouble()) {  // Right could be -0.
    1400       22254 :     return right();
    1401             :   }
    1402      256121 :   return this;
    1403             : }
    1404             : 
    1405             : 
    1406       26340 : HValue* HSub::Canonicalize() {
    1407       26350 :   if (IsIdentityOperation(left(), right(), 0)) return left();
    1408       26330 :   return this;
    1409             : }
    1410             : 
    1411             : 
    1412       27242 : HValue* HMul::Canonicalize() {
    1413       27242 :   if (IsIdentityOperation(left(), right(), 1)) return left();
    1414       27242 :   if (IsIdentityOperation(right(), left(), 1)) return right();
    1415       27242 :   return this;
    1416             : }
    1417             : 
    1418             : 
    1419        1361 : bool HMul::MulMinusOne() {
    1420        2722 :   if (left()->EqualsInteger32Constant(-1) ||
    1421        1361 :       right()->EqualsInteger32Constant(-1)) {
    1422             :     return true;
    1423             :   }
    1424             : 
    1425        1302 :   return false;
    1426             : }
    1427             : 
    1428             : 
    1429        5635 : HValue* HMod::Canonicalize() {
    1430        5635 :   return this;
    1431             : }
    1432             : 
    1433             : 
    1434       51927 : HValue* HDiv::Canonicalize() {
    1435       52754 :   if (IsIdentityOperation(left(), right(), 1)) return left();
    1436       51100 :   return this;
    1437             : }
    1438             : 
    1439             : 
    1440      509111 : HValue* HChange::Canonicalize() {
    1441      509111 :   return (from().Equals(to())) ? value() : this;
    1442             : }
    1443             : 
    1444             : 
    1445        4941 : HValue* HWrapReceiver::Canonicalize() {
    1446        4941 :   if (HasNoUses()) return NULL;
    1447        4941 :   if (receiver()->type().IsJSReceiver()) {
    1448             :     return receiver();
    1449             :   }
    1450        4941 :   return this;
    1451             : }
    1452             : 
    1453             : 
    1454           0 : std::ostream& HTypeof::PrintDataTo(std::ostream& os) const {  // NOLINT
    1455           0 :   return os << NameOf(value());
    1456             : }
    1457             : 
    1458             : 
    1459       61533 : HInstruction* HForceRepresentation::New(Isolate* isolate, Zone* zone,
    1460             :                                         HValue* context, HValue* value,
    1461             :                                         Representation representation) {
    1462       61865 :   if (FLAG_fold_constants && value->IsConstant()) {
    1463             :     HConstant* c = HConstant::cast(value);
    1464          25 :     c = c->CopyToRepresentation(representation, zone);
    1465          25 :     if (c != NULL) return c;
    1466             :   }
    1467      123028 :   return new(zone) HForceRepresentation(value, representation);
    1468             : }
    1469             : 
    1470             : 
    1471           0 : std::ostream& HForceRepresentation::PrintDataTo(
    1472             :     std::ostream& os) const {  // NOLINT
    1473           0 :   return os << representation().Mnemonic() << " " << NameOf(value());
    1474             : }
    1475             : 
    1476             : 
    1477           0 : std::ostream& HChange::PrintDataTo(std::ostream& os) const {  // NOLINT
    1478             :   HUnaryOperation::PrintDataTo(os);
    1479           0 :   os << " " << from().Mnemonic() << " to " << to().Mnemonic();
    1480             : 
    1481           0 :   if (CanTruncateToSmi()) os << " truncating-smi";
    1482           0 :   if (CanTruncateToInt32()) os << " truncating-int32";
    1483           0 :   if (CanTruncateToNumber()) os << " truncating-number";
    1484           0 :   if (CheckFlag(kBailoutOnMinusZero)) os << " -0?";
    1485           0 :   return os;
    1486             : }
    1487             : 
    1488             : 
    1489       58505 : HValue* HUnaryMathOperation::Canonicalize() {
    1490       29288 :   if (op() == kMathRound || op() == kMathFloor) {
    1491             :     HValue* val = value();
    1492       27563 :     if (val->IsChange()) val = HChange::cast(val)->value();
    1493       27563 :     if (val->representation().IsSmiOrInteger32()) {
    1494        4484 :       if (val->representation().Equals(representation())) return val;
    1495           0 :       return Prepend(new (block()->zone())
    1496           0 :                          HChange(val, representation(), false, false, true));
    1497             :     }
    1498             :   }
    1499       76703 :   if (op() == kMathFloor && representation().IsSmiOrInteger32() &&
    1500       32558 :       value()->IsDiv() && value()->HasOneUse()) {
    1501             :     HDiv* hdiv = HDiv::cast(value());
    1502             : 
    1503           0 :     HValue* left = hdiv->left();
    1504        3335 :     if (left->representation().IsInteger32() && !left->CheckFlag(kUint32)) {
    1505             :       // A value with an integer representation does not need to be transformed.
    1506        6748 :     } else if (left->IsChange() && HChange::cast(left)->from().IsInteger32() &&
    1507         806 :                !HChange::cast(left)->value()->CheckFlag(kUint32)) {
    1508             :       // A change from an integer32 can be replaced by the integer32 value.
    1509             :       left = HChange::cast(left)->value();
    1510        5070 :     } else if (hdiv->observed_input_representation(1).IsSmiOrInteger32()) {
    1511        1813 :       left = Prepend(new (block()->zone()) HChange(
    1512        5439 :           left, Representation::Integer32(), false, false, true));
    1513             :     } else {
    1514         722 :       return this;
    1515             :     }
    1516             : 
    1517        2529 :     HValue* right = hdiv->right();
    1518        2613 :     if (right->IsInteger32Constant()) {
    1519             :       right = Prepend(HConstant::cast(right)->CopyToRepresentation(
    1520        5058 :           Representation::Integer32(), right->block()->zone()));
    1521          84 :     } else if (right->representation().IsInteger32() &&
    1522             :                !right->CheckFlag(kUint32)) {
    1523             :       // A value with an integer representation does not need to be transformed.
    1524         155 :     } else if (right->IsChange() &&
    1525         155 :                HChange::cast(right)->from().IsInteger32() &&
    1526          71 :                !HChange::cast(right)->value()->CheckFlag(kUint32)) {
    1527             :       // A change from an integer32 can be replaced by the integer32 value.
    1528             :       right = HChange::cast(right)->value();
    1529          26 :     } else if (hdiv->observed_input_representation(2).IsSmiOrInteger32()) {
    1530           0 :       right = Prepend(new (block()->zone()) HChange(
    1531           0 :           right, Representation::Integer32(), false, false, true));
    1532             :     } else {
    1533          13 :       return this;
    1534             :     }
    1535             : 
    1536             :     return Prepend(HMathFloorOfDiv::New(
    1537        7800 :         block()->graph()->isolate(), block()->zone(), context(), left, right));
    1538             :   }
    1539       25882 :   return this;
    1540             : }
    1541             : 
    1542             : 
    1543       89306 : HValue* HCheckInstanceType::Canonicalize() {
    1544      180250 :   if ((check_ == IS_JS_RECEIVER && value()->type().IsJSReceiver()) ||
    1545       89306 :       (check_ == IS_JS_ARRAY && value()->type().IsJSArray()) ||
    1546       70082 :       (check_ == IS_STRING && value()->type().IsString())) {
    1547       20077 :     return value();
    1548             :   }
    1549             : 
    1550       86815 :   if (check_ == IS_INTERNALIZED_STRING && value()->IsConstant()) {
    1551        4243 :     if (HConstant::cast(value())->HasInternalizedStringValue()) {
    1552             :       return value();
    1553             :     }
    1554             :   }
    1555       64986 :   return this;
    1556             : }
    1557             : 
    1558             : 
    1559        1340 : void HCheckInstanceType::GetCheckInterval(InstanceType* first,
    1560             :                                           InstanceType* last) {
    1561             :   DCHECK(is_interval_check());
    1562        1340 :   switch (check_) {
    1563             :     case IS_JS_RECEIVER:
    1564        1340 :       *first = FIRST_JS_RECEIVER_TYPE;
    1565        1340 :       *last = LAST_JS_RECEIVER_TYPE;
    1566        1340 :       return;
    1567             :     case IS_JS_ARRAY:
    1568           0 :       *first = *last = JS_ARRAY_TYPE;
    1569           0 :       return;
    1570             :     case IS_JS_FUNCTION:
    1571           0 :       *first = *last = JS_FUNCTION_TYPE;
    1572           0 :       return;
    1573             :     case IS_JS_DATE:
    1574           0 :       *first = *last = JS_DATE_TYPE;
    1575           0 :       return;
    1576             :     default:
    1577           0 :       UNREACHABLE();
    1578             :   }
    1579             : }
    1580             : 
    1581             : 
    1582       48777 : void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) {
    1583             :   DCHECK(!is_interval_check());
    1584       48777 :   switch (check_) {
    1585             :     case IS_STRING:
    1586       36554 :       *mask = kIsNotStringMask;
    1587       36554 :       *tag = kStringTag;
    1588       36554 :       return;
    1589             :     case IS_INTERNALIZED_STRING:
    1590       12223 :       *mask = kIsNotStringMask | kIsNotInternalizedMask;
    1591       12223 :       *tag = kInternalizedTag;
    1592       12223 :       return;
    1593             :     default:
    1594           0 :       UNREACHABLE();
    1595             :   }
    1596             : }
    1597             : 
    1598             : 
    1599           0 : std::ostream& HCheckMaps::PrintDataTo(std::ostream& os) const {  // NOLINT
    1600           0 :   os << NameOf(value()) << " [" << *maps()->at(0).handle();
    1601           0 :   for (int i = 1; i < maps()->size(); ++i) {
    1602           0 :     os << "," << *maps()->at(i).handle();
    1603             :   }
    1604           0 :   os << "]";
    1605           0 :   if (IsStabilityCheck()) os << "(stability-check)";
    1606           0 :   return os;
    1607             : }
    1608             : 
    1609             : 
    1610      502951 : HValue* HCheckMaps::Canonicalize() {
    1611      894113 :   if (!IsStabilityCheck() && maps_are_stable() && value()->IsConstant()) {
    1612             :     HConstant* c_value = HConstant::cast(value());
    1613      184373 :     if (c_value->HasObjectMap()) {
    1614      368866 :       for (int i = 0; i < maps()->size(); ++i) {
    1615      368684 :         if (c_value->ObjectMap() == maps()->at(i)) {
    1616      184282 :           if (maps()->size() > 1) {
    1617             :             set_maps(new(block()->graph()->zone()) UniqueSet<Map>(
    1618           0 :                     maps()->at(i), block()->graph()->zone()));
    1619             :           }
    1620             :           MarkAsStabilityCheck();
    1621             :           break;
    1622             :         }
    1623             :       }
    1624             :     }
    1625             :   }
    1626      318547 :   return this;
    1627             : }
    1628             : 
    1629             : 
    1630           0 : std::ostream& HCheckValue::PrintDataTo(std::ostream& os) const {  // NOLINT
    1631           0 :   return os << NameOf(value()) << " " << Brief(*object().handle());
    1632             : }
    1633             : 
    1634             : 
    1635      203515 : HValue* HCheckValue::Canonicalize() {
    1636      164491 :   return (value()->IsConstant() &&
    1637      242553 :           HConstant::cast(value())->EqualsUnique(object_)) ? NULL : this;
    1638             : }
    1639             : 
    1640             : 
    1641           0 : const char* HCheckInstanceType::GetCheckName() const {
    1642           0 :   switch (check_) {
    1643             :     case IS_JS_RECEIVER: return "object";
    1644           0 :     case IS_JS_ARRAY: return "array";
    1645             :     case IS_JS_FUNCTION:
    1646           0 :       return "function";
    1647             :     case IS_JS_DATE:
    1648           0 :       return "date";
    1649           0 :     case IS_STRING: return "string";
    1650           0 :     case IS_INTERNALIZED_STRING: return "internalized_string";
    1651             :   }
    1652           0 :   UNREACHABLE();
    1653             :   return "";
    1654             : }
    1655             : 
    1656             : 
    1657           0 : std::ostream& HCheckInstanceType::PrintDataTo(
    1658             :     std::ostream& os) const {  // NOLINT
    1659           0 :   os << GetCheckName() << " ";
    1660           0 :   return HUnaryOperation::PrintDataTo(os);
    1661             : }
    1662             : 
    1663             : 
    1664           0 : std::ostream& HUnknownOSRValue::PrintDataTo(std::ostream& os) const {  // NOLINT
    1665             :   const char* type = "expression";
    1666           0 :   if (environment_->is_local_index(index_)) type = "local";
    1667           0 :   if (environment_->is_special_index(index_)) type = "special";
    1668           0 :   if (environment_->is_parameter_index(index_)) type = "parameter";
    1669           0 :   return os << type << " @ " << index_;
    1670             : }
    1671             : 
    1672             : 
    1673    14883003 : Range* HValue::InferRange(Zone* zone) {
    1674             :   Range* result;
    1675    15253427 :   if (representation().IsSmi() || type().IsSmi()) {
    1676             :     result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue);
    1677             :     result->set_can_be_minus_zero(false);
    1678             :   } else {
    1679             :     result = new(zone) Range();
    1680     7253299 :     result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32));
    1681             :     // TODO(jkummerow): The range cannot be minus zero when the upper type
    1682             :     // bound is Integer32.
    1683             :   }
    1684     7629820 :   return result;
    1685             : }
    1686             : 
    1687             : 
    1688      369991 : Range* HChange::InferRange(Zone* zone) {
    1689      371188 :   Range* input_range = value()->range();
    1690      903660 :   if (from().IsInteger32() && !value()->CheckFlag(HInstruction::kUint32) &&
    1691      128015 :       (to().IsSmi() ||
    1692      105309 :        (to().IsTagged() &&
    1693             :         input_range != NULL &&
    1694             :         input_range->IsInSmiRange()))) {
    1695      152083 :     set_type(HType::Smi());
    1696             :     ClearChangesFlag(kNewSpacePromotion);
    1697             :   }
    1698      567109 :   if (to().IsSmiOrTagged() &&
    1699             :       input_range != NULL &&
    1700      369991 :       input_range->IsInSmiRange() &&
    1701      197118 :       (!SmiValuesAre32Bits() ||
    1702      198315 :        !value()->CheckFlag(HValue::kUint32) ||
    1703             :        input_range->upper() != kMaxInt)) {
    1704             :     // The Range class can't express upper bounds in the (kMaxInt, kMaxUint32]
    1705             :     // interval, so we treat kMaxInt as a sentinel for this entire interval.
    1706             :     ClearFlag(kCanOverflow);
    1707             :   }
    1708             :   Range* result = (input_range != NULL)
    1709             :       ? input_range->Copy(zone)
    1710      369991 :       : HValue::InferRange(zone);
    1711      522076 :   result->set_can_be_minus_zero(!to().IsSmiOrInteger32() ||
    1712             :                                 !(CheckFlag(kAllUsesTruncatingToInt32) ||
    1713      152083 :                                   CheckFlag(kAllUsesTruncatingToSmi)));
    1714      369993 :   if (to().IsSmi()) result->ClampToSmi();
    1715      369993 :   return result;
    1716             : }
    1717             : 
    1718             : 
    1719     4376305 : Range* HConstant::InferRange(Zone* zone) {
    1720     4376305 :   if (HasInteger32Value()) {
    1721     2003360 :     Range* result = new(zone) Range(int32_value_, int32_value_);
    1722             :     result->set_can_be_minus_zero(false);
    1723     2003360 :     return result;
    1724             :   }
    1725     2372952 :   return HValue::InferRange(zone);
    1726             : }
    1727             : 
    1728             : 
    1729           0 : SourcePosition HPhi::position() const { return block()->first()->position(); }
    1730             : 
    1731             : 
    1732      301146 : Range* HPhi::InferRange(Zone* zone) {
    1733       49943 :   Representation r = representation();
    1734      301146 :   if (r.IsSmiOrInteger32()) {
    1735       49943 :     if (block()->IsLoopHeader()) {
    1736             :       Range* range = r.IsSmi()
    1737             :           ? new(zone) Range(Smi::kMinValue, Smi::kMaxValue)
    1738       34022 :           : new(zone) Range(kMinInt, kMaxInt);
    1739       34022 :       return range;
    1740             :     } else {
    1741       15921 :       Range* range = OperandAt(0)->range()->Copy(zone);
    1742       69876 :       for (int i = 1; i < OperandCount(); ++i) {
    1743       19017 :         range->Union(OperandAt(i)->range());
    1744             :       }
    1745             :       return range;
    1746             :     }
    1747             :   } else {
    1748      251203 :     return HValue::InferRange(zone);
    1749             :   }
    1750             : }
    1751             : 
    1752             : 
    1753      227233 : Range* HAdd::InferRange(Zone* zone) {
    1754      482868 :   Representation r = representation();
    1755      227233 :   if (r.IsSmiOrInteger32()) {
    1756      163175 :     Range* a = left()->range();
    1757      163175 :     Range* b = right()->range();
    1758      163175 :     Range* res = a->Copy(zone);
    1759      418810 :     if (!res->AddAndCheckOverflow(r, b) ||
    1760      254918 :         (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
    1761         717 :         (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) {
    1762             :       ClearFlag(kCanOverflow);
    1763             :     }
    1764      163175 :     res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
    1765      149549 :                                !CheckFlag(kAllUsesTruncatingToInt32) &&
    1766      220840 :                                a->CanBeMinusZero() && b->CanBeMinusZero());
    1767      163175 :     return res;
    1768             :   } else {
    1769       64058 :     return HValue::InferRange(zone);
    1770             :   }
    1771             : }
    1772             : 
    1773             : 
    1774       24320 : Range* HSub::InferRange(Zone* zone) {
    1775       43547 :   Representation r = representation();
    1776       24320 :   if (r.IsSmiOrInteger32()) {
    1777       13864 :     Range* a = left()->range();
    1778       15561 :     Range* b = right()->range();
    1779       13864 :     Range* res = a->Copy(zone);
    1780       33091 :     if (!res->SubAndCheckOverflow(r, b) ||
    1781       18936 :         (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
    1782         291 :         (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) {
    1783             :       ClearFlag(kCanOverflow);
    1784             :     }
    1785       13864 :     res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
    1786        7332 :                                !CheckFlag(kAllUsesTruncatingToInt32) &&
    1787       15561 :                                a->CanBeMinusZero() && b->CanBeZero());
    1788       13864 :     return res;
    1789             :   } else {
    1790       10456 :     return HValue::InferRange(zone);
    1791             :   }
    1792             : }
    1793             : 
    1794             : 
    1795       23361 : Range* HMul::InferRange(Zone* zone) {
    1796       38232 :   Representation r = representation();
    1797       23361 :   if (r.IsSmiOrInteger32()) {
    1798       14980 :     Range* a = left()->range();
    1799       17250 :     Range* b = right()->range();
    1800        7640 :     Range* res = a->Copy(zone);
    1801       22511 :     if (!res->MulAndCheckOverflow(r, b) ||
    1802        6959 :         (((r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
    1803         563 :          (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) &&
    1804         291 :          MulMinusOne())) {
    1805             :       // Truncated int multiplication is too precise and therefore not the
    1806             :       // same as converting to Double and back.
    1807             :       // Handle truncated integer multiplication by -1 special.
    1808             :       ClearFlag(kCanOverflow);
    1809             :     }
    1810        7640 :     res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
    1811       14980 :                                !CheckFlag(kAllUsesTruncatingToInt32) &&
    1812        6871 :                                ((a->CanBeZero() && b->CanBeNegative()) ||
    1813        2739 :                                 (a->CanBeNegative() && b->CanBeZero())));
    1814        7640 :     return res;
    1815             :   } else {
    1816       15721 :     return HValue::InferRange(zone);
    1817             :   }
    1818             : }
    1819             : 
    1820             : 
    1821       49911 : Range* HDiv::InferRange(Zone* zone) {
    1822       52430 :   if (representation().IsInteger32()) {
    1823        5038 :     Range* a = left()->range();
    1824        7530 :     Range* b = right()->range();
    1825             :     Range* result = new(zone) Range();
    1826        2963 :     result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
    1827         115 :                                   (a->CanBeMinusZero() ||
    1828          83 :                                    (a->CanBeZero() && b->CanBeNegative())));
    1829        4928 :     if (!a->Includes(kMinInt) || !b->Includes(-1)) {
    1830             :       ClearFlag(kCanOverflow);
    1831             :     }
    1832             : 
    1833        2519 :     if (!b->CanBeZero()) {
    1834             :       ClearFlag(kCanBeDivByZero);
    1835             :     }
    1836        2519 :     return result;
    1837             :   } else {
    1838       47392 :     return HValue::InferRange(zone);
    1839             :   }
    1840             : }
    1841             : 
    1842             : 
    1843        2600 : Range* HMathFloorOfDiv::InferRange(Zone* zone) {
    1844        5200 :   if (representation().IsInteger32()) {
    1845       13000 :     Range* a = left()->range();
    1846        8549 :     Range* b = right()->range();
    1847             :     Range* result = new(zone) Range();
    1848        5200 :     result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
    1849         773 :                                   (a->CanBeMinusZero() ||
    1850         761 :                                    (a->CanBeZero() && b->CanBeNegative())));
    1851        2600 :     if (!a->Includes(kMinInt)) {
    1852             :       ClearFlag(kLeftCanBeMinInt);
    1853             :     }
    1854             : 
    1855        2600 :     if (!a->CanBeNegative()) {
    1856             :       ClearFlag(HValue::kLeftCanBeNegative);
    1857             :     }
    1858             : 
    1859        2600 :     if (!a->CanBePositive()) {
    1860             :       ClearFlag(HValue::kLeftCanBePositive);
    1861             :     }
    1862             : 
    1863        5188 :     if (!a->Includes(kMinInt) || !b->Includes(-1)) {
    1864             :       ClearFlag(kCanOverflow);
    1865             :     }
    1866             : 
    1867        2600 :     if (!b->CanBeZero()) {
    1868             :       ClearFlag(kCanBeDivByZero);
    1869             :     }
    1870        2600 :     return result;
    1871             :   } else {
    1872           0 :     return HValue::InferRange(zone);
    1873             :   }
    1874             : }
    1875             : 
    1876             : 
    1877             : // Returns the absolute value of its argument minus one, avoiding undefined
    1878             : // behavior at kMinInt.
    1879        6228 : static int32_t AbsMinus1(int32_t a) { return a < 0 ? -(a + 1) : (a - 1); }
    1880             : 
    1881             : 
    1882        5408 : Range* HMod::InferRange(Zone* zone) {
    1883        8522 :   if (representation().IsInteger32()) {
    1884        9342 :     Range* a = left()->range();
    1885       12302 :     Range* b = right()->range();
    1886             : 
    1887             :     // The magnitude of the modulus is bounded by the right operand.
    1888             :     int32_t positive_bound = Max(AbsMinus1(b->lower()), AbsMinus1(b->upper()));
    1889             : 
    1890             :     // The result of the modulo operation has the sign of its left operand.
    1891        3114 :     bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative();
    1892             :     Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0,
    1893        6228 :                                     a->CanBePositive() ? positive_bound : 0);
    1894             : 
    1895        3114 :     result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
    1896             :                                   left_can_be_negative);
    1897             : 
    1898        3114 :     if (!a->CanBeNegative()) {
    1899             :       ClearFlag(HValue::kLeftCanBeNegative);
    1900             :     }
    1901             : 
    1902        6074 :     if (!a->Includes(kMinInt) || !b->Includes(-1)) {
    1903             :       ClearFlag(HValue::kCanOverflow);
    1904             :     }
    1905             : 
    1906        3114 :     if (!b->CanBeZero()) {
    1907             :       ClearFlag(HValue::kCanBeDivByZero);
    1908             :     }
    1909        3114 :     return result;
    1910             :   } else {
    1911        2294 :     return HValue::InferRange(zone);
    1912             :   }
    1913             : }
    1914             : 
    1915             : 
    1916        1582 : Range* HMathMinMax::InferRange(Zone* zone) {
    1917        1582 :   if (representation().IsSmiOrInteger32()) {
    1918         213 :     Range* a = left()->range();
    1919         213 :     Range* b = right()->range();
    1920         213 :     Range* res = a->Copy(zone);
    1921         213 :     if (operation_ == kMathMax) {
    1922         115 :       res->CombinedMax(b);
    1923             :     } else {
    1924             :       DCHECK(operation_ == kMathMin);
    1925          98 :       res->CombinedMin(b);
    1926             :     }
    1927         213 :     return res;
    1928             :   } else {
    1929        1369 :     return HValue::InferRange(zone);
    1930             :   }
    1931             : }
    1932             : 
    1933             : 
    1934     1599341 : void HPushArguments::AddInput(HValue* value) {
    1935     1599341 :   inputs_.Add(NULL, value->block()->zone());
    1936     1599341 :   SetOperandAt(OperandCount() - 1, value);
    1937     1599341 : }
    1938             : 
    1939             : 
    1940           0 : std::ostream& HPhi::PrintTo(std::ostream& os) const {  // NOLINT
    1941           0 :   os << "[";
    1942           0 :   for (int i = 0; i < OperandCount(); ++i) {
    1943           0 :     os << " " << NameOf(OperandAt(i)) << " ";
    1944             :   }
    1945           0 :   return os << " uses" << UseCount()
    1946           0 :             << representation_from_indirect_uses().Mnemonic() << " "
    1947           0 :             << TypeOf(this) << "]";
    1948             : }
    1949             : 
    1950             : 
    1951     2969794 : void HPhi::AddInput(HValue* value) {
    1952     1485153 :   inputs_.Add(NULL, value->block()->zone());
    1953     1485153 :   SetOperandAt(OperandCount() - 1, value);
    1954             :   // Mark phis that may have 'arguments' directly or indirectly as an operand.
    1955     2969794 :   if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) {
    1956             :     SetFlag(kIsArguments);
    1957             :   }
    1958     1485153 : }
    1959             : 
    1960             : 
    1961           0 : bool HPhi::HasRealUses() {
    1962           0 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    1963           0 :     if (!it.value()->IsPhi()) return true;
    1964             :   }
    1965           0 :   return false;
    1966             : }
    1967             : 
    1968             : 
    1969     1119925 : HValue* HPhi::GetRedundantReplacement() {
    1970             :   HValue* candidate = NULL;
    1971             :   int count = OperandCount();
    1972             :   int position = 0;
    1973     3359775 :   while (position < count && candidate == NULL) {
    1974     1119925 :     HValue* current = OperandAt(position++);
    1975     1119925 :     if (current != this) candidate = current;
    1976             :   }
    1977     1581341 :   while (position < count) {
    1978     1202322 :     HValue* current = OperandAt(position++);
    1979     1202322 :     if (current != this && current != candidate) return NULL;
    1980             :   }
    1981             :   DCHECK(candidate != this);
    1982             :   return candidate;
    1983             : }
    1984             : 
    1985             : 
    1986          25 : void HPhi::DeleteFromGraph() {
    1987             :   DCHECK(block() != NULL);
    1988          25 :   block()->RemovePhi(this);
    1989             :   DCHECK(block() == NULL);
    1990          25 : }
    1991             : 
    1992             : 
    1993      316824 : void HPhi::InitRealUses(int phi_id) {
    1994             :   // Initialize real uses.
    1995      316824 :   phi_id_ = phi_id;
    1996             :   // Compute a conservative approximation of truncating uses before inferring
    1997             :   // representations. The proper, exact computation will be done later, when
    1998             :   // inserting representation changes.
    1999      316824 :   SetFlag(kTruncatingToSmi);
    2000             :   SetFlag(kTruncatingToInt32);
    2001      958524 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    2002     2154082 :     HValue* value = it.value();
    2003      958524 :     if (!value->IsPhi()) {
    2004      693353 :       Representation rep = value->observed_input_representation(it.index());
    2005             :       representation_from_non_phi_uses_ =
    2006      693353 :           representation_from_non_phi_uses().generalize(rep);
    2007      693353 :       if (rep.IsSmi() || rep.IsInteger32() || rep.IsDouble()) {
    2008      137905 :         has_type_feedback_from_uses_ = true;
    2009             :       }
    2010             : 
    2011      693353 :       if (FLAG_trace_representation) {
    2012             :         PrintF("#%d Phi is used by real #%d %s as %s\n",
    2013           0 :                id(), value->id(), value->Mnemonic(), rep.Mnemonic());
    2014             :       }
    2015      693353 :       if (!value->IsSimulate()) {
    2016      597779 :         if (!value->CheckFlag(kTruncatingToSmi)) {
    2017             :           ClearFlag(kTruncatingToSmi);
    2018             :         }
    2019      597779 :         if (!value->CheckFlag(kTruncatingToInt32)) {
    2020             :           ClearFlag(kTruncatingToInt32);
    2021             :         }
    2022             :       }
    2023             :     }
    2024             :   }
    2025      316825 : }
    2026             : 
    2027             : 
    2028      925097 : void HPhi::AddNonPhiUsesFrom(HPhi* other) {
    2029      925097 :   if (FLAG_trace_representation) {
    2030             :     PrintF(
    2031             :         "generalizing use representation '%s' of #%d Phi "
    2032             :         "with uses of #%d Phi '%s'\n",
    2033             :         representation_from_indirect_uses().Mnemonic(), id(), other->id(),
    2034           0 :         other->representation_from_non_phi_uses().Mnemonic());
    2035             :   }
    2036             : 
    2037             :   representation_from_indirect_uses_ =
    2038             :       representation_from_indirect_uses().generalize(
    2039      925097 :           other->representation_from_non_phi_uses());
    2040      925097 : }
    2041             : 
    2042             : 
    2043     1277270 : void HSimulate::MergeWith(ZoneList<HSimulate*>* list) {
    2044     2631390 :   while (!list->is_empty()) {
    2045     1430971 :     HSimulate* from = list->RemoveLast();
    2046             :     ZoneList<HValue*>* from_values = &from->values_;
    2047      481692 :     for (int i = 0; i < from_values->length(); ++i) {
    2048      163996 :       if (from->HasAssignedIndexAt(i)) {
    2049             :         int index = from->GetAssignedIndexAt(i);
    2050       26526 :         if (HasValueForIndex(index)) continue;
    2051      257455 :         AddAssignedValue(index, from_values->at(i));
    2052             :       } else {
    2053      137470 :         if (pop_count_ > 0) {
    2054      130960 :           pop_count_--;
    2055             :         } else {
    2056        6510 :           AddPushedValue(from_values->at(i));
    2057             :         }
    2058             :       }
    2059             :     }
    2060       76850 :     pop_count_ += from->pop_count_;
    2061       76850 :     from->DeleteAndReplaceWith(NULL);
    2062             :   }
    2063     1277269 : }
    2064             : 
    2065             : 
    2066           0 : std::ostream& HSimulate::PrintDataTo(std::ostream& os) const {  // NOLINT
    2067           0 :   os << "id=" << ast_id().ToInt();
    2068           0 :   if (pop_count_ > 0) os << " pop " << pop_count_;
    2069           0 :   if (values_.length() > 0) {
    2070           0 :     if (pop_count_ > 0) os << " /";
    2071           0 :     for (int i = values_.length() - 1; i >= 0; --i) {
    2072           0 :       if (HasAssignedIndexAt(i)) {
    2073           0 :         os << " var[" << GetAssignedIndexAt(i) << "] = ";
    2074             :       } else {
    2075           0 :         os << " push ";
    2076             :       }
    2077           0 :       os << NameOf(values_[i]);
    2078           0 :       if (i > 0) os << ",";
    2079             :     }
    2080             :   }
    2081           0 :   return os;
    2082             : }
    2083             : 
    2084             : 
    2085    10771243 : void HSimulate::ReplayEnvironment(HEnvironment* env) {
    2086    12062461 :   if (is_done_with_replay()) return;
    2087             :   DCHECK(env != NULL);
    2088             :   env->set_ast_id(ast_id());
    2089     4740004 :   env->Drop(pop_count());
    2090     8596859 :   for (int i = values()->length() - 1; i >= 0; --i) {
    2091     3856872 :     HValue* value = values()->at(i);
    2092     3856872 :     if (HasAssignedIndexAt(i)) {
    2093     1254949 :       env->Bind(GetAssignedIndexAt(i), value);
    2094             :     } else {
    2095             :       env->Push(value);
    2096             :     }
    2097             :   }
    2098             :   set_done_with_replay();
    2099             : }
    2100             : 
    2101             : 
    2102       31827 : static void ReplayEnvironmentNested(const ZoneList<HValue*>* values,
    2103        8487 :                                     HCapturedObject* other) {
    2104      373668 :   for (int i = 0; i < values->length(); ++i) {
    2105      341841 :     HValue* value = values->at(i);
    2106      155007 :     if (value->IsCapturedObject()) {
    2107       16974 :       if (HCapturedObject::cast(value)->capture_id() == other->capture_id()) {
    2108        4833 :         values->at(i) = other;
    2109             :       } else {
    2110        3654 :         ReplayEnvironmentNested(HCapturedObject::cast(value)->values(), other);
    2111             :       }
    2112             :     }
    2113             :   }
    2114       31827 : }
    2115             : 
    2116             : 
    2117             : // Replay captured objects by replacing all captured objects with the
    2118             : // same capture id in the current and all outer environments.
    2119       39134 : void HCapturedObject::ReplayEnvironment(HEnvironment* env) {
    2120             :   DCHECK(env != NULL);
    2121       50095 :   while (env != NULL) {
    2122       28173 :     ReplayEnvironmentNested(env->values(), this);
    2123             :     env = env->outer();
    2124             :   }
    2125       10961 : }
    2126             : 
    2127             : 
    2128           0 : std::ostream& HCapturedObject::PrintDataTo(std::ostream& os) const {  // NOLINT
    2129           0 :   os << "#" << capture_id() << " ";
    2130           0 :   return HDematerializedObject::PrintDataTo(os);
    2131             : }
    2132             : 
    2133             : 
    2134      126898 : void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target,
    2135             :                                          Zone* zone) {
    2136             :   DCHECK(return_target->IsInlineReturnTarget());
    2137             :   return_targets_.Add(return_target, zone);
    2138      126898 : }
    2139             : 
    2140             : 
    2141           0 : std::ostream& HEnterInlined::PrintDataTo(std::ostream& os) const {  // NOLINT
    2142           0 :   os << function()->debug_name()->ToCString().get();
    2143           0 :   if (syntactic_tail_call_mode() == TailCallMode::kAllow) {
    2144           0 :     os << ", JSTailCall";
    2145             :   }
    2146           0 :   return os;
    2147             : }
    2148             : 
    2149             : 
    2150             : static bool IsInteger32(double value) {
    2151      624258 :   if (value >= std::numeric_limits<int32_t>::min() &&
    2152             :       value <= std::numeric_limits<int32_t>::max()) {
    2153      586626 :     double roundtrip_value = static_cast<double>(static_cast<int32_t>(value));
    2154      586626 :     return bit_cast<int64_t>(roundtrip_value) == bit_cast<int64_t>(value);
    2155             :   }
    2156             :   return false;
    2157             : }
    2158             : 
    2159             : 
    2160         128 : HConstant::HConstant(Special special)
    2161             :     : HTemplateInstruction<0>(HType::TaggedNumber()),
    2162             :       object_(Handle<Object>::null()),
    2163             :       object_map_(Handle<Map>::null()),
    2164             :       bit_field_(HasDoubleValueField::encode(true) |
    2165             :                  InstanceTypeField::encode(kUnknownInstanceType)),
    2166         256 :       int32_value_(0) {
    2167             :   DCHECK_EQ(kHoleNaN, special);
    2168             :   // Manipulating the signaling NaN used for the hole in C++, e.g. with bit_cast
    2169             :   // will change its value on ia32 (the x87 stack is used to return values
    2170             :   // and stores to the stack silently clear the signalling bit).
    2171             :   // Therefore we have to use memcpy for initializing |double_value_| with
    2172             :   // kHoleNanInt64 here.
    2173         128 :   std::memcpy(&double_value_, &kHoleNanInt64, sizeof(double_value_));
    2174         128 :   Initialize(Representation::Double());
    2175         128 : }
    2176             : 
    2177             : 
    2178     4622177 : HConstant::HConstant(Handle<Object> object, Representation r)
    2179             :     : HTemplateInstruction<0>(HType::FromValue(object)),
    2180             :       object_(Unique<Object>::CreateUninitialized(object)),
    2181             :       object_map_(Handle<Map>::null()),
    2182             :       bit_field_(
    2183             :           HasStableMapValueField::encode(false) |
    2184             :           HasSmiValueField::encode(false) | HasInt32ValueField::encode(false) |
    2185             :           HasDoubleValueField::encode(false) |
    2186             :           HasExternalReferenceValueField::encode(false) |
    2187     4622178 :           IsNotInNewSpaceField::encode(true) |
    2188     4622176 :           BooleanValueField::encode(object->BooleanValue()) |
    2189     4622178 :           IsUndetectableField::encode(false) | IsCallableField::encode(false) |
    2190    13866531 :           InstanceTypeField::encode(kUnknownInstanceType)) {
    2191     4622178 :   if (object->IsNumber()) {
    2192             :     double n = object->Number();
    2193             :     bool has_int32_value = IsInteger32(n);
    2194     1194224 :     bit_field_ = HasInt32ValueField::update(bit_field_, has_int32_value);
    2195      597112 :     int32_value_ = DoubleToInt32(n);
    2196             :     bit_field_ = HasSmiValueField::update(
    2197     1194224 :         bit_field_, has_int32_value && Smi::IsValid(int32_value_));
    2198      597112 :     if (std::isnan(n)) {
    2199        4375 :       double_value_ = std::numeric_limits<double>::quiet_NaN();
    2200             :       // Canonicalize object with NaN value.
    2201             :       DCHECK(object->IsHeapObject());  // NaN can't be a Smi.
    2202             :       Isolate* isolate = HeapObject::cast(*object)->GetIsolate();
    2203             :       object = isolate->factory()->nan_value();
    2204        4375 :       object_ = Unique<Object>::CreateUninitialized(object);
    2205             :     } else {
    2206      592737 :       double_value_ = n;
    2207             :       // Canonicalize object with -0.0 value.
    2208      592737 :       if (bit_cast<int64_t>(n) == bit_cast<int64_t>(-0.0)) {
    2209             :         DCHECK(object->IsHeapObject());  // -0.0 can't be a Smi.
    2210             :         Isolate* isolate = HeapObject::cast(*object)->GetIsolate();
    2211             :         object = isolate->factory()->minus_zero_value();
    2212        7869 :         object_ = Unique<Object>::CreateUninitialized(object);
    2213             :       }
    2214             :     }
    2215     1194224 :     bit_field_ = HasDoubleValueField::update(bit_field_, true);
    2216             :   }
    2217     4622178 :   if (object->IsHeapObject()) {
    2218             :     Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
    2219             :     Isolate* isolate = heap_object->GetIsolate();
    2220             :     Handle<Map> map(heap_object->map(), isolate);
    2221             :     bit_field_ = IsNotInNewSpaceField::update(
    2222     8161964 :         bit_field_, !isolate->heap()->InNewSpace(*object));
    2223     4080982 :     bit_field_ = InstanceTypeField::update(bit_field_, map->instance_type());
    2224             :     bit_field_ =
    2225     4080982 :         IsUndetectableField::update(bit_field_, map->is_undetectable());
    2226     4080982 :     bit_field_ = IsCallableField::update(bit_field_, map->is_callable());
    2227     4080982 :     if (map->is_stable()) object_map_ = Unique<Map>::CreateImmovable(map);
    2228             :     bit_field_ = HasStableMapValueField::update(
    2229             :         bit_field_,
    2230     8237090 :         HasMapValue() && Handle<Map>::cast(heap_object)->is_stable());
    2231             :   }
    2232             : 
    2233     4622178 :   Initialize(r);
    2234     4622175 : }
    2235             : 
    2236             : 
    2237      623995 : HConstant::HConstant(Unique<Object> object, Unique<Map> object_map,
    2238             :                      bool has_stable_map_value, Representation r, HType type,
    2239             :                      bool is_not_in_new_space, bool boolean_value,
    2240             :                      bool is_undetectable, InstanceType instance_type)
    2241             :     : HTemplateInstruction<0>(type),
    2242             :       object_(object),
    2243             :       object_map_(object_map),
    2244             :       bit_field_(HasStableMapValueField::encode(has_stable_map_value) |
    2245             :                  HasSmiValueField::encode(false) |
    2246             :                  HasInt32ValueField::encode(false) |
    2247             :                  HasDoubleValueField::encode(false) |
    2248      623995 :                  HasExternalReferenceValueField::encode(false) |
    2249      623995 :                  IsNotInNewSpaceField::encode(is_not_in_new_space) |
    2250      623995 :                  BooleanValueField::encode(boolean_value) |
    2251      623995 :                  IsUndetectableField::encode(is_undetectable) |
    2252     1247990 :                  InstanceTypeField::encode(instance_type)) {
    2253             :   DCHECK(!object.handle().is_null());
    2254             :   DCHECK(!type.IsTaggedNumber() || type.IsNone());
    2255      623995 :   Initialize(r);
    2256      623995 : }
    2257             : 
    2258             : 
    2259     3671761 : HConstant::HConstant(int32_t integer_value, Representation r,
    2260             :                      bool is_not_in_new_space, Unique<Object> object)
    2261             :     : object_(object),
    2262             :       object_map_(Handle<Map>::null()),
    2263             :       bit_field_(HasStableMapValueField::encode(false) |
    2264             :                  HasSmiValueField::encode(Smi::IsValid(integer_value)) |
    2265             :                  HasInt32ValueField::encode(true) |
    2266             :                  HasDoubleValueField::encode(true) |
    2267     3671761 :                  HasExternalReferenceValueField::encode(false) |
    2268     3671761 :                  IsNotInNewSpaceField::encode(is_not_in_new_space) |
    2269     3671761 :                  BooleanValueField::encode(integer_value != 0) |
    2270     3671761 :                  IsUndetectableField::encode(false) |
    2271             :                  InstanceTypeField::encode(kUnknownInstanceType)),
    2272             :       int32_value_(integer_value),
    2273    11015283 :       double_value_(FastI2D(integer_value)) {
    2274             :   // It's possible to create a constant with a value in Smi-range but stored
    2275             :   // in a (pre-existing) HeapNumber. See crbug.com/349878.
    2276     3671761 :   bool could_be_heapobject = r.IsTagged() && !object.handle().is_null();
    2277     3671761 :   bool is_smi = HasSmiValue() && !could_be_heapobject;
    2278     3671761 :   set_type(is_smi ? HType::Smi() : HType::TaggedNumber());
    2279     3671761 :   Initialize(r);
    2280     3671748 : }
    2281             : 
    2282       27146 : HConstant::HConstant(double double_value, Representation r,
    2283             :                      bool is_not_in_new_space, Unique<Object> object)
    2284             :     : object_(object),
    2285             :       object_map_(Handle<Map>::null()),
    2286             :       bit_field_(HasStableMapValueField::encode(false) |
    2287       27146 :                  HasInt32ValueField::encode(IsInteger32(double_value)) |
    2288             :                  HasDoubleValueField::encode(true) |
    2289       27146 :                  HasExternalReferenceValueField::encode(false) |
    2290       27146 :                  IsNotInNewSpaceField::encode(is_not_in_new_space) |
    2291       27146 :                  BooleanValueField::encode(double_value != 0 &&
    2292             :                                            !std::isnan(double_value)) |
    2293       27146 :                  IsUndetectableField::encode(false) |
    2294             :                  InstanceTypeField::encode(kUnknownInstanceType)),
    2295       54292 :       int32_value_(DoubleToInt32(double_value)) {
    2296             :   bit_field_ = HasSmiValueField::update(
    2297       54292 :       bit_field_, HasInteger32Value() && Smi::IsValid(int32_value_));
    2298             :   // It's possible to create a constant with a value in Smi-range but stored
    2299             :   // in a (pre-existing) HeapNumber. See crbug.com/349878.
    2300       27146 :   bool could_be_heapobject = r.IsTagged() && !object.handle().is_null();
    2301       27146 :   bool is_smi = HasSmiValue() && !could_be_heapobject;
    2302       27146 :   set_type(is_smi ? HType::Smi() : HType::TaggedNumber());
    2303       27146 :   if (std::isnan(double_value)) {
    2304        6412 :     double_value_ = std::numeric_limits<double>::quiet_NaN();
    2305             :   } else {
    2306       20734 :     double_value_ = double_value;
    2307             :   }
    2308       27146 :   Initialize(r);
    2309       27146 : }
    2310             : 
    2311             : 
    2312       11205 : HConstant::HConstant(ExternalReference reference)
    2313             :     : HTemplateInstruction<0>(HType::Any()),
    2314             :       object_(Unique<Object>(Handle<Object>::null())),
    2315             :       object_map_(Handle<Map>::null()),
    2316             :       bit_field_(
    2317             :           HasStableMapValueField::encode(false) |
    2318             :           HasSmiValueField::encode(false) | HasInt32ValueField::encode(false) |
    2319             :           HasDoubleValueField::encode(false) |
    2320             :           HasExternalReferenceValueField::encode(true) |
    2321             :           IsNotInNewSpaceField::encode(true) | BooleanValueField::encode(true) |
    2322             :           IsUndetectableField::encode(false) |
    2323             :           InstanceTypeField::encode(kUnknownInstanceType)),
    2324       22410 :       external_reference_value_(reference) {
    2325       11205 :   Initialize(Representation::External());
    2326       11205 : }
    2327             : 
    2328             : 
    2329    15801193 : void HConstant::Initialize(Representation r) {
    2330     8956313 :   if (r.IsNone()) {
    2331             :     if (HasSmiValue() && SmiValuesAre31Bits()) {
    2332             :       r = Representation::Smi();
    2333     6844880 :     } else if (HasInteger32Value()) {
    2334             :       r = Representation::Integer32();
    2335     4082422 :     } else if (HasDoubleValue()) {
    2336             :       r = Representation::Double();
    2337     4025066 :     } else if (HasExternalReferenceValue()) {
    2338             :       r = Representation::External();
    2339             :     } else {
    2340             :       Handle<Object> object = object_.handle();
    2341     4025065 :       if (object->IsJSObject()) {
    2342             :         // Try to eagerly migrate JSObjects that have deprecated maps.
    2343             :         Handle<JSObject> js_object = Handle<JSObject>::cast(object);
    2344      805824 :         if (js_object->map()->is_deprecated()) {
    2345           8 :           JSObject::TryMigrateInstance(js_object);
    2346             :         }
    2347             :       }
    2348             :       r = Representation::Tagged();
    2349             :     }
    2350             :   }
    2351     8956312 :   if (r.IsSmi()) {
    2352             :     // If we have an existing handle, zap it, because it might be a heap
    2353             :     // number which we must not re-use when copying this HConstant to
    2354             :     // Tagged representation later, because having Smi representation now
    2355             :     // could cause heap object checks not to get emitted.
    2356      867898 :     object_ = Unique<Object>(Handle<Object>::null());
    2357             :   }
    2358     8956312 :   if (r.IsSmiOrInteger32() && object_.handle().is_null()) {
    2359             :     // If it's not a heap object, it can't be in new space.
    2360     6178850 :     bit_field_ = IsNotInNewSpaceField::update(bit_field_, true);
    2361             :   }
    2362             :   set_representation(r);
    2363             :   SetFlag(kUseGVN);
    2364     8956312 : }
    2365             : 
    2366             : 
    2367      178835 : bool HConstant::ImmortalImmovable() const {
    2368      178835 :   if (HasInteger32Value()) {
    2369             :     return false;
    2370             :   }
    2371      134129 :   if (HasDoubleValue()) {
    2372         556 :     if (IsSpecialDouble()) {
    2373             :       return true;
    2374             :     }
    2375         305 :     return false;
    2376             :   }
    2377      133573 :   if (HasExternalReferenceValue()) {
    2378             :     return false;
    2379             :   }
    2380             : 
    2381             :   DCHECK(!object_.handle().is_null());
    2382    16351788 :   Heap* heap = isolate()->heap();
    2383             :   DCHECK(!object_.IsKnownGlobal(heap->minus_zero_value()));
    2384             :   DCHECK(!object_.IsKnownGlobal(heap->nan_value()));
    2385             :   return
    2386             : #define IMMORTAL_IMMOVABLE_ROOT(name) \
    2387             :   object_.IsKnownGlobal(heap->root(Heap::k##name##RootIndex)) ||
    2388    11909406 :       IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
    2389             : #undef IMMORTAL_IMMOVABLE_ROOT
    2390             : #define INTERNALIZED_STRING(name, value) \
    2391             :       object_.IsKnownGlobal(heap->name()) ||
    2392    15237488 :       INTERNALIZED_STRING_LIST(INTERNALIZED_STRING)
    2393             : #undef INTERNALIZED_STRING
    2394             : #define STRING_TYPE(NAME, size, name, Name) \
    2395             :       object_.IsKnownGlobal(heap->name##_map()) ||
    2396     1165446 :       STRING_TYPE_LIST(STRING_TYPE)
    2397             : #undef STRING_TYPE
    2398      133572 :       false;
    2399             : }
    2400             : 
    2401             : 
    2402     8781235 : bool HConstant::EmitAtUses() {
    2403             :   DCHECK(IsLinked());
    2404     9130962 :   if (block()->graph()->has_osr() &&
    2405      349727 :       block()->graph()->IsStandardConstant(this)) {
    2406             :     return true;
    2407             :   }
    2408     8741119 :   if (HasNoUses()) return true;
    2409     8008276 :   if (IsCell()) return false;
    2410     8008279 :   if (representation().IsDouble()) return false;
    2411     7874701 :   if (representation().IsExternal()) return false;
    2412     7855494 :   return true;
    2413             : }
    2414             : 
    2415             : 
    2416     3865025 : HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
    2417     2339000 :   if (r.IsSmi() && !HasSmiValue()) return NULL;
    2418     1474806 :   if (r.IsInteger32() && !HasInteger32Value()) return NULL;
    2419     1524317 :   if (r.IsDouble() && !HasDoubleValue()) return NULL;
    2420     1471208 :   if (r.IsExternal() && !HasExternalReferenceValue()) return NULL;
    2421     1471208 :   if (HasInteger32Value()) {
    2422     4336803 :     return new (zone) HConstant(int32_value_, r, NotInNewSpace(), object_);
    2423             :   }
    2424       25607 :   if (HasDoubleValue()) {
    2425       76821 :     return new (zone) HConstant(double_value_, r, NotInNewSpace(), object_);
    2426             :   }
    2427           0 :   if (HasExternalReferenceValue()) {
    2428           0 :     return new(zone) HConstant(external_reference_value_);
    2429             :   }
    2430             :   DCHECK(!object_.handle().is_null());
    2431             :   return new (zone) HConstant(object_, object_map_, HasStableMapValue(), r,
    2432             :                               type_, NotInNewSpace(), BooleanValue(),
    2433           0 :                               IsUndetectable(), GetInstanceType());
    2434             : }
    2435             : 
    2436             : 
    2437        3902 : Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) {
    2438             :   HConstant* res = NULL;
    2439        3902 :   if (HasInteger32Value()) {
    2440             :     res = new (zone) HConstant(int32_value_, Representation::Integer32(),
    2441           0 :                                NotInNewSpace(), object_);
    2442        3902 :   } else if (HasDoubleValue()) {
    2443             :     res = new (zone)
    2444        3839 :         HConstant(DoubleToInt32(double_value_), Representation::Integer32(),
    2445       11517 :                   NotInNewSpace(), object_);
    2446             :   }
    2447        3902 :   return res != NULL ? Just(res) : Nothing<HConstant*>();
    2448             : }
    2449             : 
    2450             : 
    2451      265471 : Maybe<HConstant*> HConstant::CopyToTruncatedNumber(Isolate* isolate,
    2452             :                                                    Zone* zone) {
    2453             :   HConstant* res = NULL;
    2454      265471 :   Handle<Object> handle = this->handle(isolate);
    2455      265471 :   if (handle->IsBoolean()) {
    2456        4220 :     res = handle->BooleanValue() ?
    2457        8440 :       new(zone) HConstant(1) : new(zone) HConstant(0);
    2458      261251 :   } else if (handle->IsUndefined(isolate)) {
    2459        2104 :     res = new (zone) HConstant(std::numeric_limits<double>::quiet_NaN());
    2460      260199 :   } else if (handle->IsNull(isolate)) {
    2461          54 :     res = new(zone) HConstant(0);
    2462      260172 :   } else if (handle->IsString()) {
    2463        3760 :     res = new(zone) HConstant(String::ToNumber(Handle<String>::cast(handle)));
    2464             :   }
    2465      265471 :   return res != NULL ? Just(res) : Nothing<HConstant*>();
    2466             : }
    2467             : 
    2468             : 
    2469           0 : std::ostream& HConstant::PrintDataTo(std::ostream& os) const {  // NOLINT
    2470           0 :   if (HasInteger32Value()) {
    2471           0 :     os << int32_value_ << " ";
    2472           0 :   } else if (HasDoubleValue()) {
    2473           0 :     os << double_value_ << " ";
    2474           0 :   } else if (HasExternalReferenceValue()) {
    2475           0 :     os << reinterpret_cast<void*>(external_reference_value_.address()) << " ";
    2476             :   } else {
    2477             :     // The handle() method is silently and lazily mutating the object.
    2478           0 :     Handle<Object> h = const_cast<HConstant*>(this)->handle(isolate());
    2479           0 :     os << Brief(*h) << " ";
    2480           0 :     if (HasStableMapValue()) os << "[stable-map] ";
    2481           0 :     if (HasObjectMap()) os << "[map " << *ObjectMap().handle() << "] ";
    2482             :   }
    2483           0 :   if (!NotInNewSpace()) os << "[new space] ";
    2484           0 :   return os;
    2485             : }
    2486             : 
    2487             : 
    2488           0 : std::ostream& HBinaryOperation::PrintDataTo(std::ostream& os) const {  // NOLINT
    2489           0 :   os << NameOf(left()) << " " << NameOf(right());
    2490           0 :   if (CheckFlag(kCanOverflow)) os << " !";
    2491           0 :   if (CheckFlag(kBailoutOnMinusZero)) os << " -0?";
    2492           0 :   return os;
    2493             : }
    2494             : 
    2495             : 
    2496      993796 : void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) {
    2497             :   DCHECK(CheckFlag(kFlexibleRepresentation));
    2498      993796 :   Representation new_rep = RepresentationFromInputs();
    2499      993794 :   UpdateRepresentation(new_rep, h_infer, "inputs");
    2500             : 
    2501      993795 :   if (representation().IsSmi() && HasNonSmiUse()) {
    2502             :     UpdateRepresentation(
    2503       47156 :         Representation::Integer32(), h_infer, "use requirements");
    2504             :   }
    2505             : 
    2506      993799 :   if (observed_output_representation_.IsNone()) {
    2507      440936 :     new_rep = RepresentationFromUses();
    2508      440936 :     UpdateRepresentation(new_rep, h_infer, "uses");
    2509             :   } else {
    2510      552863 :     new_rep = RepresentationFromOutput();
    2511      552864 :     UpdateRepresentation(new_rep, h_infer, "output");
    2512             :   }
    2513      993801 : }
    2514             : 
    2515             : 
    2516      989777 : Representation HBinaryOperation::RepresentationFromInputs() {
    2517             :   // Determine the worst case of observed input representations and
    2518             :   // the currently assumed output representation.
    2519      989777 :   Representation rep = representation();
    2520     2969325 :   for (int i = 1; i <= 2; ++i) {
    2521     1979549 :     rep = rep.generalize(observed_input_representation(i));
    2522             :   }
    2523             :   // If any of the actual input representation is more general than what we
    2524             :   // have so far but not Tagged, use that representation instead.
    2525             :   Representation left_rep = left()->representation();
    2526             :   Representation right_rep = right()->representation();
    2527      989776 :   if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
    2528      989780 :   if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
    2529             : 
    2530      989779 :   return rep;
    2531             : }
    2532             : 
    2533             : 
    2534       23735 : bool HBinaryOperation::IgnoreObservedOutputRepresentation(
    2535             :     Representation current_rep) {
    2536       23294 :   return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) ||
    2537       29930 :           (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) &&
    2538             :          // Mul in Integer32 mode would be too precise.
    2539        6823 :          (!this->IsMul() || HMul::cast(this)->MulMinusOne());
    2540             : }
    2541             : 
    2542             : 
    2543      552863 : Representation HBinaryOperation::RepresentationFromOutput() {
    2544      552863 :   Representation rep = representation();
    2545             :   // Consider observed output representation, but ignore it if it's Double,
    2546             :   // this instruction is not a division, and all its uses are truncating
    2547             :   // to Integer32.
    2548      576597 :   if (observed_output_representation_.is_more_general_than(rep) &&
    2549       23735 :       !IgnoreObservedOutputRepresentation(rep)) {
    2550       19015 :     return observed_output_representation_;
    2551             :   }
    2552             :   return Representation::None();
    2553             : }
    2554             : 
    2555             : 
    2556         607 : void HBinaryOperation::AssumeRepresentation(Representation r) {
    2557             :   set_observed_input_representation(1, r);
    2558             :   set_observed_input_representation(2, r);
    2559         607 :   HValue::AssumeRepresentation(r);
    2560         607 : }
    2561             : 
    2562             : 
    2563        2203 : void HMathMinMax::InferRepresentation(HInferRepresentationPhase* h_infer) {
    2564             :   DCHECK(CheckFlag(kFlexibleRepresentation));
    2565        2203 :   Representation new_rep = RepresentationFromInputs();
    2566        2203 :   UpdateRepresentation(new_rep, h_infer, "inputs");
    2567             :   // Do not care about uses.
    2568        2203 : }
    2569             : 
    2570             : 
    2571       96855 : Range* HBitwise::InferRange(Zone* zone) {
    2572       96855 :   if (op() == Token::BIT_XOR) {
    2573       44270 :     if (left()->HasRange() && right()->HasRange()) {
    2574             :       // The maximum value has the high bit, and all bits below, set:
    2575             :       // (1 << high) - 1.
    2576             :       // If the range can be negative, the minimum int is a negative number with
    2577             :       // the high bit, and all bits below, unset:
    2578             :       // -(1 << high).
    2579             :       // If it cannot be negative, conservatively choose 0 as minimum int.
    2580       22135 :       int64_t left_upper = left()->range()->upper();
    2581       22135 :       int64_t left_lower = left()->range()->lower();
    2582       22135 :       int64_t right_upper = right()->range()->upper();
    2583       22135 :       int64_t right_lower = right()->range()->lower();
    2584             : 
    2585       22135 :       if (left_upper < 0) left_upper = ~left_upper;
    2586       22135 :       if (left_lower < 0) left_lower = ~left_lower;
    2587       22135 :       if (right_upper < 0) right_upper = ~right_upper;
    2588       22135 :       if (right_lower < 0) right_lower = ~right_lower;
    2589             : 
    2590             :       int high = MostSignificantBit(
    2591             :           static_cast<uint32_t>(
    2592       22135 :               left_upper | left_lower | right_upper | right_lower));
    2593             : 
    2594             :       int64_t limit = 1;
    2595       22135 :       limit <<= high;
    2596       13629 :       int32_t min = (left()->range()->CanBeNegative() ||
    2597             :                      right()->range()->CanBeNegative())
    2598       30859 :                     ? static_cast<int32_t>(-limit) : 0;
    2599       44270 :       return new(zone) Range(min, static_cast<int32_t>(limit - 1));
    2600             :     }
    2601           0 :     Range* result = HValue::InferRange(zone);
    2602             :     result->set_can_be_minus_zero(false);
    2603           0 :     return result;
    2604             :   }
    2605             :   const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff);
    2606       74720 :   int32_t left_mask = (left()->range() != NULL)
    2607             :       ? left()->range()->Mask()
    2608       74720 :       : kDefaultMask;
    2609       74720 :   int32_t right_mask = (right()->range() != NULL)
    2610             :       ? right()->range()->Mask()
    2611       74720 :       : kDefaultMask;
    2612             :   int32_t result_mask = (op() == Token::BIT_AND)
    2613             :       ? left_mask & right_mask
    2614       74720 :       : left_mask | right_mask;
    2615      132044 :   if (result_mask >= 0) return new(zone) Range(0, result_mask);
    2616             : 
    2617       17396 :   Range* result = HValue::InferRange(zone);
    2618             :   result->set_can_be_minus_zero(false);
    2619       17396 :   return result;
    2620             : }
    2621             : 
    2622             : 
    2623       13789 : Range* HSar::InferRange(Zone* zone) {
    2624       13789 :   if (right()->IsConstant()) {
    2625       24703 :     HConstant* c = HConstant::cast(right());
    2626       12356 :     if (c->HasInteger32Value()) {
    2627       12347 :       Range* result = (left()->range() != NULL)
    2628             :           ? left()->range()->Copy(zone)
    2629       12347 :           : new(zone) Range();
    2630             :       result->Sar(c->Integer32Value());
    2631       12347 :       return result;
    2632             :     }
    2633             :   }
    2634        1442 :   return HValue::InferRange(zone);
    2635             : }
    2636             : 
    2637             : 
    2638        9094 : Range* HShr::InferRange(Zone* zone) {
    2639        9094 :   if (right()->IsConstant()) {
    2640       15903 :     HConstant* c = HConstant::cast(right());
    2641        7295 :     if (c->HasInteger32Value()) {
    2642        7288 :       int shift_count = c->Integer32Value() & 0x1f;
    2643        7288 :       if (left()->range()->CanBeNegative()) {
    2644             :         // Only compute bounds if the result always fits into an int32.
    2645             :         return (shift_count >= 1)
    2646             :             ? new(zone) Range(0,
    2647        5003 :                               static_cast<uint32_t>(0xffffffff) >> shift_count)
    2648       11936 :             : new(zone) Range();
    2649             :       } else {
    2650             :         // For positive inputs we can use the >> operator.
    2651             :         Range* result = (left()->range() != NULL)
    2652             :             ? left()->range()->Copy(zone)
    2653        1320 :             : new(zone) Range();
    2654             :         result->Sar(c->Integer32Value());
    2655        1320 :         return result;
    2656             :       }
    2657             :     }
    2658             :   }
    2659        1806 :   return HValue::InferRange(zone);
    2660             : }
    2661             : 
    2662             : 
    2663       16458 : Range* HShl::InferRange(Zone* zone) {
    2664       16458 :   if (right()->IsConstant()) {
    2665       30047 :     HConstant* c = HConstant::cast(right());
    2666       15027 :     if (c->HasInteger32Value()) {
    2667       15020 :       Range* result = (left()->range() != NULL)
    2668             :           ? left()->range()->Copy(zone)
    2669       15020 :           : new(zone) Range();
    2670             :       result->Shl(c->Integer32Value());
    2671       15020 :       return result;
    2672             :     }
    2673             :   }
    2674        1438 :   return HValue::InferRange(zone);
    2675             : }
    2676             : 
    2677             : 
    2678      254308 : Range* HLoadNamedField::InferRange(Zone* zone) {
    2679      254308 :   if (access().representation().IsInteger8()) {
    2680           0 :     return new(zone) Range(kMinInt8, kMaxInt8);
    2681             :   }
    2682      254308 :   if (access().representation().IsUInteger8()) {
    2683       22303 :     return new(zone) Range(kMinUInt8, kMaxUInt8);
    2684             :   }
    2685      232005 :   if (access().representation().IsInteger16()) {
    2686           0 :     return new(zone) Range(kMinInt16, kMaxInt16);
    2687             :   }
    2688      232005 :   if (access().representation().IsUInteger16()) {
    2689           0 :     return new(zone) Range(kMinUInt16, kMaxUInt16);
    2690             :   }
    2691      232005 :   if (access().IsStringLength()) {
    2692       18785 :     return new(zone) Range(0, String::kMaxLength);
    2693             :   }
    2694      213220 :   return HValue::InferRange(zone);
    2695             : }
    2696             : 
    2697             : 
    2698       51620 : Range* HLoadKeyed::InferRange(Zone* zone) {
    2699       51620 :   switch (elements_kind()) {
    2700             :     case INT8_ELEMENTS:
    2701         163 :       return new(zone) Range(kMinInt8, kMaxInt8);
    2702             :     case UINT8_ELEMENTS:
    2703             :     case UINT8_CLAMPED_ELEMENTS:
    2704         367 :       return new(zone) Range(kMinUInt8, kMaxUInt8);
    2705             :     case INT16_ELEMENTS:
    2706         100 :       return new(zone) Range(kMinInt16, kMaxInt16);
    2707             :     case UINT16_ELEMENTS:
    2708         112 :       return new(zone) Range(kMinUInt16, kMaxUInt16);
    2709             :     default:
    2710       50878 :       return HValue::InferRange(zone);
    2711             :   }
    2712             : }
    2713             : 
    2714             : 
    2715           0 : std::ostream& HCompareGeneric::PrintDataTo(std::ostream& os) const {  // NOLINT
    2716           0 :   os << Token::Name(token()) << " ";
    2717           0 :   return HBinaryOperation::PrintDataTo(os);
    2718             : }
    2719             : 
    2720             : 
    2721           0 : std::ostream& HStringCompareAndBranch::PrintDataTo(
    2722           0 :     std::ostream& os) const {  // NOLINT
    2723           0 :   os << Token::Name(token()) << " ";
    2724           0 :   return HControlInstruction::PrintDataTo(os);
    2725             : }
    2726             : 
    2727             : 
    2728           0 : std::ostream& HCompareNumericAndBranch::PrintDataTo(
    2729           0 :     std::ostream& os) const {  // NOLINT
    2730           0 :   os << Token::Name(token()) << " " << NameOf(left()) << " " << NameOf(right());
    2731           0 :   return HControlInstruction::PrintDataTo(os);
    2732             : }
    2733             : 
    2734             : 
    2735           0 : std::ostream& HCompareObjectEqAndBranch::PrintDataTo(
    2736             :     std::ostream& os) const {  // NOLINT
    2737           0 :   os << NameOf(left()) << " " << NameOf(right());
    2738           0 :   return HControlInstruction::PrintDataTo(os);
    2739             : }
    2740             : 
    2741             : 
    2742      282685 : bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    2743      282685 :   if (known_successor_index() != kNoKnownSuccessorIndex) {
    2744           0 :     *block = SuccessorAt(known_successor_index());
    2745           0 :     return true;
    2746             :   }
    2747      283110 :   if (FLAG_fold_constants && left()->IsConstant() && right()->IsConstant()) {
    2748          20 :     *block = HConstant::cast(left())->DataEquals(HConstant::cast(right()))
    2749          20 :         ? FirstSuccessor() : SecondSuccessor();
    2750          20 :     return true;
    2751             :   }
    2752      282665 :   *block = NULL;
    2753      282665 :   return false;
    2754             : }
    2755             : 
    2756             : 
    2757        3160 : bool HIsStringAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    2758        3160 :   if (known_successor_index() != kNoKnownSuccessorIndex) {
    2759          12 :     *block = SuccessorAt(known_successor_index());
    2760          12 :     return true;
    2761             :   }
    2762        3162 :   if (FLAG_fold_constants && value()->IsConstant()) {
    2763             :     *block = HConstant::cast(value())->HasStringValue()
    2764           0 :         ? FirstSuccessor() : SecondSuccessor();
    2765           0 :     return true;
    2766             :   }
    2767        3148 :   if (value()->type().IsString()) {
    2768          60 :     *block = FirstSuccessor();
    2769          60 :     return true;
    2770             :   }
    2771        6138 :   if (value()->type().IsSmi() ||
    2772        3050 :       value()->type().IsNull() ||
    2773        3050 :       value()->type().IsBoolean() ||
    2774        6138 :       value()->type().IsUndefined() ||
    2775             :       value()->type().IsJSReceiver()) {
    2776         114 :     *block = SecondSuccessor();
    2777         114 :     return true;
    2778             :   }
    2779        2974 :   *block = NULL;
    2780        2974 :   return false;
    2781             : }
    2782             : 
    2783             : 
    2784        8032 : bool HIsUndetectableAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    2785        8032 :   if (FLAG_fold_constants && value()->IsConstant()) {
    2786           0 :     *block = HConstant::cast(value())->IsUndetectable()
    2787           0 :         ? FirstSuccessor() : SecondSuccessor();
    2788           0 :     return true;
    2789             :   }
    2790       16003 :   if (value()->type().IsNull() || value()->type().IsUndefined()) {
    2791         778 :     *block = FirstSuccessor();
    2792         778 :     return true;
    2793             :   }
    2794       14382 :   if (value()->type().IsBoolean() ||
    2795        6772 :       value()->type().IsSmi() ||
    2796       13933 :       value()->type().IsString() ||
    2797             :       value()->type().IsJSReceiver()) {
    2798         625 :     *block = SecondSuccessor();
    2799         625 :     return true;
    2800             :   }
    2801        6629 :   *block = NULL;
    2802        6629 :   return false;
    2803             : }
    2804             : 
    2805             : 
    2806       12124 : bool HHasInstanceTypeAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    2807       12308 :   if (FLAG_fold_constants && value()->IsConstant()) {
    2808          34 :     InstanceType type = HConstant::cast(value())->GetInstanceType();
    2809          34 :     *block = (from_ <= type) && (type <= to_)
    2810          34 :         ? FirstSuccessor() : SecondSuccessor();
    2811          34 :     return true;
    2812             :   }
    2813       12090 :   *block = NULL;
    2814       12090 :   return false;
    2815             : }
    2816             : 
    2817             : 
    2818          33 : void HCompareHoleAndBranch::InferRepresentation(
    2819             :     HInferRepresentationPhase* h_infer) {
    2820          33 :   ChangeRepresentation(value()->representation());
    2821          33 : }
    2822             : 
    2823             : 
    2824     1029383 : bool HCompareNumericAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    2825     1034449 :   if (left() == right() &&
    2826             :       left()->representation().IsSmiOrInteger32()) {
    2827        3404 :     *block = (token() == Token::EQ ||
    2828         514 :               token() == Token::EQ_STRICT ||
    2829         418 :               token() == Token::LTE ||
    2830             :               token() == Token::GTE)
    2831        8802 :         ? FirstSuccessor() : SecondSuccessor();
    2832        4560 :     return true;
    2833             :   }
    2834     1020262 :   *block = NULL;
    2835     1020262 :   return false;
    2836             : }
    2837             : 
    2838             : 
    2839           0 : std::ostream& HGoto::PrintDataTo(std::ostream& os) const {  // NOLINT
    2840           0 :   return os << *SuccessorAt(0);
    2841             : }
    2842             : 
    2843             : 
    2844      321450 : void HCompareNumericAndBranch::InferRepresentation(
    2845             :     HInferRepresentationPhase* h_infer) {
    2846             :   Representation left_rep = left()->representation();
    2847             :   Representation right_rep = right()->representation();
    2848      321450 :   Representation observed_left = observed_input_representation(0);
    2849      321450 :   Representation observed_right = observed_input_representation(1);
    2850             : 
    2851      321449 :   Representation rep = Representation::None();
    2852      321449 :   rep = rep.generalize(observed_left);
    2853      321449 :   rep = rep.generalize(observed_right);
    2854      494225 :   if (rep.IsNone() || rep.IsSmiOrInteger32()) {
    2855      285099 :     if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
    2856      285099 :     if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
    2857             :   } else {
    2858       36352 :     rep = Representation::Double();
    2859             :   }
    2860             : 
    2861      321449 :   if (rep.IsDouble()) {
    2862             :     // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, ===
    2863             :     // and !=) have special handling of undefined, e.g. undefined == undefined
    2864             :     // is 'true'. Relational comparisons have a different semantic, first
    2865             :     // calling ToPrimitive() on their arguments.  The standard Crankshaft
    2866             :     // tagged-to-double conversion to ensure the HCompareNumericAndBranch's
    2867             :     // inputs are doubles caused 'undefined' to be converted to NaN. That's
    2868             :     // compatible out-of-the box with ordered relational comparisons (<, >, <=,
    2869             :     // >=). However, for equality comparisons (and for 'in' and 'instanceof'),
    2870             :     // it is not consistent with the spec. For example, it would cause undefined
    2871             :     // == undefined (should be true) to be evaluated as NaN == NaN
    2872             :     // (false). Therefore, any comparisons other than ordered relational
    2873             :     // comparisons must cause a deopt when one of their arguments is undefined.
    2874             :     // See also v8:1434
    2875       74168 :     if (Token::IsOrderedRelationalCompareOp(token_)) {
    2876             :       SetFlag(kTruncatingToNumber);
    2877             :     }
    2878             :   }
    2879      321449 :   ChangeRepresentation(rep);
    2880      321449 : }
    2881             : 
    2882             : 
    2883           0 : std::ostream& HParameter::PrintDataTo(std::ostream& os) const {  // NOLINT
    2884           0 :   return os << index();
    2885             : }
    2886             : 
    2887             : 
    2888           0 : std::ostream& HLoadNamedField::PrintDataTo(std::ostream& os) const {  // NOLINT
    2889           0 :   os << NameOf(object()) << access_;
    2890             : 
    2891           0 :   if (maps() != NULL) {
    2892           0 :     os << " [" << *maps()->at(0).handle();
    2893           0 :     for (int i = 1; i < maps()->size(); ++i) {
    2894           0 :       os << "," << *maps()->at(i).handle();
    2895             :     }
    2896           0 :     os << "]";
    2897             :   }
    2898             : 
    2899           0 :   if (HasDependency()) os << " " << NameOf(dependency());
    2900           0 :   return os;
    2901             : }
    2902             : 
    2903             : 
    2904           0 : std::ostream& HLoadKeyed::PrintDataTo(std::ostream& os) const {  // NOLINT
    2905           0 :   if (!is_fixed_typed_array()) {
    2906           0 :     os << NameOf(elements());
    2907             :   } else {
    2908             :     DCHECK(elements_kind() >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND &&
    2909             :            elements_kind() <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
    2910           0 :     os << NameOf(elements()) << "." << ElementsKindToString(elements_kind());
    2911             :   }
    2912             : 
    2913           0 :   os << "[" << NameOf(key());
    2914           0 :   if (IsDehoisted()) os << " + " << base_offset();
    2915           0 :   os << "]";
    2916             : 
    2917           0 :   if (HasDependency()) os << " " << NameOf(dependency());
    2918           0 :   if (RequiresHoleCheck()) os << " check_hole";
    2919           0 :   return os;
    2920             : }
    2921             : 
    2922             : 
    2923        8066 : bool HLoadKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) {
    2924             :   // The base offset is usually simply the size of the array header, except
    2925             :   // with dehoisting adds an addition offset due to a array index key
    2926             :   // manipulation, in which case it becomes (array header size +
    2927             :   // constant-offset-from-key * kPointerSize)
    2928        8066 :   uint32_t base_offset = BaseOffsetField::decode(bit_field_);
    2929             :   v8::base::internal::CheckedNumeric<uint32_t> addition_result = base_offset;
    2930             :   addition_result += increase_by_value;
    2931        8066 :   if (!addition_result.IsValid()) return false;
    2932        8066 :   base_offset = addition_result.ValueOrDie();
    2933        8066 :   if (!BaseOffsetField::is_valid(base_offset)) return false;
    2934        8050 :   bit_field_ = BaseOffsetField::update(bit_field_, base_offset);
    2935        8050 :   return true;
    2936             : }
    2937             : 
    2938             : 
    2939       22229 : bool HLoadKeyed::UsesMustHandleHole() const {
    2940       22229 :   if (IsFastPackedElementsKind(elements_kind())) {
    2941             :     return false;
    2942             :   }
    2943             : 
    2944       22229 :   if (IsFixedTypedArrayElementsKind(elements_kind())) {
    2945             :     return false;
    2946             :   }
    2947             : 
    2948       22229 :   if (hole_mode() == ALLOW_RETURN_HOLE) {
    2949       17854 :     if (IsFastDoubleElementsKind(elements_kind())) {
    2950         810 :       return AllUsesCanTreatHoleAsNaN();
    2951             :     }
    2952             :     return true;
    2953             :   }
    2954             : 
    2955        4375 :   if (IsFastDoubleElementsKind(elements_kind())) {
    2956             :     return false;
    2957             :   }
    2958             : 
    2959             :   // Holes are only returned as tagged values.
    2960        3960 :   if (!representation().IsTagged()) {
    2961             :     return false;
    2962             :   }
    2963             : 
    2964        2576 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    2965        4913 :     HValue* use = it.value();
    2966        4913 :     if (!use->IsChange()) return false;
    2967             :   }
    2968             : 
    2969         144 :   return true;
    2970             : }
    2971             : 
    2972             : 
    2973         810 : bool HLoadKeyed::AllUsesCanTreatHoleAsNaN() const {
    2974        1620 :   return IsFastDoubleElementsKind(elements_kind()) &&
    2975        1620 :          CheckUsesForFlag(HValue::kTruncatingToNumber);
    2976             : }
    2977             : 
    2978             : 
    2979      103441 : bool HLoadKeyed::RequiresHoleCheck() const {
    2980      103441 :   if (IsFastPackedElementsKind(elements_kind())) {
    2981             :     return false;
    2982             :   }
    2983             : 
    2984       27573 :   if (IsFixedTypedArrayElementsKind(elements_kind())) {
    2985             :     return false;
    2986             :   }
    2987             : 
    2988       27573 :   if (hole_mode() == CONVERT_HOLE_TO_UNDEFINED) {
    2989             :     return false;
    2990             :   }
    2991             : 
    2992       22229 :   return !UsesMustHandleHole();
    2993             : }
    2994             : 
    2995     1007762 : HValue* HCallWithDescriptor::Canonicalize() {
    2996     1007762 :   if (kind() != Code::KEYED_LOAD_IC) return this;
    2997             : 
    2998             :   // Recognize generic keyed loads that use property name generated
    2999             :   // by for-in statement as a key and rewrite them into fast property load
    3000             :   // by index.
    3001             :   typedef LoadWithVectorDescriptor Descriptor;
    3002             :   HValue* key = parameter(Descriptor::kName);
    3003       72411 :   if (key->IsLoadKeyed()) {
    3004             :     HLoadKeyed* key_load = HLoadKeyed::cast(key);
    3005        2763 :     if (key_load->elements()->IsForInCacheArray()) {
    3006         594 :       HForInCacheArray* names_cache =
    3007             :           HForInCacheArray::cast(key_load->elements());
    3008             : 
    3009             :       HValue* object = parameter(Descriptor::kReceiver);
    3010         652 :       if (names_cache->enumerable() == object) {
    3011             :         HForInCacheArray* index_cache =
    3012             :             names_cache->index_cache();
    3013             :         HCheckMapValue* map_check = HCheckMapValue::New(
    3014             :             block()->graph()->isolate(), block()->graph()->zone(),
    3015        2376 :             block()->graph()->GetInvalidContext(), object, names_cache->map());
    3016             :         HInstruction* index = HLoadKeyed::New(
    3017             :             block()->graph()->isolate(), block()->graph()->zone(),
    3018         594 :             block()->graph()->GetInvalidContext(), index_cache, key_load->key(),
    3019         594 :             key_load->key(), nullptr, key_load->elements_kind());
    3020         594 :         map_check->InsertBefore(this);
    3021         594 :         index->InsertBefore(this);
    3022        1782 :         return Prepend(new (block()->zone()) HLoadFieldByIndex(object, index));
    3023             :       }
    3024             :     }
    3025             :   }
    3026       71817 :   return this;
    3027             : }
    3028             : 
    3029           0 : std::ostream& HStoreNamedField::PrintDataTo(std::ostream& os) const {  // NOLINT
    3030           0 :   os << NameOf(object()) << access_ << " = " << NameOf(value());
    3031           0 :   if (NeedsWriteBarrier()) os << " (write-barrier)";
    3032           0 :   if (has_transition()) os << " (transition map " << *transition_map() << ")";
    3033           0 :   return os;
    3034             : }
    3035             : 
    3036             : 
    3037           0 : std::ostream& HStoreKeyed::PrintDataTo(std::ostream& os) const {  // NOLINT
    3038           0 :   if (!is_fixed_typed_array()) {
    3039           0 :     os << NameOf(elements());
    3040             :   } else {
    3041             :     DCHECK(elements_kind() >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND &&
    3042             :            elements_kind() <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
    3043           0 :     os << NameOf(elements()) << "." << ElementsKindToString(elements_kind());
    3044             :   }
    3045             : 
    3046           0 :   os << "[" << NameOf(key());
    3047           0 :   if (IsDehoisted()) os << " + " << base_offset();
    3048           0 :   return os << "] = " << NameOf(value());
    3049             : }
    3050             : 
    3051             : 
    3052           0 : std::ostream& HTransitionElementsKind::PrintDataTo(
    3053             :     std::ostream& os) const {  // NOLINT
    3054           0 :   os << NameOf(object());
    3055             :   ElementsKind from_kind = original_map().handle()->elements_kind();
    3056             :   ElementsKind to_kind = transitioned_map().handle()->elements_kind();
    3057           0 :   os << " " << *original_map().handle() << " ["
    3058           0 :      << ElementsAccessor::ForKind(from_kind)->name() << "] -> "
    3059           0 :      << *transitioned_map().handle() << " ["
    3060           0 :      << ElementsAccessor::ForKind(to_kind)->name() << "]";
    3061           0 :   if (IsSimpleMapChangeTransition(from_kind, to_kind)) os << " (simple)";
    3062           0 :   return os;
    3063             : }
    3064             : 
    3065             : 
    3066           0 : std::ostream& HInnerAllocatedObject::PrintDataTo(
    3067             :     std::ostream& os) const {  // NOLINT
    3068           0 :   os << NameOf(base_object()) << " offset ";
    3069           0 :   return offset()->PrintTo(os);
    3070             : }
    3071             : 
    3072             : 
    3073           0 : std::ostream& HLoadContextSlot::PrintDataTo(std::ostream& os) const {  // NOLINT
    3074           0 :   return os << NameOf(value()) << "[" << slot_index() << "]";
    3075             : }
    3076             : 
    3077             : 
    3078           0 : std::ostream& HStoreContextSlot::PrintDataTo(
    3079           0 :     std::ostream& os) const {  // NOLINT
    3080           0 :   return os << NameOf(context()) << "[" << slot_index()
    3081           0 :             << "] = " << NameOf(value());
    3082             : }
    3083             : 
    3084             : 
    3085             : // Implementation of type inference and type conversions. Calculates
    3086             : // the inferred type of this instruction based on the input operands.
    3087             : 
    3088    27945343 : HType HValue::CalculateInferredType() {
    3089    27945343 :   return type_;
    3090             : }
    3091             : 
    3092             : 
    3093      424238 : HType HPhi::CalculateInferredType() {
    3094      424238 :   if (OperandCount() == 0) return HType::Tagged();
    3095             :   HType result = OperandAt(0)->type();
    3096      947156 :   for (int i = 1; i < OperandCount(); ++i) {
    3097             :     HType current = OperandAt(i)->type();
    3098             :     result = result.Combine(current);
    3099             :   }
    3100      424238 :   return result;
    3101             : }
    3102             : 
    3103             : 
    3104      509131 : HType HChange::CalculateInferredType() {
    3105      509131 :   if (from().IsDouble() && to().IsTagged()) return HType::HeapNumber();
    3106             :   return type();
    3107             : }
    3108             : 
    3109             : 
    3110       33315 : Representation HUnaryMathOperation::RepresentationFromInputs() {
    3111       66630 :   if (SupportsFlexibleFloorAndRound() &&
    3112       33315 :       (op_ == kMathFloor || op_ == kMathRound)) {
    3113             :     // Floor and Round always take a double input. The integral result can be
    3114             :     // used as an integer or a double. Infer the representation from the uses.
    3115             :     return Representation::None();
    3116             :   }
    3117         630 :   Representation rep = representation();
    3118             :   // If any of the actual input representation is more general than what we
    3119             :   // have so far but not Tagged, use that representation instead.
    3120             :   Representation input_rep = value()->representation();
    3121         630 :   if (!input_rep.IsTagged()) {
    3122         528 :     rep = rep.generalize(input_rep);
    3123             :   }
    3124         630 :   return rep;
    3125             : }
    3126             : 
    3127             : 
    3128       19281 : bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
    3129        7737 :                                           HValue* dominator) {
    3130             :   DCHECK(side_effect == kNewSpacePromotion);
    3131             :   DCHECK(!IsAllocationFolded());
    3132       21355 :   Zone* zone = block()->zone();
    3133       19281 :   Isolate* isolate = block()->isolate();
    3134       19281 :   if (!FLAG_use_allocation_folding) return false;
    3135             : 
    3136             :   // Try to fold allocations together with their dominating allocations.
    3137       19168 :   if (!dominator->IsAllocate()) {
    3138       15993 :     if (FLAG_trace_allocation_folding) {
    3139             :       PrintF("#%d (%s) cannot fold into #%d (%s)\n",
    3140           0 :           id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
    3141             :     }
    3142             :     return false;
    3143             :   }
    3144             : 
    3145             :   // Check whether we are folding within the same block for local folding.
    3146        3175 :   if (FLAG_use_local_allocation_folding && dominator->block() != block()) {
    3147           0 :     if (FLAG_trace_allocation_folding) {
    3148             :       PrintF("#%d (%s) cannot fold into #%d (%s), crosses basic blocks\n",
    3149           0 :           id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
    3150             :     }
    3151             :     return false;
    3152             :   }
    3153             : 
    3154        3236 :   HAllocate* dominator_allocate = HAllocate::cast(dominator);
    3155             :   HValue* dominator_size = dominator_allocate->size();
    3156             :   HValue* current_size = size();
    3157             : 
    3158             :   // TODO(hpayer): Add support for non-constant allocation in dominator.
    3159        6017 :   if (!current_size->IsInteger32Constant() ||
    3160             :       !dominator_size->IsInteger32Constant()) {
    3161         341 :     if (FLAG_trace_allocation_folding) {
    3162             :       PrintF("#%d (%s) cannot fold into #%d (%s), "
    3163             :              "dynamic allocation size in dominator\n",
    3164           0 :           id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
    3165             :     }
    3166             :     return false;
    3167             :   }
    3168             : 
    3169        2834 :   if (IsAllocationFoldingDominator()) {
    3170           5 :     if (FLAG_trace_allocation_folding) {
    3171             :       PrintF("#%d (%s) cannot fold into #%d (%s), already dominator\n", id(),
    3172           0 :              Mnemonic(), dominator->id(), dominator->Mnemonic());
    3173             :     }
    3174             :     return false;
    3175             :   }
    3176             : 
    3177        2829 :   if (!IsFoldable(dominator_allocate)) {
    3178           0 :     if (FLAG_trace_allocation_folding) {
    3179             :       PrintF("#%d (%s) cannot fold into #%d (%s), different spaces\n", id(),
    3180           0 :              Mnemonic(), dominator->id(), dominator->Mnemonic());
    3181             :     }
    3182             :     return false;
    3183             :   }
    3184             : 
    3185             :   DCHECK(
    3186             :       (IsNewSpaceAllocation() && dominator_allocate->IsNewSpaceAllocation()) ||
    3187             :       (IsOldSpaceAllocation() && dominator_allocate->IsOldSpaceAllocation()));
    3188             : 
    3189             :   // First update the size of the dominator allocate instruction.
    3190             :   dominator_size = dominator_allocate->size();
    3191             :   int32_t original_object_size =
    3192             :       HConstant::cast(dominator_size)->GetInteger32Constant();
    3193             :   int32_t dominator_size_constant = original_object_size;
    3194             : 
    3195        2829 :   if (MustAllocateDoubleAligned()) {
    3196         407 :     if ((dominator_size_constant & kDoubleAlignmentMask) != 0) {
    3197           0 :       dominator_size_constant += kDoubleSize / 2;
    3198             :     }
    3199             :   }
    3200             : 
    3201             :   int32_t current_size_max_value = size()->GetInteger32Constant();
    3202        2829 :   int32_t new_dominator_size = dominator_size_constant + current_size_max_value;
    3203             : 
    3204             :   // Since we clear the first word after folded memory, we cannot use the
    3205             :   // whole kMaxRegularHeapObjectSize memory.
    3206        2829 :   if (new_dominator_size > kMaxRegularHeapObjectSize - kPointerSize) {
    3207           0 :     if (FLAG_trace_allocation_folding) {
    3208             :       PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n",
    3209             :           id(), Mnemonic(), dominator_allocate->id(),
    3210           0 :           dominator_allocate->Mnemonic(), new_dominator_size);
    3211             :     }
    3212             :     return false;
    3213             :   }
    3214             : 
    3215             :   HInstruction* new_dominator_size_value = HConstant::CreateAndInsertBefore(
    3216             :       isolate, zone, context(), new_dominator_size, Representation::None(),
    3217             :       dominator_allocate);
    3218             : 
    3219             :   dominator_allocate->UpdateSize(new_dominator_size_value);
    3220             : 
    3221        2829 :   if (MustAllocateDoubleAligned()) {
    3222         407 :     if (!dominator_allocate->MustAllocateDoubleAligned()) {
    3223             :       dominator_allocate->MakeDoubleAligned();
    3224             :     }
    3225             :   }
    3226             : 
    3227        2829 :   if (!dominator_allocate->IsAllocationFoldingDominator()) {
    3228             :     HAllocate* first_alloc =
    3229             :         HAllocate::New(isolate, zone, dominator_allocate->context(),
    3230             :                        dominator_size, dominator_allocate->type(),
    3231             :                        IsNewSpaceAllocation() ? NOT_TENURED : TENURED,
    3232        6222 :                        JS_OBJECT_TYPE, block()->graph()->GetConstant0());
    3233        2074 :     first_alloc->InsertAfter(dominator_allocate);
    3234        2074 :     dominator_allocate->ReplaceAllUsesWith(first_alloc);
    3235             :     dominator_allocate->MakeAllocationFoldingDominator();
    3236        2074 :     first_alloc->MakeFoldedAllocation(dominator_allocate);
    3237        2074 :     if (FLAG_trace_allocation_folding) {
    3238             :       PrintF("#%d (%s) inserted for dominator #%d (%s)\n", first_alloc->id(),
    3239             :              first_alloc->Mnemonic(), dominator_allocate->id(),
    3240           0 :              dominator_allocate->Mnemonic());
    3241             :     }
    3242             :   }
    3243             : 
    3244        2829 :   MakeFoldedAllocation(dominator_allocate);
    3245             : 
    3246        2829 :   if (FLAG_trace_allocation_folding) {
    3247             :     PrintF("#%d (%s) folded into #%d (%s), new dominator size: %d\n", id(),
    3248             :            Mnemonic(), dominator_allocate->id(), dominator_allocate->Mnemonic(),
    3249           0 :            new_dominator_size);
    3250             :   }
    3251             :   return true;
    3252             : }
    3253             : 
    3254             : 
    3255           0 : std::ostream& HAllocate::PrintDataTo(std::ostream& os) const {  // NOLINT
    3256           0 :   os << NameOf(size()) << " (";
    3257           0 :   if (IsNewSpaceAllocation()) os << "N";
    3258           0 :   if (IsOldSpaceAllocation()) os << "P";
    3259           0 :   if (MustAllocateDoubleAligned()) os << "A";
    3260           0 :   if (MustPrefillWithFiller()) os << "F";
    3261           0 :   if (IsAllocationFoldingDominator()) os << "d";
    3262           0 :   if (IsAllocationFolded()) os << "f";
    3263           0 :   return os << ")";
    3264             : }
    3265             : 
    3266             : 
    3267        1199 : bool HStoreKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) {
    3268             :   // The base offset is usually simply the size of the array header, except
    3269             :   // with dehoisting adds an addition offset due to a array index key
    3270             :   // manipulation, in which case it becomes (array header size +
    3271             :   // constant-offset-from-key * kPointerSize)
    3272        1199 :   v8::base::internal::CheckedNumeric<uint32_t> addition_result = base_offset_;
    3273             :   addition_result += increase_by_value;
    3274        1199 :   if (!addition_result.IsValid()) return false;
    3275        1199 :   base_offset_ = addition_result.ValueOrDie();
    3276        1199 :   return true;
    3277             : }
    3278             : 
    3279             : 
    3280        5963 : bool HStoreKeyed::NeedsCanonicalization() {
    3281        5963 :   switch (value()->opcode()) {
    3282             :     case kLoadKeyed: {
    3283             :       ElementsKind load_kind = HLoadKeyed::cast(value())->elements_kind();
    3284        5151 :       return IsFixedFloatElementsKind(load_kind);
    3285             :     }
    3286             :     case kChange: {
    3287             :       Representation from = HChange::cast(value())->from();
    3288         159 :       return from.IsTagged() || from.IsHeapObject();
    3289             :     }
    3290             :     case kConstant:
    3291             :       // Double constants are canonicalized upon construction.
    3292             :       return false;
    3293             :     default:
    3294         276 :       return !value()->IsBinaryOperation();
    3295             :   }
    3296             : }
    3297             : 
    3298             : 
    3299             : #define H_CONSTANT_INT(val) \
    3300             :   HConstant::New(isolate, zone, context, static_cast<int32_t>(val))
    3301             : #define H_CONSTANT_DOUBLE(val) \
    3302             :   HConstant::New(isolate, zone, context, static_cast<double>(val))
    3303             : 
    3304             : #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op)                     \
    3305             :   HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context,   \
    3306             :                             HValue* left, HValue* right) {                   \
    3307             :     if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {  \
    3308             :       HConstant* c_left = HConstant::cast(left);                             \
    3309             :       HConstant* c_right = HConstant::cast(right);                           \
    3310             :       if ((c_left->HasNumberValue() && c_right->HasNumberValue())) {         \
    3311             :         double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \
    3312             :         if (IsInt32Double(double_res)) {                                     \
    3313             :           return H_CONSTANT_INT(double_res);                                 \
    3314             :         }                                                                    \
    3315             :         return H_CONSTANT_DOUBLE(double_res);                                \
    3316             :       }                                                                      \
    3317             :     }                                                                        \
    3318             :     return new (zone) HInstr(context, left, right);                          \
    3319             :   }
    3320             : 
    3321      577957 : DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +)
    3322       54908 : DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *)
    3323       52808 : DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -)
    3324             : 
    3325             : #undef DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR
    3326             : 
    3327             : 
    3328       26867 : HInstruction* HStringAdd::New(Isolate* isolate, Zone* zone, HValue* context,
    3329             :                               HValue* left, HValue* right,
    3330             :                               PretenureFlag pretenure_flag,
    3331             :                               StringAddFlags flags,
    3332             :                               Handle<AllocationSite> allocation_site) {
    3333       26889 :   if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
    3334             :     HConstant* c_right = HConstant::cast(right);
    3335             :     HConstant* c_left = HConstant::cast(left);
    3336          20 :     if (c_left->HasStringValue() && c_right->HasStringValue()) {
    3337             :       Handle<String> left_string = c_left->StringValue();
    3338             :       Handle<String> right_string = c_right->StringValue();
    3339             :       // Prevent possible exception by invalid string length.
    3340          10 :       if (left_string->length() + right_string->length() < String::kMaxLength) {
    3341             :         MaybeHandle<String> concat = isolate->factory()->NewConsString(
    3342          10 :             c_left->StringValue(), c_right->StringValue());
    3343          10 :         return HConstant::New(isolate, zone, context, concat.ToHandleChecked());
    3344             :       }
    3345             :     }
    3346             :   }
    3347             :   return new (zone)
    3348       53714 :       HStringAdd(context, left, right, pretenure_flag, flags, allocation_site);
    3349             : }
    3350             : 
    3351             : 
    3352           0 : std::ostream& HStringAdd::PrintDataTo(std::ostream& os) const {  // NOLINT
    3353           0 :   if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
    3354           0 :     os << "_CheckBoth";
    3355           0 :   } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_LEFT) {
    3356           0 :     os << "_CheckLeft";
    3357           0 :   } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_RIGHT) {
    3358           0 :     os << "_CheckRight";
    3359             :   }
    3360           0 :   HBinaryOperation::PrintDataTo(os);
    3361           0 :   os << " (";
    3362           0 :   if (pretenure_flag() == NOT_TENURED)
    3363           0 :     os << "N";
    3364           0 :   else if (pretenure_flag() == TENURED)
    3365           0 :     os << "D";
    3366           0 :   return os << ")";
    3367             : }
    3368             : 
    3369             : 
    3370         516 : HInstruction* HStringCharFromCode::New(Isolate* isolate, Zone* zone,
    3371             :                                        HValue* context, HValue* char_code) {
    3372         526 :   if (FLAG_fold_constants && char_code->IsConstant()) {
    3373          14 :     HConstant* c_code = HConstant::cast(char_code);
    3374          10 :     if (c_code->HasNumberValue()) {
    3375          10 :       if (std::isfinite(c_code->DoubleValue())) {
    3376           4 :         uint32_t code = c_code->NumberValueAsInteger32() & 0xffff;
    3377             :         return HConstant::New(
    3378             :             isolate, zone, context,
    3379           8 :             isolate->factory()->LookupSingleCharacterStringFromCode(code));
    3380             :       }
    3381             :       return HConstant::New(isolate, zone, context,
    3382           6 :                             isolate->factory()->empty_string());
    3383             :     }
    3384             :   }
    3385         506 :   return new(zone) HStringCharFromCode(context, char_code);
    3386             : }
    3387             : 
    3388             : 
    3389       29396 : HInstruction* HUnaryMathOperation::New(Isolate* isolate, Zone* zone,
    3390             :                                        HValue* context, HValue* value,
    3391             :                                        BuiltinFunctionId op) {
    3392             :   do {
    3393       29396 :     if (!FLAG_fold_constants) break;
    3394         108 :     if (!value->IsConstant()) break;
    3395         108 :     HConstant* constant = HConstant::cast(value);
    3396         108 :     if (!constant->HasNumberValue()) break;
    3397             :     double d = constant->DoubleValue();
    3398         108 :     if (std::isnan(d)) {  // NaN poisons everything.
    3399          14 :       return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN());
    3400             :     }
    3401          94 :     if (std::isinf(d)) {  // +Infinity and -Infinity.
    3402          40 :       switch (op) {
    3403             :         case kMathCos:
    3404             :         case kMathSin:
    3405           0 :           return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN());
    3406             :         case kMathExp:
    3407           4 :           return H_CONSTANT_DOUBLE((d > 0.0) ? d : 0.0);
    3408             :         case kMathLog:
    3409             :         case kMathSqrt:
    3410           8 :           return H_CONSTANT_DOUBLE(
    3411             :               (d > 0.0) ? d : std::numeric_limits<double>::quiet_NaN());
    3412             :         case kMathPowHalf:
    3413             :         case kMathAbs:
    3414          16 :           return H_CONSTANT_DOUBLE((d > 0.0) ? d : -d);
    3415             :         case kMathRound:
    3416             :         case kMathFround:
    3417             :         case kMathFloor:
    3418          12 :           return H_CONSTANT_DOUBLE(d);
    3419             :         case kMathClz32:
    3420           0 :           return H_CONSTANT_INT(32);
    3421             :         default:
    3422           0 :           UNREACHABLE();
    3423             :           break;
    3424             :       }
    3425             :     }
    3426          54 :     switch (op) {
    3427             :       case kMathCos:
    3428           0 :         return H_CONSTANT_DOUBLE(base::ieee754::cos(d));
    3429             :       case kMathExp:
    3430           6 :         return H_CONSTANT_DOUBLE(base::ieee754::exp(d));
    3431             :       case kMathLog:
    3432           6 :         return H_CONSTANT_DOUBLE(base::ieee754::log(d));
    3433             :       case kMathSin:
    3434           0 :         return H_CONSTANT_DOUBLE(base::ieee754::sin(d));
    3435             :       case kMathSqrt:
    3436           6 :         lazily_initialize_fast_sqrt(isolate);
    3437           6 :         return H_CONSTANT_DOUBLE(fast_sqrt(d, isolate));
    3438             :       case kMathPowHalf:
    3439           2 :         return H_CONSTANT_DOUBLE(power_double_double(d, 0.5));
    3440             :       case kMathAbs:
    3441           4 :         return H_CONSTANT_DOUBLE((d >= 0.0) ? d + 0.0 : -d);
    3442             :       case kMathRound:
    3443             :         // -0.5 .. -0.0 round to -0.0.
    3444          18 :         if ((d >= -0.5 && Double(d).Sign() < 0)) return H_CONSTANT_DOUBLE(-0.0);
    3445             :         // Doubles are represented as Significant * 2 ^ Exponent. If the
    3446             :         // Exponent is not negative, the double value is already an integer.
    3447           8 :         if (Double(d).Exponent() >= 0) return H_CONSTANT_DOUBLE(d);
    3448          12 :         return H_CONSTANT_DOUBLE(Floor(d + 0.5));
    3449             :       case kMathFround:
    3450          10 :         return H_CONSTANT_DOUBLE(static_cast<double>(static_cast<float>(d)));
    3451             :       case kMathFloor:
    3452          10 :         return H_CONSTANT_DOUBLE(Floor(d));
    3453             :       case kMathClz32: {
    3454             :         uint32_t i = DoubleToUint32(d);
    3455           0 :         return H_CONSTANT_INT(base::bits::CountLeadingZeros32(i));
    3456             :       }
    3457             :       default:
    3458           0 :         UNREACHABLE();
    3459             :         break;
    3460             :     }
    3461             :   } while (false);
    3462       29288 :   return new(zone) HUnaryMathOperation(context, value, op);
    3463             : }
    3464             : 
    3465             : 
    3466       33315 : Representation HUnaryMathOperation::RepresentationFromUses() {
    3467       33315 :   if (op_ != kMathFloor && op_ != kMathRound) {
    3468         630 :     return HValue::RepresentationFromUses();
    3469             :   }
    3470             : 
    3471             :   // The instruction can have an int32 or double output. Prefer a double
    3472             :   // representation if there are double uses.
    3473             :   bool use_double = false;
    3474             : 
    3475       29912 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    3476       35928 :     HValue* use = it.value();
    3477       35928 :     int use_index = it.index();
    3478       35928 :     Representation rep_observed = use->observed_input_representation(use_index);
    3479       35928 :     Representation rep_required = use->RequiredInputRepresentation(use_index);
    3480       69388 :     use_double |= (rep_observed.IsDouble() || rep_required.IsDouble());
    3481       35928 :     if (use_double && !FLAG_trace_representation) {
    3482             :       // Having seen one double is enough.
    3483             :       break;
    3484             :     }
    3485       29912 :     if (FLAG_trace_representation) {
    3486           0 :       if (!rep_required.IsDouble() || rep_observed.IsDouble()) {
    3487             :         PrintF("#%d %s is used by #%d %s as %s%s\n",
    3488             :                id(), Mnemonic(), use->id(),
    3489             :                use->Mnemonic(), rep_observed.Mnemonic(),
    3490           0 :                (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : ""));
    3491             :       } else {
    3492             :         PrintF("#%d %s is required by #%d %s as %s%s\n",
    3493             :                id(), Mnemonic(), use->id(),
    3494             :                use->Mnemonic(), rep_required.Mnemonic(),
    3495           0 :                (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : ""));
    3496             :       }
    3497             :     }
    3498             :   }
    3499       32685 :   return use_double ? Representation::Double() : Representation::Integer32();
    3500             : }
    3501             : 
    3502             : 
    3503         989 : HInstruction* HPower::New(Isolate* isolate, Zone* zone, HValue* context,
    3504             :                           HValue* left, HValue* right) {
    3505        1025 :   if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
    3506          18 :     HConstant* c_left = HConstant::cast(left);
    3507          18 :     HConstant* c_right = HConstant::cast(right);
    3508          36 :     if (c_left->HasNumberValue() && c_right->HasNumberValue()) {
    3509             :       double result =
    3510          18 :           power_helper(isolate, c_left->DoubleValue(), c_right->DoubleValue());
    3511          18 :       return H_CONSTANT_DOUBLE(std::isnan(result)
    3512             :                                    ? std::numeric_limits<double>::quiet_NaN()
    3513             :                                    : result);
    3514             :     }
    3515             :   }
    3516         971 :   return new(zone) HPower(left, right);
    3517             : }
    3518             : 
    3519             : 
    3520        1751 : HInstruction* HMathMinMax::New(Isolate* isolate, Zone* zone, HValue* context,
    3521             :                                HValue* left, HValue* right, Operation op) {
    3522        1823 :   if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
    3523          36 :     HConstant* c_left = HConstant::cast(left);
    3524          36 :     HConstant* c_right = HConstant::cast(right);
    3525          72 :     if (c_left->HasNumberValue() && c_right->HasNumberValue()) {
    3526             :       double d_left = c_left->DoubleValue();
    3527             :       double d_right = c_right->DoubleValue();
    3528          36 :       if (op == kMathMin) {
    3529          18 :         if (d_left > d_right) return H_CONSTANT_DOUBLE(d_right);
    3530          14 :         if (d_left < d_right) return H_CONSTANT_DOUBLE(d_left);
    3531          10 :         if (d_left == d_right) {
    3532             :           // Handle +0 and -0.
    3533           8 :           return H_CONSTANT_DOUBLE((Double(d_left).Sign() == -1) ? d_left
    3534             :                                                                  : d_right);
    3535             :         }
    3536             :       } else {
    3537          18 :         if (d_left < d_right) return H_CONSTANT_DOUBLE(d_right);
    3538          14 :         if (d_left > d_right) return H_CONSTANT_DOUBLE(d_left);
    3539          10 :         if (d_left == d_right) {
    3540             :           // Handle +0 and -0.
    3541           8 :           return H_CONSTANT_DOUBLE((Double(d_left).Sign() == -1) ? d_right
    3542             :                                                                  : d_left);
    3543             :         }
    3544             :       }
    3545             :       // All comparisons failed, must be NaN.
    3546           4 :       return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN());
    3547             :     }
    3548             :   }
    3549        1715 :   return new(zone) HMathMinMax(context, left, right, op);
    3550             : }
    3551             : 
    3552        5637 : HInstruction* HMod::New(Isolate* isolate, Zone* zone, HValue* context,
    3553             :                         HValue* left, HValue* right) {
    3554        5650 :   if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
    3555           4 :     HConstant* c_left = HConstant::cast(left);
    3556           4 :     HConstant* c_right = HConstant::cast(right);
    3557           4 :     if (c_left->HasInteger32Value() && c_right->HasInteger32Value()) {
    3558             :       int32_t dividend = c_left->Integer32Value();
    3559             :       int32_t divisor = c_right->Integer32Value();
    3560           2 :       if (dividend == kMinInt && divisor == -1) {
    3561           2 :         return H_CONSTANT_DOUBLE(-0.0);
    3562             :       }
    3563           0 :       if (divisor != 0) {
    3564           0 :         int32_t res = dividend % divisor;
    3565           0 :         if ((res == 0) && (dividend < 0)) {
    3566           0 :           return H_CONSTANT_DOUBLE(-0.0);
    3567             :         }
    3568           0 :         return H_CONSTANT_INT(res);
    3569             :       }
    3570             :     }
    3571             :   }
    3572        5635 :   return new (zone) HMod(context, left, right);
    3573             : }
    3574             : 
    3575       52481 : HInstruction* HDiv::New(Isolate* isolate, Zone* zone, HValue* context,
    3576             :                         HValue* left, HValue* right) {
    3577             :   // If left and right are constant values, try to return a constant value.
    3578       52902 :   if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
    3579         126 :     HConstant* c_left = HConstant::cast(left);
    3580         204 :     HConstant* c_right = HConstant::cast(right);
    3581         252 :     if ((c_left->HasNumberValue() && c_right->HasNumberValue())) {
    3582         244 :       if (std::isnan(c_left->DoubleValue()) ||
    3583             :           std::isnan(c_right->DoubleValue())) {
    3584          40 :         return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN());
    3585          86 :       } else if (c_right->DoubleValue() != 0) {
    3586          32 :         double double_res = c_left->DoubleValue() / c_right->DoubleValue();
    3587          32 :         if (IsInt32Double(double_res)) {
    3588          22 :           return H_CONSTANT_INT(double_res);
    3589             :         }
    3590          10 :         return H_CONSTANT_DOUBLE(double_res);
    3591          54 :       } else if (c_left->DoubleValue() != 0) {
    3592             :         int sign = Double(c_left->DoubleValue()).Sign() *
    3593          42 :                    Double(c_right->DoubleValue()).Sign();  // Right could be -0.
    3594          42 :         return H_CONSTANT_DOUBLE(sign * V8_INFINITY);
    3595             :       } else {
    3596          12 :         return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN());
    3597             :       }
    3598             :     }
    3599             :   }
    3600       52355 :   return new (zone) HDiv(context, left, right);
    3601             : }
    3602             : 
    3603      139726 : HInstruction* HBitwise::New(Isolate* isolate, Zone* zone, HValue* context,
    3604             :                             Token::Value op, HValue* left, HValue* right) {
    3605      139806 :   if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
    3606           0 :     HConstant* c_left = HConstant::cast(left);
    3607           0 :     HConstant* c_right = HConstant::cast(right);
    3608           0 :     if ((c_left->HasNumberValue() && c_right->HasNumberValue())) {
    3609             :       int32_t result;
    3610             :       int32_t v_left = c_left->NumberValueAsInteger32();
    3611             :       int32_t v_right = c_right->NumberValueAsInteger32();
    3612           0 :       switch (op) {
    3613             :         case Token::BIT_XOR:
    3614           0 :           result = v_left ^ v_right;
    3615           0 :           break;
    3616             :         case Token::BIT_AND:
    3617           0 :           result = v_left & v_right;
    3618           0 :           break;
    3619             :         case Token::BIT_OR:
    3620           0 :           result = v_left | v_right;
    3621           0 :           break;
    3622             :         default:
    3623             :           result = 0;  // Please the compiler.
    3624           0 :           UNREACHABLE();
    3625             :       }
    3626           0 :       return H_CONSTANT_INT(result);
    3627             :     }
    3628             :   }
    3629      139726 :   return new (zone) HBitwise(context, op, left, right);
    3630             : }
    3631             : 
    3632             : #define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result)                          \
    3633             :   HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context,  \
    3634             :                             HValue* left, HValue* right) {                  \
    3635             :     if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
    3636             :       HConstant* c_left = HConstant::cast(left);                            \
    3637             :       HConstant* c_right = HConstant::cast(right);                          \
    3638             :       if ((c_left->HasNumberValue() && c_right->HasNumberValue())) {        \
    3639             :         return H_CONSTANT_INT(result);                                      \
    3640             :       }                                                                     \
    3641             :     }                                                                       \
    3642             :     return new (zone) HInstr(context, left, right);                         \
    3643             :   }
    3644             : 
    3645       29281 : DEFINE_NEW_H_BITWISE_INSTR(HSar,
    3646             : c_left->NumberValueAsInteger32() >> (c_right->NumberValueAsInteger32() & 0x1f))
    3647       33138 : DEFINE_NEW_H_BITWISE_INSTR(HShl,
    3648             : c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f))
    3649             : 
    3650             : #undef DEFINE_NEW_H_BITWISE_INSTR
    3651             : 
    3652        9359 : HInstruction* HShr::New(Isolate* isolate, Zone* zone, HValue* context,
    3653             :                         HValue* left, HValue* right) {
    3654        9363 :   if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
    3655           0 :     HConstant* c_left = HConstant::cast(left);
    3656           0 :     HConstant* c_right = HConstant::cast(right);
    3657           0 :     if ((c_left->HasNumberValue() && c_right->HasNumberValue())) {
    3658             :       int32_t left_val = c_left->NumberValueAsInteger32();
    3659           0 :       int32_t right_val = c_right->NumberValueAsInteger32() & 0x1f;
    3660           0 :       if ((right_val == 0) && (left_val < 0)) {
    3661           0 :         return H_CONSTANT_DOUBLE(static_cast<uint32_t>(left_val));
    3662             :       }
    3663           0 :       return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val);
    3664             :     }
    3665             :   }
    3666        9359 :   return new (zone) HShr(context, left, right);
    3667             : }
    3668             : 
    3669             : 
    3670       14320 : HInstruction* HSeqStringGetChar::New(Isolate* isolate, Zone* zone,
    3671             :                                      HValue* context, String::Encoding encoding,
    3672             :                                      HValue* string, HValue* index) {
    3673       14336 :   if (FLAG_fold_constants && string->IsConstant() && index->IsConstant()) {
    3674             :     HConstant* c_string = HConstant::cast(string);
    3675           0 :     HConstant* c_index = HConstant::cast(index);
    3676           0 :     if (c_string->HasStringValue() && c_index->HasInteger32Value()) {
    3677             :       Handle<String> s = c_string->StringValue();
    3678             :       int32_t i = c_index->Integer32Value();
    3679             :       DCHECK_LE(0, i);
    3680             :       DCHECK_LT(i, s->length());
    3681           0 :       return H_CONSTANT_INT(s->Get(i));
    3682             :     }
    3683             :   }
    3684       14320 :   return new(zone) HSeqStringGetChar(encoding, string, index);
    3685             : }
    3686             : 
    3687             : 
    3688             : #undef H_CONSTANT_INT
    3689             : #undef H_CONSTANT_DOUBLE
    3690             : 
    3691             : 
    3692           0 : std::ostream& HBitwise::PrintDataTo(std::ostream& os) const {  // NOLINT
    3693           0 :   os << Token::Name(op_) << " ";
    3694           0 :   return HBitwiseBinaryOperation::PrintDataTo(os);
    3695             : }
    3696             : 
    3697             : 
    3698      316825 : void HPhi::SimplifyConstantInputs() {
    3699             :   // Convert constant inputs to integers when all uses are truncating.
    3700             :   // This must happen before representation inference takes place.
    3701      321605 :   if (!CheckUsesForFlag(kTruncatingToInt32)) return;
    3702       82233 :   for (int i = 0; i < OperandCount(); ++i) {
    3703       60180 :     if (!OperandAt(i)->IsConstant()) return;
    3704             :   }
    3705        2396 :   HGraph* graph = block()->graph();
    3706       14350 :   for (int i = 0; i < OperandCount(); ++i) {
    3707        4791 :     HConstant* operand = HConstant::cast(OperandAt(i));
    3708        4785 :     if (operand->HasInteger32Value()) {
    3709             :       continue;
    3710        3516 :     } else if (operand->HasDoubleValue()) {
    3711             :       HConstant* integer_input = HConstant::New(
    3712           6 :           graph->isolate(), graph->zone(), graph->GetInvalidContext(),
    3713          12 :           DoubleToInt32(operand->DoubleValue()));
    3714           6 :       integer_input->InsertAfter(operand);
    3715           6 :       SetOperandAt(i, integer_input);
    3716        3510 :     } else if (operand->HasBooleanValue()) {
    3717             :       SetOperandAt(i, operand->BooleanValue() ? graph->GetConstant1()
    3718         569 :                                               : graph->GetConstant0());
    3719        2941 :     } else if (operand->ImmortalImmovable()) {
    3720        2730 :       SetOperandAt(i, graph->GetConstant0());
    3721             :     }
    3722             :   }
    3723             :   // Overwrite observed input representations because they are likely Tagged.
    3724         363 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    3725         363 :     HValue* use = it.value();
    3726         363 :     if (use->IsBinaryOperation()) {
    3727             :       HBinaryOperation::cast(use)->set_observed_input_representation(
    3728         253 :           it.index(), Representation::Smi());
    3729             :     }
    3730             :   }
    3731             : }
    3732             : 
    3733             : 
    3734      475831 : void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) {
    3735             :   DCHECK(CheckFlag(kFlexibleRepresentation));
    3736      475831 :   Representation new_rep = RepresentationFromUses();
    3737      475831 :   UpdateRepresentation(new_rep, h_infer, "uses");
    3738      475830 :   new_rep = RepresentationFromInputs();
    3739      475828 :   UpdateRepresentation(new_rep, h_infer, "inputs");
    3740      475833 :   new_rep = RepresentationFromUseRequirements();
    3741      475828 :   UpdateRepresentation(new_rep, h_infer, "use requirements");
    3742      475833 : }
    3743             : 
    3744             : 
    3745     2610794 : Representation HPhi::RepresentationFromInputs() {
    3746      475826 :   Representation r = representation();
    3747     5221590 :   for (int i = 0; i < OperandCount(); ++i) {
    3748             :     // Ignore conservative Tagged assumption of parameters if we have
    3749             :     // reason to believe that it's too conservative.
    3750     2366632 :     if (has_type_feedback_from_uses() && OperandAt(i)->IsParameter()) {
    3751             :       continue;
    3752             :     }
    3753             : 
    3754     2133308 :     r = r.generalize(OperandAt(i)->KnownOptimalRepresentation());
    3755             :   }
    3756      475827 :   return r;
    3757             : }
    3758             : 
    3759             : 
    3760             : // Returns a representation if all uses agree on the same representation.
    3761             : // Integer32 is also returned when some uses are Smi but others are Integer32.
    3762      951664 : Representation HValue::RepresentationFromUseRequirements() {
    3763      475832 :   Representation rep = Representation::None();
    3764     1167419 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    3765             :     // Ignore the use requirement from never run code
    3766     2403748 :     if (it.value()->block()->IsUnreachable()) continue;
    3767             : 
    3768             :     // We check for observed_input_representation elsewhere.
    3769             :     Representation use_rep =
    3770     1057819 :         it.value()->RequiredInputRepresentation(it.index());
    3771     1057842 :     if (rep.IsNone()) {
    3772      539130 :       rep = use_rep;
    3773      539130 :       continue;
    3774             :     }
    3775      518712 :     if (use_rep.IsNone() || rep.Equals(use_rep)) continue;
    3776       74568 :     if (rep.generalize(use_rep).IsInteger32()) {
    3777        2806 :       rep = Representation::Integer32();
    3778        2806 :       continue;
    3779             :     }
    3780             :     return Representation::None();
    3781             :   }
    3782      441351 :   return rep;
    3783             : }
    3784             : 
    3785             : 
    3786       95617 : bool HValue::HasNonSmiUse() {
    3787       17429 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    3788             :     // We check for observed_input_representation elsewhere.
    3789             :     Representation use_rep =
    3790      108134 :         it.value()->RequiredInputRepresentation(it.index());
    3791      206750 :     if (!use_rep.IsNone() &&
    3792      203255 :         !use_rep.IsSmi() &&
    3793             :         !use_rep.IsTagged()) {
    3794             :       return true;
    3795             :     }
    3796             :   }
    3797        4912 :   return false;
    3798             : }
    3799             : 
    3800             : 
    3801             : // Node-specific verification code is only included in debug mode.
    3802             : #ifdef DEBUG
    3803             : 
    3804             : void HPhi::Verify() {
    3805             :   DCHECK(OperandCount() == block()->predecessors()->length());
    3806             :   for (int i = 0; i < OperandCount(); ++i) {
    3807             :     HValue* value = OperandAt(i);
    3808             :     HBasicBlock* defining_block = value->block();
    3809             :     HBasicBlock* predecessor_block = block()->predecessors()->at(i);
    3810             :     DCHECK(defining_block == predecessor_block ||
    3811             :            defining_block->Dominates(predecessor_block));
    3812             :   }
    3813             : }
    3814             : 
    3815             : 
    3816             : void HSimulate::Verify() {
    3817             :   HInstruction::Verify();
    3818             :   DCHECK(HasAstId() || next()->IsEnterInlined());
    3819             : }
    3820             : 
    3821             : 
    3822             : void HCheckHeapObject::Verify() {
    3823             :   HInstruction::Verify();
    3824             :   DCHECK(HasNoUses());
    3825             : }
    3826             : 
    3827             : 
    3828             : void HCheckValue::Verify() {
    3829             :   HInstruction::Verify();
    3830             :   DCHECK(HasNoUses());
    3831             : }
    3832             : 
    3833             : #endif
    3834             : 
    3835             : 
    3836           0 : HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) {
    3837             :   DCHECK(offset >= 0);
    3838             :   DCHECK(offset < FixedArray::kHeaderSize);
    3839           0 :   if (offset == FixedArray::kLengthOffset) return ForFixedArrayLength();
    3840           0 :   return HObjectAccess(kInobject, offset);
    3841             : }
    3842             : 
    3843             : 
    3844       57349 : HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset,
    3845             :     Representation representation) {
    3846             :   DCHECK(offset >= 0);
    3847             :   Portion portion = kInobject;
    3848             : 
    3849       57349 :   if (offset == JSObject::kElementsOffset) {
    3850             :     portion = kElementsPointer;
    3851       52750 :   } else if (offset == JSObject::kMapOffset) {
    3852             :     portion = kMaps;
    3853             :   }
    3854             :   bool existing_inobject_property = true;
    3855       57349 :   if (!map.is_null()) {
    3856             :     existing_inobject_property = (offset <
    3857       50985 :         map->instance_size() - map->unused_property_fields() * kPointerSize);
    3858             :   }
    3859             :   return HObjectAccess(portion, offset, representation, Handle<String>::null(),
    3860       57349 :                        false, existing_inobject_property);
    3861             : }
    3862             : 
    3863             : 
    3864       14320 : HObjectAccess HObjectAccess::ForAllocationSiteOffset(int offset) {
    3865       14320 :   switch (offset) {
    3866             :     case AllocationSite::kTransitionInfoOffset:
    3867           0 :       return HObjectAccess(kInobject, offset, Representation::Tagged());
    3868             :     case AllocationSite::kNestedSiteOffset:
    3869           0 :       return HObjectAccess(kInobject, offset, Representation::Tagged());
    3870             :     case AllocationSite::kPretenureDataOffset:
    3871           0 :       return HObjectAccess(kInobject, offset, Representation::Smi());
    3872             :     case AllocationSite::kPretenureCreateCountOffset:
    3873       14320 :       return HObjectAccess(kInobject, offset, Representation::Smi());
    3874             :     case AllocationSite::kDependentCodeOffset:
    3875           0 :       return HObjectAccess(kInobject, offset, Representation::Tagged());
    3876             :     case AllocationSite::kWeakNextOffset:
    3877           0 :       return HObjectAccess(kInobject, offset, Representation::Tagged());
    3878             :     default:
    3879           0 :       UNREACHABLE();
    3880             :   }
    3881             :   return HObjectAccess(kInobject, offset);
    3882             : }
    3883             : 
    3884             : 
    3885       32540 : HObjectAccess HObjectAccess::ForContextSlot(int index) {
    3886             :   DCHECK(index >= 0);
    3887             :   Portion portion = kInobject;
    3888       32540 :   int offset = Context::kHeaderSize + index * kPointerSize;
    3889             :   DCHECK_EQ(offset, Context::SlotOffset(index) + kHeapObjectTag);
    3890       32540 :   return HObjectAccess(portion, offset, Representation::Tagged());
    3891             : }
    3892             : 
    3893             : 
    3894           0 : HObjectAccess HObjectAccess::ForScriptContext(int index) {
    3895             :   DCHECK(index >= 0);
    3896             :   Portion portion = kInobject;
    3897             :   int offset = ScriptContextTable::GetContextOffset(index);
    3898           0 :   return HObjectAccess(portion, offset, Representation::Tagged());
    3899             : }
    3900             : 
    3901             : 
    3902           0 : HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) {
    3903             :   DCHECK(offset >= 0);
    3904             :   Portion portion = kInobject;
    3905             : 
    3906           0 :   if (offset == JSObject::kElementsOffset) {
    3907             :     portion = kElementsPointer;
    3908           0 :   } else if (offset == JSArray::kLengthOffset) {
    3909             :     portion = kArrayLengths;
    3910           0 :   } else if (offset == JSObject::kMapOffset) {
    3911             :     portion = kMaps;
    3912             :   }
    3913           0 :   return HObjectAccess(portion, offset);
    3914             : }
    3915             : 
    3916             : 
    3917           0 : HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset,
    3918             :     Representation representation) {
    3919             :   DCHECK(offset >= 0);
    3920             :   return HObjectAccess(kBackingStore, offset, representation,
    3921           0 :                        Handle<String>::null(), false, false);
    3922             : }
    3923             : 
    3924             : 
    3925      112843 : HObjectAccess HObjectAccess::ForField(Handle<Map> map, int index,
    3926             :                                       Representation representation,
    3927             :                                       Handle<Name> name) {
    3928      112843 :   if (index < 0) {
    3929             :     // Negative property indices are in-object properties, indexed
    3930             :     // from the end of the fixed part of the object.
    3931      213476 :     int offset = (index * kPointerSize) + map->instance_size();
    3932      106738 :     return HObjectAccess(kInobject, offset, representation, name, false, true);
    3933             :   } else {
    3934             :     // Non-negative property indices are in the properties array.
    3935        6105 :     int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
    3936             :     return HObjectAccess(kBackingStore, offset, representation, name,
    3937        6105 :                          false, false);
    3938             :   }
    3939             : }
    3940             : 
    3941             : 
    3942     1138666 : void HObjectAccess::SetGVNFlags(HValue *instr, PropertyAccessType access_type) {
    3943             :   // set the appropriate GVN flags for a given load or store instruction
    3944      569333 :   if (access_type == STORE) {
    3945             :     // track dominating allocations in order to eliminate write barriers
    3946             :     instr->SetDependsOnFlag(::v8::internal::kNewSpacePromotion);
    3947             :     instr->SetFlag(HValue::kTrackSideEffectDominators);
    3948             :   } else {
    3949             :     // try to GVN loads, but don't hoist above map changes
    3950             :     instr->SetFlag(HValue::kUseGVN);
    3951             :     instr->SetDependsOnFlag(::v8::internal::kMaps);
    3952             :   }
    3953             : 
    3954      569333 :   switch (portion()) {
    3955             :     case kArrayLengths:
    3956       59357 :       if (access_type == STORE) {
    3957             :         instr->SetChangesFlag(::v8::internal::kArrayLengths);
    3958             :       } else {
    3959             :         instr->SetDependsOnFlag(::v8::internal::kArrayLengths);
    3960             :       }
    3961             :       break;
    3962             :     case kStringLengths:
    3963       62484 :       if (access_type == STORE) {
    3964             :         instr->SetChangesFlag(::v8::internal::kStringLengths);
    3965             :       } else {
    3966             :         instr->SetDependsOnFlag(::v8::internal::kStringLengths);
    3967             :       }
    3968             :       break;
    3969             :     case kInobject:
    3970      292079 :       if (access_type == STORE) {
    3971             :         instr->SetChangesFlag(::v8::internal::kInobjectFields);
    3972             :       } else {
    3973             :         instr->SetDependsOnFlag(::v8::internal::kInobjectFields);
    3974             :       }
    3975             :       break;
    3976             :     case kDouble:
    3977        2221 :       if (access_type == STORE) {
    3978             :         instr->SetChangesFlag(::v8::internal::kDoubleFields);
    3979             :       } else {
    3980             :         instr->SetDependsOnFlag(::v8::internal::kDoubleFields);
    3981             :       }
    3982             :       break;
    3983             :     case kBackingStore:
    3984        3651 :       if (access_type == STORE) {
    3985             :         instr->SetChangesFlag(::v8::internal::kBackingStoreFields);
    3986             :       } else {
    3987             :         instr->SetDependsOnFlag(::v8::internal::kBackingStoreFields);
    3988             :       }
    3989             :       break;
    3990             :     case kElementsPointer:
    3991       65142 :       if (access_type == STORE) {
    3992             :         instr->SetChangesFlag(::v8::internal::kElementsPointer);
    3993             :       } else {
    3994             :         instr->SetDependsOnFlag(::v8::internal::kElementsPointer);
    3995             :       }
    3996             :       break;
    3997             :     case kMaps:
    3998       84399 :       if (access_type == STORE) {
    3999             :         instr->SetChangesFlag(::v8::internal::kMaps);
    4000             :       } else {
    4001             :         instr->SetDependsOnFlag(::v8::internal::kMaps);
    4002             :       }
    4003             :       break;
    4004             :     case kExternalMemory:
    4005           0 :       if (access_type == STORE) {
    4006             :         instr->SetChangesFlag(::v8::internal::kExternalMemory);
    4007             :       } else {
    4008             :         instr->SetDependsOnFlag(::v8::internal::kExternalMemory);
    4009             :       }
    4010             :       break;
    4011             :   }
    4012      569333 : }
    4013             : 
    4014             : 
    4015           0 : std::ostream& operator<<(std::ostream& os, const HObjectAccess& access) {
    4016           0 :   os << ".";
    4017             : 
    4018           0 :   switch (access.portion()) {
    4019             :     case HObjectAccess::kArrayLengths:
    4020             :     case HObjectAccess::kStringLengths:
    4021           0 :       os << "%length";
    4022           0 :       break;
    4023             :     case HObjectAccess::kElementsPointer:
    4024           0 :       os << "%elements";
    4025           0 :       break;
    4026             :     case HObjectAccess::kMaps:
    4027           0 :       os << "%map";
    4028           0 :       break;
    4029             :     case HObjectAccess::kDouble:  // fall through
    4030             :     case HObjectAccess::kInobject:
    4031           0 :       if (!access.name().is_null() && access.name()->IsString()) {
    4032           0 :         os << Handle<String>::cast(access.name())->ToCString().get();
    4033             :       }
    4034           0 :       os << "[in-object]";
    4035           0 :       break;
    4036             :     case HObjectAccess::kBackingStore:
    4037           0 :       if (!access.name().is_null() && access.name()->IsString()) {
    4038           0 :         os << Handle<String>::cast(access.name())->ToCString().get();
    4039             :       }
    4040           0 :       os << "[backing-store]";
    4041           0 :       break;
    4042             :     case HObjectAccess::kExternalMemory:
    4043           0 :       os << "[external-memory]";
    4044           0 :       break;
    4045             :   }
    4046             : 
    4047           0 :   return os << "@" << access.offset();
    4048             : }
    4049             : 
    4050             : }  // namespace internal
    4051             : }  // namespace v8

Generated by: LCOV version 1.10