OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2654 } else { | 2654 } else { |
2655 return elm.cp_offset + elm.data.u_atom->data().length(); | 2655 return elm.cp_offset + elm.data.u_atom->data().length(); |
2656 } | 2656 } |
2657 } | 2657 } |
2658 | 2658 |
2659 | 2659 |
2660 // Finds the fixed match length of a sequence of nodes that goes from | 2660 // Finds the fixed match length of a sequence of nodes that goes from |
2661 // this alternative and back to this choice node. If there are variable | 2661 // this alternative and back to this choice node. If there are variable |
2662 // length nodes or other complications in the way then return a sentinel | 2662 // length nodes or other complications in the way then return a sentinel |
2663 // value indicating that a greedy loop cannot be constructed. | 2663 // value indicating that a greedy loop cannot be constructed. |
2664 int ChoiceNode::GreedyLoopTextLength(GuardedAlternative* alternative) { | 2664 int ChoiceNode::GreedyLoopTextLengthForAlternative( |
| 2665 GuardedAlternative* alternative) { |
2665 int length = 0; | 2666 int length = 0; |
2666 RegExpNode* node = alternative->node(); | 2667 RegExpNode* node = alternative->node(); |
2667 // Later we will generate code for all these text nodes using recursion | 2668 // Later we will generate code for all these text nodes using recursion |
2668 // so we have to limit the max number. | 2669 // so we have to limit the max number. |
2669 int recursion_depth = 0; | 2670 int recursion_depth = 0; |
2670 while (node != this) { | 2671 while (node != this) { |
2671 if (recursion_depth++ > RegExpCompiler::kMaxRecursion) { | 2672 if (recursion_depth++ > RegExpCompiler::kMaxRecursion) { |
2672 return kNodeIsTooComplexForGreedyLoops; | 2673 return kNodeIsTooComplexForGreedyLoops; |
2673 } | 2674 } |
2674 int node_length = node->GreedyLoopTextLength(); | 2675 int node_length = node->GreedyLoopTextLength(); |
(...skipping 18 matching lines...) Expand all Loading... |
2693 void LoopChoiceNode::AddContinueAlternative(GuardedAlternative alt) { | 2694 void LoopChoiceNode::AddContinueAlternative(GuardedAlternative alt) { |
2694 ASSERT_EQ(continue_node_, NULL); | 2695 ASSERT_EQ(continue_node_, NULL); |
2695 AddAlternative(alt); | 2696 AddAlternative(alt); |
2696 continue_node_ = alt.node(); | 2697 continue_node_ = alt.node(); |
2697 } | 2698 } |
2698 | 2699 |
2699 | 2700 |
2700 void LoopChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) { | 2701 void LoopChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) { |
2701 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler(); | 2702 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler(); |
2702 if (trace->stop_node() == this) { | 2703 if (trace->stop_node() == this) { |
2703 int text_length = GreedyLoopTextLength(&(alternatives_->at(0))); | 2704 int text_length = |
| 2705 GreedyLoopTextLengthForAlternative(&(alternatives_->at(0))); |
2704 ASSERT(text_length != kNodeIsTooComplexForGreedyLoops); | 2706 ASSERT(text_length != kNodeIsTooComplexForGreedyLoops); |
2705 // Update the counter-based backtracking info on the stack. This is an | 2707 // Update the counter-based backtracking info on the stack. This is an |
2706 // optimization for greedy loops (see below). | 2708 // optimization for greedy loops (see below). |
2707 ASSERT(trace->cp_offset() == text_length); | 2709 ASSERT(trace->cp_offset() == text_length); |
2708 macro_assembler->AdvanceCurrentPosition(text_length); | 2710 macro_assembler->AdvanceCurrentPosition(text_length); |
2709 macro_assembler->GoTo(trace->loop_label()); | 2711 macro_assembler->GoTo(trace->loop_label()); |
2710 return; | 2712 return; |
2711 } | 2713 } |
2712 ASSERT(trace->stop_node() == NULL); | 2714 ASSERT(trace->stop_node() == NULL); |
2713 if (!trace->is_trivial()) { | 2715 if (!trace->is_trivial()) { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2886 int new_flush_budget = trace->flush_budget() / choice_count; | 2888 int new_flush_budget = trace->flush_budget() / choice_count; |
2887 if (trace->flush_budget() == 0 && trace->actions() != NULL) { | 2889 if (trace->flush_budget() == 0 && trace->actions() != NULL) { |
2888 trace->Flush(compiler, this); | 2890 trace->Flush(compiler, this); |
2889 return; | 2891 return; |
2890 } | 2892 } |
2891 | 2893 |
2892 RecursionCheck rc(compiler); | 2894 RecursionCheck rc(compiler); |
2893 | 2895 |
2894 Trace* current_trace = trace; | 2896 Trace* current_trace = trace; |
2895 | 2897 |
2896 int text_length = GreedyLoopTextLength(&(alternatives_->at(0))); | 2898 int text_length = GreedyLoopTextLengthForAlternative(&(alternatives_->at(0))); |
2897 bool greedy_loop = false; | 2899 bool greedy_loop = false; |
2898 Label greedy_loop_label; | 2900 Label greedy_loop_label; |
2899 Trace counter_backtrack_trace; | 2901 Trace counter_backtrack_trace; |
2900 counter_backtrack_trace.set_backtrack(&greedy_loop_label); | 2902 counter_backtrack_trace.set_backtrack(&greedy_loop_label); |
2901 if (not_at_start()) counter_backtrack_trace.set_at_start(false); | 2903 if (not_at_start()) counter_backtrack_trace.set_at_start(false); |
2902 | 2904 |
2903 if (choice_count > 1 && text_length != kNodeIsTooComplexForGreedyLoops) { | 2905 if (choice_count > 1 && text_length != kNodeIsTooComplexForGreedyLoops) { |
2904 // Here we have special handling for greedy loops containing only text nodes | 2906 // Here we have special handling for greedy loops containing only text nodes |
2905 // and other simple nodes. These are handled by pushing the current | 2907 // and other simple nodes. These are handled by pushing the current |
2906 // position on the stack and then incrementing the current position each | 2908 // position on the stack and then incrementing the current position each |
(...skipping 2424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5331 } | 5333 } |
5332 | 5334 |
5333 return compiler.Assemble(¯o_assembler, | 5335 return compiler.Assemble(¯o_assembler, |
5334 node, | 5336 node, |
5335 data->capture_count, | 5337 data->capture_count, |
5336 pattern); | 5338 pattern); |
5337 } | 5339 } |
5338 | 5340 |
5339 | 5341 |
5340 }} // namespace v8::internal | 5342 }} // namespace v8::internal |
OLD | NEW |