Index: src/compiler/js-builtin-reducer.cc |
diff --git a/src/compiler/js-builtin-reducer.cc b/src/compiler/js-builtin-reducer.cc |
index 49a73f3e856f92f68b7490a51f6b005571f69523..2b86edf4c4171cae4fd9395e230e03aee2f0fb1e 100644 |
--- a/src/compiler/js-builtin-reducer.cc |
+++ b/src/compiler/js-builtin-reducer.cc |
@@ -1807,6 +1807,37 @@ Reduction JSBuiltinReducer::ReduceStringCharCodeAt(Node* node) { |
return NoChange(); |
} |
+// ES6 String.prototype.concat(...args) |
+// #sec-string.prototype.concat |
+Reduction JSBuiltinReducer::ReduceStringConcat(Node* node) { |
+ if (Node* receiver = GetStringWitness(node)) { |
+ JSCallReduction r(node); |
+ if (r.InputsMatchOne(Type::PlainPrimitive())) { |
+ // String.prototype.concat(lhs:string, rhs:plain-primitive) |
+ // -> Call[StringAddStub](lhs, rhs) |
+ StringAddFlags flags = r.InputsMatchOne(Type::String()) |
+ ? STRING_ADD_CHECK_NONE |
+ : STRING_ADD_CONVERT_RIGHT; |
+ // TODO(turbofan): Massage the FrameState of the {node} here once we |
+ // have an artificial builtin frame type, so that it looks like the |
+ // exception from StringAdd overflow came from String.prototype.concat |
+ // builtin instead of the calling function. |
+ Callable const callable = |
+ CodeFactory::StringAdd(isolate(), flags, NOT_TENURED); |
+ CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
+ isolate(), graph()->zone(), callable.descriptor(), 0, |
+ CallDescriptor::kNeedsFrameState, |
+ Operator::kNoDeopt | Operator::kNoWrite); |
+ node->ReplaceInput(0, jsgraph()->HeapConstant(callable.code())); |
+ node->ReplaceInput(1, receiver); |
+ NodeProperties::ChangeOp(node, common()->Call(desc)); |
+ return Changed(node); |
+ } |
+ } |
+ |
+ return NoChange(); |
+} |
+ |
// ES6 String.prototype.indexOf(searchString [, position]) |
// #sec-string.prototype.indexof |
Reduction JSBuiltinReducer::ReduceStringIndexOf(Node* node) { |
@@ -2208,6 +2239,8 @@ Reduction JSBuiltinReducer::Reduce(Node* node) { |
return ReduceStringCharAt(node); |
case kStringCharCodeAt: |
return ReduceStringCharCodeAt(node); |
+ case kStringConcat: |
+ return ReduceStringConcat(node); |
case kStringIndexOf: |
return ReduceStringIndexOf(node); |
case kStringIterator: |