[regexp-builtins] avoid calling substring in @@match

In fast mode, this CL try to avoid calling substring in @@match.
For an ATOM type regexp, hold the literal string to search for before the loop
and reuse the string instead of calling substring in the loop.

Change-Id: Ice314ebf146261cf206c21cb1530a2a44d3c42ae
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1618435
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61763}
This commit is contained in:
Jun Lim 2019-05-21 14:25:26 -05:00 committed by Commit Bot
parent 4c986c625f
commit f1d016229c

View File

@ -1924,6 +1924,22 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
Variable* vars[] = {array.var_array(), array.var_length(),
array.var_capacity()};
Label loop(this, 3, vars), out(this);
// Check if the regexp is an ATOM type. If then, keep the literal string to
// search for so that we can avoid calling substring in the loop below.
TVARIABLE(BoolT, var_atom, Int32FalseConstant());
TVARIABLE(String, var_search_string, EmptyStringConstant());
if (is_fastpath) {
TNode<JSRegExp> maybe_atom_regexp = CAST(regexp);
TNode<FixedArray> data =
CAST(LoadObjectField(maybe_atom_regexp, JSRegExp::kDataOffset));
GotoIfNot(SmiEqual(CAST(LoadFixedArrayElement(data, JSRegExp::kTagIndex)),
SmiConstant(JSRegExp::ATOM)),
&loop);
var_search_string =
CAST(LoadFixedArrayElement(data, JSRegExp::kAtomPatternIndex));
var_atom = Int32TrueConstant();
}
Goto(&loop);
BIND(&loop);
@ -1938,13 +1954,22 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
RegExpPrototypeExecBodyWithoutResult(CAST(context), CAST(regexp),
string, &if_didnotmatch, true);
Node* const match_from = UnsafeLoadFixedArrayElement(
match_indices, RegExpMatchInfo::kFirstCaptureIndex);
Node* const match_to = UnsafeLoadFixedArrayElement(
match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1);
Label dosubstring(this), donotsubstring(this);
Branch(var_atom.value(), &donotsubstring, &dosubstring);
var_match.Bind(CallBuiltin(Builtins::kSubString, context, string,
match_from, match_to));
BIND(&dosubstring);
{
Node* const match_from = UnsafeLoadFixedArrayElement(
match_indices, RegExpMatchInfo::kFirstCaptureIndex);
Node* const match_to = UnsafeLoadFixedArrayElement(
match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1);
var_match.Bind(CallBuiltin(Builtins::kSubString, context, string,
match_from, match_to));
Goto(&if_didmatch);
}
BIND(&donotsubstring);
var_match.Bind(var_search_string.value());
Goto(&if_didmatch);
} else {
DCHECK(!is_fastpath);