LCOV - code coverage report
Current view: top level - src/crankshaft - hydrogen-instructions.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1251 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    20665389 : HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE)
      47             : #undef DEFINE_COMPILE
      48             : 
      49     4377551 : Representation RepresentationFromMachineType(MachineType type) {
      50     4377551 :   if (type == MachineType::Int32()) {
      51             :     return Representation::Integer32();
      52             :   }
      53             : 
      54     3740516 :   if (type == MachineType::TaggedSigned()) {
      55             :     return Representation::Smi();
      56             :   }
      57             : 
      58     2764013 :   if (type == MachineType::Pointer()) {
      59             :     return Representation::External();
      60             :   }
      61             : 
      62             :   return Representation::Tagged();
      63             : }
      64             : 
      65      159233 : Isolate* HValue::isolate() const {
      66             :   DCHECK(block() != NULL);
      67      159233 :   return block()->isolate();
      68             : }
      69             : 
      70             : 
      71         598 : void HValue::AssumeRepresentation(Representation r) {
      72         598 :   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         598 : }
      79             : 
      80             : 
      81      114462 : void HValue::InferRepresentation(HInferRepresentationPhase* h_infer) {
      82             :   DCHECK(CheckFlag(kFlexibleRepresentation));
      83      114462 :   Representation new_rep = RepresentationFromInputs();
      84      114462 :   UpdateRepresentation(new_rep, h_infer, "inputs");
      85      114462 :   new_rep = RepresentationFromUses();
      86      114462 :   UpdateRepresentation(new_rep, h_infer, "uses");
      87      114462 :   if (representation().IsSmi() && HasNonSmiUse()) {
      88             :     UpdateRepresentation(
      89       43495 :         Representation::Integer32(), h_infer, "use requirements");
      90             :   }
      91      114462 : }
      92             : 
      93             : 
      94      996360 : Representation HValue::RepresentationFromUses() {
      95      996360 :   if (HasNoUses()) return Representation::None();
      96      963730 :   Representation result = Representation::None();
      97             : 
      98     2080790 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
      99     2080790 :     HValue* use = it.value();
     100     2080790 :     Representation rep = use->observed_input_representation(it.index());
     101     2080790 :     result = result.generalize(rep);
     102             : 
     103     2080790 :     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      963730 :   if (IsPhi()) {
     110             :     result = result.generalize(
     111      444349 :         HPhi::cast(this)->representation_from_indirect_uses());
     112             :   }
     113             : 
     114             :   // External representations are dealt with separately.
     115      963730 :   return result.IsExternal() ? Representation::None() : result;
     116             : }
     117             : 
     118             : 
     119     3809361 : void HValue::UpdateRepresentation(Representation new_rep,
     120             :                                   HInferRepresentationPhase* h_infer,
     121     1082760 :                                   const char* reason) {
     122     3809361 :   Representation r = representation();
     123     3809361 :   if (new_rep.is_more_general_than(r)) {
     124     1180033 :     if (CheckFlag(kCannotBeTagged) && new_rep.IsTagged()) return;
     125     1080802 :     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     1080802 :     AddDependantsToWorklist(h_infer);
     131             :   }
     132             : }
     133             : 
     134             : 
     135     1080802 : void HValue::AddDependantsToWorklist(HInferRepresentationPhase* h_infer) {
     136     2520421 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     137     2520421 :     h_infer->AddToWorklist(it.value());
     138             :   }
     139     3928754 :   for (int i = 0; i < OperandCount(); ++i) {
     140     2847952 :     h_infer->AddToWorklist(OperandAt(i));
     141             :   }
     142     1080804 : }
     143             : 
     144             : 
     145             : static int32_t ConvertAndSetOverflow(Representation r,
     146             :                                      int64_t result,
     147             :                                      bool* overflow) {
     148      385554 :   if (r.IsSmi()) {
     149        3146 :     if (result > Smi::kMaxValue) {
     150             :       *overflow = true;
     151             :       return Smi::kMaxValue;
     152             :     }
     153        1573 :     if (result < Smi::kMinValue) {
     154             :       *overflow = true;
     155             :       return Smi::kMinValue;
     156             :     }
     157             :   } else {
     158      680792 :     if (result > kMaxInt) {
     159             :       *overflow = true;
     160             :       return kMaxInt;
     161             :     }
     162      501829 :     if (result < kMinInt) {
     163             :       *overflow = true;
     164             :       return kMinInt;
     165             :     }
     166             :   }
     167      403207 :   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      625620 :   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       27818 :   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       30500 :   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      150730 :   if (lower_ == upper_) return lower_;
     200       95262 :   if (lower_ >= 0) {
     201             :     int32_t res = 1;
     202      560973 :     while (res < upper_) {
     203      502079 :       res = (res << 1) | 1;
     204             :     }
     205             :     return res;
     206             :   }
     207             :   return 0xffffffff;
     208             : }
     209             : 
     210             : 
     211      149192 : void Range::AddConstant(int32_t value) {
     212      298384 :   if (value == 0) return;
     213             :   bool may_overflow = false;  // Overflow is ignored here.
     214             :   Representation r = Representation::Integer32();
     215      298384 :   lower_ = AddWithoutOverflow(r, lower_, value, &may_overflow);
     216      298384 :   upper_ = AddWithoutOverflow(r, upper_, value, &may_overflow);
     217             : #ifdef DEBUG
     218             :   Verify();
     219             : #endif
     220             : }
     221             : 
     222             : 
     223      472452 : void Range::Intersect(Range* other) {
     224      944904 :   upper_ = Min(upper_, other->upper_);
     225      944904 :   lower_ = Max(lower_, other->lower_);
     226      472458 :   bool b = CanBeMinusZero() && other->CanBeMinusZero();
     227             :   set_can_be_minus_zero(b);
     228      472452 : }
     229             : 
     230             : 
     231       19036 : void Range::Union(Range* other) {
     232       38072 :   upper_ = Max(upper_, other->upper_);
     233       38072 :   lower_ = Min(lower_, other->lower_);
     234       34295 :   bool b = CanBeMinusZero() || other->CanBeMinusZero();
     235             :   set_can_be_minus_zero(b);
     236       19036 : }
     237             : 
     238             : 
     239         114 : void Range::CombinedMax(Range* other) {
     240         228 :   upper_ = Max(upper_, other->upper_);
     241         228 :   lower_ = Max(lower_, other->lower_);
     242         189 :   set_can_be_minus_zero(CanBeMinusZero() || other->CanBeMinusZero());
     243         114 : }
     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       14196 :   int32_t bits = value & 0x1F;
     255       14196 :   lower_ = lower_ >> bits;
     256       14196 :   upper_ = upper_ >> bits;
     257             :   set_can_be_minus_zero(false);
     258           0 : }
     259             : 
     260             : 
     261           0 : void Range::Shl(int32_t value) {
     262       15242 :   int32_t bits = value & 0x1F;
     263       15242 :   int old_lower = lower_;
     264       15242 :   int old_upper = upper_;
     265       15242 :   lower_ = lower_ << bits;
     266       15242 :   upper_ = upper_ << bits;
     267       15242 :   if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) {
     268       10958 :     upper_ = kMaxInt;
     269       10958 :     lower_ = kMinInt;
     270             :   }
     271             :   set_can_be_minus_zero(false);
     272           0 : }
     273             : 
     274             : 
     275      327236 : bool Range::AddAndCheckOverflow(const Representation& r, Range* other) {
     276             :   bool may_overflow = false;
     277      327236 :   lower_ = AddWithoutOverflow(r, lower_, other->lower(), &may_overflow);
     278      327236 :   upper_ = AddWithoutOverflow(r, upper_, other->upper(), &may_overflow);
     279      163618 :   if (may_overflow) {
     280             :     Clear();
     281             :   } else {
     282             :     KeepOrder();
     283             :   }
     284             : #ifdef DEBUG
     285             :   Verify();
     286             : #endif
     287      163618 :   return may_overflow;
     288             : }
     289             : 
     290             : 
     291       27818 : bool Range::SubAndCheckOverflow(const Representation& r, Range* other) {
     292             :   bool may_overflow = false;
     293       27818 :   lower_ = SubWithoutOverflow(r, lower_, other->upper(), &may_overflow);
     294       27818 :   upper_ = SubWithoutOverflow(r, upper_, other->lower(), &may_overflow);
     295       13909 :   if (may_overflow) {
     296             :     Clear();
     297             :   } else {
     298             :     KeepOrder();
     299             :   }
     300             : #ifdef DEBUG
     301             :   Verify();
     302             : #endif
     303       13909 :   return may_overflow;
     304             : }
     305             : 
     306           0 : void Range::Clear() {
     307      105136 :   lower_ = kMinInt;
     308      105136 :   upper_ = kMaxInt;
     309           0 : }
     310             : 
     311           0 : void Range::KeepOrder() {
     312       79616 :   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       15250 : bool Range::MulAndCheckOverflow(const Representation& r, Range* other) {
     328             :   bool may_overflow = false;
     329        7625 :   int v1 = MulWithoutOverflow(r, lower_, other->lower(), &may_overflow);
     330             :   int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow);
     331        7625 :   int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow);
     332             :   int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow);
     333        7625 :   if (may_overflow) {
     334             :     Clear();
     335             :   } else {
     336         400 :     lower_ = Min(Min(v1, v2), Min(v3, v4));
     337         400 :     upper_ = Max(Max(v1, v2), Max(v3, v4));
     338             :   }
     339             : #ifdef DEBUG
     340             :   Verify();
     341             : #endif
     342        7625 :   return may_overflow;
     343             : }
     344             : 
     345             : 
     346     2771726 : bool HValue::IsDefinedAfter(HBasicBlock* other) const {
     347     2771726 :   return block()->block_id() > other->block_id();
     348             : }
     349             : 
     350             : 
     351      204154 : HUseListNode* HUseListNode::tail() {
     352             :   // Skip and remove dead items in the use list.
     353   105723455 :   while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) {
     354    28998384 :     tail_ = tail_->tail_;
     355             :   }
     356      204154 :   return tail_;
     357             : }
     358             : 
     359             : 
     360      339911 : bool HValue::CheckUsesForFlag(Flag f) const {
     361       34486 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     362      651186 :     if (it.value()->IsSimulate()) continue;
     363      633746 :     if (!it.value()->CheckFlag(f)) return false;
     364             :   }
     365       48805 :   return true;
     366             : }
     367             : 
     368             : 
     369      327367 : bool HValue::CheckUsesForFlag(Flag f, HValue** value) const {
     370      290585 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     371     1009680 :     if (it.value()->IsSimulate()) continue;
     372      962144 :     if (!it.value()->CheckFlag(f)) {
     373      214255 :       *value = it.value();
     374      214255 :       return false;
     375             :     }
     376             :   }
     377      113112 :   return true;
     378             : }
     379             : 
     380             : 
     381      251595 : bool HValue::HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const {
     382             :   bool return_value = false;
     383       33412 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     384      514042 :     if (it.value()->IsSimulate()) continue;
     385      510762 :     if (!it.value()->CheckFlag(f)) return false;
     386             :     return_value = true;
     387             :   }
     388       27986 :   return return_value;
     389             : }
     390             : 
     391             : 
     392    17279563 : HUseIterator::HUseIterator(HUseListNode* head) : next_(head) {
     393    17279563 :   Advance();
     394    13220457 : }
     395             : 
     396             : 
     397    52568935 : void HUseIterator::Advance() {
     398    52568935 :   current_ = next_;
     399   124909697 :   if (current_ != NULL) {
     400    36170381 :     next_ = current_->tail();
     401    36170381 :     value_ = current_->value();
     402    36170381 :     index_ = current_->index();
     403             :   }
     404    52568935 : }
     405             : 
     406             : 
     407      171482 : int HValue::UseCount() const {
     408             :   int count = 0;
     409     1158573 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) ++count;
     410      171482 :   return count;
     411             : }
     412             : 
     413             : 
     414     3465008 : HUseListNode* HValue::RemoveUse(HValue* value, int index) {
     415             :   HUseListNode* previous = NULL;
     416    13342363 :   HUseListNode* current = use_list_;
     417     9842139 :   while (current != NULL) {
     418     9877355 :     if (current->value() == value && current->index() == index) {
     419     3464989 :       if (previous == NULL) {
     420     2805325 :         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     3465008 :   return current;
     442             : }
     443             : 
     444             : 
     445    22235027 : bool HValue::Equals(HValue* other) {
     446    15813749 :   if (other->opcode() != opcode()) return false;
     447    12928238 :   if (!other->representation().Equals(representation())) return false;
     448    10405956 :   if (!other->type_.Equals(type_)) return false;
     449     6421278 :   if (other->flags() != flags()) return false;
     450     6266693 :   if (OperandCount() != other->OperandCount()) return false;
     451      802113 :   for (int i = 0; i < OperandCount(); ++i) {
     452      825824 :     if (OperandAt(i)->id() != other->OperandAt(i)->id()) return false;
     453             :   }
     454     6242981 :   bool result = DataEquals(other);
     455             :   DCHECK(!result || Hashcode() == other->Hashcode());
     456     6242982 :   return result;
     457             : }
     458             : 
     459             : 
     460     8564659 : intptr_t HValue::Hashcode() {
     461     8564659 :   intptr_t result = opcode();
     462     8564652 :   int count = OperandCount();
     463    21793229 :   for (int i = 0; i < count; ++i) {
     464    13228627 :     result = result * 19 + OperandAt(i)->id() + (result >> 7);
     465             :   }
     466     8564602 :   return result;
     467             : }
     468             : 
     469             : 
     470    10429695 : const char* HValue::Mnemonic() const {
     471    10429695 :   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    48712905 : bool HValue::CanReplaceWithDummyUses() {
     482    48712905 :   return FLAG_unreachable_code_elimination &&
     483     3991756 :       !(block()->IsReachable() ||
     484     2916960 :         IsBlockEntry() ||
     485     4759058 :         IsControlInstruction() ||
     486     1836679 :         IsArgumentsObject() ||
     487     1833466 :         IsCapturedObject() ||
     488      861516 :         IsSimulate() ||
     489             :         IsEnterInlined() ||
     490      856103 :         IsLeaveInlined());
     491             : }
     492             : 
     493             : 
     494       30629 : bool HValue::IsInteger32Constant() {
     495     1422897 :   return IsConstant() && HConstant::cast(this)->HasInteger32Value();
     496             : }
     497             : 
     498             : 
     499       29079 : int32_t HValue::GetInteger32Constant() {
     500      377558 :   return HConstant::cast(this)->Integer32Value();
     501             : }
     502             : 
     503             : 
     504      969067 : bool HValue::EqualsInteger32Constant(int32_t value) {
     505     1311884 :   return IsInteger32Constant() && GetInteger32Constant() == value;
     506             : }
     507             : 
     508             : 
     509    27635468 : void HValue::SetOperandAt(int index, HValue* value) {
     510    27635468 :   RegisterUse(index, value);
     511    27635329 :   InternalSetOperandAt(index, value);
     512    27635359 : }
     513             : 
     514             : 
     515     6725298 : void HValue::DeleteAndReplaceWith(HValue* other) {
     516             :   // We replace all uses first, so Delete can assert that there are none.
     517     6725298 :   if (other != NULL) ReplaceAllUsesWith(other);
     518     6725298 :   Kill();
     519     6725304 :   DeleteFromGraph();
     520     6725298 : }
     521             : 
     522             : 
     523     4039971 : void HValue::ReplaceAllUsesWith(HValue* other) {
     524    13470327 :   while (use_list_ != NULL) {
     525    10780768 :     HUseListNode* list_node = use_list_;
     526             :     HValue* value = list_node->value();
     527             :     DCHECK(!value->block()->IsStartBlock());
     528    10780768 :     value->InternalSetOperandAt(list_node->index(), other);
     529     5390385 :     use_list_ = list_node->tail();
     530     5390385 :     list_node->set_tail(other->use_list_);
     531     5390385 :     other->use_list_ = list_node;
     532             :   }
     533     4039972 : }
     534             : 
     535             : 
     536     7103590 : 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    10788782 :   for (int i = 0; i < OperandCount(); ++i) {
     542     3685195 :     HValue* operand = OperandAt(i);
     543     3685192 :     if (operand == NULL) continue;
     544     4711454 :     HUseListNode* first = operand->use_list_;
     545     7018638 :     if (first != NULL && first->value()->CheckFlag(kIsDead)) {
     546      577198 :       operand->use_list_ = first->tail();
     547             :     }
     548             :   }
     549     7103588 : }
     550             : 
     551             : 
     552    67562318 : void HValue::SetBlock(HBasicBlock* block) {
     553             :   DCHECK(block_ == NULL || block == NULL);
     554    34452321 :   block_ = block;
     555    34452321 :   if (id_ == kNoNumber && block != NULL) {
     556    33109948 :     id_ = block->graph()->GetNextValueID(this);
     557             :   }
     558    34452272 : }
     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      800964 : bool HValue::HasMonomorphicJSObjectType() {
     597     1601928 :   return !GetMonomorphicJSObjectMap().is_null();
     598             : }
     599             : 
     600             : 
     601    29393539 : bool HValue::UpdateInferredType() {
     602    29393539 :   HType type = CalculateInferredType();
     603    29393550 :   bool result = (!type.Equals(type_));
     604    29393550 :   type_ = type;
     605    29393550 :   return result;
     606             : }
     607             : 
     608             : 
     609    51765333 : void HValue::RegisterUse(int index, HValue* new_value) {
     610    27635460 :   HValue* old_value = OperandAt(index);
     611    55271311 :   if (old_value == new_value) return;
     612             : 
     613             :   HUseListNode* removed = NULL;
     614    27594416 :   if (old_value != NULL) {
     615     3465012 :     removed = old_value->RemoveUse(this, index);
     616             :   }
     617             : 
     618    27594883 :   if (new_value != NULL) {
     619    27594883 :     if (removed == NULL) {
     620    24129873 :       new_value->use_list_ = new(new_value->block()->zone()) HUseListNode(
     621    48259626 :           this, index, new_value->use_list_);
     622             :     } else {
     623     3465010 :       removed->set_tail(new_value->use_list_);
     624     3465010 :       new_value->use_list_ = removed;
     625             :     }
     626             :   }
     627             : }
     628             : 
     629             : 
     630      876406 : void HValue::AddNewRange(Range* r, Zone* zone) {
     631      438203 :   if (!HasRange()) ComputeInitialRange(zone);
     632      438203 :   if (!HasRange()) range_ = new(zone) Range();
     633             :   DCHECK(HasRange());
     634      438203 :   r->StackUpon(range_);
     635      438203 :   range_ = r;
     636      438203 : }
     637             : 
     638             : 
     639      417459 : void HValue::RemoveLastAddedRange() {
     640             :   DCHECK(HasRange());
     641             :   DCHECK(range_->next() != NULL);
     642      417459 :   range_ = range_->next();
     643      417459 : }
     644             : 
     645             : 
     646    10429664 : void HValue::ComputeInitialRange(Zone* zone) {
     647             :   DCHECK(!HasRange());
     648    10429664 :   range_ = InferRange(zone);
     649             :   DCHECK(HasRange());
     650    10429732 : }
     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     7689516 : 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     7689516 :   previous_->next_ = next_;
     677     7689516 :   if (next_ == NULL) {
     678             :     DCHECK(block()->last() == this);
     679       37376 :     block()->set_last(previous_);
     680             :   } else {
     681     7652140 :     next_->previous_ = previous_;
     682             :   }
     683             :   clear_block();
     684     7689516 : }
     685             : 
     686             : 
     687     2955255 : 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     2955255 :   prev->next_ = this;
     695     2955255 :   next->previous_ = this;
     696     2955255 :   next_ = next;
     697     2955255 :   previous_ = prev;
     698     2955255 :   SetBlock(next->block());
     699     4950867 :   if (!has_position() && next->has_position()) {
     700     1556500 :     set_position(next->position());
     701             :   }
     702     2955257 : }
     703             : 
     704             : 
     705    25822457 : void HInstruction::InsertAfter(HInstruction* previous) {
     706             :   DCHECK(!IsLinked());
     707             :   DCHECK(!previous->IsControlInstruction());
     708             :   DCHECK(!IsControlInstruction() || previous->next_ == NULL);
     709    53593832 :   HBasicBlock* block = previous->block();
     710             :   // Never insert anything except constants into the start block after finishing
     711             :   // it.
     712    28456325 :   if (block->IsStartBlock() && block->IsFinished() && !IsConstant()) {
     713             :     DCHECK(block->end()->SecondSuccessor() == NULL);
     714           0 :     InsertAfter(block->end()->FirstSuccessor()->first());
     715    25822458 :     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    25822456 :   HInstruction* next = previous->next_;
     722    25822456 :   if (previous->HasObservableSideEffects() && next != NULL) {
     723             :     DCHECK(next->IsSimulate());
     724             :     previous = next;
     725           0 :     next = previous->next_;
     726             :   }
     727             : 
     728    25822456 :   previous_ = previous;
     729    25822456 :   next_ = next;
     730    25822456 :   SetBlock(block);
     731    25822458 :   previous->next_ = this;
     732    25822458 :   if (next != NULL) next->previous_ = this;
     733    25822458 :   if (block->last() == previous) {
     734             :     block->set_last(this);
     735             :   }
     736    32383087 :   if (!has_position() && previous->has_position()) {
     737       12771 :     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       58533 : void HBoundsCheck::InferRepresentation(HInferRepresentationPhase* h_infer) {
     966             :   DCHECK(CheckFlag(kFlexibleRepresentation));
     967       58533 :   HValue* actual_index = index()->ActualValue();
     968       58534 :   HValue* actual_length = length()->ActualValue();
     969       58534 :   Representation index_rep = actual_index->representation();
     970             :   Representation length_rep = actual_length->representation();
     971       67048 :   if (index_rep.IsTagged() && actual_index->type().IsSmi()) {
     972           0 :     index_rep = Representation::Smi();
     973             :   }
     974       58534 :   if (length_rep.IsTagged() && actual_length->type().IsSmi()) {
     975             :     length_rep = Representation::Smi();
     976             :   }
     977       58534 :   Representation r = index_rep.generalize(length_rep);
     978       58534 :   if (r.is_more_general_than(Representation::Integer32())) {
     979        8601 :     r = Representation::Integer32();
     980             :   }
     981       58533 :   UpdateRepresentation(r, h_infer, "boundscheck");
     982       58533 : }
     983             : 
     984             : 
     985       68496 : Range* HBoundsCheck::InferRange(Zone* zone) {
     986             :   Representation r = representation();
     987       68496 :   if (r.IsSmiOrInteger32() && length()->HasRange()) {
     988       68496 :     int upper = length()->range()->upper() - (allow_equality() ? 0 : 1);
     989             :     int lower = 0;
     990             : 
     991             :     Range* result = new(zone) Range(lower, upper);
     992       34250 :     if (index()->HasRange()) {
     993       34250 :       result->Intersect(index()->range());
     994             :     }
     995             : 
     996             :     // In case of Smi representation, clamp result to Smi::kMaxValue.
     997       34250 :     if (r.IsSmi()) result->ClampToSmi();
     998       34250 :     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       17614 : Representation HBranch::observed_input_representation(int index) {
    1074       17614 :   if (expected_input_types_ &
    1075             :       (ToBooleanHint::kNull | ToBooleanHint::kReceiver |
    1076             :        ToBooleanHint::kString | ToBooleanHint::kSymbol)) {
    1077             :     return Representation::Tagged();
    1078             :   }
    1079       14972 :   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       14920 :   if (expected_input_types_ & ToBooleanHint::kHeapNumber) {
    1086             :     return Representation::Double();
    1087             :   }
    1088       14920 :   if (expected_input_types_ & ToBooleanHint::kSmallInteger) {
    1089             :     return Representation::Smi();
    1090             :   }
    1091             :   return Representation::None();
    1092             : }
    1093             : 
    1094             : 
    1095     2818205 : bool HBranch::KnownSuccessorBlock(HBasicBlock** block) {
    1096             :   HValue* value = this->value();
    1097     2818205 :   if (value->EmitAtUses()) {
    1098             :     DCHECK(value->IsConstant());
    1099             :     DCHECK(!value->representation().IsDouble());
    1100      583189 :     *block = HConstant::cast(value)->BooleanValue()
    1101      182851 :         ? FirstSuccessor()
    1102      766040 :         : SecondSuccessor();
    1103      583189 :     return true;
    1104             :   }
    1105     2235018 :   *block = NULL;
    1106     2235018 :   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       26448 : Range* HUnaryMathOperation::InferRange(Zone* zone) {
    1160             :   Representation r = representation();
    1161       26490 :   if (op() == kMathClz32) return new(zone) Range(0, 32);
    1162       45966 :   if (r.IsSmiOrInteger32() && value()->HasRange()) {
    1163       19560 :     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       26345 :   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      320463 : bool HTypeofIsAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    1257      320742 :   if (FLAG_fold_constants && value()->IsConstant()) {
    1258             :     HConstant* constant = HConstant::cast(value());
    1259           0 :     String* type_string = TypeOfString(constant, isolate());
    1260       17030 :     bool same_type = type_literal_.IsKnownGlobal(type_string);
    1261           0 :     *block = same_type ? FirstSuccessor() : SecondSuccessor();
    1262           0 :     return true;
    1263      320463 :   } else if (value()->representation().IsSpecialization()) {
    1264             :     bool number_type =
    1265       17030 :         type_literal_.IsKnownGlobal(isolate()->heap()->number_string());
    1266       17030 :     *block = number_type ? FirstSuccessor() : SecondSuccessor();
    1267       17030 :     return true;
    1268             :   }
    1269      303433 :   *block = NULL;
    1270      303433 :   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       44568 :   if (!l->EqualsInteger32Constant(~0)) return false;
    1309        1658 :   *negated = r;
    1310             :   return true;
    1311             : }
    1312             : 
    1313             : 
    1314       94603 : static bool MatchNegationViaXor(HValue* instr, HValue** negated) {
    1315       94603 :   if (!instr->IsBitwise()) return false;
    1316       93647 :   HBitwise* b = HBitwise::cast(instr);
    1317      115931 :   return (b->op() == Token::BIT_XOR) &&
    1318       22284 :       (MatchLeftIsOnes(b->left(), b->right(), negated) ||
    1319       93647 :        MatchLeftIsOnes(b->right(), b->left(), negated));
    1320             : }
    1321             : 
    1322             : 
    1323       92983 : static bool MatchDoubleNegation(HValue* instr, HValue** arg) {
    1324             :   HValue* negated;
    1325       94603 :   return MatchNegationViaXor(instr, &negated) &&
    1326       94603 :       MatchNegationViaXor(negated, arg);
    1327             : }
    1328             : 
    1329             : 
    1330      230263 : HValue* HBitwise::Canonicalize() {
    1331      117662 :   if (!representation().IsSmiOrInteger32()) return this;
    1332             :   // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x.
    1333      112601 :   int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0;
    1334      112806 :   if (left()->EqualsInteger32Constant(nop_constant) &&
    1335         205 :       !right()->CheckFlag(kUint32)) {
    1336         204 :     return right();
    1337             :   }
    1338      131944 :   if (right()->EqualsInteger32Constant(nop_constant) &&
    1339       19547 :       !left()->CheckFlag(kUint32)) {
    1340       19415 :     return left();
    1341             :   }
    1342             :   // Optimize double negation, a common pattern used for ToInt32(x).
    1343             :   HValue* arg;
    1344       93021 :   if (MatchDoubleNegation(this, &arg) && !arg->CheckFlag(kUint32)) {
    1345          38 :     return arg;
    1346             :   }
    1347             :   return this;
    1348             : }
    1349             : 
    1350             : 
    1351             : // static
    1352        3894 : 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        3894 :   return new (zone) HAdd(context, left, right, external_add_type);
    1359             : }
    1360             : 
    1361             : 
    1362      569784 : Representation HAdd::RepresentationFromInputs() {
    1363             :   Representation left_rep = left()->representation();
    1364      569784 :   if (left_rep.IsExternal()) {
    1365             :     return Representation::External();
    1366             :   }
    1367      565771 :   return HArithmeticBinaryOperation::RepresentationFromInputs();
    1368             : }
    1369             : 
    1370             : 
    1371     1157445 : Representation HAdd::RequiredInputRepresentation(int index) {
    1372     1157445 :   if (index == 2) {
    1373             :     Representation left_rep = left()->representation();
    1374      371574 :     if (left_rep.IsExternal()) {
    1375        3894 :       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      702254 : static bool IsIdentityOperation(HValue* arg1, HValue* arg2, int32_t identity) {
    1387     1325195 :   return arg1->representation().IsSpecialization() &&
    1388     1325195 :     arg2->EqualsInteger32Constant(identity);
    1389             : }
    1390             : 
    1391             : 
    1392      288810 : HValue* HAdd::Canonicalize() {
    1393             :   // Adding 0 is an identity operation except in case of -0: -0 + 0 = +0
    1394      296686 :   if (IsIdentityOperation(left(), right(), 0) &&
    1395             :       !left()->representation().IsDouble()) {  // Left could be -0.
    1396        7812 :     return left();
    1397             :   }
    1398      303189 :   if (IsIdentityOperation(right(), left(), 0) &&
    1399             :       !left()->representation().IsDouble()) {  // Right could be -0.
    1400       22182 :     return right();
    1401             :   }
    1402      258816 :   return this;
    1403             : }
    1404             : 
    1405             : 
    1406       26398 : HValue* HSub::Canonicalize() {
    1407       26408 :   if (IsIdentityOperation(left(), right(), 0)) return left();
    1408       26388 :   return this;
    1409             : }
    1410             : 
    1411             : 
    1412       27196 : HValue* HMul::Canonicalize() {
    1413       27196 :   if (IsIdentityOperation(left(), right(), 1)) return left();
    1414       27196 :   if (IsIdentityOperation(right(), left(), 1)) return right();
    1415       27196 :   return this;
    1416             : }
    1417             : 
    1418             : 
    1419        1370 : bool HMul::MulMinusOne() {
    1420        2740 :   if (left()->EqualsInteger32Constant(-1) ||
    1421        1370 :       right()->EqualsInteger32Constant(-1)) {
    1422             :     return true;
    1423             :   }
    1424             : 
    1425        1308 :   return false;
    1426             : }
    1427             : 
    1428             : 
    1429        5595 : HValue* HMod::Canonicalize() {
    1430        5595 :   return this;
    1431             : }
    1432             : 
    1433             : 
    1434       51658 : HValue* HDiv::Canonicalize() {
    1435       52476 :   if (IsIdentityOperation(left(), right(), 1)) return left();
    1436       50840 :   return this;
    1437             : }
    1438             : 
    1439             : 
    1440      508718 : HValue* HChange::Canonicalize() {
    1441      508718 :   return (from().Equals(to())) ? value() : this;
    1442             : }
    1443             : 
    1444             : 
    1445        4911 : HValue* HWrapReceiver::Canonicalize() {
    1446        4911 :   if (HasNoUses()) return NULL;
    1447        4911 :   if (receiver()->type().IsJSReceiver()) {
    1448             :     return receiver();
    1449             :   }
    1450        4911 :   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       61475 : HInstruction* HForceRepresentation::New(Isolate* isolate, Zone* zone,
    1460             :                                         HValue* context, HValue* value,
    1461             :                                         Representation representation) {
    1462       61807 :   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      122912 :   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       58300 : HValue* HUnaryMathOperation::Canonicalize() {
    1490       29184 :   if (op() == kMathRound || op() == kMathFloor) {
    1491             :     HValue* val = value();
    1492       27456 :     if (val->IsChange()) val = HChange::cast(val)->value();
    1493       27456 :     if (val->representation().IsSmiOrInteger32()) {
    1494        4373 :       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       76452 :   if (op() == kMathFloor && representation().IsSmiOrInteger32() &&
    1500       32403 :       value()->IsDiv() && value()->HasOneUse()) {
    1501             :     HDiv* hdiv = HDiv::cast(value());
    1502             : 
    1503           0 :     HValue* left = hdiv->left();
    1504        3281 :     if (left->representation().IsInteger32() && !left->CheckFlag(kUint32)) {
    1505             :       // A value with an integer representation does not need to be transformed.
    1506        6640 :     } 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        4962 :     } else if (hdiv->observed_input_representation(1).IsSmiOrInteger32()) {
    1511        1759 :       left = Prepend(new (block()->zone()) HChange(
    1512        5277 :           left, Representation::Integer32(), false, false, true));
    1513             :     } else {
    1514         722 :       return this;
    1515             :     }
    1516             : 
    1517        2475 :     HValue* right = hdiv->right();
    1518        2559 :     if (right->IsInteger32Constant()) {
    1519             :       right = Prepend(HConstant::cast(right)->CopyToRepresentation(
    1520        4950 :           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        7638 :         block()->graph()->isolate(), block()->zone(), context(), left, right));
    1538             :   }
    1539       25835 :   return this;
    1540             : }
    1541             : 
    1542             : 
    1543       89095 : HValue* HCheckInstanceType::Canonicalize() {
    1544      179830 :   if ((check_ == IS_JS_RECEIVER && value()->type().IsJSReceiver()) ||
    1545       89095 :       (check_ == IS_JS_ARRAY && value()->type().IsJSArray()) ||
    1546       69870 :       (check_ == IS_STRING && value()->type().IsString())) {
    1547       19997 :     return value();
    1548             :   }
    1549             : 
    1550       86684 :   if (check_ == IS_INTERNALIZED_STRING && value()->IsConstant()) {
    1551        4225 :     if (HConstant::cast(value())->HasInternalizedStringValue()) {
    1552             :       return value();
    1553             :     }
    1554             :   }
    1555       64873 :   return this;
    1556             : }
    1557             : 
    1558             : 
    1559        1343 : void HCheckInstanceType::GetCheckInterval(InstanceType* first,
    1560             :                                           InstanceType* last) {
    1561             :   DCHECK(is_interval_check());
    1562        1343 :   switch (check_) {
    1563             :     case IS_JS_RECEIVER:
    1564        1343 :       *first = FIRST_JS_RECEIVER_TYPE;
    1565        1343 :       *last = LAST_JS_RECEIVER_TYPE;
    1566        1343 :       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       48721 : void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) {
    1583             :   DCHECK(!is_interval_check());
    1584       48721 :   switch (check_) {
    1585             :     case IS_STRING:
    1586       36487 :       *mask = kIsNotStringMask;
    1587       36487 :       *tag = kStringTag;
    1588       36487 :       return;
    1589             :     case IS_INTERNALIZED_STRING:
    1590       12234 :       *mask = kIsNotStringMask | kIsNotInternalizedMask;
    1591       12234 :       *tag = kInternalizedTag;
    1592       12234 :       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      498975 : HValue* HCheckMaps::Canonicalize() {
    1611      886762 :   if (!IsStabilityCheck() && maps_are_stable() && value()->IsConstant()) {
    1612             :     HConstant* c_value = HConstant::cast(value());
    1613      183004 :     if (c_value->HasObjectMap()) {
    1614      366128 :       for (int i = 0; i < maps()->size(); ++i) {
    1615      365948 :         if (c_value->ObjectMap() == maps()->at(i)) {
    1616      182914 :           if (maps()->size() > 1) {
    1617             :             set_maps(new(block()->graph()->zone()) UniqueSet<Map>(
    1618           2 :                     maps()->at(i), block()->graph()->zone()));
    1619             :           }
    1620             :           MarkAsStabilityCheck();
    1621             :           break;
    1622             :         }
    1623             :       }
    1624             :     }
    1625             :   }
    1626      315938 :   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      203552 : HValue* HCheckValue::Canonicalize() {
    1636      164651 :   return (value()->IsConstant() &&
    1637      242467 :           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    14846987 : Range* HValue::InferRange(Zone* zone) {
    1674             :   Range* result;
    1675    15216795 :   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     7235599 :     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     7611438 :   return result;
    1685             : }
    1686             : 
    1687             : 
    1688      369527 : Range* HChange::InferRange(Zone* zone) {
    1689      370725 :   Range* input_range = value()->range();
    1690      902433 :   if (from().IsInteger32() && !value()->CheckFlag(HInstruction::kUint32) &&
    1691      127743 :       (to().IsSmi() ||
    1692      105039 :        (to().IsTagged() &&
    1693             :         input_range != NULL &&
    1694             :         input_range->IsInSmiRange()))) {
    1695      152054 :     set_type(HType::Smi());
    1696             :     ClearChangesFlag(kNewSpacePromotion);
    1697             :   }
    1698      566451 :   if (to().IsSmiOrTagged() &&
    1699             :       input_range != NULL &&
    1700      369527 :       input_range->IsInSmiRange() &&
    1701      196924 :       (!SmiValuesAre32Bits() ||
    1702      198122 :        !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      369527 :       : HValue::InferRange(zone);
    1711      521581 :   result->set_can_be_minus_zero(!to().IsSmiOrInteger32() ||
    1712             :                                 !(CheckFlag(kAllUsesTruncatingToInt32) ||
    1713      152054 :                                   CheckFlag(kAllUsesTruncatingToSmi)));
    1714      369527 :   if (to().IsSmi()) result->ClampToSmi();
    1715      369527 :   return result;
    1716             : }
    1717             : 
    1718             : 
    1719     4366960 : Range* HConstant::InferRange(Zone* zone) {
    1720     4366960 :   if (HasInteger32Value()) {
    1721     1999535 :     Range* result = new(zone) Range(int32_value_, int32_value_);
    1722             :     result->set_can_be_minus_zero(false);
    1723     1999535 :     return result;
    1724             :   }
    1725     2367425 :   return HValue::InferRange(zone);
    1726             : }
    1727             : 
    1728             : 
    1729           0 : SourcePosition HPhi::position() const { return block()->first()->position(); }
    1730             : 
    1731             : 
    1732      299951 : Range* HPhi::InferRange(Zone* zone) {
    1733       49881 :   Representation r = representation();
    1734      299951 :   if (r.IsSmiOrInteger32()) {
    1735       49881 :     if (block()->IsLoopHeader()) {
    1736             :       Range* range = r.IsSmi()
    1737             :           ? new(zone) Range(Smi::kMinValue, Smi::kMaxValue)
    1738       33951 :           : new(zone) Range(kMinInt, kMaxInt);
    1739       33951 :       return range;
    1740             :     } else {
    1741       15930 :       Range* range = OperandAt(0)->range()->Copy(zone);
    1742       69932 :       for (int i = 1; i < OperandCount(); ++i) {
    1743       19036 :         range->Union(OperandAt(i)->range());
    1744             :       }
    1745             :       return range;
    1746             :     }
    1747             :   } else {
    1748      250070 :     return HValue::InferRange(zone);
    1749             :   }
    1750             : }
    1751             : 
    1752             : 
    1753      229908 : Range* HAdd::InferRange(Zone* zone) {
    1754      486008 :   Representation r = representation();
    1755      229908 :   if (r.IsSmiOrInteger32()) {
    1756      163618 :     Range* a = left()->range();
    1757      163618 :     Range* b = right()->range();
    1758      163618 :     Range* res = a->Copy(zone);
    1759      419718 :     if (!res->AddAndCheckOverflow(r, b) ||
    1760      255357 :         (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
    1761         743 :         (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) {
    1762             :       ClearFlag(kCanOverflow);
    1763             :     }
    1764      163618 :     res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
    1765      149561 :                                !CheckFlag(kAllUsesTruncatingToInt32) &&
    1766      221239 :                                a->CanBeMinusZero() && b->CanBeMinusZero());
    1767      163618 :     return res;
    1768             :   } else {
    1769       66290 :     return HValue::InferRange(zone);
    1770             :   }
    1771             : }
    1772             : 
    1773             : 
    1774       24341 : Range* HSub::InferRange(Zone* zone) {
    1775       43679 :   Representation r = representation();
    1776       24341 :   if (r.IsSmiOrInteger32()) {
    1777       13909 :     Range* a = left()->range();
    1778       15652 :     Range* b = right()->range();
    1779       13909 :     Range* res = a->Copy(zone);
    1780       33247 :     if (!res->SubAndCheckOverflow(r, b) ||
    1781       19048 :         (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
    1782         290 :         (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) {
    1783             :       ClearFlag(kCanOverflow);
    1784             :     }
    1785       13909 :     res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
    1786        7366 :                                !CheckFlag(kAllUsesTruncatingToInt32) &&
    1787       15652 :                                a->CanBeMinusZero() && b->CanBeZero());
    1788       13909 :     return res;
    1789             :   } else {
    1790       10432 :     return HValue::InferRange(zone);
    1791             :   }
    1792             : }
    1793             : 
    1794             : 
    1795       23317 : Range* HMul::InferRange(Zone* zone) {
    1796       38169 :   Representation r = representation();
    1797       23317 :   if (r.IsSmiOrInteger32()) {
    1798       14950 :     Range* a = left()->range();
    1799       17268 :     Range* b = right()->range();
    1800        7625 :     Range* res = a->Copy(zone);
    1801       22478 :     if (!res->MulAndCheckOverflow(r, b) ||
    1802        6956 :         (((r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
    1803         561 :          (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) &&
    1804         290 :          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        7625 :     res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
    1811       14951 :                                !CheckFlag(kAllUsesTruncatingToInt32) &&
    1812        6865 :                                ((a->CanBeZero() && b->CanBeNegative()) ||
    1813        2778 :                                 (a->CanBeNegative() && b->CanBeZero())));
    1814        7626 :     return res;
    1815             :   } else {
    1816       15692 :     return HValue::InferRange(zone);
    1817             :   }
    1818             : }
    1819             : 
    1820             : 
    1821       49650 : Range* HDiv::InferRange(Zone* zone) {
    1822       52082 :   if (representation().IsInteger32()) {
    1823        4864 :     Range* a = left()->range();
    1824        7269 :     Range* b = right()->range();
    1825             :     Range* result = new(zone) Range();
    1826        2878 :     result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
    1827         123 :                                   (a->CanBeMinusZero() ||
    1828          87 :                                    (a->CanBeZero() && b->CanBeNegative())));
    1829        4750 :     if (!a->Includes(kMinInt) || !b->Includes(-1)) {
    1830             :       ClearFlag(kCanOverflow);
    1831             :     }
    1832             : 
    1833        2432 :     if (!b->CanBeZero()) {
    1834             :       ClearFlag(kCanBeDivByZero);
    1835             :     }
    1836        2432 :     return result;
    1837             :   } else {
    1838       47218 :     return HValue::InferRange(zone);
    1839             :   }
    1840             : }
    1841             : 
    1842             : 
    1843        2546 : Range* HMathFloorOfDiv::InferRange(Zone* zone) {
    1844        5092 :   if (representation().IsInteger32()) {
    1845       12730 :     Range* a = left()->range();
    1846        8387 :     Range* b = right()->range();
    1847             :     Range* result = new(zone) Range();
    1848        5092 :     result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
    1849         773 :                                   (a->CanBeMinusZero() ||
    1850         761 :                                    (a->CanBeZero() && b->CanBeNegative())));
    1851        2546 :     if (!a->Includes(kMinInt)) {
    1852             :       ClearFlag(kLeftCanBeMinInt);
    1853             :     }
    1854             : 
    1855        2546 :     if (!a->CanBeNegative()) {
    1856             :       ClearFlag(HValue::kLeftCanBeNegative);
    1857             :     }
    1858             : 
    1859        2546 :     if (!a->CanBePositive()) {
    1860             :       ClearFlag(HValue::kLeftCanBePositive);
    1861             :     }
    1862             : 
    1863        5080 :     if (!a->Includes(kMinInt) || !b->Includes(-1)) {
    1864             :       ClearFlag(kCanOverflow);
    1865             :     }
    1866             : 
    1867        2546 :     if (!b->CanBeZero()) {
    1868             :       ClearFlag(kCanBeDivByZero);
    1869             :     }
    1870        2546 :     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        6154 : static int32_t AbsMinus1(int32_t a) { return a < 0 ? -(a + 1) : (a - 1); }
    1880             : 
    1881             : 
    1882        5368 : Range* HMod::InferRange(Zone* zone) {
    1883        8445 :   if (representation().IsInteger32()) {
    1884        9231 :     Range* a = left()->range();
    1885       12154 :     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        3077 :     bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative();
    1892             :     Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0,
    1893        6154 :                                     a->CanBePositive() ? positive_bound : 0);
    1894             : 
    1895        3077 :     result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
    1896             :                                   left_can_be_negative);
    1897             : 
    1898        3077 :     if (!a->CanBeNegative()) {
    1899             :       ClearFlag(HValue::kLeftCanBeNegative);
    1900             :     }
    1901             : 
    1902        6000 :     if (!a->Includes(kMinInt) || !b->Includes(-1)) {
    1903             :       ClearFlag(HValue::kCanOverflow);
    1904             :     }
    1905             : 
    1906        3077 :     if (!b->CanBeZero()) {
    1907             :       ClearFlag(HValue::kCanBeDivByZero);
    1908             :     }
    1909        3077 :     return result;
    1910             :   } else {
    1911        2291 :     return HValue::InferRange(zone);
    1912             :   }
    1913             : }
    1914             : 
    1915             : 
    1916        1580 : Range* HMathMinMax::InferRange(Zone* zone) {
    1917        1580 :   if (representation().IsSmiOrInteger32()) {
    1918         212 :     Range* a = left()->range();
    1919         212 :     Range* b = right()->range();
    1920         212 :     Range* res = a->Copy(zone);
    1921         212 :     if (operation_ == kMathMax) {
    1922         114 :       res->CombinedMax(b);
    1923             :     } else {
    1924             :       DCHECK(operation_ == kMathMin);
    1925          98 :       res->CombinedMin(b);
    1926             :     }
    1927         212 :     return res;
    1928             :   } else {
    1929        1368 :     return HValue::InferRange(zone);
    1930             :   }
    1931             : }
    1932             : 
    1933             : 
    1934     1595708 : void HPushArguments::AddInput(HValue* value) {
    1935     1595708 :   inputs_.Add(NULL, value->block()->zone());
    1936     1595708 :   SetOperandAt(OperandCount() - 1, value);
    1937     1595707 : }
    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     2961356 : void HPhi::AddInput(HValue* value) {
    1952     1480932 :   inputs_.Add(NULL, value->block()->zone());
    1953     1480932 :   SetOperandAt(OperandCount() - 1, value);
    1954             :   // Mark phis that may have 'arguments' directly or indirectly as an operand.
    1955     2961356 :   if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) {
    1956             :     SetFlag(kIsArguments);
    1957             :   }
    1958     1480932 : }
    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     1116786 : HValue* HPhi::GetRedundantReplacement() {
    1970             :   HValue* candidate = NULL;
    1971             :   int count = OperandCount();
    1972             :   int position = 0;
    1973     3350358 :   while (position < count && candidate == NULL) {
    1974     1116786 :     HValue* current = OperandAt(position++);
    1975     1116786 :     if (current != this) candidate = current;
    1976             :   }
    1977     1577451 :   while (position < count) {
    1978     1199191 :     HValue* current = OperandAt(position++);
    1979     1199191 :     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      315630 : void HPhi::InitRealUses(int phi_id) {
    1994             :   // Initialize real uses.
    1995      315630 :   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      315630 :   SetFlag(kTruncatingToSmi);
    2000             :   SetFlag(kTruncatingToInt32);
    2001      950819 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    2002     2134191 :     HValue* value = it.value();
    2003      950819 :     if (!value->IsPhi()) {
    2004      686392 :       Representation rep = value->observed_input_representation(it.index());
    2005             :       representation_from_non_phi_uses_ =
    2006      686391 :           representation_from_non_phi_uses().generalize(rep);
    2007      686391 :       if (rep.IsSmi() || rep.IsInteger32() || rep.IsDouble()) {
    2008      137853 :         has_type_feedback_from_uses_ = true;
    2009             :       }
    2010             : 
    2011      686391 :       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      686392 :       if (!value->IsSimulate()) {
    2016      591686 :         if (!value->CheckFlag(kTruncatingToSmi)) {
    2017             :           ClearFlag(kTruncatingToSmi);
    2018             :         }
    2019      591686 :         if (!value->CheckFlag(kTruncatingToInt32)) {
    2020             :           ClearFlag(kTruncatingToInt32);
    2021             :         }
    2022             :       }
    2023             :     }
    2024             :   }
    2025      315630 : }
    2026             : 
    2027             : 
    2028      923358 : void HPhi::AddNonPhiUsesFrom(HPhi* other) {
    2029      923358 :   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      923358 :           other->representation_from_non_phi_uses());
    2040      923358 : }
    2041             : 
    2042             : 
    2043     1275755 : void HSimulate::MergeWith(ZoneList<HSimulate*>* list) {
    2044     2628520 :   while (!list->is_empty()) {
    2045     1429776 :     HSimulate* from = list->RemoveLast();
    2046             :     ZoneList<HValue*>* from_values = &from->values_;
    2047      481674 :     for (int i = 0; i < from_values->length(); ++i) {
    2048      163826 :       if (from->HasAssignedIndexAt(i)) {
    2049             :         int index = from->GetAssignedIndexAt(i);
    2050       26449 :         if (HasValueForIndex(index)) continue;
    2051      257375 :         AddAssignedValue(index, from_values->at(i));
    2052             :       } else {
    2053      137377 :         if (pop_count_ > 0) {
    2054      130937 :           pop_count_--;
    2055             :         } else {
    2056        6440 :           AddPushedValue(from_values->at(i));
    2057             :         }
    2058             :       }
    2059             :     }
    2060       77011 :     pop_count_ += from->pop_count_;
    2061       77011 :     from->DeleteAndReplaceWith(NULL);
    2062             :   }
    2063     1275754 : }
    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    10741172 : void HSimulate::ReplayEnvironment(HEnvironment* env) {
    2086    12030293 :   if (is_done_with_replay()) return;
    2087             :   DCHECK(env != NULL);
    2088             :   env->set_ast_id(ast_id());
    2089     4726032 :   env->Drop(pop_count());
    2090     8575077 :   for (int i = values()->length() - 1; i >= 0; --i) {
    2091     3849032 :     HValue* value = values()->at(i);
    2092     3849032 :     if (HasAssignedIndexAt(i)) {
    2093     1251836 :       env->Bind(GetAssignedIndexAt(i), value);
    2094             :     } else {
    2095             :       env->Push(value);
    2096             :     }
    2097             :   }
    2098             :   set_done_with_replay();
    2099             : }
    2100             : 
    2101             : 
    2102       31815 : static void ReplayEnvironmentNested(const ZoneList<HValue*>* values,
    2103        8484 :                                     HCapturedObject* other) {
    2104      373526 :   for (int i = 0; i < values->length(); ++i) {
    2105      341711 :     HValue* value = values->at(i);
    2106      154948 :     if (value->IsCapturedObject()) {
    2107       16968 :       if (HCapturedObject::cast(value)->capture_id() == other->capture_id()) {
    2108        4830 :         values->at(i) = other;
    2109             :       } else {
    2110        3654 :         ReplayEnvironmentNested(HCapturedObject::cast(value)->values(), other);
    2111             :       }
    2112             :     }
    2113             :   }
    2114       31815 : }
    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       39110 : void HCapturedObject::ReplayEnvironment(HEnvironment* env) {
    2120             :   DCHECK(env != NULL);
    2121       50059 :   while (env != NULL) {
    2122       28161 :     ReplayEnvironmentNested(env->values(), this);
    2123             :     env = env->outer();
    2124             :   }
    2125       10949 : }
    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      126795 : void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target,
    2135             :                                          Zone* zone) {
    2136             :   DCHECK(return_target->IsInlineReturnTarget());
    2137             :   return_targets_.Add(return_target, zone);
    2138      126795 : }
    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      625403 :   if (value >= std::numeric_limits<int32_t>::min() &&
    2152             :       value <= std::numeric_limits<int32_t>::max()) {
    2153      587795 :     double roundtrip_value = static_cast<double>(static_cast<int32_t>(value));
    2154      587795 :     return bit_cast<int64_t>(roundtrip_value) == bit_cast<int64_t>(value);
    2155             :   }
    2156             :   return false;
    2157             : }
    2158             : 
    2159             : 
    2160         130 : 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         260 :       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         130 :   std::memcpy(&double_value_, &kHoleNanInt64, sizeof(double_value_));
    2174         130 :   Initialize(Representation::Double());
    2175         130 : }
    2176             : 
    2177             : 
    2178     4613822 : 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     4613822 :           IsNotInNewSpaceField::encode(true) |
    2188     4613817 :           BooleanValueField::encode(object->BooleanValue()) |
    2189     4613822 :           IsUndetectableField::encode(false) | IsCallableField::encode(false) |
    2190    13841461 :           InstanceTypeField::encode(kUnknownInstanceType)) {
    2191     4613824 :   if (object->IsNumber()) {
    2192             :     double n = object->Number();
    2193             :     bool has_int32_value = IsInteger32(n);
    2194     1196536 :     bit_field_ = HasInt32ValueField::update(bit_field_, has_int32_value);
    2195      598268 :     int32_value_ = DoubleToInt32(n);
    2196             :     bit_field_ = HasSmiValueField::update(
    2197     1196536 :         bit_field_, has_int32_value && Smi::IsValid(int32_value_));
    2198      598268 :     if (std::isnan(n)) {
    2199        4364 :       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        4364 :       object_ = Unique<Object>::CreateUninitialized(object);
    2205             :     } else {
    2206      593904 :       double_value_ = n;
    2207             :       // Canonicalize object with -0.0 value.
    2208      593904 :       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        7837 :         object_ = Unique<Object>::CreateUninitialized(object);
    2213             :       }
    2214             :     }
    2215     1196536 :     bit_field_ = HasDoubleValueField::update(bit_field_, true);
    2216             :   }
    2217     4613824 :   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     8144370 :         bit_field_, !isolate->heap()->InNewSpace(*object));
    2223     4072185 :     bit_field_ = InstanceTypeField::update(bit_field_, map->instance_type());
    2224             :     bit_field_ =
    2225     4072185 :         IsUndetectableField::update(bit_field_, map->is_undetectable());
    2226     4072185 :     bit_field_ = IsCallableField::update(bit_field_, map->is_callable());
    2227     4072185 :     if (map->is_stable()) object_map_ = Unique<Map>::CreateImmovable(map);
    2228             :     bit_field_ = HasStableMapValueField::update(
    2229             :         bit_field_,
    2230     8218855 :         HasMapValue() && Handle<Map>::cast(heap_object)->is_stable());
    2231             :   }
    2232             : 
    2233     4613824 :   Initialize(r);
    2234     4613826 : }
    2235             : 
    2236             : 
    2237      622756 : 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      622756 :                  HasExternalReferenceValueField::encode(false) |
    2249      622756 :                  IsNotInNewSpaceField::encode(is_not_in_new_space) |
    2250      622756 :                  BooleanValueField::encode(boolean_value) |
    2251      622756 :                  IsUndetectableField::encode(is_undetectable) |
    2252     1245512 :                  InstanceTypeField::encode(instance_type)) {
    2253             :   DCHECK(!object.handle().is_null());
    2254             :   DCHECK(!type.IsTaggedNumber() || type.IsNone());
    2255      622756 :   Initialize(r);
    2256      622754 : }
    2257             : 
    2258             : 
    2259     3664783 : 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     3664783 :                  HasExternalReferenceValueField::encode(false) |
    2268     3664783 :                  IsNotInNewSpaceField::encode(is_not_in_new_space) |
    2269     3664783 :                  BooleanValueField::encode(integer_value != 0) |
    2270     3664783 :                  IsUndetectableField::encode(false) |
    2271             :                  InstanceTypeField::encode(kUnknownInstanceType)),
    2272             :       int32_value_(integer_value),
    2273    10994349 :       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     3664783 :   bool could_be_heapobject = r.IsTagged() && !object.handle().is_null();
    2277     3664783 :   bool is_smi = HasSmiValue() && !could_be_heapobject;
    2278     3664783 :   set_type(is_smi ? HType::Smi() : HType::TaggedNumber());
    2279     3664783 :   Initialize(r);
    2280     3664773 : }
    2281             : 
    2282       27135 : 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       27135 :                  HasInt32ValueField::encode(IsInteger32(double_value)) |
    2288             :                  HasDoubleValueField::encode(true) |
    2289       27135 :                  HasExternalReferenceValueField::encode(false) |
    2290       27135 :                  IsNotInNewSpaceField::encode(is_not_in_new_space) |
    2291       27135 :                  BooleanValueField::encode(double_value != 0 &&
    2292             :                                            !std::isnan(double_value)) |
    2293       27135 :                  IsUndetectableField::encode(false) |
    2294             :                  InstanceTypeField::encode(kUnknownInstanceType)),
    2295       54270 :       int32_value_(DoubleToInt32(double_value)) {
    2296             :   bit_field_ = HasSmiValueField::update(
    2297       54270 :       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       27135 :   bool could_be_heapobject = r.IsTagged() && !object.handle().is_null();
    2301       27135 :   bool is_smi = HasSmiValue() && !could_be_heapobject;
    2302       27135 :   set_type(is_smi ? HType::Smi() : HType::TaggedNumber());
    2303       27135 :   if (std::isnan(double_value)) {
    2304        6390 :     double_value_ = std::numeric_limits<double>::quiet_NaN();
    2305             :   } else {
    2306       20745 :     double_value_ = double_value;
    2307             :   }
    2308       27135 :   Initialize(r);
    2309       27135 : }
    2310             : 
    2311             : 
    2312       11220 : 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       22440 :       external_reference_value_(reference) {
    2325       11220 :   Initialize(Representation::External());
    2326       11220 : }
    2327             : 
    2328             : 
    2329    15772404 : void HConstant::Initialize(Representation r) {
    2330     8939750 :   if (r.IsNone()) {
    2331             :     if (HasSmiValue() && SmiValuesAre31Bits()) {
    2332             :       r = Representation::Smi();
    2333     6832654 :     } else if (HasInteger32Value()) {
    2334             :       r = Representation::Integer32();
    2335     4073614 :     } else if (HasDoubleValue()) {
    2336             :       r = Representation::Double();
    2337     4015557 :     } else if (HasExternalReferenceValue()) {
    2338             :       r = Representation::External();
    2339             :     } else {
    2340             :       Handle<Object> object = object_.handle();
    2341     4015557 :       if (object->IsJSObject()) {
    2342             :         // Try to eagerly migrate JSObjects that have deprecated maps.
    2343             :         Handle<JSObject> js_object = Handle<JSObject>::cast(object);
    2344      803928 :         if (js_object->map()->is_deprecated()) {
    2345           8 :           JSObject::TryMigrateInstance(js_object);
    2346             :         }
    2347             :       }
    2348             :       r = Representation::Tagged();
    2349             :     }
    2350             :   }
    2351     8939750 :   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      865875 :     object_ = Unique<Object>(Handle<Object>::null());
    2357             :   }
    2358     8939750 :   if (r.IsSmiOrInteger32() && object_.handle().is_null()) {
    2359             :     // If it's not a heap object, it can't be in new space.
    2360     6167096 :     bit_field_ = IsNotInNewSpaceField::update(bit_field_, true);
    2361             :   }
    2362             :   set_representation(r);
    2363             :   SetFlag(kUseGVN);
    2364     8939750 : }
    2365             : 
    2366             : 
    2367      178210 : bool HConstant::ImmortalImmovable() const {
    2368      178210 :   if (HasInteger32Value()) {
    2369             :     return false;
    2370             :   }
    2371      133504 :   if (HasDoubleValue()) {
    2372         558 :     if (IsSpecialDouble()) {
    2373             :       return true;
    2374             :     }
    2375         305 :     return false;
    2376             :   }
    2377      132946 :   if (HasExternalReferenceValue()) {
    2378             :     return false;
    2379             :   }
    2380             : 
    2381             :   DCHECK(!object_.handle().is_null());
    2382    16281710 :   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    11859450 :       IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
    2389             : #undef IMMORTAL_IMMOVABLE_ROOT
    2390             : #define INTERNALIZED_STRING(name, value) \
    2391             :       object_.IsKnownGlobal(heap->name()) ||
    2392    15172837 :       INTERNALIZED_STRING_LIST(INTERNALIZED_STRING)
    2393             : #undef INTERNALIZED_STRING
    2394             : #define STRING_TYPE(NAME, size, name, Name) \
    2395             :       object_.IsKnownGlobal(heap->name##_map()) ||
    2396     1159743 :       STRING_TYPE_LIST(STRING_TYPE)
    2397             : #undef STRING_TYPE
    2398      132947 :       false;
    2399             : }
    2400             : 
    2401             : 
    2402     8768176 : bool HConstant::EmitAtUses() {
    2403             :   DCHECK(IsLinked());
    2404     9115468 :   if (block()->graph()->has_osr() &&
    2405      347292 :       block()->graph()->IsStandardConstant(this)) {
    2406             :     return true;
    2407             :   }
    2408     8728076 :   if (HasNoUses()) return true;
    2409     7996413 :   if (IsCell()) return false;
    2410     7996412 :   if (representation().IsDouble()) return false;
    2411     7860218 :   if (representation().IsExternal()) return false;
    2412     7841006 :   return true;
    2413             : }
    2414             : 
    2415             : 
    2416     3856677 : HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
    2417     2333907 :   if (r.IsSmi() && !HasSmiValue()) return NULL;
    2418     1471660 :   if (r.IsInteger32() && !HasInteger32Value()) return NULL;
    2419     1521121 :   if (r.IsDouble() && !HasDoubleValue()) return NULL;
    2420     1468113 :   if (r.IsExternal() && !HasExternalReferenceValue()) return NULL;
    2421     1468111 :   if (HasInteger32Value()) {
    2422     4327519 :     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      268986 : Maybe<HConstant*> HConstant::CopyToTruncatedNumber(Isolate* isolate,
    2452             :                                                    Zone* zone) {
    2453             :   HConstant* res = NULL;
    2454      268986 :   Handle<Object> handle = this->handle(isolate);
    2455      268986 :   if (handle->IsBoolean()) {
    2456        4193 :     res = handle->BooleanValue() ?
    2457        8386 :       new(zone) HConstant(1) : new(zone) HConstant(0);
    2458      264793 :   } else if (handle->IsUndefined(isolate)) {
    2459        2090 :     res = new (zone) HConstant(std::numeric_limits<double>::quiet_NaN());
    2460      263748 :   } else if (handle->IsNull(isolate)) {
    2461          54 :     res = new(zone) HConstant(0);
    2462      263721 :   } else if (handle->IsString()) {
    2463        3740 :     res = new(zone) HConstant(String::ToNumber(Handle<String>::cast(handle)));
    2464             :   }
    2465      268986 :   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     1002091 : void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) {
    2497             :   DCHECK(CheckFlag(kFlexibleRepresentation));
    2498     1002091 :   Representation new_rep = RepresentationFromInputs();
    2499     1002093 :   UpdateRepresentation(new_rep, h_infer, "inputs");
    2500             : 
    2501     1002093 :   if (representation().IsSmi() && HasNonSmiUse()) {
    2502             :     UpdateRepresentation(
    2503       48132 :         Representation::Integer32(), h_infer, "use requirements");
    2504             :   }
    2505             : 
    2506     1002093 :   if (observed_output_representation_.IsNone()) {
    2507      439785 :     new_rep = RepresentationFromUses();
    2508      439785 :     UpdateRepresentation(new_rep, h_infer, "uses");
    2509             :   } else {
    2510      562308 :     new_rep = RepresentationFromOutput();
    2511      562308 :     UpdateRepresentation(new_rep, h_infer, "output");
    2512             :   }
    2513     1002093 : }
    2514             : 
    2515             : 
    2516      998078 : Representation HBinaryOperation::RepresentationFromInputs() {
    2517             :   // Determine the worst case of observed input representations and
    2518             :   // the currently assumed output representation.
    2519      998078 :   Representation rep = representation();
    2520     2994236 :   for (int i = 1; i <= 2; ++i) {
    2521     1996156 :     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      998080 :   if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
    2528      998080 :   if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
    2529             : 
    2530      998080 :   return rep;
    2531             : }
    2532             : 
    2533             : 
    2534       23470 : bool HBinaryOperation::IgnoreObservedOutputRepresentation(
    2535             :     Representation current_rep) {
    2536       23031 :   return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) ||
    2537       29491 :           (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) &&
    2538             :          // Mul in Integer32 mode would be too precise.
    2539        6661 :          (!this->IsMul() || HMul::cast(this)->MulMinusOne());
    2540             : }
    2541             : 
    2542             : 
    2543      562308 : Representation HBinaryOperation::RepresentationFromOutput() {
    2544      562308 :   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      585778 :   if (observed_output_representation_.is_more_general_than(rep) &&
    2549       23470 :       !IgnoreObservedOutputRepresentation(rep)) {
    2550       18929 :     return observed_output_representation_;
    2551             :   }
    2552             :   return Representation::None();
    2553             : }
    2554             : 
    2555             : 
    2556         598 : void HBinaryOperation::AssumeRepresentation(Representation r) {
    2557             :   set_observed_input_representation(1, r);
    2558             :   set_observed_input_representation(2, r);
    2559         598 :   HValue::AssumeRepresentation(r);
    2560         598 : }
    2561             : 
    2562             : 
    2563        2197 : void HMathMinMax::InferRepresentation(HInferRepresentationPhase* h_infer) {
    2564             :   DCHECK(CheckFlag(kFlexibleRepresentation));
    2565        2197 :   Representation new_rep = RepresentationFromInputs();
    2566        2197 :   UpdateRepresentation(new_rep, h_infer, "inputs");
    2567             :   // Do not care about uses.
    2568        2197 : }
    2569             : 
    2570             : 
    2571       97534 : Range* HBitwise::InferRange(Zone* zone) {
    2572       97534 :   if (op() == Token::BIT_XOR) {
    2573       44338 :     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       22169 :       int64_t left_upper = left()->range()->upper();
    2581       22169 :       int64_t left_lower = left()->range()->lower();
    2582       22169 :       int64_t right_upper = right()->range()->upper();
    2583       22169 :       int64_t right_lower = right()->range()->lower();
    2584             : 
    2585       22169 :       if (left_upper < 0) left_upper = ~left_upper;
    2586       22169 :       if (left_lower < 0) left_lower = ~left_lower;
    2587       22169 :       if (right_upper < 0) right_upper = ~right_upper;
    2588       22169 :       if (right_lower < 0) right_lower = ~right_lower;
    2589             : 
    2590             :       int high = MostSignificantBit(
    2591             :           static_cast<uint32_t>(
    2592       22169 :               left_upper | left_lower | right_upper | right_lower));
    2593             : 
    2594             :       int64_t limit = 1;
    2595       22169 :       limit <<= high;
    2596       13585 :       int32_t min = (left()->range()->CanBeNegative() ||
    2597             :                      right()->range()->CanBeNegative())
    2598       30968 :                     ? static_cast<int32_t>(-limit) : 0;
    2599       44338 :       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       75365 :   int32_t left_mask = (left()->range() != NULL)
    2607             :       ? left()->range()->Mask()
    2608       75365 :       : kDefaultMask;
    2609       75365 :   int32_t right_mask = (right()->range() != NULL)
    2610             :       ? right()->range()->Mask()
    2611       75365 :       : kDefaultMask;
    2612             :   int32_t result_mask = (op() == Token::BIT_AND)
    2613             :       ? left_mask & right_mask
    2614       75365 :       : left_mask | right_mask;
    2615      133093 :   if (result_mask >= 0) return new(zone) Range(0, result_mask);
    2616             : 
    2617       17637 :   Range* result = HValue::InferRange(zone);
    2618             :   result->set_can_be_minus_zero(false);
    2619       17637 :   return result;
    2620             : }
    2621             : 
    2622             : 
    2623       14312 : Range* HSar::InferRange(Zone* zone) {
    2624       14312 :   if (right()->IsConstant()) {
    2625       25747 :     HConstant* c = HConstant::cast(right());
    2626       12878 :     if (c->HasInteger32Value()) {
    2627       12869 :       Range* result = (left()->range() != NULL)
    2628             :           ? left()->range()->Copy(zone)
    2629       12869 :           : new(zone) Range();
    2630             :       result->Sar(c->Integer32Value());
    2631       12869 :       return result;
    2632             :     }
    2633             :   }
    2634        1443 :   return HValue::InferRange(zone);
    2635             : }
    2636             : 
    2637             : 
    2638        9165 : Range* HShr::InferRange(Zone* zone) {
    2639        9165 :   if (right()->IsConstant()) {
    2640       15954 :     HConstant* c = HConstant::cast(right());
    2641        7317 :     if (c->HasInteger32Value()) {
    2642        7310 :       int shift_count = c->Integer32Value() & 0x1f;
    2643        7310 :       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        5021 :                               static_cast<uint32_t>(0xffffffff) >> shift_count)
    2648       11966 :             : 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        1327 :             : new(zone) Range();
    2654             :         result->Sar(c->Integer32Value());
    2655        1327 :         return result;
    2656             :       }
    2657             :     }
    2658             :   }
    2659        1855 :   return HValue::InferRange(zone);
    2660             : }
    2661             : 
    2662             : 
    2663       16677 : Range* HShl::InferRange(Zone* zone) {
    2664       16677 :   if (right()->IsConstant()) {
    2665       30491 :     HConstant* c = HConstant::cast(right());
    2666       15249 :     if (c->HasInteger32Value()) {
    2667       15242 :       Range* result = (left()->range() != NULL)
    2668             :           ? left()->range()->Copy(zone)
    2669       15242 :           : new(zone) Range();
    2670             :       result->Shl(c->Integer32Value());
    2671       15242 :       return result;
    2672             :     }
    2673             :   }
    2674        1435 :   return HValue::InferRange(zone);
    2675             : }
    2676             : 
    2677             : 
    2678      252577 : Range* HLoadNamedField::InferRange(Zone* zone) {
    2679      252577 :   if (access().representation().IsInteger8()) {
    2680           0 :     return new(zone) Range(kMinInt8, kMaxInt8);
    2681             :   }
    2682      252577 :   if (access().representation().IsUInteger8()) {
    2683       22261 :     return new(zone) Range(kMinUInt8, kMaxUInt8);
    2684             :   }
    2685      230316 :   if (access().representation().IsInteger16()) {
    2686           0 :     return new(zone) Range(kMinInt16, kMaxInt16);
    2687             :   }
    2688      230316 :   if (access().representation().IsUInteger16()) {
    2689           0 :     return new(zone) Range(kMinUInt16, kMaxUInt16);
    2690             :   }
    2691      230316 :   if (access().IsStringLength()) {
    2692       18719 :     return new(zone) Range(0, String::kMaxLength);
    2693             :   }
    2694      211597 :   return HValue::InferRange(zone);
    2695             : }
    2696             : 
    2697             : 
    2698       52283 : Range* HLoadKeyed::InferRange(Zone* zone) {
    2699       52283 :   switch (elements_kind()) {
    2700             :     case INT8_ELEMENTS:
    2701         165 :       return new(zone) Range(kMinInt8, kMaxInt8);
    2702             :     case UINT8_ELEMENTS:
    2703             :     case UINT8_CLAMPED_ELEMENTS:
    2704         369 :       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       51537 :       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      282183 : bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    2743      282183 :   if (known_successor_index() != kNoKnownSuccessorIndex) {
    2744           0 :     *block = SuccessorAt(known_successor_index());
    2745           0 :     return true;
    2746             :   }
    2747      282608 :   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      282163 :   *block = NULL;
    2753      282163 :   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        7988 : bool HIsUndetectableAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    2785        7988 :   if (FLAG_fold_constants && value()->IsConstant()) {
    2786           0 :     *block = HConstant::cast(value())->IsUndetectable()
    2787           0 :         ? FirstSuccessor() : SecondSuccessor();
    2788           0 :     return true;
    2789             :   }
    2790       15915 :   if (value()->type().IsNull() || value()->type().IsUndefined()) {
    2791         778 :     *block = FirstSuccessor();
    2792         778 :     return true;
    2793             :   }
    2794       14294 :   if (value()->type().IsBoolean() ||
    2795        6728 :       value()->type().IsSmi() ||
    2796       13845 :       value()->type().IsString() ||
    2797             :       value()->type().IsJSReceiver()) {
    2798         625 :     *block = SecondSuccessor();
    2799         625 :     return true;
    2800             :   }
    2801        6585 :   *block = NULL;
    2802        6585 :   return false;
    2803             : }
    2804             : 
    2805             : 
    2806       12196 : bool HHasInstanceTypeAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    2807       12380 :   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       12162 :   *block = NULL;
    2814       12162 :   return false;
    2815             : }
    2816             : 
    2817             : 
    2818          33 : void HCompareHoleAndBranch::InferRepresentation(
    2819             :     HInferRepresentationPhase* h_infer) {
    2820          33 :   ChangeRepresentation(value()->representation());
    2821          33 : }
    2822             : 
    2823             : 
    2824     1027232 : bool HCompareNumericAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
    2825     1032296 :   if (left() == right() &&
    2826             :       left()->representation().IsSmiOrInteger32()) {
    2827        3424 :     *block = (token() == Token::EQ ||
    2828         510 :               token() == Token::EQ_STRICT ||
    2829         414 :               token() == Token::LTE ||
    2830             :               token() == Token::GTE)
    2831        8846 :         ? FirstSuccessor() : SecondSuccessor();
    2832        4580 :     return true;
    2833             :   }
    2834     1018071 :   *block = NULL;
    2835     1018071 :   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      320815 : void HCompareNumericAndBranch::InferRepresentation(
    2845             :     HInferRepresentationPhase* h_infer) {
    2846             :   Representation left_rep = left()->representation();
    2847             :   Representation right_rep = right()->representation();
    2848      320816 :   Representation observed_left = observed_input_representation(0);
    2849      320815 :   Representation observed_right = observed_input_representation(1);
    2850             : 
    2851      320816 :   Representation rep = Representation::None();
    2852      320816 :   rep = rep.generalize(observed_left);
    2853      320816 :   rep = rep.generalize(observed_right);
    2854      493381 :   if (rep.IsNone() || rep.IsSmiOrInteger32()) {
    2855      284632 :     if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
    2856      284631 :     if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
    2857             :   } else {
    2858       36184 :     rep = Representation::Double();
    2859             :   }
    2860             : 
    2861      320815 :   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       73834 :     if (Token::IsOrderedRelationalCompareOp(token_)) {
    2876             :       SetFlag(kTruncatingToNumber);
    2877             :     }
    2878             :   }
    2879      320815 :   ChangeRepresentation(rep);
    2880      320815 : }
    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        8072 : 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        8072 :   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        8072 :   if (!addition_result.IsValid()) return false;
    2932        8072 :   base_offset = addition_result.ValueOrDie();
    2933        8072 :   if (!BaseOffsetField::is_valid(base_offset)) return false;
    2934        8056 :   bit_field_ = BaseOffsetField::update(bit_field_, base_offset);
    2935        8056 :   return true;
    2936             : }
    2937             : 
    2938             : 
    2939       22330 : bool HLoadKeyed::UsesMustHandleHole() const {
    2940       22330 :   if (IsFastPackedElementsKind(elements_kind())) {
    2941             :     return false;
    2942             :   }
    2943             : 
    2944       22330 :   if (IsFixedTypedArrayElementsKind(elements_kind())) {
    2945             :     return false;
    2946             :   }
    2947             : 
    2948       22330 :   if (hole_mode() == ALLOW_RETURN_HOLE) {
    2949       17894 :     if (IsFastDoubleElementsKind(elements_kind())) {
    2950         812 :       return AllUsesCanTreatHoleAsNaN();
    2951             :     }
    2952             :     return true;
    2953             :   }
    2954             : 
    2955        4436 :   if (IsFastDoubleElementsKind(elements_kind())) {
    2956             :     return false;
    2957             :   }
    2958             : 
    2959             :   // Holes are only returned as tagged values.
    2960        4021 :   if (!representation().IsTagged()) {
    2961             :     return false;
    2962             :   }
    2963             : 
    2964        2656 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    2965        5084 :     HValue* use = it.value();
    2966        5084 :     if (!use->IsChange()) return false;
    2967             :   }
    2968             : 
    2969         114 :   return true;
    2970             : }
    2971             : 
    2972             : 
    2973         812 : bool HLoadKeyed::AllUsesCanTreatHoleAsNaN() const {
    2974        1624 :   return IsFastDoubleElementsKind(elements_kind()) &&
    2975        1624 :          CheckUsesForFlag(HValue::kTruncatingToNumber);
    2976             : }
    2977             : 
    2978             : 
    2979      104771 : bool HLoadKeyed::RequiresHoleCheck() const {
    2980      104771 :   if (IsFastPackedElementsKind(elements_kind())) {
    2981             :     return false;
    2982             :   }
    2983             : 
    2984       27650 :   if (IsFixedTypedArrayElementsKind(elements_kind())) {
    2985             :     return false;
    2986             :   }
    2987             : 
    2988       27650 :   if (hole_mode() == CONVERT_HOLE_TO_UNDEFINED) {
    2989             :     return false;
    2990             :   }
    2991             : 
    2992       22330 :   return !UsesMustHandleHole();
    2993             : }
    2994             : 
    2995     1005597 : HValue* HCallWithDescriptor::Canonicalize() {
    2996     1005597 :   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       72233 :   if (key->IsLoadKeyed()) {
    3004             :     HLoadKeyed* key_load = HLoadKeyed::cast(key);
    3005        2755 :     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       71639 :   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    27870762 : HType HValue::CalculateInferredType() {
    3089    27870762 :   return type_;
    3090             : }
    3091             : 
    3092             : 
    3093      422698 : HType HPhi::CalculateInferredType() {
    3094      422698 :   if (OperandCount() == 0) return HType::Tagged();
    3095             :   HType result = OperandAt(0)->type();
    3096      943758 :   for (int i = 1; i < OperandCount(); ++i) {
    3097             :     HType current = OperandAt(i)->type();
    3098             :     result = result.Combine(current);
    3099             :   }
    3100      422698 :   return result;
    3101             : }
    3102             : 
    3103             : 
    3104      508739 : HType HChange::CalculateInferredType() {
    3105      508739 :   if (from().IsDouble() && to().IsTagged()) return HType::HeapNumber();
    3106             :   return type();
    3107             : }
    3108             : 
    3109             : 
    3110       33150 : Representation HUnaryMathOperation::RepresentationFromInputs() {
    3111       66300 :   if (SupportsFlexibleFloorAndRound() &&
    3112       33150 :       (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         529 :     rep = rep.generalize(input_rep);
    3123             :   }
    3124         630 :   return rep;
    3125             : }
    3126             : 
    3127             : 
    3128       19184 : bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
    3129        7740 :                                           HValue* dominator) {
    3130             :   DCHECK(side_effect == kNewSpacePromotion);
    3131             :   DCHECK(!IsAllocationFolded());
    3132       21257 :   Zone* zone = block()->zone();
    3133       19184 :   Isolate* isolate = block()->isolate();
    3134       19184 :   if (!FLAG_use_allocation_folding) return false;
    3135             : 
    3136             :   // Try to fold allocations together with their dominating allocations.
    3137       19071 :   if (!dominator->IsAllocate()) {
    3138       15904 :     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        3167 :   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        3241 :   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        6011 :   if (!current_size->IsInteger32Constant() ||
    3160             :       !dominator_size->IsInteger32Constant()) {
    3161         331 :     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        2836 :   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        2831 :   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        2831 :   if (MustAllocateDoubleAligned()) {
    3196         410 :     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        2831 :   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        2831 :   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        2831 :   if (MustAllocateDoubleAligned()) {
    3222         410 :     if (!dominator_allocate->MustAllocateDoubleAligned()) {
    3223             :       dominator_allocate->MakeDoubleAligned();
    3224             :     }
    3225             :   }
    3226             : 
    3227        2831 :   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        6219 :                        JS_OBJECT_TYPE, block()->graph()->GetConstant0());
    3233        2073 :     first_alloc->InsertAfter(dominator_allocate);
    3234        2073 :     dominator_allocate->ReplaceAllUsesWith(first_alloc);
    3235             :     dominator_allocate->MakeAllocationFoldingDominator();
    3236        2073 :     first_alloc->MakeFoldedAllocation(dominator_allocate);
    3237        2073 :     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        2831 :   MakeFoldedAllocation(dominator_allocate);
    3245             : 
    3246        2831 :   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        1216 : 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        1216 :   v8::base::internal::CheckedNumeric<uint32_t> addition_result = base_offset_;
    3273             :   addition_result += increase_by_value;
    3274        1216 :   if (!addition_result.IsValid()) return false;
    3275        1216 :   base_offset_ = addition_result.ValueOrDie();
    3276        1216 :   return true;
    3277             : }
    3278             : 
    3279             : 
    3280        6672 : bool HStoreKeyed::NeedsCanonicalization() {
    3281        6672 :   switch (value()->opcode()) {
    3282             :     case kLoadKeyed: {
    3283             :       ElementsKind load_kind = HLoadKeyed::cast(value())->elements_kind();
    3284        5857 :       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         277 :       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      583183 : DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +)
    3322       54812 : DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *)
    3323       52912 : DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -)
    3324             : 
    3325             : #undef DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR
    3326             : 
    3327             : 
    3328       26881 : 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       26903 :   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       53742 :       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         509 : HInstruction* HStringCharFromCode::New(Isolate* isolate, Zone* zone,
    3371             :                                        HValue* context, HValue* char_code) {
    3372         519 :   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         499 :   return new(zone) HStringCharFromCode(context, char_code);
    3386             : }
    3387             : 
    3388             : 
    3389       29292 : HInstruction* HUnaryMathOperation::New(Isolate* isolate, Zone* zone,
    3390             :                                        HValue* context, HValue* value,
    3391             :                                        BuiltinFunctionId op) {
    3392             :   do {
    3393       29292 :     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       29184 :   return new(zone) HUnaryMathOperation(context, value, op);
    3463             : }
    3464             : 
    3465             : 
    3466       33150 : Representation HUnaryMathOperation::RepresentationFromUses() {
    3467       33150 :   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       29786 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    3476       35761 :     HValue* use = it.value();
    3477       35761 :     int use_index = it.index();
    3478       35761 :     Representation rep_observed = use->observed_input_representation(use_index);
    3479       35761 :     Representation rep_required = use->RequiredInputRepresentation(use_index);
    3480       69076 :     use_double |= (rep_observed.IsDouble() || rep_required.IsDouble());
    3481       35761 :     if (use_double && !FLAG_trace_representation) {
    3482             :       // Having seen one double is enough.
    3483             :       break;
    3484             :     }
    3485       29786 :     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       32520 :   return use_double ? Representation::Double() : Representation::Integer32();
    3500             : }
    3501             : 
    3502             : 
    3503         991 : HInstruction* HPower::New(Isolate* isolate, Zone* zone, HValue* context,
    3504             :                           HValue* left, HValue* right) {
    3505        1027 :   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         973 :   return new(zone) HPower(left, right);
    3517             : }
    3518             : 
    3519             : 
    3520        1750 : HInstruction* HMathMinMax::New(Isolate* isolate, Zone* zone, HValue* context,
    3521             :                                HValue* left, HValue* right, Operation op) {
    3522        1822 :   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        1714 :   return new(zone) HMathMinMax(context, left, right, op);
    3550             : }
    3551             : 
    3552        5597 : HInstruction* HMod::New(Isolate* isolate, Zone* zone, HValue* context,
    3553             :                         HValue* left, HValue* right) {
    3554        5610 :   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        5595 :   return new (zone) HMod(context, left, right);
    3573             : }
    3574             : 
    3575       52208 : 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       52629 :   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       52082 :   return new (zone) HDiv(context, left, right);
    3601             : }
    3602             : 
    3603      140195 : HInstruction* HBitwise::New(Isolate* isolate, Zone* zone, HValue* context,
    3604             :                             Token::Value op, HValue* left, HValue* right) {
    3605      140275 :   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      140195 :   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       30425 : DEFINE_NEW_H_BITWISE_INSTR(HSar,
    3646             : c_left->NumberValueAsInteger32() >> (c_right->NumberValueAsInteger32() & 0x1f))
    3647       33572 : DEFINE_NEW_H_BITWISE_INSTR(HShl,
    3648             : c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f))
    3649             : 
    3650             : #undef DEFINE_NEW_H_BITWISE_INSTR
    3651             : 
    3652        9428 : HInstruction* HShr::New(Isolate* isolate, Zone* zone, HValue* context,
    3653             :                         HValue* left, HValue* right) {
    3654        9432 :   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        9428 :   return new (zone) HShr(context, left, right);
    3667             : }
    3668             : 
    3669             : 
    3670       14272 : HInstruction* HSeqStringGetChar::New(Isolate* isolate, Zone* zone,
    3671             :                                      HValue* context, String::Encoding encoding,
    3672             :                                      HValue* string, HValue* index) {
    3673       14288 :   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       14272 :   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      315630 : void HPhi::SimplifyConstantInputs() {
    3699             :   // Convert constant inputs to integers when all uses are truncating.
    3700             :   // This must happen before representation inference takes place.
    3701      320392 :   if (!CheckUsesForFlag(kTruncatingToInt32)) return;
    3702       82173 :   for (int i = 0; i < OperandCount(); ++i) {
    3703       60143 :     if (!OperandAt(i)->IsConstant()) return;
    3704             :   }
    3705        2387 :   HGraph* graph = block()->graph();
    3706       14296 :   for (int i = 0; i < OperandCount(); ++i) {
    3707        4773 :     HConstant* operand = HConstant::cast(OperandAt(i));
    3708        4767 :     if (operand->HasInteger32Value()) {
    3709             :       continue;
    3710        3495 :     } 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        3489 :     } else if (operand->HasBooleanValue()) {
    3717             :       SetOperandAt(i, operand->BooleanValue() ? graph->GetConstant1()
    3718         551 :                                               : graph->GetConstant0());
    3719        2938 :     } else if (operand->ImmortalImmovable()) {
    3720        2730 :       SetOperandAt(i, graph->GetConstant0());
    3721             :     }
    3722             :   }
    3723             :   // Overwrite observed input representations because they are likely Tagged.
    3724         354 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    3725         354 :     HValue* use = it.value();
    3726         354 :     if (use->IsBinaryOperation()) {
    3727             :       HBinaryOperation::cast(use)->set_observed_input_representation(
    3728         241 :           it.index(), Representation::Smi());
    3729             :     }
    3730             :   }
    3731             : }
    3732             : 
    3733             : 
    3734      474634 : void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) {
    3735             :   DCHECK(CheckFlag(kFlexibleRepresentation));
    3736      474634 :   Representation new_rep = RepresentationFromUses();
    3737      474634 :   UpdateRepresentation(new_rep, h_infer, "uses");
    3738      474634 :   new_rep = RepresentationFromInputs();
    3739      474634 :   UpdateRepresentation(new_rep, h_infer, "inputs");
    3740      474634 :   new_rep = RepresentationFromUseRequirements();
    3741      474634 :   UpdateRepresentation(new_rep, h_infer, "use requirements");
    3742      474634 : }
    3743             : 
    3744             : 
    3745     2606908 : Representation HPhi::RepresentationFromInputs() {
    3746      474632 :   Representation r = representation();
    3747     5213820 :   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     2363927 :     if (has_type_feedback_from_uses() && OperandAt(i)->IsParameter()) {
    3751             :       continue;
    3752             :     }
    3753             : 
    3754     2130615 :     r = r.generalize(OperandAt(i)->KnownOptimalRepresentation());
    3755             :   }
    3756      474634 :   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      949268 : Representation HValue::RepresentationFromUseRequirements() {
    3763      474634 :   Representation rep = Representation::None();
    3764     1159797 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    3765             :     // Ignore the use requirement from never run code
    3766     2388670 :     if (it.value()->block()->IsUnreachable()) continue;
    3767             : 
    3768             :     // We check for observed_input_representation elsewhere.
    3769             :     Representation use_rep =
    3770     1050716 :         it.value()->RequiredInputRepresentation(it.index());
    3771     1050715 :     if (rep.IsNone()) {
    3772      537995 :       rep = use_rep;
    3773      537995 :       continue;
    3774             :     }
    3775      512720 :     if (use_rep.IsNone() || rep.Equals(use_rep)) continue;
    3776       74666 :     if (rep.generalize(use_rep).IsInteger32()) {
    3777        2796 :       rep = Representation::Integer32();
    3778        2796 :       continue;
    3779             :     }
    3780             :     return Representation::None();
    3781             :   }
    3782      440097 :   return rep;
    3783             : }
    3784             : 
    3785             : 
    3786       96562 : bool HValue::HasNonSmiUse() {
    3787       17480 :   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
    3788             :     // We check for observed_input_representation elsewhere.
    3789             :     Representation use_rep =
    3790      109107 :         it.value()->RequiredInputRepresentation(it.index());
    3791      208686 :     if (!use_rep.IsNone() &&
    3792      205187 :         !use_rep.IsSmi() &&
    3793             :         !use_rep.IsTagged()) {
    3794             :       return true;
    3795             :     }
    3796             :   }
    3797        4935 :   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       56951 : HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset,
    3845             :     Representation representation) {
    3846             :   DCHECK(offset >= 0);
    3847             :   Portion portion = kInobject;
    3848             : 
    3849       56951 :   if (offset == JSObject::kElementsOffset) {
    3850             :     portion = kElementsPointer;
    3851       52400 :   } else if (offset == JSObject::kMapOffset) {
    3852             :     portion = kMaps;
    3853             :   }
    3854             :   bool existing_inobject_property = true;
    3855       56951 :   if (!map.is_null()) {
    3856             :     existing_inobject_property = (offset <
    3857       50589 :         map->instance_size() - map->unused_property_fields() * kPointerSize);
    3858             :   }
    3859             :   return HObjectAccess(portion, offset, representation, Handle<String>::null(),
    3860       56951 :                        false, existing_inobject_property);
    3861             : }
    3862             : 
    3863             : 
    3864       14272 : HObjectAccess HObjectAccess::ForAllocationSiteOffset(int offset) {
    3865       14272 :   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       14272 :       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       32546 : HObjectAccess HObjectAccess::ForContextSlot(int index) {
    3886             :   DCHECK(index >= 0);
    3887             :   Portion portion = kInobject;
    3888       32546 :   int offset = Context::kHeaderSize + index * kPointerSize;
    3889             :   DCHECK_EQ(offset, Context::SlotOffset(index) + kHeapObjectTag);
    3890       32546 :   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      106642 : HObjectAccess HObjectAccess::ForField(Handle<Map> map, int index,
    3926             :                                       Representation representation,
    3927             :                                       Handle<Name> name) {
    3928      106642 :   if (index < 0) {
    3929             :     // Negative property indices are in-object properties, indexed
    3930             :     // from the end of the fixed part of the object.
    3931      201192 :     int offset = (index * kPointerSize) + map->instance_size();
    3932      100596 :     return HObjectAccess(kInobject, offset, representation, name, false, true);
    3933             :   } else {
    3934             :     // Non-negative property indices are in the properties array.
    3935        6046 :     int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
    3936             :     return HObjectAccess(kBackingStore, offset, representation, name,
    3937        6046 :                          false, false);
    3938             :   }
    3939             : }
    3940             : 
    3941             : 
    3942     1131304 : void HObjectAccess::SetGVNFlags(HValue *instr, PropertyAccessType access_type) {
    3943             :   // set the appropriate GVN flags for a given load or store instruction
    3944      565652 :   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      565652 :   switch (portion()) {
    3955             :     case kArrayLengths:
    3956       59263 :       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       62333 :       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      289036 :       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        2189 :       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        3599 :       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       65042 :       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       84190 :       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      565652 : }
    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