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

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
« no previous file with comments | « runtime/vm/regexp.h ('k') | runtime/vm/regexp_assembler_bytecode.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/regexp.cc
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index 19b88c5605940ceb7a33674b3970fa2061a5911d..75ee7ebe16c6a397c8e8ba6f1053c681d1aa5273 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
- // 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);
@@ -4900,7 +4901,7 @@ RegExpEngine::CompilationResult RegExpEngine::CompileIR(
// Inserted here, instead of in Assembler, because it depends on information
// in the AST that isn't replicated in the Node structure.
static const intptr_t kMaxBacksearchLimit = 1024;
- if (is_end_anchored && !is_start_anchored &&
+ if (is_end_anchored && !is_start_anchored && !is_sticky &&
max_length < kMaxBacksearchLimit) {
macro_assembler->SetCurrentPositionFromEnd(max_length);
}
@@ -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();
« no previous file with comments | « runtime/vm/regexp.h ('k') | runtime/vm/regexp_assembler_bytecode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698