Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1291)

Unified Diff: runtime/vm/regexp.cc

Issue 2510783002: VM: Optimize RegExp.matchAsPrefix(...) by generating a sticky RegExp specialization. (Closed)
Patch Set: Done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/regexp.cc
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index 19b88c5605940ceb7a33674b3970fa2061a5911d..7f8890925c8fd56e1c7a28411ea679c6bf4871e1 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -4824,6 +4824,7 @@ RegExpEngine::CompilationResult RegExpEngine::CompileIR(
const Function& function = parsed_function->function();
const intptr_t specialization_cid = function.string_specialization_cid();
+ const intptr_t is_sticky = function.is_sticky_specialization();
const bool is_one_byte = (specialization_cid == kOneByteStringCid ||
specialization_cid == kExternalOneByteStringCid);
RegExp& regexp = RegExp::Handle(zone, function.regexp());
@@ -4851,12 +4852,12 @@ RegExpEngine::CompilationResult RegExpEngine::CompileIR(
RegExpCapture::ToNode(data->tree, 0, &compiler, compiler.accept());
RegExpNode* node = captured_body;
- bool is_end_anchored = data->tree->IsAnchoredAtEnd();
- bool is_start_anchored = data->tree->IsAnchoredAtStart();
+ const bool is_end_anchored = data->tree->IsAnchoredAtEnd();
+ const bool is_start_anchored = data->tree->IsAnchoredAtStart();
intptr_t max_length = data->tree->max_match();
- if (!is_start_anchored) {
+ if (!is_start_anchored && !is_sticky) {
// Add a .*? at the beginning, outside the body capture, unless
rmacnak 2016/11/17 00:49:52 Not sure I see why this property is called sticky,
erikcorry 2016/11/17 13:56:17 From es-discuss (!): I believe the y actually com
- // this expression is anchored at the beginning.
+ // this expression is anchored at the beginning or is sticky.
RegExpNode* loop_node = RegExpQuantifier::ToNode(
0, RegExpTree::kInfinity, false, new (zone) RegExpCharacterClass('*'),
&compiler, captured_body, data->contains_anchor);
@@ -4927,6 +4928,7 @@ RegExpEngine::CompilationResult RegExpEngine::CompileBytecode(
RegExpCompileData* data,
const RegExp& regexp,
bool is_one_byte,
+ bool is_sticky,
Zone* zone) {
ASSERT(FLAG_interpret_irregexp);
const String& pattern = String::Handle(zone, regexp.pattern());
@@ -4956,7 +4958,7 @@ RegExpEngine::CompilationResult RegExpEngine::CompileBytecode(
bool is_end_anchored = data->tree->IsAnchoredAtEnd();
bool is_start_anchored = data->tree->IsAnchoredAtStart();
intptr_t max_length = data->tree->max_match();
- if (!is_start_anchored) {
+ if (!is_start_anchored && !is_sticky) {
// Add a .*? at the beginning, outside the body capture, unless
// this expression is anchored at the beginning.
RegExpNode* loop_node = RegExpQuantifier::ToNode(
@@ -5029,6 +5031,7 @@ static void CreateSpecializedFunction(Thread* thread,
Zone* zone,
const RegExp& regexp,
intptr_t specialization_cid,
+ bool sticky,
const Object& owner) {
const intptr_t kParamCount = RegExpMacroAssembler::kParamCount;
@@ -5063,9 +5066,9 @@ static void CreateSpecializedFunction(Thread* thread,
fn.set_result_type(Type::Handle(zone, Type::ArrayType()));
// Cache the result.
- regexp.set_function(specialization_cid, fn);
+ regexp.set_function(specialization_cid, sticky, fn);
- fn.SetRegExpData(regexp, specialization_cid);
+ fn.SetRegExpData(regexp, specialization_cid, sticky);
fn.set_is_debuggable(false);
// The function is compiled lazily during the first call.
@@ -5098,12 +5101,13 @@ RawRegExp* RegExpEngine::CreateRegExp(Thread* thread,
const Class& owner =
Class::Handle(zone, lib.LookupClass(Symbols::RegExp()));
- CreateSpecializedFunction(thread, zone, regexp, kOneByteStringCid, owner);
- CreateSpecializedFunction(thread, zone, regexp, kTwoByteStringCid, owner);
- CreateSpecializedFunction(thread, zone, regexp, kExternalOneByteStringCid,
- owner);
- CreateSpecializedFunction(thread, zone, regexp, kExternalTwoByteStringCid,
- owner);
+ for (intptr_t cid = kOneByteStringCid; cid <= kExternalTwoByteStringCid;
+ cid++) {
+ CreateSpecializedFunction(thread, zone, regexp, cid, /*sticky=*/false,
+ owner);
+ CreateSpecializedFunction(thread, zone, regexp, cid, /*sticky=*/true,
+ owner);
+ }
}
return regexp.raw();

Powered by Google App Engine
This is Rietveld 408576698