Skip to content

Commit 265ef0b

Browse files
sigurdschneiderCommit Bot
authored andcommitted
[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 <[email protected]> Reviewed-by: Benedikt Meurer <[email protected]> Cr-Commit-Position: refs/heads/master@{#51624}
1 parent 7071504 commit 265ef0b

2 files changed

Lines changed: 107 additions & 3 deletions

File tree

src/compiler/js-call-reducer.cc

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3327,6 +3327,8 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
33273327
simplified()->StringCodePointAt(UnicodeEncoding::UTF32), node);
33283328
case Builtins::kStringPrototypeSubstring:
33293329
return ReduceStringPrototypeSubstring(node);
3330+
case Builtins::kStringPrototypeSlice:
3331+
return ReduceStringPrototypeSlice(node);
33303332
#ifdef V8_INTL_SUPPORT
33313333
case Builtins::kStringPrototypeToLowerCaseIntl:
33323334
return ReduceStringPrototypeToLowerCaseIntl(node);
@@ -3612,8 +3614,7 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
36123614
return NoChange();
36133615
}
36143616

3615-
// ES6 String.prototype.indexOf(searchString [, position])
3616-
// #sec-string.prototype.indexof
3617+
// ES #sec-string.prototype.indexof
36173618
Reduction JSCallReducer::ReduceStringPrototypeIndexOf(Node* node) {
36183619
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
36193620
CallParameters const& p = CallParametersOf(node->op());
@@ -3652,7 +3653,7 @@ Reduction JSCallReducer::ReduceStringPrototypeIndexOf(Node* node) {
36523653
return NoChange();
36533654
}
36543655

3655-
// #sec-string.prototype.substring
3656+
// ES #sec-string.prototype.substring
36563657
Reduction JSCallReducer::ReduceStringPrototypeSubstring(Node* node) {
36573658
if (node->op()->ValueInputCount() < 3) return NoChange();
36583659
CallParameters const& p = CallParametersOf(node->op());
@@ -3715,6 +3716,108 @@ Reduction JSCallReducer::ReduceStringPrototypeSubstring(Node* node) {
37153716
return Replace(value);
37163717
}
37173718

3719+
// ES #sec-string.prototype.slice
3720+
Reduction JSCallReducer::ReduceStringPrototypeSlice(Node* node) {
3721+
if (node->op()->ValueInputCount() < 3) return NoChange();
3722+
CallParameters const& p = CallParametersOf(node->op());
3723+
if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) {
3724+
return NoChange();
3725+
}
3726+
3727+
Node* effect = NodeProperties::GetEffectInput(node);
3728+
Node* control = NodeProperties::GetControlInput(node);
3729+
Node* receiver = NodeProperties::GetValueInput(node, 1);
3730+
Node* start = NodeProperties::GetValueInput(node, 2);
3731+
Node* end = node->op()->ValueInputCount() > 3
3732+
? NodeProperties::GetValueInput(node, 3)
3733+
: jsgraph()->UndefinedConstant();
3734+
3735+
receiver = effect = graph()->NewNode(simplified()->CheckString(p.feedback()),
3736+
receiver, effect, control);
3737+
3738+
start = effect = graph()->NewNode(simplified()->CheckSmi(p.feedback()), start,
3739+
effect, control);
3740+
3741+
Node* length = graph()->NewNode(simplified()->StringLength(), receiver);
3742+
3743+
// Replace {end} argument with {length} if it is undefined.
3744+
{
3745+
Node* check = graph()->NewNode(simplified()->ReferenceEqual(), end,
3746+
jsgraph()->UndefinedConstant());
3747+
3748+
Node* branch =
3749+
graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
3750+
3751+
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
3752+
Node* etrue = effect;
3753+
Node* vtrue = length;
3754+
3755+
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
3756+
Node* efalse = effect;
3757+
Node* vfalse = efalse = graph()->NewNode(
3758+
simplified()->CheckSmi(p.feedback()), end, efalse, if_false);
3759+
3760+
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
3761+
effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
3762+
end = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
3763+
vtrue, vfalse, control);
3764+
}
3765+
3766+
Node* from = graph()->NewNode(
3767+
common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse),
3768+
graph()->NewNode(simplified()->NumberLessThan(), start,
3769+
jsgraph()->ZeroConstant()),
3770+
graph()->NewNode(
3771+
simplified()->NumberMax(),
3772+
graph()->NewNode(simplified()->NumberAdd(), length, start),
3773+
jsgraph()->ZeroConstant()),
3774+
graph()->NewNode(simplified()->NumberMin(), start, length));
3775+
// {from} is always in non-negative Smi range, but our typer cannot
3776+
// figure that out yet.
3777+
from = effect = graph()->NewNode(common()->TypeGuard(Type::UnsignedSmall()),
3778+
from, effect, control);
3779+
3780+
Node* to = graph()->NewNode(
3781+
common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse),
3782+
graph()->NewNode(simplified()->NumberLessThan(), end,
3783+
jsgraph()->ZeroConstant()),
3784+
graph()->NewNode(simplified()->NumberMax(),
3785+
graph()->NewNode(simplified()->NumberAdd(), length, end),
3786+
jsgraph()->ZeroConstant()),
3787+
graph()->NewNode(simplified()->NumberMin(), end, length));
3788+
// {to} is always in non-negative Smi range, but our typer cannot
3789+
// figure that out yet.
3790+
to = effect = graph()->NewNode(common()->TypeGuard(Type::UnsignedSmall()), to,
3791+
effect, control);
3792+
3793+
Node* result_string = nullptr;
3794+
// Return empty string if {from} is smaller than {to}.
3795+
{
3796+
Node* check = graph()->NewNode(simplified()->NumberLessThan(), from, to);
3797+
3798+
Node* branch =
3799+
graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
3800+
3801+
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
3802+
Node* etrue = effect;
3803+
Node* vtrue = etrue = graph()->NewNode(simplified()->StringSubstring(),
3804+
receiver, from, to, etrue, if_true);
3805+
3806+
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
3807+
Node* efalse = effect;
3808+
Node* vfalse = jsgraph()->EmptyStringConstant();
3809+
3810+
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
3811+
effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
3812+
result_string =
3813+
graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
3814+
vtrue, vfalse, control);
3815+
}
3816+
3817+
ReplaceWithValue(node, result_string, effect, control);
3818+
return Replace(result_string);
3819+
}
3820+
37183821
Reduction JSCallReducer::ReduceJSConstructWithArrayLike(Node* node) {
37193822
DCHECK_EQ(IrOpcode::kJSConstructWithArrayLike, node->opcode());
37203823
CallFrequency frequency = CallFrequencyOf(node->op());

src/compiler/js-call-reducer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
100100
Reduction ReduceReturnReceiver(Node* node);
101101
Reduction ReduceStringPrototypeIndexOf(Node* node);
102102
Reduction ReduceStringPrototypeSubstring(Node* node);
103+
Reduction ReduceStringPrototypeSlice(Node* node);
103104
Reduction ReduceStringPrototypeStringAt(
104105
const Operator* string_access_operator, Node* node);
105106

0 commit comments

Comments
 (0)