OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |