Chromium Code Reviews

Unified Diff: src/compiler/js-builtin-reducer.cc

Issue 2638393002: [builtins] Add String.prototype.indexOf fast path in TF (Closed)
Patch Set: update comments Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Index: src/compiler/js-builtin-reducer.cc
diff --git a/src/compiler/js-builtin-reducer.cc b/src/compiler/js-builtin-reducer.cc
index d782340baf81bdb1fa9dc9afbd1d52bb537f52b6..76eb0e9f92ebd896ea8e0c62285069db504e7907 100644
--- a/src/compiler/js-builtin-reducer.cc
+++ b/src/compiler/js-builtin-reducer.cc
@@ -5,9 +5,11 @@
#include "src/compiler/js-builtin-reducer.h"
#include "src/base/bits.h"
+#include "src/code-factory.h"
#include "src/compilation-dependencies.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/js-graph.h"
+#include "src/compiler/linkage.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/simplified-operator.h"
@@ -1610,18 +1612,17 @@ Reduction JSBuiltinReducer::ReduceStringFromCharCode(Node* node) {
}
namespace {
-
-Node* GetStringWitness(Node* node) {
- Node* receiver = NodeProperties::GetValueInput(node, 1);
- Type* receiver_type = NodeProperties::GetType(receiver);
+Node* GetInputStringWitness(Node* node, int input_index) {
+ Node* input = NodeProperties::GetValueInput(node, input_index);
+ Type* input_type = NodeProperties::GetType(input);
Node* effect = NodeProperties::GetEffectInput(node);
- if (receiver_type->Is(Type::String())) return receiver;
+ if (input_type->Is(Type::String())) return input;
// Check if the {node} is dominated by a CheckString renaming for
- // it's {receiver}, and if so use that renaming as {receiver} for
+ // it's {input}, and if so use that renaming as {input} for
// the lowering below.
for (Node* dominator = effect;;) {
if (dominator->opcode() == IrOpcode::kCheckString &&
- IsSame(dominator->InputAt(0), receiver)) {
+ IsSame(dominator->InputAt(0), input)) {
return dominator;
}
if (dominator->op()->EffectInputCount() != 1) {
@@ -1632,6 +1633,7 @@ Node* GetStringWitness(Node* node) {
}
}
+Node* GetStringWitness(Node* node) { return GetInputStringWitness(node, 1); }
} // namespace
// ES6 section 21.1.3.1 String.prototype.charAt ( pos )
@@ -1742,6 +1744,34 @@ Reduction JSBuiltinReducer::ReduceStringCharCodeAt(Node* node) {
return NoChange();
}
+// ES6 String.prototype.indexOf(searchString [, position])
+// #sec-string.prototype.indexof
+Reduction JSBuiltinReducer::ReduceStringIndexOf(Node* node) {
+ int arg_count = node->op()->ValueInputCount();
+ if (arg_count != 3 && arg_count != 4) return NoChange();
+ Node* receiver;
+ if (!(receiver = GetStringWitness(node))) return NoChange();
+ Node* search_string;
+ if (!(search_string = GetInputStringWitness(node, 2))) return NoChange();
Benedikt Meurer 2017/01/18 18:10:40 I'm not convinced this is beneficial; can we limit
Camillo Bruni 2017/01/24 15:51:43 ack. replaced by simple type check,
+ // Replace the current JSFunctionCall to String.prototype.indexOf with a
+ // simple Call to the unchecked StringIndexOf builtin.
+ Callable callable = CodeFactory::StringIndexOf(isolate());
+ const CallInterfaceDescriptor& descriptor = callable.descriptor();
+ CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
Benedikt Meurer 2017/01/18 18:10:40 StringIndexOf builtin cannot deopt, so you don't n
Camillo Bruni 2017/01/24 15:51:43 done.
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ isolate(), graph()->zone(), descriptor,
+ descriptor.GetStackParameterCount(), flags, node->op()->properties());
Benedikt Meurer 2017/01/18 18:10:40 Also it doesn't have a side effect, so it should u
Camillo Bruni 2017/01/24 15:51:43 done.
+ Node* stub_code = jsgraph()->HeapConstant(callable.code());
+ // Replace the JSFunction from the JSFunctionCall node with the CodeStub.
+ node->ReplaceInput(0, stub_code);
+ if (arg_count == 3) {
+ // Insert the missing position argument.
+ node->InsertInput(graph()->zone(), 3, jsgraph()->ZeroConstant());
+ }
+ NodeProperties::ChangeOp(node, common()->Call(desc));
+ return Changed(node);
+}
+
Reduction JSBuiltinReducer::ReduceStringIterator(Node* node) {
if (Node* receiver = GetStringWitness(node)) {
Node* effect = NodeProperties::GetEffectInput(node);
@@ -2112,6 +2142,8 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
return ReduceStringCharAt(node);
case kStringCharCodeAt:
return ReduceStringCharCodeAt(node);
+ case kStringIndexOf:
+ return ReduceStringIndexOf(node);
case kStringIterator:
return ReduceStringIterator(node);
case kStringIteratorNext:

Powered by Google App Engine