Commit f1d01622 authored by Jun Lim's avatar Jun Lim Committed by Commit Bot

[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/+/1618435Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61763}
parent 4c986c62
...@@ -1924,6 +1924,22 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, ...@@ -1924,6 +1924,22 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
Variable* vars[] = {array.var_array(), array.var_length(), Variable* vars[] = {array.var_array(), array.var_length(),
array.var_capacity()}; array.var_capacity()};
Label loop(this, 3, vars), out(this); 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); Goto(&loop);
BIND(&loop); BIND(&loop);
...@@ -1938,14 +1954,23 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, ...@@ -1938,14 +1954,23 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
RegExpPrototypeExecBodyWithoutResult(CAST(context), CAST(regexp), RegExpPrototypeExecBodyWithoutResult(CAST(context), CAST(regexp),
string, &if_didnotmatch, true); string, &if_didnotmatch, true);
Label dosubstring(this), donotsubstring(this);
Branch(var_atom.value(), &donotsubstring, &dosubstring);
BIND(&dosubstring);
{
Node* const match_from = UnsafeLoadFixedArrayElement( Node* const match_from = UnsafeLoadFixedArrayElement(
match_indices, RegExpMatchInfo::kFirstCaptureIndex); match_indices, RegExpMatchInfo::kFirstCaptureIndex);
Node* const match_to = UnsafeLoadFixedArrayElement( Node* const match_to = UnsafeLoadFixedArrayElement(
match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1);
var_match.Bind(CallBuiltin(Builtins::kSubString, context, string, var_match.Bind(CallBuiltin(Builtins::kSubString, context, string,
match_from, match_to)); match_from, match_to));
Goto(&if_didmatch); Goto(&if_didmatch);
}
BIND(&donotsubstring);
var_match.Bind(var_search_string.value());
Goto(&if_didmatch);
} else { } else {
DCHECK(!is_fastpath); DCHECK(!is_fastpath);
Node* const result = RegExpExec(context, regexp, string); Node* const result = RegExpExec(context, regexp, string);
......
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