Commit 265ef0b6 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Lower String.p.slice to StringSubstring operator

Bug: v8:7250, v8:7340
Change-Id: Ice54ee684f77a575d7479f4e7d4fdb55e7427da9
Reviewed-on: https://chromium-review.googlesource.com/919164
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51624}
parent 7071504d
......@@ -3327,6 +3327,8 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
simplified()->StringCodePointAt(UnicodeEncoding::UTF32), node);
case Builtins::kStringPrototypeSubstring:
return ReduceStringPrototypeSubstring(node);
case Builtins::kStringPrototypeSlice:
return ReduceStringPrototypeSlice(node);
#ifdef V8_INTL_SUPPORT
case Builtins::kStringPrototypeToLowerCaseIntl:
return ReduceStringPrototypeToLowerCaseIntl(node);
......@@ -3612,8 +3614,7 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
return NoChange();
}
// ES6 String.prototype.indexOf(searchString [, position])
// #sec-string.prototype.indexof
// ES #sec-string.prototype.indexof
Reduction JSCallReducer::ReduceStringPrototypeIndexOf(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op());
......@@ -3652,7 +3653,7 @@ Reduction JSCallReducer::ReduceStringPrototypeIndexOf(Node* node) {
return NoChange();
}
// #sec-string.prototype.substring
// ES #sec-string.prototype.substring
Reduction JSCallReducer::ReduceStringPrototypeSubstring(Node* node) {
if (node->op()->ValueInputCount() < 3) return NoChange();
CallParameters const& p = CallParametersOf(node->op());
......@@ -3715,6 +3716,108 @@ Reduction JSCallReducer::ReduceStringPrototypeSubstring(Node* node) {
return Replace(value);
}
// ES #sec-string.prototype.slice
Reduction JSCallReducer::ReduceStringPrototypeSlice(Node* node) {
if (node->op()->ValueInputCount() < 3) return NoChange();
CallParameters const& p = CallParametersOf(node->op());
if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) {
return NoChange();
}
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* receiver = NodeProperties::GetValueInput(node, 1);
Node* start = NodeProperties::GetValueInput(node, 2);
Node* end = node->op()->ValueInputCount() > 3
? NodeProperties::GetValueInput(node, 3)
: jsgraph()->UndefinedConstant();
receiver = effect = graph()->NewNode(simplified()->CheckString(p.feedback()),
receiver, effect, control);
start = effect = graph()->NewNode(simplified()->CheckSmi(p.feedback()), start,
effect, control);
Node* length = graph()->NewNode(simplified()->StringLength(), receiver);
// Replace {end} argument with {length} if it is undefined.
{
Node* check = graph()->NewNode(simplified()->ReferenceEqual(), end,
jsgraph()->UndefinedConstant());
Node* branch =
graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* etrue = effect;
Node* vtrue = length;
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* efalse = effect;
Node* vfalse = efalse = graph()->NewNode(
simplified()->CheckSmi(p.feedback()), end, efalse, if_false);
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
end = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
vtrue, vfalse, control);
}
Node* from = graph()->NewNode(
common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse),
graph()->NewNode(simplified()->NumberLessThan(), start,
jsgraph()->ZeroConstant()),
graph()->NewNode(
simplified()->NumberMax(),
graph()->NewNode(simplified()->NumberAdd(), length, start),
jsgraph()->ZeroConstant()),
graph()->NewNode(simplified()->NumberMin(), start, length));
// {from} is always in non-negative Smi range, but our typer cannot
// figure that out yet.
from = effect = graph()->NewNode(common()->TypeGuard(Type::UnsignedSmall()),
from, effect, control);
Node* to = graph()->NewNode(
common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse),
graph()->NewNode(simplified()->NumberLessThan(), end,
jsgraph()->ZeroConstant()),
graph()->NewNode(simplified()->NumberMax(),
graph()->NewNode(simplified()->NumberAdd(), length, end),
jsgraph()->ZeroConstant()),
graph()->NewNode(simplified()->NumberMin(), end, length));
// {to} is always in non-negative Smi range, but our typer cannot
// figure that out yet.
to = effect = graph()->NewNode(common()->TypeGuard(Type::UnsignedSmall()), to,
effect, control);
Node* result_string = nullptr;
// Return empty string if {from} is smaller than {to}.
{
Node* check = graph()->NewNode(simplified()->NumberLessThan(), from, to);
Node* branch =
graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* etrue = effect;
Node* vtrue = etrue = graph()->NewNode(simplified()->StringSubstring(),
receiver, from, to, etrue, if_true);
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* efalse = effect;
Node* vfalse = jsgraph()->EmptyStringConstant();
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
result_string =
graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
vtrue, vfalse, control);
}
ReplaceWithValue(node, result_string, effect, control);
return Replace(result_string);
}
Reduction JSCallReducer::ReduceJSConstructWithArrayLike(Node* node) {
DCHECK_EQ(IrOpcode::kJSConstructWithArrayLike, node->opcode());
CallFrequency frequency = CallFrequencyOf(node->op());
......
......@@ -100,6 +100,7 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
Reduction ReduceReturnReceiver(Node* node);
Reduction ReduceStringPrototypeIndexOf(Node* node);
Reduction ReduceStringPrototypeSubstring(Node* node);
Reduction ReduceStringPrototypeSlice(Node* node);
Reduction ReduceStringPrototypeStringAt(
const Operator* string_access_operator, Node* node);
......
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