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

Side by Side Diff: src/jsregexp.cc

Issue 5524006: Irregexp: Preload more characters when we are not at the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years 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
« src/jsregexp.h ('K') | « src/jsregexp.h ('k') | no next file » | 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-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after
1643 } 1643 }
1644 1644
1645 // If we get here code has been generated for this node too many times or 1645 // If we get here code has been generated for this node too many times or
1646 // recursion is too deep. Time to switch to a generic version. The code for 1646 // recursion is too deep. Time to switch to a generic version. The code for
1647 // generic versions above can handle deep recursion properly. 1647 // generic versions above can handle deep recursion properly.
1648 trace->Flush(compiler, this); 1648 trace->Flush(compiler, this);
1649 return DONE; 1649 return DONE;
1650 } 1650 }
1651 1651
1652 1652
1653 int ActionNode::EatsAtLeast(int still_to_find, int recursion_depth) { 1653 int ActionNode::EatsAtLeast(int still_to_find,
1654 int recursion_depth,
1655 bool not_at_start) {
1654 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 1656 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
1655 if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input! 1657 if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input!
1656 return on_success()->EatsAtLeast(still_to_find, recursion_depth + 1); 1658 return on_success()->EatsAtLeast(still_to_find,
1659 recursion_depth + 1,
1660 not_at_start);
1657 } 1661 }
1658 1662
1659 1663
1660 int AssertionNode::EatsAtLeast(int still_to_find, int recursion_depth) { 1664 int AssertionNode::EatsAtLeast(int still_to_find,
1665 int recursion_depth,
1666 bool not_at_start) {
1661 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 1667 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
1662 return on_success()->EatsAtLeast(still_to_find, recursion_depth + 1); 1668 // If we know we are not at the start and we are asked "how many characters
1669 // will you match if you succeed?" then we can answer anything since false
1670 // implies false. So lets just return the max answer (still_to_find) since
1671 // that won't prevent us from preloading a lot of characters for the other
1672 // branches in the node graph.
1673 if (type() == AT_START && not_at_start) return still_to_find;
1674 return on_success()->EatsAtLeast(still_to_find,
1675 recursion_depth + 1,
1676 not_at_start);
1663 } 1677 }
1664 1678
1665 1679
1666 int BackReferenceNode::EatsAtLeast(int still_to_find, int recursion_depth) { 1680 int BackReferenceNode::EatsAtLeast(int still_to_find,
1681 int recursion_depth,
1682 bool not_at_start) {
1667 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 1683 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
1668 return on_success()->EatsAtLeast(still_to_find, recursion_depth + 1); 1684 return on_success()->EatsAtLeast(still_to_find,
1685 recursion_depth + 1,
1686 not_at_start);
1669 } 1687 }
1670 1688
1671 1689
1672 int TextNode::EatsAtLeast(int still_to_find, int recursion_depth) { 1690 int TextNode::EatsAtLeast(int still_to_find,
1691 int recursion_depth,
1692 bool not_at_start) {
1673 int answer = Length(); 1693 int answer = Length();
1674 if (answer >= still_to_find) return answer; 1694 if (answer >= still_to_find) return answer;
1675 if (recursion_depth > RegExpCompiler::kMaxRecursion) return answer; 1695 if (recursion_depth > RegExpCompiler::kMaxRecursion) return answer;
1696 // We are not at start after this node so we set the last argument to 'true'.
1676 return answer + on_success()->EatsAtLeast(still_to_find - answer, 1697 return answer + on_success()->EatsAtLeast(still_to_find - answer,
1677 recursion_depth + 1); 1698 recursion_depth + 1,
1699 true);
1678 } 1700 }
1679 1701
1680 1702
1681 int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find, 1703 int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find,
1682 int recursion_depth) { 1704 int recursion_depth,
1705 bool not_at_start) {
1683 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 1706 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
1684 // Alternative 0 is the negative lookahead, alternative 1 is what comes 1707 // Alternative 0 is the negative lookahead, alternative 1 is what comes
1685 // afterwards. 1708 // afterwards.
1686 RegExpNode* node = alternatives_->at(1).node(); 1709 RegExpNode* node = alternatives_->at(1).node();
1687 return node->EatsAtLeast(still_to_find, recursion_depth + 1); 1710 return node->EatsAtLeast(still_to_find, recursion_depth + 1, not_at_start);
1688 } 1711 }
1689 1712
1690 1713
1691 void NegativeLookaheadChoiceNode::GetQuickCheckDetails( 1714 void NegativeLookaheadChoiceNode::GetQuickCheckDetails(
1692 QuickCheckDetails* details, 1715 QuickCheckDetails* details,
1693 RegExpCompiler* compiler, 1716 RegExpCompiler* compiler,
1694 int filled_in, 1717 int filled_in,
1695 bool not_at_start) { 1718 bool not_at_start) {
1696 // Alternative 0 is the negative lookahead, alternative 1 is what comes 1719 // Alternative 0 is the negative lookahead, alternative 1 is what comes
1697 // afterwards. 1720 // afterwards.
1698 RegExpNode* node = alternatives_->at(1).node(); 1721 RegExpNode* node = alternatives_->at(1).node();
1699 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start); 1722 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start);
1700 } 1723 }
1701 1724
1702 1725
1703 int ChoiceNode::EatsAtLeastHelper(int still_to_find, 1726 int ChoiceNode::EatsAtLeastHelper(int still_to_find,
1704 int recursion_depth, 1727 int recursion_depth,
1705 RegExpNode* ignore_this_node) { 1728 RegExpNode* ignore_this_node,
1729 bool not_at_start) {
1706 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 1730 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
1707 int min = 100; 1731 int min = 100;
1708 int choice_count = alternatives_->length(); 1732 int choice_count = alternatives_->length();
1709 for (int i = 0; i < choice_count; i++) { 1733 for (int i = 0; i < choice_count; i++) {
1710 RegExpNode* node = alternatives_->at(i).node(); 1734 RegExpNode* node = alternatives_->at(i).node();
1711 if (node == ignore_this_node) continue; 1735 if (node == ignore_this_node) continue;
1712 int node_eats_at_least = node->EatsAtLeast(still_to_find, 1736 int node_eats_at_least = node->EatsAtLeast(still_to_find,
1713 recursion_depth + 1); 1737 recursion_depth + 1,
1738 not_at_start);
1714 if (node_eats_at_least < min) min = node_eats_at_least; 1739 if (node_eats_at_least < min) min = node_eats_at_least;
1715 } 1740 }
1716 return min; 1741 return min;
1717 } 1742 }
1718 1743
1719 1744
1720 int LoopChoiceNode::EatsAtLeast(int still_to_find, int recursion_depth) { 1745 int LoopChoiceNode::EatsAtLeast(int still_to_find,
1721 return EatsAtLeastHelper(still_to_find, recursion_depth, loop_node_); 1746 int recursion_depth,
1747 bool not_at_start) {
1748 return EatsAtLeastHelper(still_to_find,
1749 recursion_depth,
1750 loop_node_,
1751 not_at_start);
1722 } 1752 }
1723 1753
1724 1754
1725 int ChoiceNode::EatsAtLeast(int still_to_find, int recursion_depth) { 1755 int ChoiceNode::EatsAtLeast(int still_to_find,
1726 return EatsAtLeastHelper(still_to_find, recursion_depth, NULL); 1756 int recursion_depth,
1757 bool not_at_start) {
1758 return EatsAtLeastHelper(still_to_find,
1759 recursion_depth,
1760 NULL,
1761 not_at_start);
1727 } 1762 }
1728 1763
1729 1764
1730 // Takes the left-most 1-bit and smears it out, setting all bits to its right. 1765 // Takes the left-most 1-bit and smears it out, setting all bits to its right.
1731 static inline uint32_t SmearBitsRight(uint32_t v) { 1766 static inline uint32_t SmearBitsRight(uint32_t v) {
1732 v |= v >> 1; 1767 v |= v >> 1;
1733 v |= v >> 2; 1768 v |= v >> 2;
1734 v |= v >> 4; 1769 v |= v >> 4;
1735 v |= v >> 8; 1770 v |= v >> 8;
1736 v |= v >> 16; 1771 v |= v >> 16;
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
2623 } 2658 }
2624 ASSERT(trace->stop_node() == NULL); 2659 ASSERT(trace->stop_node() == NULL);
2625 if (!trace->is_trivial()) { 2660 if (!trace->is_trivial()) {
2626 trace->Flush(compiler, this); 2661 trace->Flush(compiler, this);
2627 return; 2662 return;
2628 } 2663 }
2629 ChoiceNode::Emit(compiler, trace); 2664 ChoiceNode::Emit(compiler, trace);
2630 } 2665 }
2631 2666
2632 2667
2633 int ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler) { 2668 int ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler,
2634 int preload_characters = EatsAtLeast(4, 0); 2669 bool not_at_start) {
2670 int preload_characters = EatsAtLeast(4, 0, not_at_start);
2635 if (compiler->macro_assembler()->CanReadUnaligned()) { 2671 if (compiler->macro_assembler()->CanReadUnaligned()) {
2636 bool ascii = compiler->ascii(); 2672 bool ascii = compiler->ascii();
2637 if (ascii) { 2673 if (ascii) {
2638 if (preload_characters > 4) preload_characters = 4; 2674 if (preload_characters > 4) preload_characters = 4;
2639 // We can't preload 3 characters because there is no machine instruction 2675 // We can't preload 3 characters because there is no machine instruction
2640 // to do that. We can't just load 4 because we could be reading 2676 // to do that. We can't just load 4 because we could be reading
2641 // beyond the end of the string, which could cause a memory fault. 2677 // beyond the end of the string, which could cause a memory fault.
2642 if (preload_characters == 3) preload_characters = 2; 2678 if (preload_characters == 3) preload_characters = 2;
2643 } else { 2679 } else {
2644 if (preload_characters > 2) preload_characters = 2; 2680 if (preload_characters > 2) preload_characters = 2;
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
2832 greedy_match_trace.set_loop_label(&loop_label); 2868 greedy_match_trace.set_loop_label(&loop_label);
2833 alternatives_->at(0).node()->Emit(compiler, &greedy_match_trace); 2869 alternatives_->at(0).node()->Emit(compiler, &greedy_match_trace);
2834 macro_assembler->Bind(&greedy_match_failed); 2870 macro_assembler->Bind(&greedy_match_failed);
2835 } 2871 }
2836 2872
2837 Label second_choice; // For use in greedy matches. 2873 Label second_choice; // For use in greedy matches.
2838 macro_assembler->Bind(&second_choice); 2874 macro_assembler->Bind(&second_choice);
2839 2875
2840 int first_normal_choice = greedy_loop ? 1 : 0; 2876 int first_normal_choice = greedy_loop ? 1 : 0;
2841 2877
2842 int preload_characters = CalculatePreloadCharacters(compiler); 2878 int preload_characters =
2879 CalculatePreloadCharacters(compiler,
2880 current_trace->at_start() == Trace::FALSE);
2843 bool preload_is_current = 2881 bool preload_is_current =
2844 (current_trace->characters_preloaded() == preload_characters); 2882 (current_trace->characters_preloaded() == preload_characters);
2845 bool preload_has_checked_bounds = preload_is_current; 2883 bool preload_has_checked_bounds = preload_is_current;
2846 2884
2847 AlternativeGenerationList alt_gens(choice_count); 2885 AlternativeGenerationList alt_gens(choice_count);
2848 2886
2849 // For now we just call all choices one after the other. The idea ultimately 2887 // For now we just call all choices one after the other. The idea ultimately
2850 // is to use the Dispatch table to try only the relevant ones. 2888 // is to use the Dispatch table to try only the relevant ones.
2851 for (int i = first_normal_choice; i < choice_count; i++) { 2889 for (int i = first_normal_choice; i < choice_count; i++) {
2852 GuardedAlternative alternative = alternatives_->at(i); 2890 GuardedAlternative alternative = alternatives_->at(i);
(...skipping 2440 matching lines...) Expand 10 before | Expand all | Expand 10 after
5293 node, 5331 node,
5294 data->capture_count, 5332 data->capture_count,
5295 pattern); 5333 pattern);
5296 } 5334 }
5297 5335
5298 5336
5299 int OffsetsVector::static_offsets_vector_[ 5337 int OffsetsVector::static_offsets_vector_[
5300 OffsetsVector::kStaticOffsetsVectorSize]; 5338 OffsetsVector::kStaticOffsetsVectorSize];
5301 5339
5302 }} // namespace v8::internal 5340 }} // namespace v8::internal
OLDNEW
« src/jsregexp.h ('K') | « src/jsregexp.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698