LCOV - code coverage report
Current view: top level - src/compiler - js-type-hint-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 152 158 96.2 %
Date: 2019-02-19 Functions: 24 25 96.0 %

          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      446189 :   switch (binop_hint) {
      23             :     case BinaryOperationHint::kSignedSmall:
      24      158814 :       *number_hint = NumberOperationHint::kSignedSmall;
      25             :       return true;
      26             :     case BinaryOperationHint::kSignedSmallInputs:
      27       13780 :       *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       74805 :       *number_hint = NumberOperationHint::kNumber;
      34             :       return true;
      35             :     case BinaryOperationHint::kNumberOrOddball:
      36        3339 :       *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      519452 :         slot_(slot) {}
      61             : 
      62      419314 :   BinaryOperationHint GetBinaryOperationHint() {
      63      419314 :     FeedbackNexus nexus(feedback_vector(), slot_);
      64      419314 :     return nexus.GetBinaryOperationFeedback();
      65             :   }
      66             : 
      67      100138 :   CompareOperationHint GetCompareOperationHint() {
      68      100138 :     FeedbackNexus nexus(feedback_vector(), slot_);
      69      100138 :     return nexus.GetCompareOperationFeedback();
      70             :   }
      71             : 
      72      419314 :   bool GetBinaryNumberOperationHint(NumberOperationHint* hint) {
      73             :     return BinaryOperationHintToNumberOperationHint(GetBinaryOperationHint(),
      74      838628 :                                                     hint);
      75             :   }
      76             : 
      77      100138 :   bool GetCompareNumberOperationHint(NumberOperationHint* hint) {
      78      100138 :     switch (GetCompareOperationHint()) {
      79             :       case CompareOperationHint::kSignedSmall:
      80       55810 :         *hint = NumberOperationHint::kSignedSmall;
      81       55810 :         return true;
      82             :       case CompareOperationHint::kNumber:
      83        1409 :         *hint = NumberOperationHint::kNumber;
      84        1409 :         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      250738 :   const Operator* SpeculativeNumberOp(NumberOperationHint hint) {
     102      250738 :     switch (op_->opcode()) {
     103             :       case IrOpcode::kJSAdd:
     104      336160 :         if (hint == NumberOperationHint::kSignedSmall ||
     105      168080 :             hint == NumberOperationHint::kSigned32) {
     106      117358 :           return simplified()->SpeculativeSafeIntegerAdd(hint);
     107             :         } else {
     108       50722 :           return simplified()->SpeculativeNumberAdd(hint);
     109             :         }
     110             :       case IrOpcode::kJSSubtract:
     111       20864 :         if (hint == NumberOperationHint::kSignedSmall ||
     112       10432 :             hint == NumberOperationHint::kSigned32) {
     113        9573 :           return simplified()->SpeculativeSafeIntegerSubtract(hint);
     114             :         } else {
     115         859 :           return simplified()->SpeculativeNumberSubtract(hint);
     116             :         }
     117             :       case IrOpcode::kJSMultiply:
     118       18667 :         return simplified()->SpeculativeNumberMultiply(hint);
     119             :       case IrOpcode::kJSDivide:
     120       19674 :         return simplified()->SpeculativeNumberDivide(hint);
     121             :       case IrOpcode::kJSModulus:
     122        3520 :         return simplified()->SpeculativeNumberModulus(hint);
     123             :       case IrOpcode::kJSBitwiseAnd:
     124        5450 :         return simplified()->SpeculativeNumberBitwiseAnd(hint);
     125             :       case IrOpcode::kJSBitwiseOr:
     126       14803 :         return simplified()->SpeculativeNumberBitwiseOr(hint);
     127             :       case IrOpcode::kJSBitwiseXor:
     128        1059 :         return simplified()->SpeculativeNumberBitwiseXor(hint);
     129             :       case IrOpcode::kJSShiftLeft:
     130        2156 :         return simplified()->SpeculativeNumberShiftLeft(hint);
     131             :       case IrOpcode::kJSShiftRight:
     132        4763 :         return simplified()->SpeculativeNumberShiftRight(hint);
     133             :       case IrOpcode::kJSShiftRightLogical:
     134        2134 :         return simplified()->SpeculativeNumberShiftRightLogical(hint);
     135             :       default:
     136             :         break;
     137             :     }
     138           0 :     UNREACHABLE();
     139             :   }
     140             : 
     141       57226 :   const Operator* SpeculativeCompareOp(NumberOperationHint hint) {
     142       57226 :     switch (op_->opcode()) {
     143             :       case IrOpcode::kJSEqual:
     144       10423 :         return simplified()->SpeculativeNumberEqual(hint);
     145             :       case IrOpcode::kJSLessThan:
     146       13608 :         return simplified()->SpeculativeNumberLessThan(hint);
     147             :       case IrOpcode::kJSGreaterThan:
     148             :         std::swap(left_, right_);  // a > b => b < a
     149       32244 :         return simplified()->SpeculativeNumberLessThan(hint);
     150             :       case IrOpcode::kJSLessThanOrEqual:
     151         517 :         return simplified()->SpeculativeNumberLessThanOrEqual(hint);
     152             :       case IrOpcode::kJSGreaterThanOrEqual:
     153             :         std::swap(left_, right_);  // a >= b => b <= a
     154         434 :         return simplified()->SpeculativeNumberLessThanOrEqual(hint);
     155             :       default:
     156             :         break;
     157             :     }
     158           0 :     UNREACHABLE();
     159             :   }
     160             : 
     161      307964 :   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      615928 :     return graph()->NewNode(op, left_, right_, effect_, control_);
     170             :   }
     171             : 
     172      419314 :   Node* TryBuildNumberBinop() {
     173             :     NumberOperationHint hint;
     174      419314 :     if (GetBinaryNumberOperationHint(&hint)) {
     175      250738 :       const Operator* op = SpeculativeNumberOp(hint);
     176      250738 :       Node* node = BuildSpeculativeOperation(op);
     177      250738 :       return node;
     178             :     }
     179             :     return nullptr;
     180             :   }
     181             : 
     182      100138 :   Node* TryBuildNumberCompare() {
     183             :     NumberOperationHint hint;
     184      100138 :     if (GetCompareNumberOperationHint(&hint)) {
     185       57226 :       const Operator* op = SpeculativeCompareOp(hint);
     186       57226 :       Node* node = BuildSpeculativeOperation(op);
     187       57226 :       return node;
     188             :     }
     189             :     return nullptr;
     190             :   }
     191             : 
     192      615928 :   JSGraph* jsgraph() const { return lowering_->jsgraph(); }
     193             :   Isolate* isolate() const { return jsgraph()->isolate(); }
     194      615928 :   Graph* graph() const { return jsgraph()->graph(); }
     195             :   JSOperatorBuilder* javascript() { return jsgraph()->javascript(); }
     196      615928 :   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      522833 : JSTypeHintLowering::JSTypeHintLowering(JSGraph* jsgraph,
     213             :                                        Handle<FeedbackVector> feedback_vector,
     214             :                                        Flags flags)
     215      522833 :     : jsgraph_(jsgraph), flags_(flags), feedback_vector_(feedback_vector) {}
     216             : 
     217           0 : Isolate* JSTypeHintLowering::isolate() const { return jsgraph()->isolate(); }
     218             : 
     219       66761 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceUnaryOperation(
     220       65804 :     const Operator* op, Node* operand, Node* effect, Node* control,
     221      131608 :     FeedbackSlot slot) const {
     222             :   DCHECK(!slot.IsInvalid());
     223       66761 :   FeedbackNexus nexus(feedback_vector(), slot);
     224       66761 :   if (Node* node = TryBuildSoftDeopt(
     225             :           nexus, effect, control,
     226       66761 :           DeoptimizeReason::kInsufficientTypeFeedbackForUnaryOperation)) {
     227             :     return LoweringResult::Exit(node);
     228             :   }
     229             : 
     230             :   Node* node;
     231       65804 :   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         457 :                                   control, slot);
     238         457 :       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        8070 :                                   control, slot);
     247        8070 :       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       39739 :                                   control, slot);
     257       39739 :       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       17538 :                                   control, slot);
     266       17538 :       node = b.TryBuildNumberBinop();
     267             :       break;
     268             :     }
     269             :     default:
     270           0 :       UNREACHABLE();
     271             :       break;
     272             :   }
     273             : 
     274       65804 :   if (node != nullptr) {
     275             :     return LoweringResult::SideEffectFree(node, node, control);
     276             :   } else {
     277             :     return LoweringResult::NoChange();
     278             :   }
     279             : }
     280             : 
     281      645501 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceBinaryOperation(
     282      645501 :     const Operator* op, Node* left, Node* right, Node* effect, Node* control,
     283             :     FeedbackSlot slot) const {
     284      645501 :   switch (op->opcode()) {
     285             :     case IrOpcode::kJSStrictEqual: {
     286             :       DCHECK(!slot.IsInvalid());
     287      172820 :       FeedbackNexus nexus(feedback_vector(), slot);
     288      172820 :       if (Node* node = TryBuildSoftDeopt(
     289             :               nexus, effect, control,
     290      172820 :               DeoptimizeReason::kInsufficientTypeFeedbackForCompareOperation)) {
     291       13212 :         return LoweringResult::Exit(node);
     292             :       }
     293             :       // TODO(turbofan): Should we generally support early lowering of
     294             :       // JSStrictEqual operators here?
     295      159608 :       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      100912 :       FeedbackNexus nexus(feedback_vector(), slot);
     304      100912 :       if (Node* node = TryBuildSoftDeopt(
     305             :               nexus, effect, control,
     306      100912 :               DeoptimizeReason::kInsufficientTypeFeedbackForCompareOperation)) {
     307       58000 :         return LoweringResult::Exit(node);
     308             :       }
     309             :       JSSpeculativeBinopBuilder b(this, op, left, right, effect, control, slot);
     310      100138 :       if (Node* node = b.TryBuildNumberCompare()) {
     311             :         return LoweringResult::SideEffectFree(node, node, control);
     312             :       }
     313       42912 :       break;
     314             :     }
     315             :     case IrOpcode::kJSInstanceOf: {
     316             :       DCHECK(!slot.IsInvalid());
     317        3835 :       FeedbackNexus nexus(feedback_vector(), slot);
     318        3835 :       if (Node* node = TryBuildSoftDeopt(
     319             :               nexus, effect, control,
     320        3835 :               DeoptimizeReason::kInsufficientTypeFeedbackForCompareOperation)) {
     321          51 :         return LoweringResult::Exit(node);
     322             :       }
     323             :       // TODO(turbofan): Should we generally support early lowering of
     324             :       // JSInstanceOf operators here?
     325        3784 :       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      367751 :       FeedbackNexus nexus(feedback_vector(), slot);
     340      367751 :       if (Node* node = TryBuildSoftDeopt(
     341             :               nexus, effect, control,
     342      367751 :               DeoptimizeReason::kInsufficientTypeFeedbackForBinaryOperation)) {
     343      223837 :         return LoweringResult::Exit(node);
     344             :       }
     345             :       JSSpeculativeBinopBuilder b(this, op, left, right, effect, control, slot);
     346      353510 :       if (Node* node = b.TryBuildNumberBinop()) {
     347             :         return LoweringResult::SideEffectFree(node, node, control);
     348             :       }
     349      143914 :       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        1564 : 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        1564 :   FeedbackNexus nexus(feedback_vector(), slot);
     367        1564 :   if (Node* node = TryBuildSoftDeopt(
     368             :           nexus, effect, control,
     369        1564 :           DeoptimizeReason::kInsufficientTypeFeedbackForForIn)) {
     370             :     return LoweringResult::Exit(node);
     371             :   }
     372             :   return LoweringResult::NoChange();
     373             : }
     374             : 
     375             : JSTypeHintLowering::LoweringResult
     376        1417 : JSTypeHintLowering::ReduceForInPrepareOperation(Node* enumerator, Node* effect,
     377             :                                                 Node* control,
     378             :                                                 FeedbackSlot slot) const {
     379             :   DCHECK(!slot.IsInvalid());
     380        1417 :   FeedbackNexus nexus(feedback_vector(), slot);
     381        1417 :   if (Node* node = TryBuildSoftDeopt(
     382             :           nexus, effect, control,
     383        1417 :           DeoptimizeReason::kInsufficientTypeFeedbackForForIn)) {
     384             :     return LoweringResult::Exit(node);
     385             :   }
     386             :   return LoweringResult::NoChange();
     387             : }
     388             : 
     389       26875 : JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceToNumberOperation(
     390       27380 :     Node* input, Node* effect, Node* control, FeedbackSlot slot) const {
     391             :   DCHECK(!slot.IsInvalid());
     392       26875 :   FeedbackNexus nexus(feedback_vector(), slot);
     393             :   NumberOperationHint hint;
     394       26875 :   if (BinaryOperationHintToNumberOperationHint(
     395       26875 :           nexus.GetBinaryOperationFeedback(), &hint)) {
     396             :     Node* node = jsgraph()->graph()->NewNode(
     397             :         jsgraph()->simplified()->SpeculativeToNumber(hint, VectorSlotPair()),
     398       54760 :         input, effect, control);
     399             :     return LoweringResult::SideEffectFree(node, node, control);
     400             :   }
     401             :   return LoweringResult::NoChange();
     402             : }
     403             : 
     404      463151 : 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      463151 :   FeedbackNexus nexus(feedback_vector(), slot);
     411      463151 :   if (Node* node = TryBuildSoftDeopt(
     412             :           nexus, effect, control,
     413      463151 :           DeoptimizeReason::kInsufficientTypeFeedbackForCall)) {
     414             :     return LoweringResult::Exit(node);
     415             :   }
     416             :   return LoweringResult::NoChange();
     417             : }
     418             : 
     419       40839 : 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       40839 :   FeedbackNexus nexus(feedback_vector(), slot);
     426       40839 :   if (Node* node = TryBuildSoftDeopt(
     427             :           nexus, effect, control,
     428       40839 :           DeoptimizeReason::kInsufficientTypeFeedbackForConstruct)) {
     429             :     return LoweringResult::Exit(node);
     430             :   }
     431             :   return LoweringResult::NoChange();
     432             : }
     433             : 
     434      333653 : 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      333653 :   FeedbackNexus nexus(feedback_vector(), slot);
     440      333653 :   if (Node* node = TryBuildSoftDeopt(
     441             :           nexus, effect, control,
     442      333653 :           DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess)) {
     443             :     return LoweringResult::Exit(node);
     444             :   }
     445             :   return LoweringResult::NoChange();
     446             : }
     447             : 
     448       43238 : 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       43238 :   FeedbackNexus nexus(feedback_vector(), slot);
     454       43238 :   if (Node* node = TryBuildSoftDeopt(
     455             :           nexus, effect, control,
     456       43238 :           DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess)) {
     457             :     return LoweringResult::Exit(node);
     458             :   }
     459             :   return LoweringResult::NoChange();
     460             : }
     461             : 
     462             : JSTypeHintLowering::LoweringResult
     463      112618 : 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      112618 :   FeedbackNexus nexus(feedback_vector(), slot);
     471      112618 :   if (Node* node = TryBuildSoftDeopt(
     472             :           nexus, effect, control,
     473      112618 :           DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess)) {
     474             :     return LoweringResult::Exit(node);
     475             :   }
     476             :   return LoweringResult::NoChange();
     477             : }
     478             : 
     479             : JSTypeHintLowering::LoweringResult
     480       55660 : 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       55660 :   FeedbackNexus nexus(feedback_vector(), slot);
     488       55660 :   if (Node* node = TryBuildSoftDeopt(
     489             :           nexus, effect, control,
     490       55660 :           DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess)) {
     491             :     return LoweringResult::Exit(node);
     492             :   }
     493             :   return LoweringResult::NoChange();
     494             : }
     495             : 
     496     1764218 : Node* JSTypeHintLowering::TryBuildSoftDeopt(FeedbackNexus& nexus, Node* effect,
     497             :                                             Node* control,
     498      194757 :                                             DeoptimizeReason reason) const {
     499     2553006 :   if ((flags() & kBailoutOnUninitialized) && nexus.IsUninitialized()) {
     500             :     Node* deoptimize = jsgraph()->graph()->NewNode(
     501             :         jsgraph()->common()->Deoptimize(DeoptimizeKind::kSoft, reason,
     502             :                                         VectorSlotPair()),
     503      259676 :         jsgraph()->Dead(), effect, control);
     504       64919 :     Node* frame_state = NodeProperties::FindFrameStateBefore(deoptimize);
     505       64919 :     deoptimize->ReplaceInput(0, frame_state);
     506       64919 :     return deoptimize;
     507             :   }
     508             :   return nullptr;
     509             : }
     510             : 
     511             : }  // namespace compiler
     512             : }  // namespace internal
     513      178779 : }  // namespace v8

Generated by: LCOV version 1.10