| 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) { | 
|  |