Make BitState avoid touching the bitmap unnecessarily.
Change-Id: Ifceba996ab4fd591a1a24c14e3d011559875ef35
Reviewed-on: https://code-review.googlesource.com/c/re2/+/38832
Reviewed-by: Paul Wankadia <junyer@google.com>
diff --git a/re2/bitstate.cc b/re2/bitstate.cc
index 2f5b247..f53f80d 100644
--- a/re2/bitstate.cc
+++ b/re2/bitstate.cc
@@ -153,6 +153,7 @@
cap_[prog_->inst(-id)->cap()] = p;
continue;
}
+
if (rle > 0) {
p += rle;
// Revivify job on stack.
@@ -160,23 +161,7 @@
++njob_;
}
- // Optimization: rather than push and pop,
- // code that is going to Push and continue
- // the loop simply updates (ip, p) and jumps
- // to CheckAndLoop. We have to do the
- // ShouldVisit check that Push would have,
- // but we avoid the stack manipulation.
- if (0) {
- Next:
- if (prog_->inst(id)->last())
- continue;
- id++;
-
- CheckAndLoop:
- if (!ShouldVisit(id, p))
- continue;
- }
-
+ Loop:
// Visit ip, p.
Prog::Inst* ip = prog_->inst(id);
switch (ip->opcode()) {
@@ -185,21 +170,21 @@
return false;
case kInstFail:
- continue;
+ break;
case kInstAltMatch:
if (ip->greedy(prog_)) {
// out1 is the Match instruction.
id = ip->out1();
p = end;
- goto CheckAndLoop;
+ goto Loop;
}
if (longest_) {
// ip must be non-greedy...
// out is the Match instruction.
id = ip->out();
p = end;
- goto CheckAndLoop;
+ goto Loop;
}
goto Next;
@@ -243,7 +228,20 @@
if (!ip->last())
Push(id+1, p); // try the next when we're done
id = ip->out();
- goto CheckAndLoop;
+
+ // Optimization: rather than push and pop,
+ // code that is going to Push and continue
+ // the loop simply updates (ip, p) and jumps
+ // to CheckAndLoop. We have to do the
+ // ShouldVisit check that Push would have,
+ // but we avoid the stack manipulation.
+ CheckAndLoop:
+ // id must be the head of its list, which must
+ // be the case if id-1 is the last of *its* list. :)
+ DCHECK(id == 0 || prog_->inst(id-1)->last());
+ if (ShouldVisit(id, p))
+ goto Loop;
+ break;
case kInstMatch: {
if (endmatch_ && p != end)
@@ -276,7 +274,14 @@
return true;
// Otherwise, continue on in hope of a longer match.
- goto Next;
+ // Note the absence of the ShouldVisit check here
+ // due to execution remaining in the same list.
+ Next:
+ if (!ip->last()) {
+ id++;
+ goto Loop;
+ }
+ break;
}
}
}