[turbofan] Inline String.prototype.concat with PlainPrimitive parameter.
When we hit a call to String.prototype.concat builtin, where we can infer that the receiver is a String and there's exactly one parameter, which is of type PlainPrimitive, then we can reduce that to a call to the StringAddStub instead, optionally converting the non-String - but PlainPrimitive - parameter to a String. BUG=v8:5267 R=jarin@chromium.org Review-Url: https://codereview.chromium.org/2758383002 Cr-Commit-Position: refs/heads/master@{#43957}
This commit is contained in:
parent
de04df7412
commit
f08c3fd324
@ -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:
|
||||
|
@ -103,6 +103,7 @@ class V8_EXPORT_PRIVATE JSBuiltinReducer final
|
||||
Reduction ReduceObjectCreate(Node* node);
|
||||
Reduction ReduceStringCharAt(Node* node);
|
||||
Reduction ReduceStringCharCodeAt(Node* node);
|
||||
Reduction ReduceStringConcat(Node* node);
|
||||
Reduction ReduceStringFromCharCode(Node* node);
|
||||
Reduction ReduceStringIndexOf(Node* node);
|
||||
Reduction ReduceStringIterator(Node* node);
|
||||
|
Loading…
Reference in New Issue
Block a user