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