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

Unified Diff: src/jsregexp.cc

Issue 565043003: Clean up regexp code gen a little (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 months 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 | « src/jsregexp.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/jsregexp.cc
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 0d9f83af37ba48b7ee7b2cf24e81e3ed34d151ab..ab2fb085db94a0c1f54c333bf148f034a742269a 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -2437,6 +2437,7 @@ bool QuickCheckDetails::Rationalize(bool asc) {
bool RegExpNode::EmitQuickCheck(RegExpCompiler* compiler,
+ Trace* bounds_check_trace,
Trace* trace,
bool preload_has_checked_bounds,
Label* on_possible_success,
@@ -2455,8 +2456,13 @@ bool RegExpNode::EmitQuickCheck(RegExpCompiler* compiler,
RegExpMacroAssembler* assembler = compiler->macro_assembler();
if (trace->characters_preloaded() != details->characters()) {
+ DCHECK(trace->cp_offset() == bounds_check_trace->cp_offset());
+ // We are attempting to preload the minimum number of characters
+ // any choice would eat, so if the bounds check fails, then none of the
+ // choices can succeed, so we can just immediately backtrack, rather
+ // than go to the next choice.
assembler->LoadCurrentCharacter(trace->cp_offset(),
- trace->backtrack(),
+ bounds_check_trace->backtrack(),
!preload_has_checked_bounds,
details->characters());
}
@@ -3855,10 +3861,12 @@ void BoyerMooreLookahead::EmitSkipInstructions(RegExpMacroAssembler* masm) {
* \ F V
* \-----S4
*
- * For greedy loops we reverse our expectation and expect to match rather
- * than fail. Therefore we want the loop code to look like this (U is the
- * unwind code that steps back in the greedy loop). The following alternatives
- * look the same as above.
+ * For greedy loops we push the current position, then generate the code that
+ * eats the input specially in EmitGreedyLoop. The other choice (the
+ * continuation) is generated by the normal code in EmitChoices, and steps back
+ * in the input to the starting position when it fails to match. The loop code
+ * looks like this (U is the unwind code that steps back in the greedy loop).
+ *
* _____
* / \
* V |
@@ -3867,20 +3875,14 @@ void BoyerMooreLookahead::EmitSkipInstructions(RegExpMacroAssembler* masm) {
* / |S |
* F/ \_____/
* /
- * |<-----------
- * | \
- * V \
- * Q2 ---> S2 \
- * | S / |
- * F| / |
- * | F/ |
- * | / |
- * | R |
- * | / |
- * F VL |
- * <------U |
- * back |S |
- * \______________/
+ * |<-----
+ * | \
+ * V |S
+ * Q2 ---> U----->backtrack
+ * | F /
+ * S| /
+ * V F /
+ * S2--/
*/
GreedyLoopState::GreedyLoopState(bool not_at_start) {
@@ -3966,7 +3968,6 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
&alt_gens,
0,
trace,
- false, // Not greedy loop.
&preload);
}
@@ -3974,7 +3975,7 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
// the quick check was inlined. We can recognize these because the associated
// label was bound.
int new_flush_budget = trace->flush_budget() / choice_count;
- for (int i = 0; i < choice_count - 1; i++) {
+ for (int i = 0; i < choice_count; i++) {
AlternativeGeneration* alt_gen = alt_gens.at(i);
Trace new_trace(*trace);
// If there are actions to be flushed we have to limit how many times
@@ -3983,12 +3984,14 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
if (new_trace.actions() != NULL) {
new_trace.set_flush_budget(new_flush_budget);
}
+ bool next_expects_preload =
+ i == choice_count - 1 ? false : alt_gens.at(i + 1)->expects_preload;
EmitOutOfLineContinuation(compiler,
&new_trace,
alternatives_->at(i),
alt_gen,
preload.preload_characters_,
- alt_gens.at(i + 1)->expects_preload);
+ next_expects_preload);
}
}
@@ -4029,7 +4032,6 @@ Trace* ChoiceNode::EmitGreedyLoop(RegExpCompiler* compiler,
alt_gens,
1,
new_trace,
- true, // Is greedy loop.
preload);
macro_assembler->Bind(greedy_loop_state->label());
@@ -4096,7 +4098,6 @@ void ChoiceNode::EmitChoices(RegExpCompiler* compiler,
AlternativeGenerationList* alt_gens,
int first_choice,
Trace* trace,
- bool is_greedy_loop,
PreloadState* preload) {
RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
SetUpPreLoad(compiler, trace, preload);
@@ -4109,6 +4110,7 @@ void ChoiceNode::EmitChoices(RegExpCompiler* compiler,
for (int i = first_choice; i < choice_count; i++) {
bool is_last = i == choice_count - 1;
+ bool fall_through_on_failure = !is_last;
GuardedAlternative alternative = alternatives_->at(i);
AlternativeGeneration* alt_gen = alt_gens->at(i);
alt_gen->quick_check_details.set_characters(preload->preload_characters_);
@@ -4123,23 +4125,26 @@ void ChoiceNode::EmitChoices(RegExpCompiler* compiler,
}
new_trace.quick_check_performed()->Clear();
if (not_at_start_) new_trace.set_at_start(Trace::FALSE_VALUE);
+ if (!is_last) {
+ new_trace.set_backtrack(&alt_gen->after);
+ }
alt_gen->expects_preload = preload->preload_is_current_;
bool generate_full_check_inline = false;
if (FLAG_regexp_optimization &&
try_to_emit_quick_check_for_alternative(i == 0) &&
alternative.node()->EmitQuickCheck(compiler,
+ trace,
&new_trace,
preload->preload_has_checked_bounds_,
&alt_gen->possible_success,
&alt_gen->quick_check_details,
- !is_last)) {
+ fall_through_on_failure)) {
// Quick check was generated for this choice.
preload->preload_is_current_ = true;
preload->preload_has_checked_bounds_ = true;
- // On the last choice in the ChoiceNode we generated the quick
- // check to fall through on possible success. So now we need to
- // generate the full check inline.
- if (is_last) {
+ // If we generated the quick check to fall through on possible success,
+ // we now need to generate the full check inline.
+ if (!fall_through_on_failure) {
macro_assembler->Bind(&alt_gen->possible_success);
new_trace.set_quick_check_performed(&alt_gen->quick_check_details);
new_trace.set_characters_preloaded(preload->preload_characters_);
@@ -4147,9 +4152,9 @@ void ChoiceNode::EmitChoices(RegExpCompiler* compiler,
generate_full_check_inline = true;
}
} else if (alt_gen->quick_check_details.cannot_match()) {
- if (is_last && !is_greedy_loop) {
+ if (!fall_through_on_failure) {
macro_assembler->GoTo(trace->backtrack());
- } // Else just fall through to the next test.
+ }
continue;
} else {
// No quick check was generated. Put the full code here.
@@ -4161,9 +4166,6 @@ void ChoiceNode::EmitChoices(RegExpCompiler* compiler,
alt_gen->expects_preload = false;
new_trace.InvalidateCurrentCharacter();
}
- if (!is_last) {
- new_trace.set_backtrack(&alt_gen->after);
- }
generate_full_check_inline = true;
}
if (generate_full_check_inline) {
« no previous file with comments | « src/jsregexp.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698