Commit b44f8205 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Move String.indexOf inlining to call reducer

This also adds speculative checks asserting that all arguments
are of the right types; each check disables speculation if it
fails.

Bug: v8:7127, v8:6270
Change-Id: Ifcb8bc509b86c712f0fab50ef1caee0c3a289e86
Reviewed-on: https://chromium-review.googlesource.com/832449
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50289}
parent 5950c007
......@@ -2531,34 +2531,6 @@ Reduction JSBuiltinReducer::ReduceStringConcat(Node* node) {
return NoChange();
}
// ES6 String.prototype.indexOf(searchString [, position])
// #sec-string.prototype.indexof
Reduction JSBuiltinReducer::ReduceStringIndexOf(Node* node) {
// We need at least target, receiver and search_string parameters.
if (node->op()->ValueInputCount() >= 3) {
Node* search_string = NodeProperties::GetValueInput(node, 2);
Type* search_string_type = NodeProperties::GetType(search_string);
Node* position = (node->op()->ValueInputCount() >= 4)
? NodeProperties::GetValueInput(node, 3)
: jsgraph()->ZeroConstant();
Type* position_type = NodeProperties::GetType(position);
if (search_string_type->Is(Type::String()) &&
position_type->Is(Type::SignedSmall())) {
if (Node* receiver = GetStringWitness(node)) {
RelaxEffectsAndControls(node);
node->ReplaceInput(0, receiver);
node->ReplaceInput(1, search_string);
node->ReplaceInput(2, position);
node->TrimInputCount(3);
NodeProperties::ChangeOp(node, simplified()->StringIndexOf());
return Changed(node);
}
}
}
return NoChange();
}
Reduction JSBuiltinReducer::ReduceStringIterator(Node* node) {
if (Node* receiver = GetStringWitness(node)) {
Node* effect = NodeProperties::GetEffectInput(node);
......@@ -3041,8 +3013,6 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
return ReduceStringCharCodeAt(node);
case kStringConcat:
return ReduceStringConcat(node);
case kStringIndexOf:
return ReduceStringIndexOf(node);
case kStringIterator:
return ReduceStringIterator(node);
case kStringIteratorNext:
......
......@@ -114,7 +114,6 @@ class V8_EXPORT_PRIVATE JSBuiltinReducer final
Reduction ReduceStringCharCodeAt(Node* node);
Reduction ReduceStringConcat(Node* node);
Reduction ReduceStringFromCharCode(Node* node);
Reduction ReduceStringIndexOf(Node* node);
Reduction ReduceStringIterator(Node* node);
Reduction ReduceStringIteratorNext(Node* node);
Reduction ReduceStringSlice(Node* node);
......
......@@ -2623,6 +2623,8 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
return ReduceArrayFind(ArrayFindVariant::kFindIndex, function, node);
case Builtins::kReturnReceiver:
return ReduceReturnReceiver(node);
case Builtins::kStringPrototypeIndexOf:
return ReduceStringPrototypeIndexOf(function, node);
default:
break;
}
......@@ -2977,6 +2979,47 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
return NoChange();
}
// ES6 String.prototype.indexOf(searchString [, position])
// #sec-string.prototype.indexof
Reduction JSCallReducer::ReduceStringPrototypeIndexOf(
Handle<JSFunction> function, Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op());
if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) {
return NoChange();
}
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
if (node->op()->ValueInputCount() >= 3) {
Node* receiver = NodeProperties::GetValueInput(node, 1);
Node* new_receiver = effect = graph()->NewNode(
simplified()->CheckString(p.feedback()), receiver, effect, control);
Node* search_string = NodeProperties::GetValueInput(node, 2);
Node* new_search_string = effect =
graph()->NewNode(simplified()->CheckString(p.feedback()), search_string,
effect, control);
Node* new_position = jsgraph()->ZeroConstant();
if (node->op()->ValueInputCount() >= 4) {
Node* position = NodeProperties::GetValueInput(node, 3);
new_position = effect = graph()->NewNode(
simplified()->CheckSmi(p.feedback()), position, effect, control);
}
NodeProperties::ReplaceEffectInput(node, effect);
RelaxEffectsAndControls(node);
node->ReplaceInput(0, new_receiver);
node->ReplaceInput(1, new_search_string);
node->ReplaceInput(2, new_position);
node->TrimInputCount(3);
NodeProperties::ChangeOp(node, simplified()->StringIndexOf());
return Changed(node);
}
return NoChange();
}
Reduction JSCallReducer::ReduceJSConstructWithArrayLike(Node* node) {
DCHECK_EQ(IrOpcode::kJSConstructWithArrayLike, node->opcode());
CallFrequency frequency = CallFrequencyOf(node->op());
......
......@@ -89,6 +89,8 @@ class JSCallReducer final : public AdvancedReducer {
Reduction ReduceJSCallWithArrayLike(Node* node);
Reduction ReduceJSCallWithSpread(Node* node);
Reduction ReduceReturnReceiver(Node* node);
Reduction ReduceStringPrototypeIndexOf(Handle<JSFunction> function,
Node* node);
Reduction ReduceSoftDeoptimize(Node* node, DeoptimizeReason reason);
......
......@@ -1952,7 +1952,9 @@ Type* Typer::Visitor::TypeStringFromCodePoint(Node* node) {
return TypeUnaryOp(node, StringFromCodePointTyper);
}
Type* Typer::Visitor::TypeStringIndexOf(Node* node) { UNREACHABLE(); }
Type* Typer::Visitor::TypeStringIndexOf(Node* node) {
return Type::Range(-1.0, String::kMaxLength, zone());
}
Type* Typer::Visitor::TypeStringLength(Node* node) {
return typer_->cache_.kStringLengthType;
......
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