LCOV - code coverage report
Current view: top level - src/compiler - js-type-hint-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 128 134 95.5 %
Date: 2019-04-19 Functions: 23 24 95.8 %

          Line data    Source code
       1             : // Copyright 2017 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/compiler/js-type-hint-lowering.h"
       6             : 
       7             : #include "src/compiler/access-builder.h"
       8             : #include "src/compiler/js-graph.h"
       9             : #include "src/compiler/operator-properties.h"
      10             : #include "src/compiler/simplified-operator.h"
      11             : #include "src/feedback-vector.h"
      12             : #include "src/type-hints.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : namespace compiler {
      17             : 
      18             : namespace {
      19             : 
      20             : bool BinaryOperationHintToNumberOperationHint(
      21             :     BinaryOperationHint binop_hint, NumberOperationHint* number_hint) {
      22      437461 :   switch (binop_hint) {
      23             :     case BinaryOperationHint::kSignedSmall:
      24      158646 :       *number_hint = NumberOperationHint::kSignedSmall;
      25             :       return true;
      26             :     case BinaryOperationHint::kSignedSmallInputs:
      27       14354 :       *number_hint = NumberOperationHint::kSignedSmallInputs;
      28             :       return true;
      29             :     case BinaryOperationHint::kSigned32:
      30           0 :       *number_hint = NumberOperationHint::kSigned32;
      31             :       return true;
      32             :     case BinaryOperationHint::kNumber:
      33       74620 :       *number_hint = NumberOperationHint::kNumber;
      34             :       return true;
      35             :     case BinaryOperationHint::kNumberOrOddball:
      36        3173 :       *number_hint = NumberOperationHint::kNumberOrOddball;
      37             :       return true;
      38             :     case BinaryOperationHint::kAny:
      39             :     case BinaryOperationHint::kNone:
      40             :     case BinaryOperationHint::kString:
      41             :     case BinaryOperationHint::kBigInt:
      42             :       break;
      43             :   }
      44             :   return false;
      45             : }
      46             : 
      47             : }  // namespace
      48             : 
      49             : class JSSpeculativeBinopBuilder final {
      50             :  public:
      51             :   JSSpeculativeBinopBuilder(const JSTypeHintLowering* lowering,
      52             :                             const Operator* op, Node* left, Node* right,
      53             :                             Node* effect, Node* control, FeedbackSlot slot)
      54             :       : lowering_(lowering),
      55             :         op_(op),
      56             :         left_(left),
      57             :         right_(right),
      58             :         effect_(effect),
      59             :         control_(control),
      60      510196 :         slot_(slot) {}
      61             : 
      62      409408 :   BinaryOperationHint GetBinaryOperationHint() {
      63             :     FeedbackNexus nexus(feedback_vector(), slot_);
      64      409408 :     return nexus.GetBinaryOperationFeedback();
      65             :   }
      66             : 
      67      100788 :   CompareOperationHint GetCompareOperationHint() {
      68             :     FeedbackNexus nexus(feedback_vector(), slot_);
      69      100788 :     return nexus.GetCompareOperationFeedback();
      70             :   }
      71             : 
      72      409408 :   bool GetBinaryNumberOperationHint(NumberOperationHint* hint) {
      73      409408 :     return BinaryOperationHintToNumberOperationHint(GetBinaryOperationHint(),
      74      409408 :                                                     hint);
      75             :   }
      76             : 
      77      100788 :   bool GetCompareNumberOperationHint(NumberOperationHint* hint) {
      78      100788 :     switch (GetCompareOperationHint()) {
      79             :       case CompareOperationHint::kSignedSmall:
      80       54596 :         *hint = NumberOperationHint::kSignedSmall;
      81       54596 :         return true;
      82             :       case CompareOperationHint::kNumber:
      83        1372 :         *hint = NumberOperationHint::kNumber;
      84        1372 :         return true;
      85             :       case CompareOperationHint::kNumberOrOddball:
      86           7 :         *hint = NumberOperationHint::kNumberOrOddball;
      87           7 :         return true;
      88             :       case CompareOperationHint::kAny:
      89             :       case CompareOperationHint::kNone:
      90             :       case CompareOperationHint::kString:
      91             :       case CompareOperationHint::kSymbol:
      92             :       case CompareOperationHint::kBigInt:
      93             :       case CompareOperationHint::kReceiver:
      94             :       case CompareOperationHint::kReceiverOrNullOrUndefined:
      95             :       case CompareOperationHint::kInternalizedString:
      96             :         break;
      97             :     }
      98             :     return false;
      99             :   }
     100             : 
     101      250793 :   const Operator* SpeculativeNumberOp(NumberOperationHint hint) {
     102      250793 :     switch (op_->opcode()) {
     103             :       case IrOpcode::kJSAdd:
     104      335228 :         if (hint == NumberOperationHint::kSignedSmall ||
     105      167614 :             hint == NumberOperationHint::kSigned32) {
     106      117009 :           return simplified()->SpeculativeSafeIntegerAdd(hint);
     107             :         } else {
     108       50605 :           return simplified()->SpeculativeNumberAdd(hint);
     109             :         }
     110             :       case IrOpcode::kJSSubtract:
     111       20886 :         if (hint == NumberOperationHint::kSignedSmall ||
     112       10443 :             hint == NumberOperationHint::kSigned32) {
     113        9655 :           return simplified()->SpeculativeSafeIntegerSubtract(hint);
     114             :         } else {
     115         788 :           return simplified()->SpeculativeNumberSubtract(hint);
     116             :         }
     117             :       case IrOpcode::kJSMultiply:
     118       18795 :         return simplified()->SpeculativeNumberMultiply(hint);
     119             :       case IrOpcode::kJSDivide:
     120       20113 :         return simplified()->SpeculativeNumberDivide(hint);
     121             :       case IrOpcode::kJSModulus:
     122        3774 :         return simplified()->SpeculativeNumberModulus(hint);
     123             :       case IrOpcode::kJSBitwiseAnd:
     124        4622 :         return simplified()->SpeculativeNumberBitwiseAnd(hint);
     125             :       case IrOpcode::kJSBitwiseOr:
     126       15885 :         return simplified()->SpeculativeNumberBitwiseOr(hint);
     127             :       case IrOpcode::kJSBitwiseXor:
     128         995 :         return simplified()->SpeculativeNumberBitwiseXor(hint);
     129             :       case IrOpcode::kJSShiftLeft:
     130        2157 :         return simplified()->SpeculativeNumberShiftLeft(hint);
     131             :       case IrOpcode::kJSShiftRight:
     132        4820 :         return simplified()->SpeculativeNumberShiftRight(hint);
     133             :       case IrOpcode::kJSShiftRightLogical:
     134        1575 :         return simplified()->SpeculativeNumberShiftRightLogical(hint);
     135             :       default:
     136             :         break;
     137             :     }
     138           0 :     UNREACHABLE();
     139             :   }
     140             : 
     141       55975 :   const Operator* SpeculativeCompareOp(NumberOperationHint hint) {
     142       55975 :     switch (op_->opcode()) {
     143             :       case IrOpcode::kJSEqual:
     144        9780 :         return simplified()->SpeculativeNumberEqual(hint);
     145             :       case IrOpcode::kJSLessThan:
     146       13260 :         return simplified()->SpeculativeNumberLessThan(hint);
     147             :       case IrOpcode::kJSGreaterThan:
     148             :         std::swap(left_, right_);  // a > b => b < a
     149       31931 :         return simplified()->SpeculativeNumberLessThan(hint);
     150             :       case IrOpcode::kJSLessThanOrEqual:
     151         402 :         return simplified()->SpeculativeNumberLessThanOrEqual(hint);
     152             :       case IrOpcode::kJSGreaterThanOrEqual:
     153             :         std::swap(left_, right_);  // a >= b => b <= a
     154         602 :         return simplified()->SpeculativeNumberLessThanOrEqual(hint);
     155             :       default:
     156             :         break;
     157             :     }
     158           0 :     UNREACHABLE();
     159             :   }
     160             : 
     161      306768 :   Node* BuildSpeculativeOperation(const Operator* op) {
     162             :     DCHECK_EQ(2, op->ValueInputCount());
     163             :     DCHECK_EQ(1, op->EffectInputCount());
     164             :     DCHECK_EQ(1, op->ControlInputCount());
     165             :     DCHECK_EQ(false, OperatorProperties::HasFrameStateInput(op));
     166             :     DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
     167             :     DCHECK_EQ(1, op->EffectOutputCount());
     168             :     DCHECK_EQ(0, op->ControlOutputCount());
     169      613536 :     return graph()->NewNode(op, left_, right_, effect_, control_);
     170             :   }
     171             : 
     172      409408 :   Node* TryBuildNumberBinop() {
     173             :     NumberOperationHint hint;
     174      409408 :     if (GetBinaryNumberOperationHint(&hint)) {
     175      250793 :       const Operator* op = SpeculativeNumberOp(hint);
     176      250793 :       Node* node = BuildSpeculativeOperation(op);
     177      250793 :       return node;
     178             :     }
     179             :     return nullptr;
     180             :   }
     181             : 
     182      100788 :   Node* TryBuildNumberCompare() {
     183             :     NumberOperationHint hint;
     184      100788 :     if (GetCompareNumberOperationHint(&hint)) {
     185       55975 :       const Operator* op = SpeculativeCompareOp(hint);
     186       55975 :       Node* node = BuildSpeculativeOperation(op);
     187       55975 :       return node;
     188             :     }
     189             :     return nullptr;
     190             :   }
     191             : 
     192             :   JSGraph* jsgraph() const { return lowering_->jsgraph(); }
     193             :   Isolate* isolate() const { return jsgraph()->isolate(); }
     194             :   Graph* graph() const { return jsgraph()->graph(); }
     195             :   JSOperatorBuilder* javascript() { return jsgraph()->javascript(); }
     196             :   SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); }
     197             :   CommonOperatorBuilder* common() { return jsgraph()->common(); }
     198             :   const Handle<FeedbackVector>& feedback_vector() const {
     199             :     return lowering_->feedback_vector();
     200             :   }
     201             : 
     202             :  private:
     203             :   const JSTypeHintLowering* lowering_;
     204             :   const Operator* op_;
     205             :   Node* left_;
     206             :   Node* right_;
     207             :   Node* effect_;
     208             :   Node* control_;
     209             :   FeedbackSlot slot_;
     210             : };
     211             : 
     212      529971 : JSTypeHintLowering::JSTypeHintLowering(JSGraph* jsgraph,
     213             :                                        Handle<FeedbackVector> feedback_vector,
     214             :                                        Flags flags)
     215      529971 :     : jsgraph_(jsgraph), flags_(flags), feedback_vector_(feedback_vector) {}
     216             : 
     217           0 : Isolate* JSTypeHintLowering::isolate() const { return jsgraph()->isolate(); }
     218             : 
     219       67663 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceUnaryOperation(
     220             :     const Operator* op, Node* operand, Node* effect, Node* control,
     221             :     FeedbackSlot slot) const {
     222             :   DCHECK(!slot.IsInvalid());
     223             :   FeedbackNexus nexus(feedback_vector(), slot);
     224       67663 :   if (Node* node = TryBuildSoftDeopt(
     225             :           nexus, effect, control,
     226       67663 :           DeoptimizeReason::kInsufficientTypeFeedbackForUnaryOperation)) {
     227             :     return LoweringResult::Exit(node);
     228             :   }
     229             : 
     230             :   Node* node;
     231       66697 :   switch (op->opcode()) {
     232             :     case IrOpcode::kJSBitwiseNot: {
     233             :       // Lower to a speculative xor with -1 if we have some kind of Number
     234             :       // feedback.
     235             :       JSSpeculativeBinopBuilder b(this, jsgraph()->javascript()->BitwiseXor(),
     236             :                                   operand, jsgraph()->SmiConstant(-1), effect,
     237         455 :                                   control, slot);
     238         455 :       node = b.TryBuildNumberBinop();
     239             :       break;
     240             :     }
     241             :     case IrOpcode::kJSDecrement: {
     242             :       // Lower to a speculative subtraction of 1 if we have some kind of Number
     243             :       // feedback.
     244             :       JSSpeculativeBinopBuilder b(this, jsgraph()->javascript()->Subtract(),
     245             :                                   operand, jsgraph()->SmiConstant(1), effect,
     246        8083 :                                   control, slot);
     247        8083 :       node = b.TryBuildNumberBinop();
     248             :       break;
     249             :     }
     250             :     case IrOpcode::kJSIncrement: {
     251             :       // Lower to a speculative addition of 1 if we have some kind of Number
     252             :       // feedback.
     253             :       BinaryOperationHint hint = BinaryOperationHint::kAny;  // Dummy.
     254             :       JSSpeculativeBinopBuilder b(this, jsgraph()->javascript()->Add(hint),
     255             :                                   operand, jsgraph()->SmiConstant(1), effect,
     256       40689 :                                   control, slot);
     257       40689 :       node = b.TryBuildNumberBinop();
     258             :       break;
     259             :     }
     260             :     case IrOpcode::kJSNegate: {
     261             :       // Lower to a speculative multiplication with -1 if we have some kind of
     262             :       // Number feedback.
     263             :       JSSpeculativeBinopBuilder b(this, jsgraph()->javascript()->Multiply(),
     264             :                                   operand, jsgraph()->SmiConstant(-1), effect,
     265       17470 :                                   control, slot);
     266       17470 :       node = b.TryBuildNumberBinop();
     267             :       break;
     268             :     }
     269             :     default:
     270           0 :       UNREACHABLE();
     271             :       break;
     272             :   }
     273             : 
     274       66697 :   if (node != nullptr) {
     275             :     return LoweringResult::SideEffectFree(node, node, control);
     276             :   } else {
     277             :     return LoweringResult::NoChange();
     278             :   }
     279             : }
     280             : 
     281      636199 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceBinaryOperation(
     282             :     const Operator* op, Node* left, Node* right, Node* effect, Node* control,
     283             :     FeedbackSlot slot) const {
     284      636199 :   switch (op->opcode()) {
     285             :     case IrOpcode::kJSStrictEqual: {
     286             :       DCHECK(!slot.IsInvalid());
     287             :       FeedbackNexus nexus(feedback_vector(), slot);
     288      173687 :       if (Node* node = TryBuildSoftDeopt(
     289             :               nexus, effect, control,
     290      173687 :               DeoptimizeReason::kInsufficientTypeFeedbackForCompareOperation)) {
     291       13147 :         return LoweringResult::Exit(node);
     292             :       }
     293             :       // TODO(turbofan): Should we generally support early lowering of
     294             :       // JSStrictEqual operators here?
     295      160540 :       break;
     296             :     }
     297             :     case IrOpcode::kJSEqual:
     298             :     case IrOpcode::kJSLessThan:
     299             :     case IrOpcode::kJSGreaterThan:
     300             :     case IrOpcode::kJSLessThanOrEqual:
     301             :     case IrOpcode::kJSGreaterThanOrEqual: {
     302             :       DCHECK(!slot.IsInvalid());
     303             :       FeedbackNexus nexus(feedback_vector(), slot);
     304      101509 :       if (Node* node = TryBuildSoftDeopt(
     305             :               nexus, effect, control,
     306      101509 :               DeoptimizeReason::kInsufficientTypeFeedbackForCompareOperation)) {
     307       56696 :         return LoweringResult::Exit(node);
     308             :       }
     309             :       JSSpeculativeBinopBuilder b(this, op, left, right, effect, control, slot);
     310      100788 :       if (Node* node = b.TryBuildNumberCompare()) {
     311             :         return LoweringResult::SideEffectFree(node, node, control);
     312             :       }
     313       44813 :       break;
     314             :     }
     315             :     case IrOpcode::kJSInstanceOf: {
     316             :       DCHECK(!slot.IsInvalid());
     317             :       FeedbackNexus nexus(feedback_vector(), slot);
     318        3898 :       if (Node* node = TryBuildSoftDeopt(
     319             :               nexus, effect, control,
     320        3898 :               DeoptimizeReason::kInsufficientTypeFeedbackForCompareOperation)) {
     321          54 :         return LoweringResult::Exit(node);
     322             :       }
     323             :       // TODO(turbofan): Should we generally support early lowering of
     324             :       // JSInstanceOf operators here?
     325        3844 :       break;
     326             :     }
     327             :     case IrOpcode::kJSBitwiseOr:
     328             :     case IrOpcode::kJSBitwiseXor:
     329             :     case IrOpcode::kJSBitwiseAnd:
     330             :     case IrOpcode::kJSShiftLeft:
     331             :     case IrOpcode::kJSShiftRight:
     332             :     case IrOpcode::kJSShiftRightLogical:
     333             :     case IrOpcode::kJSAdd:
     334             :     case IrOpcode::kJSSubtract:
     335             :     case IrOpcode::kJSMultiply:
     336             :     case IrOpcode::kJSDivide:
     337             :     case IrOpcode::kJSModulus: {
     338             :       DCHECK(!slot.IsInvalid());
     339             :       FeedbackNexus nexus(feedback_vector(), slot);
     340      356921 :       if (Node* node = TryBuildSoftDeopt(
     341             :               nexus, effect, control,
     342      356921 :               DeoptimizeReason::kInsufficientTypeFeedbackForBinaryOperation)) {
     343      224172 :         return LoweringResult::Exit(node);
     344             :       }
     345             :       JSSpeculativeBinopBuilder b(this, op, left, right, effect, control, slot);
     346      342711 :       if (Node* node = b.TryBuildNumberBinop()) {
     347             :         return LoweringResult::SideEffectFree(node, node, control);
     348             :       }
     349      132749 :       break;
     350             :     }
     351             :     case IrOpcode::kJSExponentiate: {
     352             :       // TODO(neis): Introduce a SpeculativeNumberPow operator?
     353             :       break;
     354             :     }
     355             :     default:
     356           0 :       UNREACHABLE();
     357             :       break;
     358             :   }
     359             :   return LoweringResult::NoChange();
     360             : }
     361             : 
     362        1557 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceForInNextOperation(
     363             :     Node* receiver, Node* cache_array, Node* cache_type, Node* index,
     364             :     Node* effect, Node* control, FeedbackSlot slot) const {
     365             :   DCHECK(!slot.IsInvalid());
     366             :   FeedbackNexus nexus(feedback_vector(), slot);
     367        1557 :   if (Node* node = TryBuildSoftDeopt(
     368             :           nexus, effect, control,
     369        1557 :           DeoptimizeReason::kInsufficientTypeFeedbackForForIn)) {
     370             :     return LoweringResult::Exit(node);
     371             :   }
     372             :   return LoweringResult::NoChange();
     373             : }
     374             : 
     375             : JSTypeHintLowering::LoweringResult
     376        1418 : JSTypeHintLowering::ReduceForInPrepareOperation(Node* enumerator, Node* effect,
     377             :                                                 Node* control,
     378             :                                                 FeedbackSlot slot) const {
     379             :   DCHECK(!slot.IsInvalid());
     380             :   FeedbackNexus nexus(feedback_vector(), slot);
     381        1418 :   if (Node* node = TryBuildSoftDeopt(
     382             :           nexus, effect, control,
     383        1418 :           DeoptimizeReason::kInsufficientTypeFeedbackForForIn)) {
     384             :     return LoweringResult::Exit(node);
     385             :   }
     386             :   return LoweringResult::NoChange();
     387             : }
     388             : 
     389       28053 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceToNumberOperation(
     390             :     Node* input, Node* effect, Node* control, FeedbackSlot slot) const {
     391             :   DCHECK(!slot.IsInvalid());
     392             :   FeedbackNexus nexus(feedback_vector(), slot);
     393             :   NumberOperationHint hint;
     394       56106 :   if (BinaryOperationHintToNumberOperationHint(
     395             :           nexus.GetBinaryOperationFeedback(), &hint)) {
     396       28006 :     Node* node = jsgraph()->graph()->NewNode(
     397             :         jsgraph()->simplified()->SpeculativeToNumber(hint, VectorSlotPair()),
     398             :         input, effect, control);
     399             :     return LoweringResult::SideEffectFree(node, node, control);
     400             :   }
     401             :   return LoweringResult::NoChange();
     402             : }
     403             : 
     404      467615 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceCallOperation(
     405             :     const Operator* op, Node* const* args, int arg_count, Node* effect,
     406             :     Node* control, FeedbackSlot slot) const {
     407             :   DCHECK(op->opcode() == IrOpcode::kJSCall ||
     408             :          op->opcode() == IrOpcode::kJSCallWithSpread);
     409             :   DCHECK(!slot.IsInvalid());
     410             :   FeedbackNexus nexus(feedback_vector(), slot);
     411      467616 :   if (Node* node = TryBuildSoftDeopt(
     412             :           nexus, effect, control,
     413      467616 :           DeoptimizeReason::kInsufficientTypeFeedbackForCall)) {
     414             :     return LoweringResult::Exit(node);
     415             :   }
     416             :   return LoweringResult::NoChange();
     417             : }
     418             : 
     419       43592 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceConstructOperation(
     420             :     const Operator* op, Node* const* args, int arg_count, Node* effect,
     421             :     Node* control, FeedbackSlot slot) const {
     422             :   DCHECK(op->opcode() == IrOpcode::kJSConstruct ||
     423             :          op->opcode() == IrOpcode::kJSConstructWithSpread);
     424             :   DCHECK(!slot.IsInvalid());
     425             :   FeedbackNexus nexus(feedback_vector(), slot);
     426       43592 :   if (Node* node = TryBuildSoftDeopt(
     427             :           nexus, effect, control,
     428       43592 :           DeoptimizeReason::kInsufficientTypeFeedbackForConstruct)) {
     429             :     return LoweringResult::Exit(node);
     430             :   }
     431             :   return LoweringResult::NoChange();
     432             : }
     433             : 
     434      350853 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceLoadNamedOperation(
     435             :     const Operator* op, Node* receiver, Node* effect, Node* control,
     436             :     FeedbackSlot slot) const {
     437             :   DCHECK_EQ(IrOpcode::kJSLoadNamed, op->opcode());
     438             :   DCHECK(!slot.IsInvalid());
     439             :   FeedbackNexus nexus(feedback_vector(), slot);
     440      350853 :   if (Node* node = TryBuildSoftDeopt(
     441             :           nexus, effect, control,
     442      350853 :           DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess)) {
     443             :     return LoweringResult::Exit(node);
     444             :   }
     445             :   return LoweringResult::NoChange();
     446             : }
     447             : 
     448       42943 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceLoadKeyedOperation(
     449             :     const Operator* op, Node* obj, Node* key, Node* effect, Node* control,
     450             :     FeedbackSlot slot) const {
     451             :   DCHECK_EQ(IrOpcode::kJSLoadProperty, op->opcode());
     452             :   DCHECK(!slot.IsInvalid());
     453             :   FeedbackNexus nexus(feedback_vector(), slot);
     454       42943 :   if (Node* node = TryBuildSoftDeopt(
     455             :           nexus, effect, control,
     456       42943 :           DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess)) {
     457             :     return LoweringResult::Exit(node);
     458             :   }
     459             :   return LoweringResult::NoChange();
     460             : }
     461             : 
     462             : JSTypeHintLowering::LoweringResult
     463      118029 : JSTypeHintLowering::ReduceStoreNamedOperation(const Operator* op, Node* obj,
     464             :                                               Node* val, Node* effect,
     465             :                                               Node* control,
     466             :                                               FeedbackSlot slot) const {
     467             :   DCHECK(op->opcode() == IrOpcode::kJSStoreNamed ||
     468             :          op->opcode() == IrOpcode::kJSStoreNamedOwn);
     469             :   DCHECK(!slot.IsInvalid());
     470             :   FeedbackNexus nexus(feedback_vector(), slot);
     471      118029 :   if (Node* node = TryBuildSoftDeopt(
     472             :           nexus, effect, control,
     473      118032 :           DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess)) {
     474             :     return LoweringResult::Exit(node);
     475             :   }
     476             :   return LoweringResult::NoChange();
     477             : }
     478             : 
     479             : JSTypeHintLowering::LoweringResult
     480       65026 : JSTypeHintLowering::ReduceStoreKeyedOperation(const Operator* op, Node* obj,
     481             :                                               Node* key, Node* val,
     482             :                                               Node* effect, Node* control,
     483             :                                               FeedbackSlot slot) const {
     484             :   DCHECK(op->opcode() == IrOpcode::kJSStoreProperty ||
     485             :          op->opcode() == IrOpcode::kJSStoreInArrayLiteral);
     486             :   DCHECK(!slot.IsInvalid());
     487             :   FeedbackNexus nexus(feedback_vector(), slot);
     488       65026 :   if (Node* node = TryBuildSoftDeopt(
     489             :           nexus, effect, control,
     490       65026 :           DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess)) {
     491             :     return LoweringResult::Exit(node);
     492             :   }
     493             :   return LoweringResult::NoChange();
     494             : }
     495             : 
     496     1794712 : Node* JSTypeHintLowering::TryBuildSoftDeopt(FeedbackNexus& nexus, Node* effect,
     497             :                                             Node* control,
     498             :                                             DeoptimizeReason reason) const {
     499     2572513 :   if ((flags() & kBailoutOnUninitialized) && nexus.IsUninitialized()) {
     500      126276 :     Node* deoptimize = jsgraph()->graph()->NewNode(
     501             :         jsgraph()->common()->Deoptimize(DeoptimizeKind::kSoft, reason,
     502             :                                         VectorSlotPair()),
     503             :         jsgraph()->Dead(), effect, control);
     504       63138 :     Node* frame_state = NodeProperties::FindFrameStateBefore(deoptimize);
     505       63138 :     deoptimize->ReplaceInput(0, frame_state);
     506       63138 :     return deoptimize;
     507             :   }
     508             :   return nullptr;
     509             : }
     510             : 
     511             : }  // namespace compiler
     512             : }  // namespace internal
     513      122036 : }  // namespace v8

Generated by: LCOV version 1.10