aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/effect-control-linearizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/effect-control-linearizer.cc')
-rw-r--r--deps/v8/src/compiler/effect-control-linearizer.cc549
1 files changed, 398 insertions, 151 deletions
diff --git a/deps/v8/src/compiler/effect-control-linearizer.cc b/deps/v8/src/compiler/effect-control-linearizer.cc
index 4bb4f8df77..97f78418d0 100644
--- a/deps/v8/src/compiler/effect-control-linearizer.cc
+++ b/deps/v8/src/compiler/effect-control-linearizer.cc
@@ -628,9 +628,15 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kChangeInt32ToTagged:
result = LowerChangeInt32ToTagged(node);
break;
+ case IrOpcode::kChangeInt64ToTagged:
+ result = LowerChangeInt64ToTagged(node);
+ break;
case IrOpcode::kChangeUint32ToTagged:
result = LowerChangeUint32ToTagged(node);
break;
+ case IrOpcode::kChangeUint64ToTagged:
+ result = LowerChangeUint64ToTagged(node);
+ break;
case IrOpcode::kChangeFloat64ToTagged:
result = LowerChangeFloat64ToTagged(node);
break;
@@ -640,6 +646,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kChangeTaggedSignedToInt32:
result = LowerChangeTaggedSignedToInt32(node);
break;
+ case IrOpcode::kChangeTaggedSignedToInt64:
+ result = LowerChangeTaggedSignedToInt64(node);
+ break;
case IrOpcode::kChangeTaggedToBit:
result = LowerChangeTaggedToBit(node);
break;
@@ -649,6 +658,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kChangeTaggedToUint32:
result = LowerChangeTaggedToUint32(node);
break;
+ case IrOpcode::kChangeTaggedToInt64:
+ result = LowerChangeTaggedToInt64(node);
+ break;
case IrOpcode::kChangeTaggedToFloat64:
result = LowerChangeTaggedToFloat64(node);
break;
@@ -718,12 +730,24 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kCheckedInt32ToTaggedSigned:
result = LowerCheckedInt32ToTaggedSigned(node, frame_state);
break;
+ case IrOpcode::kCheckedInt64ToInt32:
+ result = LowerCheckedInt64ToInt32(node, frame_state);
+ break;
+ case IrOpcode::kCheckedInt64ToTaggedSigned:
+ result = LowerCheckedInt64ToTaggedSigned(node, frame_state);
+ break;
case IrOpcode::kCheckedUint32ToInt32:
result = LowerCheckedUint32ToInt32(node, frame_state);
break;
case IrOpcode::kCheckedUint32ToTaggedSigned:
result = LowerCheckedUint32ToTaggedSigned(node, frame_state);
break;
+ case IrOpcode::kCheckedUint64ToInt32:
+ result = LowerCheckedUint64ToInt32(node, frame_state);
+ break;
+ case IrOpcode::kCheckedUint64ToTaggedSigned:
+ result = LowerCheckedUint64ToTaggedSigned(node, frame_state);
+ break;
case IrOpcode::kCheckedFloat64ToInt32:
result = LowerCheckedFloat64ToInt32(node, frame_state);
break;
@@ -824,15 +848,15 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
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);
break;
+ case IrOpcode::kStringConcat:
+ result = LowerStringConcat(node);
+ break;
case IrOpcode::kStringFromSingleCharCode:
result = LowerStringFromSingleCharCode(node);
break;
@@ -1120,6 +1144,35 @@ Node* EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node) {
return done.PhiAt(0);
}
+Node* EffectControlLinearizer::LowerChangeInt64ToTagged(Node* node) {
+ Node* value = node->InputAt(0);
+
+ auto if_not_in_smi_range = __ MakeDeferredLabel();
+ auto done = __ MakeLabel(MachineRepresentation::kTagged);
+
+ Node* value32 = __ TruncateInt64ToInt32(value);
+ __ GotoIfNot(__ Word64Equal(__ ChangeInt32ToInt64(value32), value),
+ &if_not_in_smi_range);
+
+ if (SmiValuesAre32Bits()) {
+ Node* value_smi = ChangeInt64ToSmi(value);
+ __ Goto(&done, value_smi);
+ } else {
+ Node* add = __ Int32AddWithOverflow(value32, value32);
+ Node* ovf = __ Projection(1, add);
+ __ GotoIf(ovf, &if_not_in_smi_range);
+ Node* value_smi = ChangeInt32ToIntPtr(__ Projection(0, add));
+ __ Goto(&done, value_smi);
+ }
+
+ __ Bind(&if_not_in_smi_range);
+ Node* number = AllocateHeapNumberWithValue(__ ChangeInt64ToFloat64(value));
+ __ Goto(&done, number);
+
+ __ Bind(&done);
+ return done.PhiAt(0);
+}
+
Node* EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node) {
Node* value = node->InputAt(0);
@@ -1139,11 +1192,36 @@ Node* EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node) {
return done.PhiAt(0);
}
+Node* EffectControlLinearizer::LowerChangeUint64ToTagged(Node* node) {
+ Node* value = node->InputAt(0);
+
+ auto if_not_in_smi_range = __ MakeDeferredLabel();
+ auto done = __ MakeLabel(MachineRepresentation::kTagged);
+
+ Node* check =
+ __ Uint64LessThanOrEqual(value, __ Int64Constant(Smi::kMaxValue));
+ __ GotoIfNot(check, &if_not_in_smi_range);
+ __ Goto(&done, ChangeInt64ToSmi(value));
+
+ __ Bind(&if_not_in_smi_range);
+ Node* number = AllocateHeapNumberWithValue(__ ChangeInt64ToFloat64(value));
+
+ __ Goto(&done, number);
+ __ Bind(&done);
+
+ return done.PhiAt(0);
+}
+
Node* EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node) {
Node* value = node->InputAt(0);
return ChangeSmiToInt32(value);
}
+Node* EffectControlLinearizer::LowerChangeTaggedSignedToInt64(Node* node) {
+ Node* value = node->InputAt(0);
+ return ChangeSmiToInt64(value);
+}
+
Node* EffectControlLinearizer::LowerChangeTaggedToBit(Node* node) {
Node* value = node->InputAt(0);
return __ WordEqual(value, __ TrueConstant());
@@ -1280,6 +1358,26 @@ Node* EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node) {
return done.PhiAt(0);
}
+Node* EffectControlLinearizer::LowerChangeTaggedToInt64(Node* node) {
+ Node* value = node->InputAt(0);
+
+ auto if_not_smi = __ MakeDeferredLabel();
+ auto done = __ MakeLabel(MachineRepresentation::kWord64);
+
+ Node* check = ObjectIsSmi(value);
+ __ GotoIfNot(check, &if_not_smi);
+ __ Goto(&done, ChangeSmiToInt64(value));
+
+ __ Bind(&if_not_smi);
+ STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
+ Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
+ vfalse = __ ChangeFloat64ToInt64(vfalse);
+ __ Goto(&done, vfalse);
+
+ __ Bind(&done);
+ return done.PhiAt(0);
+}
+
Node* EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node) {
return LowerTruncateTaggedToFloat64(node);
}
@@ -1353,7 +1451,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
size_t const map_count = maps.size();
if (p.flags() & CheckMapsFlag::kTryMigrateInstance) {
- auto done = __ MakeDeferredLabel();
+ auto done = __ MakeLabel();
auto migrate = __ MakeDeferredLabel();
// Load the current map of the {value}.
@@ -1364,10 +1462,11 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
Node* map = __ HeapConstant(maps[i]);
Node* check = __ WordEqual(value_map, map);
if (i == map_count - 1) {
- __ GotoIfNot(check, &migrate);
- __ Goto(&done);
+ __ Branch(check, &done, &migrate, IsSafetyCheck::kCriticalSafetyCheck);
} else {
- __ GotoIf(check, &done);
+ auto next_map = __ MakeLabel();
+ __ Branch(check, &done, &next_map, IsSafetyCheck::kCriticalSafetyCheck);
+ __ Bind(&next_map);
}
}
@@ -1382,7 +1481,8 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
__ Int32Constant(Map::IsDeprecatedBit::kMask)),
__ Int32Constant(0));
__ DeoptimizeIf(DeoptimizeReason::kWrongMap, p.feedback(),
- if_not_deprecated, frame_state);
+ if_not_deprecated, frame_state,
+ IsSafetyCheck::kCriticalSafetyCheck);
Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
Runtime::FunctionId id = Runtime::kTryMigrateInstance;
@@ -1393,7 +1493,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
__ Int32Constant(1), __ NoContextConstant());
Node* check = ObjectIsSmi(result);
__ DeoptimizeIf(DeoptimizeReason::kInstanceMigrationFailed, p.feedback(),
- check, frame_state);
+ check, frame_state, IsSafetyCheck::kCriticalSafetyCheck);
}
// Reload the current map of the {value}.
@@ -1405,9 +1505,11 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
Node* check = __ WordEqual(value_map, map);
if (i == map_count - 1) {
__ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, p.feedback(), check,
- frame_state);
+ frame_state, IsSafetyCheck::kCriticalSafetyCheck);
} else {
- __ GotoIf(check, &done);
+ auto next_map = __ MakeLabel();
+ __ Branch(check, &done, &next_map, IsSafetyCheck::kCriticalSafetyCheck);
+ __ Bind(&next_map);
}
}
@@ -1424,9 +1526,11 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
Node* check = __ WordEqual(value_map, map);
if (i == map_count - 1) {
__ DeoptimizeIfNot(DeoptimizeReason::kWrongMap, p.feedback(), check,
- frame_state);
+ frame_state, IsSafetyCheck::kCriticalSafetyCheck);
} else {
- __ GotoIf(check, &done);
+ auto next_map = __ MakeLabel();
+ __ Branch(check, &done, &next_map, IsSafetyCheck::kCriticalSafetyCheck);
+ __ Bind(&next_map);
}
}
__ Goto(&done);
@@ -1447,7 +1551,14 @@ Node* EffectControlLinearizer::LowerCompareMaps(Node* node) {
for (size_t i = 0; i < map_count; ++i) {
Node* map = __ HeapConstant(maps[i]);
Node* check = __ WordEqual(value_map, map);
- __ GotoIf(check, &done, __ Int32Constant(1));
+ auto next_map = __ MakeLabel();
+ auto passed = __ MakeLabel();
+ __ Branch(check, &passed, &next_map, IsSafetyCheck::kCriticalSafetyCheck);
+
+ __ Bind(&passed);
+ __ Goto(&done, __ Int32Constant(1));
+
+ __ Bind(&next_map);
}
__ Goto(&done, __ Int32Constant(0));
@@ -1544,6 +1655,24 @@ void EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state) {
__ DeoptimizeIfNot(p.reason(), p.feedback(), value, frame_state);
}
+Node* EffectControlLinearizer::LowerStringConcat(Node* node) {
+ Node* lhs = node->InputAt(1);
+ Node* rhs = node->InputAt(2);
+
+ Callable const callable =
+ CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE);
+ auto call_descriptor = Linkage::GetStubCallDescriptor(
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
+ Operator::kNoDeopt | Operator::kNoWrite | Operator::kNoThrow);
+
+ Node* value =
+ __ Call(call_descriptor, jsgraph()->HeapConstant(callable.code()), lhs,
+ rhs, __ NoContextConstant());
+
+ return value;
+}
+
Node* EffectControlLinearizer::LowerCheckedInt32Add(Node* node,
Node* frame_state) {
Node* lhs = node->InputAt(0);
@@ -1572,63 +1701,87 @@ Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node,
Node* frame_state) {
Node* lhs = node->InputAt(0);
Node* rhs = node->InputAt(1);
-
- auto if_not_positive = __ MakeDeferredLabel();
- auto if_is_minint = __ MakeDeferredLabel();
- auto done = __ MakeLabel(MachineRepresentation::kWord32);
- auto minint_check_done = __ MakeLabel();
-
Node* zero = __ Int32Constant(0);
- // Check if {rhs} is positive (and not zero).
- Node* check0 = __ Int32LessThan(zero, rhs);
- __ GotoIfNot(check0, &if_not_positive);
+ // Check if the {rhs} is a known power of two.
+ Int32Matcher m(rhs);
+ if (m.IsPowerOf2()) {
+ // Since we know that {rhs} is a power of two, we can perform a fast
+ // check to see if the relevant least significant bits of the {lhs}
+ // are all zero, and if so we know that we can perform a division
+ // safely (and fast by doing an arithmetic - aka sign preserving -
+ // right shift on {lhs}).
+ int32_t divisor = m.Value();
+ Node* mask = __ Int32Constant(divisor - 1);
+ Node* shift = __ Int32Constant(WhichPowerOf2(divisor));
+ Node* check = __ Word32Equal(__ Word32And(lhs, mask), zero);
+ __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(),
+ check, frame_state);
+ return __ Word32Sar(lhs, shift);
+ } else {
+ auto if_rhs_positive = __ MakeLabel();
+ auto if_rhs_negative = __ MakeDeferredLabel();
+ auto done = __ MakeLabel(MachineRepresentation::kWord32);
- // Fast case, no additional checking required.
- __ Goto(&done, __ Int32Div(lhs, rhs));
+ // Check if {rhs} is positive (and not zero).
+ Node* check_rhs_positive = __ Int32LessThan(zero, rhs);
+ __ Branch(check_rhs_positive, &if_rhs_positive, &if_rhs_negative);
- {
- __ Bind(&if_not_positive);
+ __ Bind(&if_rhs_positive);
+ {
+ // Fast case, no additional checking required.
+ __ Goto(&done, __ Int32Div(lhs, rhs));
+ }
- // Check if {rhs} is zero.
- Node* check = __ Word32Equal(rhs, zero);
- __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(), check,
- frame_state);
+ __ Bind(&if_rhs_negative);
+ {
+ auto if_lhs_minint = __ MakeDeferredLabel();
+ auto if_lhs_notminint = __ MakeLabel();
+
+ // Check if {rhs} is zero.
+ Node* check_rhs_zero = __ Word32Equal(rhs, zero);
+ __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(),
+ check_rhs_zero, frame_state);
+
+ // Check if {lhs} is zero, as that would produce minus zero.
+ Node* check_lhs_zero = __ Word32Equal(lhs, zero);
+ __ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(),
+ check_lhs_zero, frame_state);
+
+ // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have
+ // to return -kMinInt, which is not representable as Word32.
+ Node* check_lhs_minint = graph()->NewNode(machine()->Word32Equal(), lhs,
+ __ Int32Constant(kMinInt));
+ __ Branch(check_lhs_minint, &if_lhs_minint, &if_lhs_notminint);
+
+ __ Bind(&if_lhs_minint);
+ {
+ // Check that {rhs} is not -1, otherwise result would be -kMinInt.
+ Node* check_rhs_minusone = __ Word32Equal(rhs, __ Int32Constant(-1));
+ __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(),
+ check_rhs_minusone, frame_state);
- // Check if {lhs} is zero, as that would produce minus zero.
- check = __ Word32Equal(lhs, zero);
- __ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(), check,
- frame_state);
+ // Perform the actual integer division.
+ __ Goto(&done, __ Int32Div(lhs, rhs));
+ }
- // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have
- // to return -kMinInt, which is not representable.
- Node* minint = __ Int32Constant(std::numeric_limits<int32_t>::min());
- Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint);
- __ GotoIf(check1, &if_is_minint);
- __ Goto(&minint_check_done);
-
- __ Bind(&if_is_minint);
- // Check if {rhs} is -1.
- Node* minusone = __ Int32Constant(-1);
- Node* is_minus_one = __ Word32Equal(rhs, minusone);
- __ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(), is_minus_one,
- frame_state);
- __ Goto(&minint_check_done);
+ __ Bind(&if_lhs_notminint);
+ {
+ // Perform the actual integer division.
+ __ Goto(&done, __ Int32Div(lhs, rhs));
+ }
+ }
- __ Bind(&minint_check_done);
- // Perform the actual integer division.
- __ Goto(&done, __ Int32Div(lhs, rhs));
- }
+ __ Bind(&done);
+ Node* value = done.PhiAt(0);
- __ Bind(&done);
- Node* value = done.PhiAt(0);
+ // Check if the remainder is non-zero.
+ Node* check = __ Word32Equal(lhs, __ Int32Mul(value, rhs));
+ __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(),
+ check, frame_state);
- // Check if the remainder is non-zero.
- Node* check = __ Word32Equal(lhs, __ Int32Mul(rhs, value));
- __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(), check,
- frame_state);
-
- return value;
+ return value;
+ }
}
Node* EffectControlLinearizer::BuildUint32Mod(Node* lhs, Node* rhs) {
@@ -1722,8 +1875,11 @@ Node* EffectControlLinearizer::LowerCheckedInt32Mod(Node* node,
__ Bind(&if_lhs_negative);
{
- // The {lhs} is a negative integer.
- Node* res = BuildUint32Mod(__ Int32Sub(zero, lhs), rhs);
+ // The {lhs} is a negative integer. This is very unlikely and
+ // we intentionally don't use the BuildUint32Mod() here, which
+ // would try to figure out whether {rhs} is a power of two,
+ // since this is intended to be a slow-path.
+ Node* res = __ Uint32Mod(__ Int32Sub(zero, lhs), rhs);
// Check if we would have to return -0.
__ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(),
@@ -1739,22 +1895,38 @@ Node* EffectControlLinearizer::LowerCheckedUint32Div(Node* node,
Node* frame_state) {
Node* lhs = node->InputAt(0);
Node* rhs = node->InputAt(1);
-
Node* zero = __ Int32Constant(0);
- // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
- Node* check = __ Word32Equal(rhs, zero);
- __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(), check,
- frame_state);
+ // Check if the {rhs} is a known power of two.
+ Uint32Matcher m(rhs);
+ if (m.IsPowerOf2()) {
+ // Since we know that {rhs} is a power of two, we can perform a fast
+ // check to see if the relevant least significant bits of the {lhs}
+ // are all zero, and if so we know that we can perform a division
+ // safely (and fast by doing a logical - aka zero extending - right
+ // shift on {lhs}).
+ uint32_t divisor = m.Value();
+ Node* mask = __ Uint32Constant(divisor - 1);
+ Node* shift = __ Uint32Constant(WhichPowerOf2(divisor));
+ Node* check = __ Word32Equal(__ Word32And(lhs, mask), zero);
+ __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(),
+ check, frame_state);
+ return __ Word32Shr(lhs, shift);
+ } else {
+ // Ensure that {rhs} is not zero, otherwise we'd have to return NaN.
+ Node* check = __ Word32Equal(rhs, zero);
+ __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, VectorSlotPair(), check,
+ frame_state);
- // Perform the actual unsigned integer division.
- Node* value = __ Uint32Div(lhs, rhs);
+ // 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, VectorSlotPair(), check,
- frame_state);
- return value;
+ // Check if the remainder is non-zero.
+ check = __ Word32Equal(lhs, __ Int32Mul(rhs, value));
+ __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(),
+ check, frame_state);
+ return value;
+ }
}
Node* EffectControlLinearizer::LowerCheckedUint32Mod(Node* node,
@@ -1815,13 +1987,48 @@ Node* EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(
Node* add = __ Int32AddWithOverflow(value, value);
Node* check = __ Projection(1, add);
- __ DeoptimizeIf(DeoptimizeReason::kOverflow, params.feedback(), check,
+ __ DeoptimizeIf(DeoptimizeReason::kLostPrecision, params.feedback(), check,
frame_state);
Node* result = __ Projection(0, add);
result = ChangeInt32ToIntPtr(result);
return result;
}
+Node* EffectControlLinearizer::LowerCheckedInt64ToInt32(Node* node,
+ Node* frame_state) {
+ Node* value = node->InputAt(0);
+ const CheckParameters& params = CheckParametersOf(node->op());
+
+ Node* value32 = __ TruncateInt64ToInt32(value);
+ Node* check = __ Word64Equal(__ ChangeInt32ToInt64(value32), value);
+ __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
+ frame_state);
+ return value32;
+}
+
+Node* EffectControlLinearizer::LowerCheckedInt64ToTaggedSigned(
+ Node* node, Node* frame_state) {
+ Node* value = node->InputAt(0);
+ const CheckParameters& params = CheckParametersOf(node->op());
+
+ Node* value32 = __ TruncateInt64ToInt32(value);
+ Node* check = __ Word64Equal(__ ChangeInt32ToInt64(value32), value);
+ __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
+ frame_state);
+
+ if (SmiValuesAre32Bits()) {
+ return ChangeInt64ToSmi(value);
+ } else {
+ Node* add = __ Int32AddWithOverflow(value32, value32);
+ Node* check = __ Projection(1, add);
+ __ DeoptimizeIf(DeoptimizeReason::kLostPrecision, params.feedback(), check,
+ frame_state);
+ Node* result = __ Projection(0, add);
+ result = ChangeInt32ToIntPtr(result);
+ return result;
+ }
+}
+
Node* EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
Node* frame_state) {
Node* value = node->InputAt(0);
@@ -1842,6 +2049,29 @@ Node* EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(
return ChangeUint32ToSmi(value);
}
+Node* EffectControlLinearizer::LowerCheckedUint64ToInt32(Node* node,
+ Node* frame_state) {
+ Node* value = node->InputAt(0);
+ const CheckParameters& params = CheckParametersOf(node->op());
+
+ Node* check = __ Uint64LessThanOrEqual(value, __ Int64Constant(kMaxInt));
+ __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
+ frame_state);
+ return __ TruncateInt64ToInt32(value);
+}
+
+Node* EffectControlLinearizer::LowerCheckedUint64ToTaggedSigned(
+ Node* node, Node* frame_state) {
+ Node* value = node->InputAt(0);
+ const CheckParameters& params = CheckParametersOf(node->op());
+
+ Node* check =
+ __ Uint64LessThanOrEqual(value, __ Int64Constant(Smi::kMaxValue));
+ __ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
+ frame_state);
+ return ChangeInt64ToSmi(value);
+}
+
Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32(
CheckForMinusZeroMode mode, const VectorSlotPair& feedback, Node* value,
Node* frame_state) {
@@ -2065,7 +2295,8 @@ Node* EffectControlLinearizer::LowerNumberToString(Node* node) {
Operator::Properties properties = Operator::kEliminatable;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), argument,
__ NoContextConstant());
}
@@ -2521,7 +2752,8 @@ Node* EffectControlLinearizer::LowerTypeOf(Node* node) {
Operator::Properties const properties = Operator::kEliminatable;
CallDescriptor::Flags const flags = CallDescriptor::kNoAllocate;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), obj,
__ NoContextConstant());
}
@@ -2533,7 +2765,8 @@ Node* EffectControlLinearizer::LowerToBoolean(Node* node) {
Operator::Properties const properties = Operator::kEliminatable;
CallDescriptor::Flags const flags = CallDescriptor::kNoAllocate;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), obj,
__ NoContextConstant());
}
@@ -2721,7 +2954,8 @@ Node* EffectControlLinearizer::LowerNewArgumentsElements(Node* node) {
Operator::Properties const properties = node->op()->properties();
CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), frame,
length, __ SmiConstant(mapped_count), __ NoContextConstant());
}
@@ -2765,26 +2999,13 @@ Node* EffectControlLinearizer::LowerNewConsString(Node* node) {
Node* result = __ Allocate(NOT_TENURED, __ Int32Constant(ConsString::kSize));
__ StoreField(AccessBuilder::ForMap(), result, result_map);
__ StoreField(AccessBuilder::ForNameHashField(), result,
- jsgraph()->Int32Constant(Name::kEmptyHashField));
+ __ 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);
-
- Node* value_bit_field =
- __ LoadField(AccessBuilder::ForJSArrayBufferBitField(), value);
- return __ Word32Equal(
- __ Word32Equal(
- __ Word32And(value_bit_field,
- __ Int32Constant(JSArrayBuffer::WasNeutered::kMask)),
- __ Int32Constant(0)),
- __ Int32Constant(0));
-}
-
Node* EffectControlLinearizer::LowerSameValue(Node* node) {
Node* lhs = node->InputAt(0);
Node* rhs = node->InputAt(1);
@@ -2794,7 +3015,8 @@ Node* EffectControlLinearizer::LowerSameValue(Node* node) {
Operator::Properties properties = Operator::kEliminatable;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, rhs,
__ NoContextConstant());
}
@@ -2816,7 +3038,8 @@ Node* EffectControlLinearizer::LowerStringToNumber(Node* node) {
Operator::Properties properties = Operator::kEliminatable;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), string,
__ NoContextConstant());
}
@@ -2828,9 +3051,9 @@ Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
// We need a loop here to properly deal with indirect strings
// (SlicedString, ConsString and ThinString).
auto loop = __ MakeLoopLabel(MachineRepresentation::kTagged,
- MachineRepresentation::kWord32);
+ MachineType::PointerRepresentation());
auto loop_next = __ MakeLabel(MachineRepresentation::kTagged,
- MachineRepresentation::kWord32);
+ MachineType::PointerRepresentation());
auto loop_done = __ MakeLabel(MachineRepresentation::kWord32);
__ Goto(&loop, receiver, position);
__ Bind(&loop);
@@ -2897,11 +3120,11 @@ Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
__ Bind(&if_externalstring);
{
- // We need to bailout to the runtime for short external strings.
+ // We need to bailout to the runtime for uncached external strings.
__ GotoIf(__ Word32Equal(
__ Word32And(receiver_instance_type,
- __ Int32Constant(kShortExternalStringMask)),
- __ Int32Constant(kShortExternalStringTag)),
+ __ Int32Constant(kUncachedExternalStringMask)),
+ __ Int32Constant(kUncachedExternalStringTag)),
&if_runtime);
Node* receiver_data = __ LoadField(
@@ -2917,16 +3140,14 @@ Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
__ Bind(&if_onebyte);
{
- Node* result = __ Load(MachineType::Uint8(), receiver_data,
- ChangeInt32ToIntPtr(position));
+ Node* result = __ Load(MachineType::Uint8(), receiver_data, position);
__ Goto(&loop_done, result);
}
__ Bind(&if_twobyte);
{
- Node* result = __ Load(
- MachineType::Uint16(), receiver_data,
- __ Word32Shl(ChangeInt32ToIntPtr(position), __ Int32Constant(1)));
+ Node* result = __ Load(MachineType::Uint16(), receiver_data,
+ __ WordShl(position, __ IntPtrConstant(1)));
__ Goto(&loop_done, result);
}
}
@@ -2938,7 +3159,7 @@ Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
Node* receiver_parent =
__ LoadField(AccessBuilder::ForSlicedStringParent(), receiver);
__ Goto(&loop_next, receiver_parent,
- __ Int32Add(position, ChangeSmiToInt32(receiver_offset)));
+ __ IntAdd(position, ChangeSmiToIntPtr(receiver_offset)));
}
__ Bind(&if_runtime);
@@ -2948,7 +3169,7 @@ Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
Node* result = __ Call(call_descriptor, __ CEntryStubConstant(1),
- receiver, ChangeInt32ToSmi(position),
+ receiver, ChangeIntPtrToSmi(position),
__ ExternalConstant(ExternalReference::Create(id)),
__ Int32Constant(2), __ NoContextConstant());
__ Goto(&loop_done, ChangeSmiToInt32(result));
@@ -2974,7 +3195,8 @@ Node* EffectControlLinearizer::LowerStringCodePointAt(
Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), receiver,
position, __ NoContextConstant());
}
@@ -3035,9 +3257,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
__ StoreField(AccessBuilder::ForMap(), vtrue2,
__ HeapConstant(factory()->one_byte_string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
- __ IntPtrConstant(Name::kEmptyHashField));
+ __ Int32Constant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vtrue2,
- __ SmiConstant(1));
+ __ Int32Constant(1));
__ Store(
StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
vtrue2,
@@ -3059,8 +3281,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCharCode(Node* node) {
__ StoreField(AccessBuilder::ForMap(), vfalse1,
__ HeapConstant(factory()->string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
- __ IntPtrConstant(Name::kEmptyHashField));
- __ StoreField(AccessBuilder::ForStringLength(), vfalse1, __ SmiConstant(1));
+ __ Int32Constant(Name::kEmptyHashField));
+ __ StoreField(AccessBuilder::ForStringLength(), vfalse1,
+ __ Int32Constant(1));
__ Store(
StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
vfalse1,
@@ -3083,7 +3306,8 @@ Node* EffectControlLinearizer::LowerStringToLowerCaseIntl(Node* node) {
Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), receiver,
__ NoContextConstant());
}
@@ -3157,9 +3381,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
__ StoreField(AccessBuilder::ForMap(), vtrue2,
__ HeapConstant(factory()->one_byte_string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vtrue2,
- __ IntPtrConstant(Name::kEmptyHashField));
+ __ Int32Constant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vtrue2,
- __ SmiConstant(1));
+ __ Int32Constant(1));
__ Store(
StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier),
vtrue2,
@@ -3183,7 +3407,7 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
__ StoreField(AccessBuilder::ForNameHashField(), vfalse1,
__ IntPtrConstant(Name::kEmptyHashField));
__ StoreField(AccessBuilder::ForStringLength(), vfalse1,
- __ SmiConstant(1));
+ __ Int32Constant(1));
__ Store(
StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier),
vfalse1,
@@ -3228,8 +3452,9 @@ Node* EffectControlLinearizer::LowerStringFromSingleCodePoint(Node* node) {
__ StoreField(AccessBuilder::ForMap(), vfalse0,
__ HeapConstant(factory()->string_map()));
__ StoreField(AccessBuilder::ForNameHashField(), vfalse0,
- __ IntPtrConstant(Name::kEmptyHashField));
- __ StoreField(AccessBuilder::ForStringLength(), vfalse0, __ SmiConstant(2));
+ __ Int32Constant(Name::kEmptyHashField));
+ __ StoreField(AccessBuilder::ForStringLength(), vfalse0,
+ __ Int32Constant(2));
__ Store(
StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
vfalse0,
@@ -3252,7 +3477,8 @@ Node* EffectControlLinearizer::LowerStringIndexOf(Node* node) {
Operator::Properties properties = Operator::kEliminatable;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), subject,
search_string, position, __ NoContextConstant());
}
@@ -3271,7 +3497,8 @@ Node* EffectControlLinearizer::LowerStringComparison(Callable const& callable,
Operator::Properties properties = Operator::kEliminatable;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, rhs,
__ NoContextConstant());
}
@@ -3286,7 +3513,8 @@ Node* EffectControlLinearizer::LowerStringSubstring(Node* node) {
Operator::Properties properties = Operator::kEliminatable;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), receiver,
start, end, __ NoContextConstant());
}
@@ -3314,10 +3542,25 @@ Node* EffectControlLinearizer::LowerCheckFloat64Hole(Node* node,
CheckFloat64HoleParameters const& params =
CheckFloat64HoleParametersOf(node->op());
Node* value = node->InputAt(0);
- Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value),
- __ Int32Constant(kHoleNanUpper32));
- __ DeoptimizeIf(DeoptimizeReason::kHole, params.feedback(), check,
- frame_state);
+
+ auto if_nan = __ MakeDeferredLabel();
+ auto done = __ MakeLabel();
+
+ // First check whether {value} is a NaN at all...
+ __ Branch(__ Float64Equal(value, value), &done, &if_nan);
+
+ __ Bind(&if_nan);
+ {
+ // ...and only if {value} is a NaN, perform the expensive bit
+ // check. See http://crbug.com/v8/8264 for details.
+ Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value),
+ __ Int32Constant(kHoleNanUpper32));
+ __ DeoptimizeIf(DeoptimizeReason::kHole, params.feedback(), check,
+ frame_state);
+ __ Goto(&done);
+ }
+
+ __ Bind(&done);
return value;
}
@@ -3440,8 +3683,8 @@ Node* EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value) {
return result;
}
-Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
- return __ WordShl(ChangeInt32ToIntPtr(value), SmiShiftBitsConstant());
+Node* EffectControlLinearizer::ChangeIntPtrToSmi(Node* value) {
+ return __ WordShl(value, SmiShiftBitsConstant());
}
Node* EffectControlLinearizer::ChangeInt32ToIntPtr(Node* value) {
@@ -3458,6 +3701,15 @@ Node* EffectControlLinearizer::ChangeIntPtrToInt32(Node* value) {
return value;
}
+Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
+ return ChangeIntPtrToSmi(ChangeInt32ToIntPtr(value));
+}
+
+Node* EffectControlLinearizer::ChangeInt64ToSmi(Node* value) {
+ DCHECK(machine()->Is64());
+ return ChangeIntPtrToSmi(value);
+}
+
Node* EffectControlLinearizer::ChangeUint32ToUintPtr(Node* value) {
if (machine()->Is64()) {
value = __ ChangeUint32ToUint64(value);
@@ -3482,6 +3734,11 @@ Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) {
return value;
}
+Node* EffectControlLinearizer::ChangeSmiToInt64(Node* value) {
+ CHECK(machine()->Is64());
+ return ChangeSmiToIntPtr(value);
+}
+
Node* EffectControlLinearizer::ObjectIsSmi(Node* value) {
return __ WordEqual(__ WordAnd(value, __ IntPtrConstant(kSmiTagMask)),
__ IntPtrConstant(kSmiTag));
@@ -3578,7 +3835,8 @@ Node* EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node) {
Builtins::CallableFor(isolate(), Builtins::kCopyFastSmiOrObjectElements);
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
Node* result = __ Call(call_descriptor, __ HeapConstant(callable.code()),
object, __ NoContextConstant());
__ Goto(&done, result);
@@ -3614,7 +3872,8 @@ Node* EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node,
Builtins::kGrowFastSmiOrObjectElements);
CallDescriptor::Flags call_flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, call_flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), call_flags, properties);
Node* new_elements =
__ Call(call_descriptor, __ HeapConstant(callable.code()), object,
ChangeInt32ToSmi(index), __ NoContextConstant());
@@ -3830,12 +4089,6 @@ Node* EffectControlLinearizer::LowerLoadDataViewElement(Node* node) {
Node* index = node->InputAt(2);
Node* is_little_endian = node->InputAt(3);
- // On 64-bit platforms, we need to feed a Word64 index to the Load and
- // Store operators.
- if (machine()->Is64()) {
- index = __ ChangeUint32ToUint64(index);
- }
-
// We need to keep the {buffer} alive so that the GC will not release the
// ArrayBuffer (if there's any) as long as we are still operating on it.
__ Retain(buffer);
@@ -3878,12 +4131,6 @@ void EffectControlLinearizer::LowerStoreDataViewElement(Node* node) {
Node* value = node->InputAt(3);
Node* is_little_endian = node->InputAt(4);
- // On 64-bit platforms, we need to feed a Word64 index to the Load and
- // Store operators.
- if (machine()->Is64()) {
- index = __ ChangeUint32ToUint64(index);
- }
-
// We need to keep the {buffer} alive so that the GC will not release the
// ArrayBuffer (if there's any) as long as we are still operating on it.
__ Retain(buffer);
@@ -4366,7 +4613,8 @@ Node* EffectControlLinearizer::LowerConvertReceiver(Node* node) {
Callable callable = Builtins::CallableFor(isolate(), Builtins::kToObject);
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
Node* native_context = __ LoadField(
AccessBuilder::ForJSGlobalProxyNativeContext(), global_proxy);
Node* result = __ Call(call_descriptor, __ HeapConstant(callable.code()),
@@ -4401,7 +4649,8 @@ Node* EffectControlLinearizer::LowerConvertReceiver(Node* node) {
Callable callable = Builtins::CallableFor(isolate(), Builtins::kToObject);
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
Node* native_context = __ LoadField(
AccessBuilder::ForJSGlobalProxyNativeContext(), global_proxy);
Node* result = __ Call(call_descriptor, __ HeapConstant(callable.code()),
@@ -4762,7 +5011,8 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
Operator::Properties const properties = node->op()->properties();
CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), callable.descriptor(), 0, flags, properties);
+ graph()->zone(), callable.descriptor(),
+ callable.descriptor().GetStackParameterCount(), flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), table,
key, __ NoContextConstant());
}
@@ -4799,14 +5049,14 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key(
kHeapObjectTag))));
auto loop = __ MakeLoopLabel(MachineType::PointerRepresentation());
- auto done = __ MakeLabel(MachineRepresentation::kWord32);
+ auto done = __ MakeLabel(MachineType::PointerRepresentation());
__ Goto(&loop, first_entry);
__ Bind(&loop);
{
Node* entry = loop.PhiAt(0);
Node* check =
__ WordEqual(entry, __ IntPtrConstant(OrderedHashMap::kNotFound));
- __ GotoIf(check, &done, __ Int32Constant(-1));
+ __ GotoIf(check, &done, entry);
entry = __ IntAdd(
__ IntMul(entry, __ IntPtrConstant(OrderedHashMap::kEntrySize)),
number_of_buckets);
@@ -4835,10 +5085,7 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key(
&if_match, &if_notmatch);
__ Bind(&if_match);
- {
- Node* index = ChangeIntPtrToInt32(entry);
- __ Goto(&done, index);
- }
+ __ Goto(&done, entry);
__ Bind(&if_notmatch);
{