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

Side by Side Diff: src/jsregexp.cc

Issue 18360: Optimization: The quick check should ignore the negative lookahead instead of... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 11 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/jsregexp.h ('k') | src/regexp-macro-assembler-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 1962 matching lines...) Expand 10 before | Expand all | Expand 10 after
1973 return on_success()->EatsAtLeast(recursion_depth + 1); 1973 return on_success()->EatsAtLeast(recursion_depth + 1);
1974 } 1974 }
1975 1975
1976 1976
1977 int BackReferenceNode::EatsAtLeast(int recursion_depth) { 1977 int BackReferenceNode::EatsAtLeast(int recursion_depth) {
1978 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 1978 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
1979 return on_success()->EatsAtLeast(recursion_depth + 1); 1979 return on_success()->EatsAtLeast(recursion_depth + 1);
1980 } 1980 }
1981 1981
1982 1982
1983
1984 int TextNode::EatsAtLeast(int recursion_depth) { 1983 int TextNode::EatsAtLeast(int recursion_depth) {
1985 int answer = Length(); 1984 int answer = Length();
1986 if (answer >= 4) return answer; 1985 if (answer >= 4) return answer;
1987 if (recursion_depth > RegExpCompiler::kMaxRecursion) return answer; 1986 if (recursion_depth > RegExpCompiler::kMaxRecursion) return answer;
1988 return answer + on_success()->EatsAtLeast(recursion_depth + 1); 1987 return answer + on_success()->EatsAtLeast(recursion_depth + 1);
1989 } 1988 }
1990 1989
1991 1990
1991 int NegativeLookaheadChoiceNode:: EatsAtLeast(int recursion_depth) {
1992 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
1993 // Alternative 0 is the negative lookahead, alternative 1 is what comes
1994 // afterwards.
1995 RegExpNode* node = alternatives_->at(1).node();
1996 return node->EatsAtLeast(recursion_depth + 1);
1997 }
1998
1999
2000 void NegativeLookaheadChoiceNode::GetQuickCheckDetails(
2001 QuickCheckDetails* details,
2002 RegExpCompiler* compiler,
2003 int filled_in) {
2004 // Alternative 0 is the negative lookahead, alternative 1 is what comes
2005 // afterwards.
2006 RegExpNode* node = alternatives_->at(1).node();
2007 return node->GetQuickCheckDetails(details, compiler, filled_in);
2008 }
2009
2010
1992 int ChoiceNode::EatsAtLeastHelper(int recursion_depth, 2011 int ChoiceNode::EatsAtLeastHelper(int recursion_depth,
1993 RegExpNode* ignore_this_node) { 2012 RegExpNode* ignore_this_node) {
1994 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2013 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
1995 int min = 100; 2014 int min = 100;
1996 int choice_count = alternatives_->length(); 2015 int choice_count = alternatives_->length();
1997 for (int i = 0; i < choice_count; i++) { 2016 for (int i = 0; i < choice_count; i++) {
1998 RegExpNode* node = alternatives_->at(i).node(); 2017 RegExpNode* node = alternatives_->at(i).node();
1999 if (node == ignore_this_node) continue; 2018 if (node == ignore_this_node) continue;
2000 int node_eats_at_least = node->EatsAtLeast(recursion_depth + 1); 2019 int node_eats_at_least = node->EatsAtLeast(recursion_depth + 1);
2001 if (node_eats_at_least < min) min = node_eats_at_least; 2020 if (node_eats_at_least < min) min = node_eats_at_least;
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
3017 Trace new_trace(*current_trace); 3036 Trace new_trace(*current_trace);
3018 new_trace.set_characters_preloaded(preload_is_current ? 3037 new_trace.set_characters_preloaded(preload_is_current ?
3019 preload_characters : 3038 preload_characters :
3020 0); 3039 0);
3021 if (preload_has_checked_bounds) { 3040 if (preload_has_checked_bounds) {
3022 new_trace.set_bound_checked_up_to(preload_characters); 3041 new_trace.set_bound_checked_up_to(preload_characters);
3023 } 3042 }
3024 new_trace.quick_check_performed()->Clear(); 3043 new_trace.quick_check_performed()->Clear();
3025 alt_gen->expects_preload = preload_is_current; 3044 alt_gen->expects_preload = preload_is_current;
3026 bool generate_full_check_inline = false; 3045 bool generate_full_check_inline = false;
3027 if (alternative.node()->EmitQuickCheck(compiler, 3046 if (try_to_emit_quick_check_for_alternative(i) &&
3047 alternative.node()->EmitQuickCheck(compiler,
3028 &new_trace, 3048 &new_trace,
3029 preload_has_checked_bounds, 3049 preload_has_checked_bounds,
3030 &alt_gen->possible_success, 3050 &alt_gen->possible_success,
3031 &alt_gen->quick_check_details, 3051 &alt_gen->quick_check_details,
3032 i < choice_count - 1)) { 3052 i < choice_count - 1)) {
3033 // Quick check was generated for this choice. 3053 // Quick check was generated for this choice.
3034 preload_is_current = true; 3054 preload_is_current = true;
3035 preload_has_checked_bounds = true; 3055 preload_has_checked_bounds = true;
3036 // On the last choice in the ChoiceNode we generated the quick 3056 // On the last choice in the ChoiceNode we generated the quick
3037 // check to fall through on possible success. So now we need to 3057 // check to fall through on possible success. So now we need to
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after
3950 position_register, 3970 position_register,
3951 on_success))); 3971 on_success)));
3952 } else { 3972 } else {
3953 // We use a ChoiceNode for a negative lookahead because it has most of 3973 // We use a ChoiceNode for a negative lookahead because it has most of
3954 // the characteristics we need. It has the body of the lookahead as its 3974 // the characteristics we need. It has the body of the lookahead as its
3955 // first alternative and the expression after the lookahead of the second 3975 // first alternative and the expression after the lookahead of the second
3956 // alternative. If the first alternative succeeds then the 3976 // alternative. If the first alternative succeeds then the
3957 // NegativeSubmatchSuccess will unwind the stack including everything the 3977 // NegativeSubmatchSuccess will unwind the stack including everything the
3958 // choice node set up and backtrack. If the first alternative fails then 3978 // choice node set up and backtrack. If the first alternative fails then
3959 // the second alternative is tried, which is exactly the desired result 3979 // the second alternative is tried, which is exactly the desired result
3960 // for a negative lookahead. In the case where the dispatch table 3980 // for a negative lookahead. The NegativeLookaheadChoiceNode is a special
3961 // determines that the first alternative cannot match we will save time 3981 // ChoiceNode that knows to ignore the first exit when calculating quick
3962 // by not trying it. Things are not quite so well-optimized if the 3982 // checks.
3963 // dispatch table determines that the second alternative cannot match.
3964 // In this case we could optimize by immediately backtracking.
3965 ChoiceNode* choice_node = new ChoiceNode(2);
3966 GuardedAlternative body_alt( 3983 GuardedAlternative body_alt(
3967 body()->ToNode( 3984 body()->ToNode(
3968 compiler, 3985 compiler,
3969 success = new NegativeSubmatchSuccess(stack_pointer_register, 3986 success = new NegativeSubmatchSuccess(stack_pointer_register,
3970 position_register))); 3987 position_register)));
3971 choice_node->AddAlternative(body_alt); 3988 ChoiceNode* choice_node =
3972 choice_node->AddAlternative(GuardedAlternative(on_success)); 3989 new NegativeLookaheadChoiceNode(body_alt,
3990 GuardedAlternative(on_success));
3973 return ActionNode::BeginSubmatch(stack_pointer_register, 3991 return ActionNode::BeginSubmatch(stack_pointer_register,
3974 position_register, 3992 position_register,
3975 choice_node); 3993 choice_node);
3976 } 3994 }
3977 } 3995 }
3978 3996
3979 3997
3980 RegExpNode* RegExpCapture::ToNode(RegExpCompiler* compiler, 3998 RegExpNode* RegExpCapture::ToNode(RegExpCompiler* compiler,
3981 RegExpNode* on_success) { 3999 RegExpNode* on_success) {
3982 return ToNode(body(), index(), compiler, on_success); 4000 return ToNode(body(), index(), compiler, on_success);
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
4663 EmbeddedVector<byte, 1024> codes; 4681 EmbeddedVector<byte, 1024> codes;
4664 RegExpMacroAssemblerIrregexp macro_assembler(codes); 4682 RegExpMacroAssemblerIrregexp macro_assembler(codes);
4665 return compiler.Assemble(&macro_assembler, 4683 return compiler.Assemble(&macro_assembler,
4666 node, 4684 node,
4667 data->capture_count, 4685 data->capture_count,
4668 pattern); 4686 pattern);
4669 } 4687 }
4670 4688
4671 4689
4672 }} // namespace v8::internal 4690 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jsregexp.h ('k') | src/regexp-macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698