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

Generated by: LCOV version 1.10