| Index: src/jsregexp.cc
|
| ===================================================================
|
| --- src/jsregexp.cc (revision 1301)
|
| +++ src/jsregexp.cc (working copy)
|
| @@ -1527,6 +1527,13 @@
|
| // Generate deferred actions here along with code to undo them again.
|
| OutSet affected_registers;
|
|
|
| + if (backtrack() != NULL) {
|
| + // Here we have a concrete backtrack location. These are set up by choice
|
| + // nodes and so they indicate that we have a deferred save of the current
|
| + // position which we may need to emit here.
|
| + assembler->PushCurrentPosition();
|
| + }
|
| +
|
| int max_register = FindAffectedRegisters(&affected_registers);
|
| OutSet registers_to_pop;
|
| OutSet registers_to_clear;
|
| @@ -1535,12 +1542,6 @@
|
| affected_registers,
|
| ®isters_to_pop,
|
| ®isters_to_clear);
|
| - if (backtrack() != NULL) {
|
| - // Here we have a concrete backtrack location. These are set up by choice
|
| - // nodes and so they indicate that we have a deferred save of the current
|
| - // position which we may need to emit here.
|
| - assembler->PushCurrentPosition();
|
| - }
|
| if (cp_offset_ != 0) {
|
| assembler->AdvanceCurrentPosition(cp_offset_);
|
| }
|
| @@ -1553,9 +1554,6 @@
|
|
|
| // On backtrack we need to restore state.
|
| assembler->Bind(&undo);
|
| - if (backtrack() != NULL) {
|
| - assembler->PopCurrentPosition();
|
| - }
|
| RestoreAffectedRegisters(assembler,
|
| max_register,
|
| registers_to_pop,
|
| @@ -1563,6 +1561,7 @@
|
| if (backtrack() == NULL) {
|
| assembler->Backtrack();
|
| } else {
|
| + assembler->PopCurrentPosition();
|
| assembler->GoTo(backtrack());
|
| }
|
| }
|
| @@ -2998,10 +2997,6 @@
|
| }
|
| }
|
| ~AlternativeGenerationList() {
|
| - for (int i = 0; i < alt_gens_.length(); i++) {
|
| - alt_gens_[i]->possible_success.Unuse();
|
| - alt_gens_[i]->after.Unuse();
|
| - }
|
| for (int i = kAFew; i < alt_gens_.length(); i++) {
|
| delete alt_gens_[i];
|
| alt_gens_[i] = NULL;
|
| @@ -3115,6 +3110,12 @@
|
| if (limit_result == DONE) return;
|
| ASSERT(limit_result == CONTINUE);
|
|
|
| + int new_flush_budget = trace->flush_budget() / choice_count;
|
| + if (trace->flush_budget() == 0 && trace->actions() != NULL) {
|
| + trace->Flush(compiler, this);
|
| + return;
|
| + }
|
| +
|
| RecursionCheck rc(compiler);
|
|
|
| Trace* current_trace = trace;
|
| @@ -3223,6 +3224,9 @@
|
| generate_full_check_inline = true;
|
| }
|
| if (generate_full_check_inline) {
|
| + if (new_trace.actions() != NULL) {
|
| + new_trace.set_flush_budget(new_flush_budget);
|
| + }
|
| for (int j = 0; j < guard_count; j++) {
|
| GenerateGuard(macro_assembler, guards->at(j), &new_trace);
|
| }
|
| @@ -3239,13 +3243,21 @@
|
| macro_assembler->AdvanceCurrentPosition(-text_length);
|
| macro_assembler->GoTo(&second_choice);
|
| }
|
| +
|
| // At this point we need to generate slow checks for the alternatives where
|
| // the quick check was inlined. We can recognize these because the associated
|
| // label was bound.
|
| for (int i = first_normal_choice; i < choice_count - 1; i++) {
|
| AlternativeGeneration* alt_gen = alt_gens.at(i);
|
| + Trace new_trace(*current_trace);
|
| + // If there are actions to be flushed we have to limit how many times
|
| + // they are flushed. Take the budget of the parent trace and distribute
|
| + // it fairly amongst the children.
|
| + if (new_trace.actions() != NULL) {
|
| + new_trace.set_flush_budget(new_flush_budget);
|
| + }
|
| EmitOutOfLineContinuation(compiler,
|
| - current_trace,
|
| + &new_trace,
|
| alternatives_->at(i),
|
| alt_gen,
|
| preload_characters,
|
|
|