Commit 27905a33 authored by Michael Hablich (vacation)'s avatar Michael Hablich (vacation) Committed by Commit Bot

Revert "[turbofan] Speculate on bounds checks for String#charAt and String#charCodeAt."

This reverts commit db129b65.

Reason for revert: blocks roll: https://chromium-review.googlesource.com/c/chromium/src/+/873150

Original change's description:
> [turbofan] Speculate on bounds checks for String#charAt and String#charCodeAt.
> 
> With the new builtin optimization guard we can just speculatively assume
> that the index passed to String#charAt and String#charCodeAt (in optimized
> code) is going to be within the valid range for the receiver. This is
> what Crankshaft used to do, and it avoids Smi checks on the result for
> String#charCodeAt, since it can no longer return NaN.
> 
> This gives rise to further optimizations of these builtins (i.e. to
> completely avoid the tagging of char codes), and by itself already
> improves the regression test originally reported from 650ms to
> 610ms.
> 
> Bug: v8:7127, v8:7326
> Change-Id: Ia25a555c5c1a48d229c094b1ecd2487eec81e390
> Reviewed-on: https://chromium-review.googlesource.com/872850
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#50667}

TBR=yangguo@chromium.org,bmeurer@chromium.org

Change-Id: I6d393a0797cac2fdfd67487a26ac1b178bd52813
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:7127, v8:7326
Reviewed-on: https://chromium-review.googlesource.com/873355Reviewed-by: 's avatarMichael Hablich (vacation) <hablich@chromium.org>
Commit-Queue: Michael Hablich (vacation) <hablich@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50672}
parent a7c91c77
...@@ -4047,7 +4047,7 @@ Reduction JSCallReducer::ReduceArrayPrototypeShift(Node* node) { ...@@ -4047,7 +4047,7 @@ Reduction JSCallReducer::ReduceArrayPrototypeShift(Node* node) {
return Replace(value); return Replace(value);
} }
// ES section #sec-string.prototype.charat // ES6 section 21.1.3.1 String.prototype.charAt ( pos )
Reduction JSCallReducer::ReduceStringPrototypeCharAt(Node* node) { Reduction JSCallReducer::ReduceStringPrototypeCharAt(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
...@@ -4060,32 +4060,52 @@ Reduction JSCallReducer::ReduceStringPrototypeCharAt(Node* node) { ...@@ -4060,32 +4060,52 @@ Reduction JSCallReducer::ReduceStringPrototypeCharAt(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
// Ensure that the {receiver} is actually a String.
receiver = effect = graph()->NewNode(simplified()->CheckString(p.feedback()), receiver = effect = graph()->NewNode(simplified()->CheckString(p.feedback()),
receiver, effect, control); receiver, effect, control);
if (node->op()->ValueInputCount() >= 3) {
index = effect = graph()->NewNode(simplified()->CheckSmi(p.feedback()),
NodeProperties::GetValueInput(node, 2),
effect, control);
// Map -0 and NaN to 0 (as per ToInteger), and the values in
// the [-2^31,-1] range to the [2^31,2^32-1] range, which will
// be considered out-of-bounds as well, because of the maximal
// String length limit in V8.
STATIC_ASSERT(String::kMaxLength <= kMaxInt);
index = graph()->NewNode(simplified()->NumberToUint32(), index);
}
// Determine the {receiver} length. // Determine the {receiver} length.
Node* receiver_length = Node* receiver_length =
graph()->NewNode(simplified()->StringLength(), receiver); graph()->NewNode(simplified()->StringLength(), receiver);
// Check that the {index} is within range (if specified). // Check if {index} is less than {receiver} length.
if (node->op()->ValueInputCount() >= 3) { Node* check =
index = effect = graph()->NewNode(simplified()->CheckBounds(p.feedback()), graph()->NewNode(simplified()->NumberLessThan(), index, receiver_length);
NodeProperties::GetValueInput(node, 2), Node* branch =
receiver_length, effect, control); graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
}
// Return the character from the {receiver} as single character string. // Return the character from the {receiver} as single character string.
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* masked_index = graph()->NewNode(simplified()->MaskIndexWithBound(), Node* masked_index = graph()->NewNode(simplified()->MaskIndexWithBound(),
index, receiver_length); index, receiver_length);
Node* value = graph()->NewNode(simplified()->StringCharAt(), receiver,
masked_index, control); Node* vtrue = graph()->NewNode(simplified()->StringCharAt(), receiver,
masked_index, if_true);
// Return the empty string otherwise.
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* vfalse = jsgraph()->EmptyStringConstant();
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* value = graph()->NewNode(
common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control);
ReplaceWithValue(node, value, effect, control); ReplaceWithValue(node, value, effect, control);
return Replace(value); return Replace(value);
} }
// ES section #sec-string.prototype.charcodeat // ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos )
Reduction JSCallReducer::ReduceStringPrototypeCharCodeAt(Node* node) { Reduction JSCallReducer::ReduceStringPrototypeCharCodeAt(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
...@@ -4098,26 +4118,47 @@ Reduction JSCallReducer::ReduceStringPrototypeCharCodeAt(Node* node) { ...@@ -4098,26 +4118,47 @@ Reduction JSCallReducer::ReduceStringPrototypeCharCodeAt(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
// Ensure that the {receiver} is actually a String.
receiver = effect = graph()->NewNode(simplified()->CheckString(p.feedback()), receiver = effect = graph()->NewNode(simplified()->CheckString(p.feedback()),
receiver, effect, control); receiver, effect, control);
if (node->op()->ValueInputCount() >= 3) {
index = effect = graph()->NewNode(simplified()->CheckSmi(p.feedback()),
NodeProperties::GetValueInput(node, 2),
effect, control);
// Map -0 and NaN to 0 (as per ToInteger), and the values in
// the [-2^31,-1] range to the [2^31,2^32-1] range, which will
// be considered out-of-bounds as well, because of the maximal
// String length limit in V8.
STATIC_ASSERT(String::kMaxLength <= kMaxInt);
index = graph()->NewNode(simplified()->NumberToUint32(), index);
}
// Determine the {receiver} length. // Determine the {receiver} length.
Node* receiver_length = Node* receiver_length =
graph()->NewNode(simplified()->StringLength(), receiver); graph()->NewNode(simplified()->StringLength(), receiver);
// Check that the {index} is within range (if specified). // Check if {index} is less than {receiver} length.
if (node->op()->ValueInputCount() >= 3) { Node* check =
index = effect = graph()->NewNode(simplified()->CheckBounds(p.feedback()), graph()->NewNode(simplified()->NumberLessThan(), index, receiver_length);
NodeProperties::GetValueInput(node, 2), Node* branch =
receiver_length, effect, control); graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
}
// Load the character from the {receiver}. // Load the character from the {receiver}.
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* masked_index = graph()->NewNode(simplified()->MaskIndexWithBound(), Node* masked_index = graph()->NewNode(simplified()->MaskIndexWithBound(),
index, receiver_length); index, receiver_length);
Node* value = graph()->NewNode(simplified()->StringCharCodeAt(), receiver,
masked_index, control); Node* vtrue = graph()->NewNode(simplified()->StringCharCodeAt(), receiver,
masked_index, if_true);
// Return NaN otherwise.
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* vfalse = jsgraph()->NaNConstant();
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* value = graph()->NewNode(
common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control);
ReplaceWithValue(node, value, effect, control); ReplaceWithValue(node, value, effect, control);
return Replace(value); return Replace(value);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment