diff options
Diffstat (limited to 'chromium/v8/src/compiler/effect-control-linearizer.cc')
-rw-r--r-- | chromium/v8/src/compiler/effect-control-linearizer.cc | 510 |
1 files changed, 368 insertions, 142 deletions
diff --git a/chromium/v8/src/compiler/effect-control-linearizer.cc b/chromium/v8/src/compiler/effect-control-linearizer.cc index 2372a0fe40f..2b7d1ef9ddf 100644 --- a/chromium/v8/src/compiler/effect-control-linearizer.cc +++ b/chromium/v8/src/compiler/effect-control-linearizer.cc @@ -145,9 +145,10 @@ bool HasIncomingBackEdges(BasicBlock* block) { return false; } -void RemoveRegionNode(Node* node) { +void RemoveRenameNode(Node* node) { DCHECK(IrOpcode::kFinishRegion == node->opcode() || - IrOpcode::kBeginRegion == node->opcode()); + IrOpcode::kBeginRegion == node->opcode() || + IrOpcode::kTypeGuard == node->opcode()); // Update the value/context uses to the value input of the finish node and // the effect uses to the effect input. for (Edge edge : node->use_edges()) { @@ -318,28 +319,6 @@ void TryCloneBranch(Node* node, BasicBlock* block, Zone* temp_zone, merge->Kill(); } -Node* DummyValue(JSGraph* jsgraph, MachineRepresentation rep) { - switch (rep) { - case MachineRepresentation::kTagged: - case MachineRepresentation::kTaggedSigned: - return jsgraph->SmiConstant(0xdead); - case MachineRepresentation::kTaggedPointer: - return jsgraph->TheHoleConstant(); - case MachineRepresentation::kWord64: - return jsgraph->Int64Constant(0xdead); - case MachineRepresentation::kWord32: - return jsgraph->Int32Constant(0xdead); - case MachineRepresentation::kFloat64: - return jsgraph->Float64Constant(0xdead); - case MachineRepresentation::kFloat32: - return jsgraph->Float32Constant(0xdead); - case MachineRepresentation::kBit: - return jsgraph->Int32Constant(0); - default: - UNREACHABLE(); - } -} - } // namespace void EffectControlLinearizer::Run() { @@ -369,7 +348,6 @@ void EffectControlLinearizer::Run() { // Iterate over the phis and update the effect phis. Node* effect_phi = nullptr; Node* terminate = nullptr; - int predecessor_count = static_cast<int>(block->PredecessorCount()); for (; instr < block->NodeCount(); instr++) { Node* node = block->NodeAt(instr); // Only go through the phis and effect phis. @@ -380,19 +358,7 @@ void EffectControlLinearizer::Run() { DCHECK_NE(IrOpcode::kIfException, control->opcode()); effect_phi = node; } else if (node->opcode() == IrOpcode::kPhi) { - DCHECK_EQ(predecessor_count, node->op()->ValueInputCount()); - for (int i = 0; i < predecessor_count; ++i) { - if (NodeProperties::GetValueInput(node, i)->opcode() == - IrOpcode::kDeadValue) { - // Phi uses of {DeadValue} must originate from unreachable code. Due - // to schedule freedom between the effect and the control chain, - // they might still appear in reachable code. So we replace them - // with a dummy value. - NodeProperties::ReplaceValueInput( - node, DummyValue(jsgraph(), PhiRepresentationOf(node->op())), - i); - } - } + // Just skip phis. } else if (node->opcode() == IrOpcode::kTerminate) { DCHECK_NULL(terminate); terminate = node; @@ -573,7 +539,7 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state, region_observability_ = RegionObservability::kObservable; // Update the value uses to the value input of the finish node and // the effect uses to the effect input. - return RemoveRegionNode(node); + return RemoveRenameNode(node); } if (node->opcode() == IrOpcode::kBeginRegion) { // Determine the observability for this region and use that for all @@ -583,7 +549,10 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state, region_observability_ = RegionObservabilityOf(node->op()); // Update the value uses to the value input of the finish node and // the effect uses to the effect input. - return RemoveRegionNode(node); + return RemoveRenameNode(node); + } + if (node->opcode() == IrOpcode::kTypeGuard) { + return RemoveRenameNode(node); } // Special treatment for checkpoint nodes. @@ -781,6 +750,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, case IrOpcode::kCheckedTruncateTaggedToWord32: result = LowerCheckedTruncateTaggedToWord32(node, frame_state); break; + case IrOpcode::kNumberToString: + result = LowerNumberToString(node); + break; case IrOpcode::kObjectIsArrayBufferView: result = LowerObjectIsArrayBufferView(node); break; @@ -847,12 +819,17 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, case IrOpcode::kNewArgumentsElements: result = LowerNewArgumentsElements(node); break; + case IrOpcode::kNewConsString: + result = LowerNewConsString(node); + break; case IrOpcode::kArrayBufferWasNeutered: result = LowerArrayBufferWasNeutered(node); break; case IrOpcode::kSameValue: result = LowerSameValue(node); break; + case IrOpcode::kDeadValue: + result = LowerDeadValue(node); case IrOpcode::kStringFromCharCode: result = LowerStringFromCharCode(node); break; @@ -862,6 +839,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, case IrOpcode::kStringIndexOf: result = LowerStringIndexOf(node); break; + case IrOpcode::kStringLength: + result = LowerStringLength(node); + break; case IrOpcode::kStringToNumber: result = LowerStringToNumber(node); break; @@ -874,6 +854,12 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, case IrOpcode::kSeqStringCharCodeAt: result = LowerSeqStringCharCodeAt(node); break; + case IrOpcode::kStringCodePointAt: + result = LowerStringCodePointAt(node); + break; + case IrOpcode::kSeqStringCodePointAt: + result = LowerSeqStringCharCodeAt(node); + break; case IrOpcode::kStringToLowerCaseIntl: result = LowerStringToLowerCaseIntl(node); break; @@ -889,6 +875,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, case IrOpcode::kStringLessThanOrEqual: result = LowerStringLessThanOrEqual(node); break; + case IrOpcode::kNumberIsFloat64Hole: + result = LowerNumberIsFloat64Hole(node); + break; case IrOpcode::kCheckFloat64Hole: result = LowerCheckFloat64Hole(node, frame_state); break; @@ -1136,6 +1125,7 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit( Node* value = node->InputAt(0); auto if_heapnumber = __ MakeDeferredLabel(); + auto if_bigint = __ MakeDeferredLabel(); Node* zero = __ Int32Constant(0); Node* fzero = __ Float64Constant(0.0); @@ -1154,15 +1144,22 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit( Node* value_map_bitfield = __ LoadField(AccessBuilder::ForMapBitField(), value_map); __ GotoIfNot( - __ Word32Equal(__ Word32And(value_map_bitfield, - __ Int32Constant(1 << Map::kIsUndetectable)), - zero), + __ Word32Equal( + __ Word32And(value_map_bitfield, + __ Int32Constant(Map::IsUndetectableBit::kMask)), + zero), done, zero); // Check if {value} is a HeapNumber. __ GotoIf(__ WordEqual(value_map, __ HeapNumberMapConstant()), &if_heapnumber); + // Check if {value} is a BigInt. + Node* value_instance_type = + __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); + __ GotoIf(__ Word32Equal(value_instance_type, __ Int32Constant(BIGINT_TYPE)), + &if_bigint); + // All other values that reach here are true. __ Goto(done, __ Int32Constant(1)); @@ -1174,6 +1171,15 @@ void EffectControlLinearizer::TruncateTaggedPointerToBit( __ LoadField(AccessBuilder::ForHeapNumberValue(), value); __ Goto(done, __ Float64LessThan(fzero, __ Float64Abs(value_value))); } + + __ Bind(&if_bigint); + { + Node* bitfield = __ LoadField(AccessBuilder::ForBigIntBitfield(), value); + Node* length_is_zero = __ Word32Equal( + __ Word32And(bitfield, __ Int32Constant(BigInt::LengthBits::kMask)), + zero); + __ Goto(done, __ Word32Equal(length_is_zero, zero)); + } } Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) { @@ -1294,9 +1300,11 @@ Node* EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node) { Node* EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state) { Node* index = node->InputAt(0); Node* limit = node->InputAt(1); + const CheckParameters& params = CheckParametersOf(node->op()); Node* check = __ Uint32LessThan(index, limit); - __ DeoptimizeIfNot(DeoptimizeReason::kOutOfBounds, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kOutOfBounds, params.feedback(), check, + frame_state); return index; } @@ -1305,9 +1313,12 @@ Node* EffectControlLinearizer::LowerMaskIndexWithBound(Node* node) { if (mask_array_index_ == kMaskArrayIndex) { Node* limit = node->InputAt(1); - Node* mask = __ Word32Sar(__ Word32Or(__ Int32Sub(limit, index), index), - __ Int32Constant(31)); - mask = __ Word32Xor(mask, __ Int32Constant(-1)); + // mask = ((index - limit) & ~index) >> 31 + // index = index & mask + Node* neg_index = __ Word32Xor(index, __ Int32Constant(-1)); + Node* mask = + __ Word32Sar(__ Word32And(__ Int32Sub(index, limit), neg_index), + __ Int32Constant(31)); index = __ Word32And(index, mask); } return index; @@ -1346,10 +1357,11 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { Node* bitfield3 = __ LoadField(AccessBuilder::ForMapBitField3(), value_map); Node* if_not_deprecated = __ WordEqual( - __ Word32And(bitfield3, __ Int32Constant(Map::Deprecated::kMask)), + __ Word32And(bitfield3, + __ Int32Constant(Map::IsDeprecatedBit::kMask)), __ Int32Constant(0)); - __ DeoptimizeIf(DeoptimizeReason::kWrongMap, if_not_deprecated, - frame_state); + __ DeoptimizeIf(DeoptimizeReason::kWrongMap, p.feedback(), + if_not_deprecated, frame_state); Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow; Runtime::FunctionId id = Runtime::kTryMigrateInstance; @@ -1360,8 +1372,8 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { __ ExternalConstant(ExternalReference(id, isolate())), __ Int32Constant(1), __ NoContextConstant()); Node* check = ObjectIsSmi(result); - __ DeoptimizeIf(DeoptimizeReason::kInstanceMigrationFailed, check, - frame_state); + __ DeoptimizeIf(DeoptimizeReason::kInstanceMigrationFailed, p.feedback(), + check, frame_state); } // Reload the current map of the {value}. @@ -1372,7 +1384,8 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { Node* map = __ HeapConstant(maps[i]); Node* check = __ WordEqual(value_map, map); if (i == map_count - 1) { - __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, p.feedback(), check, + frame_state); } else { __ GotoIf(check, &done); } @@ -1390,7 +1403,8 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { Node* map = __ HeapConstant(maps[i]); Node* check = __ WordEqual(value_map, map); if (i == map_count - 1) { - __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, p.feedback(), check, + frame_state); } else { __ GotoIf(check, &done); } @@ -1423,6 +1437,7 @@ Node* EffectControlLinearizer::LowerCompareMaps(Node* node) { Node* EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state) { Node* value = node->InputAt(0); + const CheckParameters& params = CheckParametersOf(node->op()); auto if_not_smi = __ MakeDeferredLabel(); auto done = __ MakeLabel(); @@ -1434,7 +1449,8 @@ Node* EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state) { __ Bind(&if_not_smi); Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); Node* check1 = __ WordEqual(value_map, __ HeapNumberMapConstant()); - __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, check1, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, params.feedback(), + check1, frame_state); __ Goto(&done); __ Bind(&done); @@ -1452,8 +1468,8 @@ Node* EffectControlLinearizer::LowerCheckReceiver(Node* node, STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); Node* check = __ Uint32LessThanOrEqual( __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type); - __ DeoptimizeIfNot(DeoptimizeReason::kNotAJavaScriptObject, check, - frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kNotAJavaScriptObject, VectorSlotPair(), + check, frame_state); return value; } @@ -1464,12 +1480,14 @@ Node* EffectControlLinearizer::LowerCheckSymbol(Node* node, Node* frame_state) { Node* check = __ WordEqual(value_map, __ HeapConstant(factory()->symbol_map())); - __ DeoptimizeIfNot(DeoptimizeReason::kNotASymbol, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kNotASymbol, VectorSlotPair(), check, + frame_state); return value; } Node* EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state) { Node* value = node->InputAt(0); + const CheckParameters& params = CheckParametersOf(node->op()); Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); Node* value_instance_type = @@ -1477,7 +1495,8 @@ Node* EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state) { Node* check = __ Uint32LessThan(value_instance_type, __ Uint32Constant(FIRST_NONSTRING_TYPE)); - __ DeoptimizeIfNot(DeoptimizeReason::kWrongInstanceType, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kWrongInstanceType, params.feedback(), + check, frame_state); return value; } @@ -1494,7 +1513,8 @@ Node* EffectControlLinearizer::LowerCheckSeqString(Node* node, value_instance_type, __ Int32Constant(kStringRepresentationMask | kIsNotStringMask)), __ Int32Constant(kSeqStringTag | kStringTag)); - __ DeoptimizeIfNot(DeoptimizeReason::kWrongInstanceType, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kWrongInstanceType, VectorSlotPair(), + check, frame_state); return value; } @@ -1510,7 +1530,8 @@ Node* EffectControlLinearizer::LowerCheckInternalizedString(Node* node, __ Word32And(value_instance_type, __ Int32Constant(kIsNotStringMask | kIsNotInternalizedMask)), __ Int32Constant(kInternalizedTag)); - __ DeoptimizeIfNot(DeoptimizeReason::kWrongInstanceType, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kWrongInstanceType, VectorSlotPair(), + check, frame_state); return value; } @@ -1518,7 +1539,7 @@ Node* EffectControlLinearizer::LowerCheckInternalizedString(Node* node, void EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state) { Node* value = node->InputAt(0); __ DeoptimizeIfNot(DeoptimizeKind::kEager, DeoptimizeReasonOf(node->op()), - value, frame_state); + VectorSlotPair(), value, frame_state); } Node* EffectControlLinearizer::LowerCheckedInt32Add(Node* node, @@ -1528,7 +1549,8 @@ Node* EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* value = __ Int32AddWithOverflow(lhs, rhs); Node* check = __ Projection(1, value); - __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(), check, + frame_state); return __ Projection(0, value); } @@ -1539,7 +1561,8 @@ Node* EffectControlLinearizer::LowerCheckedInt32Sub(Node* node, Node* value = __ Int32SubWithOverflow(lhs, rhs); Node* check = __ Projection(1, value); - __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(), check, + frame_state); return __ Projection(0, value); } @@ -1567,11 +1590,13 @@ Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node, // Check if {rhs} is zero. Node* check = __ Word32Equal(rhs, zero); - __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(), check, + frame_state); // Check if {lhs} is zero, as that would produce minus zero. check = __ Word32Equal(lhs, zero); - __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(), check, + frame_state); // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have // to return -kMinInt, which is not representable. @@ -1584,7 +1609,8 @@ Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node, // Check if {rhs} is -1. Node* minusone = __ Int32Constant(-1); Node* is_minus_one = __ Word32Equal(rhs, minusone); - __ DeoptimizeIf(DeoptimizeReason::kOverflow, is_minus_one, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(), is_minus_one, + frame_state); __ Goto(&minint_check_done); __ Bind(&minint_check_done); @@ -1597,7 +1623,8 @@ Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node, // Check if the remainder is non-zero. Node* check = __ Word32Equal(lhs, __ Int32Mul(rhs, value)); - __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(), check, + frame_state); return value; } @@ -1645,7 +1672,8 @@ Node* EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, // Ensure that {rhs} is not zero, otherwise we'd have to return NaN. Node* check = __ Word32Equal(vtrue0, zero); - __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(), check, + frame_state); __ Goto(&rhs_checked, vtrue0); } @@ -1679,7 +1707,8 @@ Node* EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, // Check if we would have to return -0. Node* check = __ Word32Equal(vtrue1, zero); - __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(), check, + frame_state); __ Goto(&done, vtrue1); } @@ -1696,14 +1725,16 @@ Node* EffectControlLinearizer::LowerCheckedUint32Div(Node* node, // Ensure that {rhs} is not zero, otherwise we'd have to return NaN. Node* check = __ Word32Equal(rhs, zero); - __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(), check, + frame_state); // Perform the actual unsigned integer division. Node* value = __ Uint32Div(lhs, rhs); // Check if the remainder is non-zero. check = __ Word32Equal(lhs, __ Int32Mul(rhs, value)); - __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(), check, + frame_state); return value; } @@ -1716,7 +1747,8 @@ Node* EffectControlLinearizer::LowerCheckedUint32Mod(Node* node, // Ensure that {rhs} is not zero, otherwise we'd have to return NaN. Node* check = __ Word32Equal(rhs, zero); - __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(), check, + frame_state); // Perform the actual unsigned integer modulus. return __ Uint32Mod(lhs, rhs); @@ -1730,7 +1762,8 @@ Node* EffectControlLinearizer::LowerCheckedInt32Mul(Node* node, Node* projection = __ Int32MulWithOverflow(lhs, rhs); Node* check = __ Projection(1, projection); - __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(), check, + frame_state); Node* value = __ Projection(0, projection); @@ -1745,7 +1778,8 @@ Node* EffectControlLinearizer::LowerCheckedInt32Mul(Node* node, __ Bind(&if_zero); // We may need to return negative zero. Node* check_or = __ Int32LessThan(__ Word32Or(lhs, rhs), zero); - __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check_or, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(), check_or, + frame_state); __ Goto(&check_done); __ Bind(&check_done); @@ -1758,35 +1792,42 @@ Node* EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned( Node* node, Node* frame_state) { DCHECK(SmiValuesAre31Bits()); Node* value = node->InputAt(0); + const CheckParameters& params = CheckParametersOf(node->op()); Node* add = __ Int32AddWithOverflow(value, value); Node* check = __ Projection(1, add); - __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kOverflow, params.feedback(), check, + frame_state); return __ Projection(0, add); } Node* EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, Node* frame_state) { Node* value = node->InputAt(0); + const CheckParameters& params = CheckParametersOf(node->op()); Node* unsafe = __ Int32LessThan(value, __ Int32Constant(0)); - __ DeoptimizeIf(DeoptimizeReason::kLostPrecision, unsafe, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kLostPrecision, params.feedback(), unsafe, + frame_state); return value; } Node* EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned( Node* node, Node* frame_state) { Node* value = node->InputAt(0); + const CheckParameters& params = CheckParametersOf(node->op()); Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant()); - __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check, + frame_state); return ChangeUint32ToSmi(value); } Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32( - CheckForMinusZeroMode mode, Node* value, Node* frame_state) { + CheckForMinusZeroMode mode, const VectorSlotPair& feedback, Node* value, + Node* frame_state) { Node* value32 = __ RoundFloat64ToInt32(value); Node* check_same = __ Float64Equal(value, __ ChangeInt32ToFloat64(value32)); - __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, check_same, - frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, feedback, + check_same, frame_state); if (mode == CheckForMinusZeroMode::kCheckForMinusZero) { // Check if {value} is -0. @@ -1801,7 +1842,8 @@ Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32( // In case of 0, we need to check the high bits for the IEEE -0 pattern. Node* check_negative = __ Int32LessThan(__ Float64ExtractHighWord32(value), __ Int32Constant(0)); - __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check_negative, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kMinusZero, feedback, check_negative, + frame_state); __ Goto(&check_done); __ Bind(&check_done); @@ -1811,22 +1853,27 @@ Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32( Node* EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, Node* frame_state) { - CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op()); + const CheckMinusZeroParameters& params = + CheckMinusZeroParametersOf(node->op()); Node* value = node->InputAt(0); - return BuildCheckedFloat64ToInt32(mode, value, frame_state); + return BuildCheckedFloat64ToInt32(params.mode(), params.feedback(), value, + frame_state); } Node* EffectControlLinearizer::LowerCheckedTaggedSignedToInt32( Node* node, Node* frame_state) { Node* value = node->InputAt(0); + const CheckParameters& params = CheckParametersOf(node->op()); Node* check = ObjectIsSmi(value); - __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check, + frame_state); return ChangeSmiToInt32(value); } Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, Node* frame_state) { - CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op()); + const CheckMinusZeroParameters& params = + CheckMinusZeroParametersOf(node->op()); Node* value = node->InputAt(0); auto if_not_smi = __ MakeDeferredLabel(); @@ -1842,9 +1889,11 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, __ Bind(&if_not_smi); Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); Node* check_map = __ WordEqual(value_map, __ HeapNumberMapConstant()); - __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, check_map, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, params.feedback(), + check_map, frame_state); Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value); - vfalse = BuildCheckedFloat64ToInt32(mode, vfalse, frame_state); + vfalse = BuildCheckedFloat64ToInt32(params.mode(), params.feedback(), vfalse, + frame_state); __ Goto(&done, vfalse); __ Bind(&done); @@ -1852,13 +1901,14 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, } Node* EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64( - CheckTaggedInputMode mode, Node* value, Node* frame_state) { + CheckTaggedInputMode mode, const VectorSlotPair& feedback, Node* value, + Node* frame_state) { Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); Node* check_number = __ WordEqual(value_map, __ HeapNumberMapConstant()); switch (mode) { case CheckTaggedInputMode::kNumber: { - __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, check_number, - frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, feedback, + check_number, frame_state); break; } case CheckTaggedInputMode::kNumberOrOddball: { @@ -1871,8 +1921,8 @@ Node* EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64( __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); Node* check_oddball = __ Word32Equal(instance_type, __ Int32Constant(ODDBALL_TYPE)); - __ DeoptimizeIfNot(DeoptimizeReason::kNotANumberOrOddball, check_oddball, - frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kNotANumberOrOddball, feedback, + check_oddball, frame_state); STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); __ Goto(&check_done); @@ -1896,8 +1946,8 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, // In the Smi case, just convert to int32 and then float64. // Otherwise, check heap numberness and load the number. - Node* number = - BuildCheckedHeapNumberOrOddballToFloat64(mode, value, frame_state); + Node* number = BuildCheckedHeapNumberOrOddballToFloat64( + mode, VectorSlotPair(), value, frame_state); __ Goto(&done, number); __ Bind(&if_smi); @@ -1912,9 +1962,11 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned( Node* node, Node* frame_state) { Node* value = node->InputAt(0); + const CheckParameters& params = CheckParametersOf(node->op()); Node* check = ObjectIsSmi(value); - __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check, + frame_state); return value; } @@ -1922,9 +1974,11 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned( Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer( Node* node, Node* frame_state) { Node* value = node->InputAt(0); + const CheckParameters& params = CheckParametersOf(node->op()); Node* check = ObjectIsSmi(value); - __ DeoptimizeIf(DeoptimizeReason::kSmi, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kSmi, params.feedback(), check, + frame_state); return value; } @@ -1950,7 +2004,8 @@ Node* EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node) { Node* EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32( Node* node, Node* frame_state) { - CheckTaggedInputMode mode = CheckTaggedInputModeOf(node->op()); + const CheckTaggedInputParameters& params = + CheckTaggedInputParametersOf(node->op()); Node* value = node->InputAt(0); auto if_not_smi = __ MakeLabel(); @@ -1964,8 +2019,8 @@ Node* EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32( // Otherwise, check that it's a heap number or oddball and truncate the value // to int32. __ Bind(&if_not_smi); - Node* number = - BuildCheckedHeapNumberOrOddballToFloat64(mode, value, frame_state); + Node* number = BuildCheckedHeapNumberOrOddballToFloat64( + params.mode(), params.feedback(), value, frame_state); number = __ TruncateFloat64ToWord32(number); __ Goto(&done, number); @@ -1980,6 +2035,19 @@ Node* EffectControlLinearizer::LowerAllocate(Node* node) { return new_node; } +Node* EffectControlLinearizer::LowerNumberToString(Node* node) { + Node* argument = node->InputAt(0); + + Callable const callable = + Builtins::CallableFor(isolate(), Builtins::kNumberToString); + Operator::Properties properties = Operator::kEliminatable; + CallDescriptor::Flags flags = CallDescriptor::kNoFlags; + CallDescriptor* desc = Linkage::GetStubCallDescriptor( + isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); + return __ Call(desc, __ HeapConstant(callable.code()), argument, + __ NoContextConstant()); +} + Node* EffectControlLinearizer::LowerObjectIsArrayBufferView(Node* node) { Node* value = node->InputAt(0); @@ -2039,9 +2107,10 @@ Node* EffectControlLinearizer::LowerObjectIsCallable(Node* node) { Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); Node* value_bit_field = __ LoadField(AccessBuilder::ForMapBitField(), value_map); - Node* vfalse = __ Word32Equal( - __ Int32Constant(1 << Map::kIsCallable), - __ Word32And(value_bit_field, __ Int32Constant(1 << Map::kIsCallable))); + Node* vfalse = + __ Word32Equal(__ Int32Constant(Map::IsCallableBit::kMask), + __ Word32And(value_bit_field, + __ Int32Constant(Map::IsCallableBit::kMask))); __ Goto(&done, vfalse); __ Bind(&if_smi); @@ -2063,10 +2132,10 @@ Node* EffectControlLinearizer::LowerObjectIsConstructor(Node* node) { Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); Node* value_bit_field = __ LoadField(AccessBuilder::ForMapBitField(), value_map); - Node* vfalse = - __ Word32Equal(__ Int32Constant(1 << Map::kIsConstructor), - __ Word32And(value_bit_field, - __ Int32Constant(1 << Map::kIsConstructor))); + Node* vfalse = __ Word32Equal( + __ Int32Constant(Map::IsConstructorBit::kMask), + __ Word32And(value_bit_field, + __ Int32Constant(Map::IsConstructorBit::kMask))); __ Goto(&done, vfalse); __ Bind(&if_smi); @@ -2089,10 +2158,10 @@ Node* EffectControlLinearizer::LowerObjectIsDetectableCallable(Node* node) { Node* value_bit_field = __ LoadField(AccessBuilder::ForMapBitField(), value_map); Node* vfalse = __ Word32Equal( - __ Int32Constant(1 << Map::kIsCallable), + __ Int32Constant(Map::IsCallableBit::kMask), __ Word32And(value_bit_field, - __ Int32Constant((1 << Map::kIsCallable) | - (1 << Map::kIsUndetectable)))); + __ Int32Constant((Map::IsCallableBit::kMask) | + (Map::IsUndetectableBit::kMask)))); __ Goto(&done, vfalse); __ Bind(&if_smi); @@ -2102,6 +2171,13 @@ Node* EffectControlLinearizer::LowerObjectIsDetectableCallable(Node* node) { return done.PhiAt(0); } +Node* EffectControlLinearizer::LowerNumberIsFloat64Hole(Node* node) { + Node* value = node->InputAt(0); + Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value), + __ Int32Constant(kHoleNanUpper32)); + return check; +} + Node* EffectControlLinearizer::LowerObjectIsMinusZero(Node* node) { Node* value = node->InputAt(0); Node* zero = __ Int32Constant(0); @@ -2169,9 +2245,10 @@ Node* EffectControlLinearizer::LowerObjectIsNonCallable(Node* node) { Node* value_bit_field = __ LoadField(AccessBuilder::ForMapBitField(), value_map); - Node* check2 = __ Word32Equal( - __ Int32Constant(0), - __ Word32And(value_bit_field, __ Int32Constant(1 << Map::kIsCallable))); + Node* check2 = + __ Word32Equal(__ Int32Constant(0), + __ Word32And(value_bit_field, + __ Int32Constant(Map::IsCallableBit::kMask))); __ Goto(&done, check2); __ Bind(&if_primitive); @@ -2283,9 +2360,10 @@ Node* EffectControlLinearizer::LowerObjectIsUndetectable(Node* node) { Node* value_bit_field = __ LoadField(AccessBuilder::ForMapBitField(), value_map); Node* vfalse = __ Word32Equal( - __ Word32Equal(__ Int32Constant(0), - __ Word32And(value_bit_field, - __ Int32Constant(1 << Map::kIsUndetectable))), + __ Word32Equal( + __ Int32Constant(0), + __ Word32And(value_bit_field, + __ Int32Constant(Map::IsUndetectableBit::kMask))), __ Int32Constant(0)); __ Goto(&done, vfalse); @@ -2511,6 +2589,52 @@ Node* EffectControlLinearizer::LowerNewArgumentsElements(Node* node) { __ SmiConstant(mapped_count), __ NoContextConstant()); } +Node* EffectControlLinearizer::LowerNewConsString(Node* node) { + Node* length = node->InputAt(0); + Node* first = node->InputAt(1); + Node* second = node->InputAt(2); + + // Determine the instance types of {first} and {second}. + Node* first_map = __ LoadField(AccessBuilder::ForMap(), first); + Node* first_instance_type = + __ LoadField(AccessBuilder::ForMapInstanceType(), first_map); + Node* second_map = __ LoadField(AccessBuilder::ForMap(), second); + Node* second_instance_type = + __ LoadField(AccessBuilder::ForMapInstanceType(), second_map); + + // Determine the proper map for the resulting ConsString. + // If both {first} and {second} are one-byte strings, we + // create a new ConsOneByteString, otherwise we create a + // new ConsString instead. + auto if_onebyte = __ MakeLabel(); + auto if_twobyte = __ MakeLabel(); + auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer); + STATIC_ASSERT(kOneByteStringTag != 0); + STATIC_ASSERT(kTwoByteStringTag == 0); + Node* instance_type = __ Word32And(first_instance_type, second_instance_type); + Node* encoding = + __ Word32And(instance_type, __ Int32Constant(kStringEncodingMask)); + __ Branch(__ Word32Equal(encoding, __ Int32Constant(kTwoByteStringTag)), + &if_twobyte, &if_onebyte); + __ Bind(&if_onebyte); + __ Goto(&done, + jsgraph()->HeapConstant(factory()->cons_one_byte_string_map())); + __ Bind(&if_twobyte); + __ Goto(&done, jsgraph()->HeapConstant(factory()->cons_string_map())); + __ Bind(&done); + Node* result_map = done.PhiAt(0); + + // Allocate the resulting ConsString. + Node* result = __ Allocate(NOT_TENURED, __ Int32Constant(ConsString::kSize)); + __ StoreField(AccessBuilder::ForMap(), result, result_map); + __ StoreField(AccessBuilder::ForNameHashField(), result, + jsgraph()->Int32Constant(Name::kEmptyHashField)); + __ StoreField(AccessBuilder::ForStringLength(), result, length); + __ StoreField(AccessBuilder::ForConsStringFirst(), result, first); + __ StoreField(AccessBuilder::ForConsStringSecond(), result, second); + return result; +} + Node* EffectControlLinearizer::LowerArrayBufferWasNeutered(Node* node) { Node* value = node->InputAt(0); @@ -2538,6 +2662,15 @@ Node* EffectControlLinearizer::LowerSameValue(Node* node) { __ NoContextConstant()); } +Node* EffectControlLinearizer::LowerDeadValue(Node* node) { + Node* input = NodeProperties::GetValueInput(node, 0); + if (input->opcode() != IrOpcode::kUnreachable) { + Node* unreachable = __ Unreachable(); + NodeProperties::ReplaceValueInput(node, unreachable, 0); + } + return node; +} + Node* EffectControlLinearizer::LowerStringToNumber(Node* node) { Node* string = node->InputAt(0); @@ -2580,19 +2713,25 @@ Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) { __ NoContextConstant()); } -Node* EffectControlLinearizer::LowerSeqStringCharCodeAt(Node* node) { +Node* EffectControlLinearizer::LowerStringCodePointAt(Node* node) { Node* receiver = node->InputAt(0); Node* position = node->InputAt(1); + Callable const callable = + Builtins::CallableFor(isolate(), Builtins::kStringCodePointAt); + Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite; + CallDescriptor::Flags flags = CallDescriptor::kNoFlags; + CallDescriptor* desc = Linkage::GetStubCallDescriptor( + isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties, + MachineType::TaggedSigned()); + return __ Call(desc, __ HeapConstant(callable.code()), receiver, position, + __ NoContextConstant()); +} + +Node* EffectControlLinearizer::LoadFromString(Node* receiver, Node* position, + Node* is_one_byte) { auto one_byte_load = __ MakeLabel(); auto done = __ MakeLabel(MachineRepresentation::kWord32); - - Node* map = __ LoadField(AccessBuilder::ForMap(), receiver); - Node* instance_type = __ LoadField(AccessBuilder::ForMapInstanceType(), map); - Node* is_one_byte = __ Word32Equal( - __ Word32And(instance_type, __ Int32Constant(kStringEncodingMask)), - __ Int32Constant(kOneByteStringTag)); - __ GotoIf(is_one_byte, &one_byte_load); Node* two_byte_result = __ LoadElement( AccessBuilder::ForSeqTwoByteStringCharacter(), receiver, position); @@ -2607,6 +2746,85 @@ Node* EffectControlLinearizer::LowerSeqStringCharCodeAt(Node* node) { return done.PhiAt(0); } +Node* EffectControlLinearizer::LowerSeqStringCharCodeAt(Node* node) { + Node* receiver = node->InputAt(0); + Node* position = node->InputAt(1); + + Node* map = __ LoadField(AccessBuilder::ForMap(), receiver); + Node* instance_type = __ LoadField(AccessBuilder::ForMapInstanceType(), map); + Node* is_one_byte = __ Word32Equal( + __ Word32And(instance_type, __ Int32Constant(kStringEncodingMask)), + __ Int32Constant(kOneByteStringTag)); + + return LoadFromString(receiver, position, is_one_byte); +} + +Node* EffectControlLinearizer::LowerSeqStringCodePointAt( + Node* node, UnicodeEncoding encoding) { + Node* receiver = node->InputAt(0); + Node* position = node->InputAt(1); + + Node* map = __ LoadField(AccessBuilder::ForMap(), receiver); + Node* instance_type = __ LoadField(AccessBuilder::ForMapInstanceType(), map); + Node* is_one_byte = __ Word32Equal( + __ Word32And(instance_type, __ Int32Constant(kStringEncodingMask)), + __ Int32Constant(kOneByteStringTag)); + + Node* first_char_code = LoadFromString(receiver, position, is_one_byte); + + auto return_result = __ MakeLabel(MachineRepresentation::kWord32); + + // Check if first character code is outside of interval [0xD800, 0xDBFF]. + Node* first_out = + __ Word32Equal(__ Word32And(first_char_code, __ Int32Constant(0xFC00)), + __ Int32Constant(0xD800)); + // Return first character code. + __ GotoIf(first_out, &return_result, first_char_code); + // Check if position + 1 is still in range. + Node* length = __ LoadField(AccessBuilder::ForStringLength(), receiver); + Node* next_position = __ Int32Add(position, __ Int32Constant(1)); + Node* next_position_in_range = __ Int32LessThan(next_position, length); + __ GotoIf(next_position_in_range, &return_result, first_char_code); + + // Load second character code. + Node* second_char_code = LoadFromString(receiver, next_position, is_one_byte); + // Check if first character code is outside of interval [0xD800, 0xDBFF]. + Node* second_out = + __ Word32Equal(__ Word32And(second_char_code, __ Int32Constant(0xFC00)), + __ Int32Constant(0xDC00)); + __ GotoIfNot(second_out, &return_result, first_char_code); + + Node* result; + switch (encoding) { + case UnicodeEncoding::UTF16: + result = __ Word32Or( +// Need to swap the order for big-endian platforms +#if V8_TARGET_BIG_ENDIAN + __ Word32Shl(first_char_code, __ Int32Constant(16)), + second_char_code); +#else + __ Word32Shl(second_char_code, __ Int32Constant(16)), + first_char_code); +#endif + break; + case UnicodeEncoding::UTF32: { + // Convert UTF16 surrogate pair into |word32| code point, encoded as + // UTF32. + Node* surrogate_offset = + __ Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00); + + // (lead << 10) + trail + SURROGATE_OFFSET + result = __ Int32Add(__ Word32Shl(first_char_code, __ Int32Constant(10)), + __ Int32Add(second_char_code, surrogate_offset)); + break; + } + } + __ Goto(&return_result, result); + + __ Bind(&return_result); + return return_result.PhiAt(0); +} + Node* EffectControlLinearizer::LowerStringFromCharCode(Node* node) { Node* value = node->InputAt(0); @@ -2836,6 +3054,12 @@ Node* EffectControlLinearizer::LowerStringIndexOf(Node* node) { position, __ NoContextConstant()); } +Node* EffectControlLinearizer::LowerStringLength(Node* node) { + Node* subject = node->InputAt(0); + + return __ LoadField(AccessBuilder::ForStringLength(), subject); +} + Node* EffectControlLinearizer::LowerStringComparison(Callable const& callable, Node* node) { Node* lhs = node->InputAt(0); @@ -2872,7 +3096,8 @@ Node* EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* value = node->InputAt(0); Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value), __ Int32Constant(kHoleNanUpper32)); - __ DeoptimizeIf(DeoptimizeReason::kHole, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kHole, VectorSlotPair(), check, + frame_state); return value; } @@ -2881,7 +3106,8 @@ Node* EffectControlLinearizer::LowerCheckNotTaggedHole(Node* node, Node* frame_state) { Node* value = node->InputAt(0); Node* check = __ WordEqual(value, __ TheHoleConstant()); - __ DeoptimizeIf(DeoptimizeReason::kHole, check, frame_state); + __ DeoptimizeIf(DeoptimizeReason::kHole, VectorSlotPair(), check, + frame_state); return value; } @@ -2918,8 +3144,8 @@ void EffectControlLinearizer::LowerCheckEqualsInternalizedString( __ Bind(&if_notsame); { // Now {val} could still be a non-internalized String that matches {exp}. - __ DeoptimizeIf(DeoptimizeReason::kWrongName, ObjectIsSmi(val), - frame_state); + __ DeoptimizeIf(DeoptimizeReason::kWrongName, VectorSlotPair(), + ObjectIsSmi(val), frame_state); Node* val_map = __ LoadField(AccessBuilder::ForMap(), val); Node* val_instance_type = __ LoadField(AccessBuilder::ForMapInstanceType(), val_map); @@ -2937,7 +3163,7 @@ void EffectControlLinearizer::LowerCheckEqualsInternalizedString( // Check that the {val} is a non-internalized String, if it's anything // else it cannot match the recorded feedback {exp} anyways. __ DeoptimizeIfNot( - DeoptimizeReason::kWrongName, + DeoptimizeReason::kWrongName, VectorSlotPair(), __ Word32Equal(__ Word32And(val_instance_type, __ Int32Constant(kIsNotStringMask | kIsNotInternalizedMask)), @@ -2956,7 +3182,7 @@ void EffectControlLinearizer::LowerCheckEqualsInternalizedString( __ Call(common()->Call(desc), try_internalize_string_function, val); // Now see if the results match. - __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, + __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, VectorSlotPair(), __ WordEqual(exp, val_internalized), frame_state); __ Goto(&if_same); } @@ -2966,7 +3192,7 @@ void EffectControlLinearizer::LowerCheckEqualsInternalizedString( // The {val} is a ThinString, let's check the actual value. Node* val_actual = __ LoadField(AccessBuilder::ForThinStringActual(), val); - __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, + __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, VectorSlotPair(), __ WordEqual(exp, val_actual), frame_state); __ Goto(&if_same); } @@ -2980,7 +3206,8 @@ void EffectControlLinearizer::LowerCheckEqualsSymbol(Node* node, Node* exp = node->InputAt(0); Node* val = node->InputAt(1); Node* check = __ WordEqual(exp, val); - __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, check, frame_state); + __ DeoptimizeIfNot(DeoptimizeReason::kWrongName, VectorSlotPair(), check, + frame_state); } Node* EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value) { @@ -3135,7 +3362,7 @@ Node* EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node) { Node* EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node, Node* frame_state) { - GrowFastElementsMode mode = GrowFastElementsModeOf(node->op()); + GrowFastElementsParameters params = GrowFastElementsParametersOf(node->op()); Node* object = node->InputAt(0); Node* elements = node->InputAt(1); Node* index = node->InputAt(2); @@ -3154,7 +3381,7 @@ Node* EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node, // We need to grow the {elements} for {object}. Operator::Properties properties = Operator::kEliminatable; Callable callable = - (mode == GrowFastElementsMode::kDoubleElements) + (params.mode() == GrowFastElementsMode::kDoubleElements) ? Builtins::CallableFor(isolate(), Builtins::kGrowFastDoubleElements) : Builtins::CallableFor(isolate(), Builtins::kGrowFastSmiOrObjectElements); @@ -3166,10 +3393,8 @@ Node* EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node, ChangeInt32ToSmi(index), __ NoContextConstant()); // Ensure that we were able to grow the {elements}. - // TODO(turbofan): We use kSmi as reason here similar to Crankshaft, - // but maybe we should just introduce a reason that makes sense. - __ DeoptimizeIf(DeoptimizeReason::kSmi, ObjectIsSmi(new_elements), - frame_state); + __ DeoptimizeIf(DeoptimizeReason::kCouldNotGrowElements, params.feedback(), + ObjectIsSmi(new_elements), frame_state); __ Goto(&done, new_elements); __ Bind(&done); @@ -3723,12 +3948,13 @@ void EffectControlLinearizer::LowerStoreSignedSmallElement(Node* node) { } void EffectControlLinearizer::LowerRuntimeAbort(Node* node) { - BailoutReason reason = BailoutReasonOf(node->op()); + AbortReason reason = AbortReasonOf(node->op()); Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow; Runtime::FunctionId id = Runtime::kAbort; CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor( graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags); - __ Call(desc, __ CEntryStubConstant(1), jsgraph()->SmiConstant(reason), + __ Call(desc, __ CEntryStubConstant(1), + jsgraph()->SmiConstant(static_cast<int>(reason)), __ ExternalConstant(ExternalReference(id, isolate())), __ Int32Constant(1), __ NoContextConstant()); } @@ -4165,14 +4391,14 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) { Node* EffectControlLinearizer::ComputeIntegerHash(Node* value) { // See v8::internal::ComputeIntegerHash() - value = __ Int32Add(__ Word32Xor(value, __ Int32Constant(0xffffffff)), + value = __ Int32Add(__ Word32Xor(value, __ Int32Constant(0xFFFFFFFF)), __ Word32Shl(value, __ Int32Constant(15))); value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(12))); value = __ Int32Add(value, __ Word32Shl(value, __ Int32Constant(2))); value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(4))); value = __ Int32Mul(value, __ Int32Constant(2057)); value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(16))); - value = __ Word32And(value, __ Int32Constant(0x3fffffff)); + value = __ Word32And(value, __ Int32Constant(0x3FFFFFFF)); return value; } |