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

Side by Side Diff: src/jsregexp.h

Issue 9965010: Regexp: Improve the speed that we scan for an initial point where a non-anchored (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 8 years, 8 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 | « no previous file | src/jsregexp.cc » ('j') | src/jsregexp.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 // is not tracked, however. As a conservative approximation we track the 183 // is not tracked, however. As a conservative approximation we track the
184 // total regexp code compiled including code that has subsequently been freed 184 // total regexp code compiled including code that has subsequently been freed
185 // and the total executable memory at any point. 185 // and the total executable memory at any point.
186 static const int kRegExpExecutableMemoryLimit = 16 * MB; 186 static const int kRegExpExecutableMemoryLimit = 16 * MB;
187 static const int kRegWxpCompiledLimit = 1 * MB; 187 static const int kRegWxpCompiledLimit = 1 * MB;
188 188
189 private: 189 private:
190 static String* last_ascii_string_; 190 static String* last_ascii_string_;
191 static String* two_byte_cached_string_; 191 static String* two_byte_cached_string_;
192 192
193 static bool CompileIrregexp(Handle<JSRegExp> re, bool is_ascii); 193 static bool CompileIrregexp(
194 static inline bool EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii); 194 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii);
195 static inline bool EnsureCompiledIrregexp(
196 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii);
195 197
196 198
197 // Set the subject cache. The previous string buffer is not deleted, so the 199 // Set the subject cache. The previous string buffer is not deleted, so the
198 // caller should ensure that it doesn't leak. 200 // caller should ensure that it doesn't leak.
199 static void SetSubjectCache(String* subject, 201 static void SetSubjectCache(String* subject,
200 char* utf8_subject, 202 char* utf8_subject,
201 int uft8_length, 203 int uft8_length,
202 int character_position, 204 int character_position,
203 int utf8_position); 205 int utf8_position);
204 206
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 private: 414 private:
413 // There can't be a static empty set since it allocates its 415 // There can't be a static empty set since it allocates its
414 // successors in a zone and caches them. 416 // successors in a zone and caches them.
415 OutSet* empty() { return &empty_; } 417 OutSet* empty() { return &empty_; }
416 OutSet empty_; 418 OutSet empty_;
417 ZoneSplayTree<Config>* tree() { return &tree_; } 419 ZoneSplayTree<Config>* tree() { return &tree_; }
418 ZoneSplayTree<Config> tree_; 420 ZoneSplayTree<Config> tree_;
419 }; 421 };
420 422
421 423
424 class BoyerMooreLookahead {
425 public:
426 BoyerMooreLookahead(int length, int map_length, RegExpCompiler* compiler);
ulan 2012/03/30 16:54:51 We need comments for this class. In particular for
427
428 int length() { return length_; }
429 int max_char() { return max_char_; }
430 RegExpCompiler* compiler() { return compiler_; }
431
432 static const int kTooManyCharacters = 32;
433
434 int Count(int map_number) {
435 ZoneList<bool>* map = bitmaps_->at(map_number);
436 if (map == NULL) return map_length_;
437 int count = 0;
438 for (int i = 0; i < map_length_; i++) {
439 if (map->at(i)) count++;
440 }
441 return count;
442 }
443
444 void Set(int map_number, int character) {
445 if (character > max_char_) return;
446 ZoneList<bool>* map = bitmaps_->at(map_number);
447 if (map == NULL) return;
448 map->at(character & (map_length_ - 1)) = true;
449 }
450
451 void SetAll(int map_number) {
452 bitmaps_->at(map_number) = NULL;
453 }
454
455 void SetRest(int from_map) {
456 for (int i = from_map; i < length_; i++) SetAll(i);
457 }
458 bool EmitSkipInstructions(RegExpMacroAssembler* masm);
459
460 private:
461 int length_;
462 int map_length_;
463 RegExpCompiler* compiler_;
464 int max_char_;
465 ZoneList<ZoneList<bool>*>* bitmaps_;
466
467 bool TooVague(int offset, int limit);
468 int GetSkipTable(int max_lookahead, Handle<ByteArray> boolean_skip_table);
469 bool FindWorthwhileInterval(int* from, int* to);
470 };
471
472
422 #define FOR_EACH_NODE_TYPE(VISIT) \ 473 #define FOR_EACH_NODE_TYPE(VISIT) \
423 VISIT(End) \ 474 VISIT(End) \
424 VISIT(Action) \ 475 VISIT(Action) \
425 VISIT(Choice) \ 476 VISIT(Choice) \
426 VISIT(BackReference) \ 477 VISIT(BackReference) \
427 VISIT(Assertion) \ 478 VISIT(Assertion) \
428 VISIT(Text) 479 VISIT(Text)
429 480
430 481
431 #define FOR_EACH_REG_EXP_TREE_TYPE(VISIT) \ 482 #define FOR_EACH_REG_EXP_TREE_TYPE(VISIT) \
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 // For a given number of characters this returns a mask and a value. The 679 // For a given number of characters this returns a mask and a value. The
629 // next n characters are anded with the mask and compared with the value. 680 // next n characters are anded with the mask and compared with the value.
630 // A comparison failure indicates the node cannot match the next n characters. 681 // A comparison failure indicates the node cannot match the next n characters.
631 // A comparison success indicates the node may match. 682 // A comparison success indicates the node may match.
632 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 683 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
633 RegExpCompiler* compiler, 684 RegExpCompiler* compiler,
634 int characters_filled_in, 685 int characters_filled_in,
635 bool not_at_start) = 0; 686 bool not_at_start) = 0;
636 static const int kNodeIsTooComplexForGreedyLoops = -1; 687 static const int kNodeIsTooComplexForGreedyLoops = -1;
637 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; } 688 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
689 // Only returns the successor for a text node of length 1 that matches any
690 // character and that has no guards on it.
691 virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
692 RegExpCompiler* compiler) {
693 return NULL;
694 }
695
696 // Collects information on the possible code units (mod 128) that can match if
697 // we look forward. This is used for a Boyer-Moore-like string searching
698 // implementation. TODO(erikcorry): This should share more code with
699 // EatsAtLeast, GetQuickCheckDetails and ComputeFirstCharacterSet.
700 virtual void FillInBMInfo(
701 int offset, BoyerMooreLookahead* bm, bool not_at_start) {
702 UNREACHABLE();
703 }
704
638 Label* label() { return &label_; } 705 Label* label() { return &label_; }
639 // If non-generic code is generated for a node (i.e. the node is not at the 706 // If non-generic code is generated for a node (i.e. the node is not at the
640 // start of the trace) then it cannot be reused. This variable sets a limit 707 // start of the trace) then it cannot be reused. This variable sets a limit
641 // on how often we allow that to happen before we insist on starting a new 708 // on how often we allow that to happen before we insist on starting a new
642 // trace and generating generic code for a node that can be reused by flushing 709 // trace and generating generic code for a node that can be reused by flushing
643 // the deferred actions in the current trace and generating a goto. 710 // the deferred actions in the current trace and generating a goto.
644 static const int kMaxCopiesCodeGenerated = 10; 711 static const int kMaxCopiesCodeGenerated = 10;
645 712
646 NodeInfo* info() { return &info_; } 713 NodeInfo* info() { return &info_; }
647 714
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 int to_; 807 int to_;
741 }; 808 };
742 809
743 810
744 class SeqRegExpNode: public RegExpNode { 811 class SeqRegExpNode: public RegExpNode {
745 public: 812 public:
746 explicit SeqRegExpNode(RegExpNode* on_success) 813 explicit SeqRegExpNode(RegExpNode* on_success)
747 : on_success_(on_success) { } 814 : on_success_(on_success) { }
748 RegExpNode* on_success() { return on_success_; } 815 RegExpNode* on_success() { return on_success_; }
749 void set_on_success(RegExpNode* node) { on_success_ = node; } 816 void set_on_success(RegExpNode* node) { on_success_ = node; }
817 virtual void FillInBMInfo(
818 int offset, BoyerMooreLookahead* bm, bool not_at_start) {
819 on_success_->FillInBMInfo(offset, bm, not_at_start);
820 }
750 private: 821 private:
751 RegExpNode* on_success_; 822 RegExpNode* on_success_;
752 }; 823 };
753 824
754 825
755 class ActionNode: public SeqRegExpNode { 826 class ActionNode: public SeqRegExpNode {
756 public: 827 public:
757 enum Type { 828 enum Type {
758 SET_REGISTER, 829 SET_REGISTER,
759 INCREMENT_REGISTER, 830 INCREMENT_REGISTER,
(...skipping 26 matching lines...) Expand all
786 virtual int EatsAtLeast(int still_to_find, 857 virtual int EatsAtLeast(int still_to_find,
787 int recursion_depth, 858 int recursion_depth,
788 bool not_at_start); 859 bool not_at_start);
789 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 860 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
790 RegExpCompiler* compiler, 861 RegExpCompiler* compiler,
791 int filled_in, 862 int filled_in,
792 bool not_at_start) { 863 bool not_at_start) {
793 return on_success()->GetQuickCheckDetails( 864 return on_success()->GetQuickCheckDetails(
794 details, compiler, filled_in, not_at_start); 865 details, compiler, filled_in, not_at_start);
795 } 866 }
867 virtual void FillInBMInfo(
868 int offset, BoyerMooreLookahead* bm, bool not_at_start);
796 Type type() { return type_; } 869 Type type() { return type_; }
797 // TODO(erikcorry): We should allow some action nodes in greedy loops. 870 // TODO(erikcorry): We should allow some action nodes in greedy loops.
798 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; } 871 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
799 virtual ActionNode* Clone() { return new ActionNode(*this); } 872 virtual ActionNode* Clone() { return new ActionNode(*this); }
800 virtual int ComputeFirstCharacterSet(int budget); 873 virtual int ComputeFirstCharacterSet(int budget);
801 874
802 private: 875 private:
803 union { 876 union {
804 struct { 877 struct {
805 int reg; 878 int reg;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 virtual int EatsAtLeast(int still_to_find, 926 virtual int EatsAtLeast(int still_to_find,
854 int recursion_depth, 927 int recursion_depth,
855 bool not_at_start); 928 bool not_at_start);
856 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 929 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
857 RegExpCompiler* compiler, 930 RegExpCompiler* compiler,
858 int characters_filled_in, 931 int characters_filled_in,
859 bool not_at_start); 932 bool not_at_start);
860 ZoneList<TextElement>* elements() { return elms_; } 933 ZoneList<TextElement>* elements() { return elms_; }
861 void MakeCaseIndependent(bool is_ascii); 934 void MakeCaseIndependent(bool is_ascii);
862 virtual int GreedyLoopTextLength(); 935 virtual int GreedyLoopTextLength();
936 virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
937 RegExpCompiler* compiler);
938 virtual void FillInBMInfo(
939 int offset, BoyerMooreLookahead* bm, bool not_at_start);
863 virtual TextNode* Clone() { 940 virtual TextNode* Clone() {
864 TextNode* result = new TextNode(*this); 941 TextNode* result = new TextNode(*this);
865 result->CalculateOffsets(); 942 result->CalculateOffsets();
866 return result; 943 return result;
867 } 944 }
868 void CalculateOffsets(); 945 void CalculateOffsets();
869 virtual int ComputeFirstCharacterSet(int budget); 946 virtual int ComputeFirstCharacterSet(int budget);
870 947
871 private: 948 private:
872 enum TextEmitPassType { 949 enum TextEmitPassType {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 } 998 }
922 virtual void Accept(NodeVisitor* visitor); 999 virtual void Accept(NodeVisitor* visitor);
923 virtual void Emit(RegExpCompiler* compiler, Trace* trace); 1000 virtual void Emit(RegExpCompiler* compiler, Trace* trace);
924 virtual int EatsAtLeast(int still_to_find, 1001 virtual int EatsAtLeast(int still_to_find,
925 int recursion_depth, 1002 int recursion_depth,
926 bool not_at_start); 1003 bool not_at_start);
927 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 1004 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
928 RegExpCompiler* compiler, 1005 RegExpCompiler* compiler,
929 int filled_in, 1006 int filled_in,
930 bool not_at_start); 1007 bool not_at_start);
1008 virtual void FillInBMInfo(
1009 int offset, BoyerMooreLookahead* bm, bool not_at_start);
931 virtual int ComputeFirstCharacterSet(int budget); 1010 virtual int ComputeFirstCharacterSet(int budget);
932 virtual AssertionNode* Clone() { return new AssertionNode(*this); } 1011 virtual AssertionNode* Clone() { return new AssertionNode(*this); }
933 AssertionNodeType type() { return type_; } 1012 AssertionNodeType type() { return type_; }
934 void set_type(AssertionNodeType type) { type_ = type; } 1013 void set_type(AssertionNodeType type) { type_ = type; }
935 1014
936 private: 1015 private:
937 AssertionNode(AssertionNodeType t, RegExpNode* on_success) 1016 AssertionNode(AssertionNodeType t, RegExpNode* on_success)
938 : SeqRegExpNode(on_success), type_(t) { } 1017 : SeqRegExpNode(on_success), type_(t) { }
939 AssertionNodeType type_; 1018 AssertionNodeType type_;
940 }; 1019 };
(...skipping 13 matching lines...) Expand all
954 virtual void Emit(RegExpCompiler* compiler, Trace* trace); 1033 virtual void Emit(RegExpCompiler* compiler, Trace* trace);
955 virtual int EatsAtLeast(int still_to_find, 1034 virtual int EatsAtLeast(int still_to_find,
956 int recursion_depth, 1035 int recursion_depth,
957 bool not_at_start); 1036 bool not_at_start);
958 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 1037 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
959 RegExpCompiler* compiler, 1038 RegExpCompiler* compiler,
960 int characters_filled_in, 1039 int characters_filled_in,
961 bool not_at_start) { 1040 bool not_at_start) {
962 return; 1041 return;
963 } 1042 }
1043 virtual void FillInBMInfo(
1044 int offset, BoyerMooreLookahead* bm, bool not_at_start) {
1045 // Working out the set of characters that a backreference can match is too
1046 // hard, so we just say that any character can match.
1047 bm->SetRest(offset);
1048 }
964 virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); } 1049 virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); }
965 virtual int ComputeFirstCharacterSet(int budget); 1050 virtual int ComputeFirstCharacterSet(int budget);
966 1051
967 private: 1052 private:
968 int start_reg_; 1053 int start_reg_;
969 int end_reg_; 1054 int end_reg_;
970 }; 1055 };
971 1056
972 1057
973 class EndNode: public RegExpNode { 1058 class EndNode: public RegExpNode {
974 public: 1059 public:
975 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; 1060 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS };
976 explicit EndNode(Action action) : action_(action) { } 1061 explicit EndNode(Action action) : action_(action) { }
977 virtual void Accept(NodeVisitor* visitor); 1062 virtual void Accept(NodeVisitor* visitor);
978 virtual void Emit(RegExpCompiler* compiler, Trace* trace); 1063 virtual void Emit(RegExpCompiler* compiler, Trace* trace);
979 virtual int EatsAtLeast(int still_to_find, 1064 virtual int EatsAtLeast(int still_to_find,
980 int recursion_depth, 1065 int recursion_depth,
981 bool not_at_start) { return 0; } 1066 bool not_at_start) { return 0; }
982 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 1067 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
983 RegExpCompiler* compiler, 1068 RegExpCompiler* compiler,
984 int characters_filled_in, 1069 int characters_filled_in,
985 bool not_at_start) { 1070 bool not_at_start) {
986 // Returning 0 from EatsAtLeast should ensure we never get here. 1071 // Returning 0 from EatsAtLeast should ensure we never get here.
987 UNREACHABLE(); 1072 UNREACHABLE();
988 } 1073 }
1074 virtual void FillInBMInfo(
1075 int offset, BoyerMooreLookahead* bm, bool not_at_start) {
1076 // Returning 0 from EatsAtLeast should ensure we never get here.
1077 UNREACHABLE();
1078 }
989 virtual EndNode* Clone() { return new EndNode(*this); } 1079 virtual EndNode* Clone() { return new EndNode(*this); }
990 private: 1080 private:
991 Action action_; 1081 Action action_;
992 }; 1082 };
993 1083
994 1084
995 class NegativeSubmatchSuccess: public EndNode { 1085 class NegativeSubmatchSuccess: public EndNode {
996 public: 1086 public:
997 NegativeSubmatchSuccess(int stack_pointer_reg, 1087 NegativeSubmatchSuccess(int stack_pointer_reg,
998 int position_reg, 1088 int position_reg,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 int recursion_depth, 1154 int recursion_depth,
1065 bool not_at_start); 1155 bool not_at_start);
1066 int EatsAtLeastHelper(int still_to_find, 1156 int EatsAtLeastHelper(int still_to_find,
1067 int recursion_depth, 1157 int recursion_depth,
1068 RegExpNode* ignore_this_node, 1158 RegExpNode* ignore_this_node,
1069 bool not_at_start); 1159 bool not_at_start);
1070 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 1160 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
1071 RegExpCompiler* compiler, 1161 RegExpCompiler* compiler,
1072 int characters_filled_in, 1162 int characters_filled_in,
1073 bool not_at_start); 1163 bool not_at_start);
1164 virtual void FillInBMInfo(
1165 int offset, BoyerMooreLookahead* bm, bool not_at_start);
1074 virtual ChoiceNode* Clone() { return new ChoiceNode(*this); } 1166 virtual ChoiceNode* Clone() { return new ChoiceNode(*this); }
1075 1167
1076 bool being_calculated() { return being_calculated_; } 1168 bool being_calculated() { return being_calculated_; }
1077 bool not_at_start() { return not_at_start_; } 1169 bool not_at_start() { return not_at_start_; }
1078 void set_not_at_start() { not_at_start_ = true; } 1170 void set_not_at_start() { not_at_start_ = true; }
1079 void set_being_calculated(bool b) { being_calculated_ = b; } 1171 void set_being_calculated(bool b) { being_calculated_ = b; }
1080 virtual bool try_to_emit_quick_check_for_alternative(int i) { return true; } 1172 virtual bool try_to_emit_quick_check_for_alternative(int i) { return true; }
1081 1173
1082 protected: 1174 protected:
1083 int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative); 1175 int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative);
1084 ZoneList<GuardedAlternative>* alternatives_; 1176 ZoneList<GuardedAlternative>* alternatives_;
1085 1177
1086 private: 1178 private:
1087 friend class DispatchTableConstructor; 1179 friend class DispatchTableConstructor;
1088 friend class Analysis; 1180 friend class Analysis;
1089 void GenerateGuard(RegExpMacroAssembler* macro_assembler, 1181 void GenerateGuard(RegExpMacroAssembler* macro_assembler,
1090 Guard* guard, 1182 Guard* guard,
1091 Trace* trace); 1183 Trace* trace);
1092 int CalculatePreloadCharacters(RegExpCompiler* compiler, bool not_at_start); 1184 int CalculatePreloadCharacters(RegExpCompiler* compiler, int eats_at_least);
1093 void EmitOutOfLineContinuation(RegExpCompiler* compiler, 1185 void EmitOutOfLineContinuation(RegExpCompiler* compiler,
1094 Trace* trace, 1186 Trace* trace,
1095 GuardedAlternative alternative, 1187 GuardedAlternative alternative,
1096 AlternativeGeneration* alt_gen, 1188 AlternativeGeneration* alt_gen,
1097 int preload_characters, 1189 int preload_characters,
1098 bool next_expects_preload); 1190 bool next_expects_preload);
1099 DispatchTable* table_; 1191 DispatchTable* table_;
1100 // If true, this node is never checked at the start of the input. 1192 // If true, this node is never checked at the start of the input.
1101 // Allows a new trace to start with at_start() set to false. 1193 // Allows a new trace to start with at_start() set to false.
1102 bool not_at_start_; 1194 bool not_at_start_;
1103 bool being_calculated_; 1195 bool being_calculated_;
1104 }; 1196 };
1105 1197
1106 1198
1107 class NegativeLookaheadChoiceNode: public ChoiceNode { 1199 class NegativeLookaheadChoiceNode: public ChoiceNode {
1108 public: 1200 public:
1109 explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail, 1201 explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail,
1110 GuardedAlternative then_do_this) 1202 GuardedAlternative then_do_this)
1111 : ChoiceNode(2) { 1203 : ChoiceNode(2) {
1112 AddAlternative(this_must_fail); 1204 AddAlternative(this_must_fail);
1113 AddAlternative(then_do_this); 1205 AddAlternative(then_do_this);
1114 } 1206 }
1115 virtual int EatsAtLeast(int still_to_find, 1207 virtual int EatsAtLeast(int still_to_find,
1116 int recursion_depth, 1208 int recursion_depth,
1117 bool not_at_start); 1209 bool not_at_start);
1118 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 1210 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
1119 RegExpCompiler* compiler, 1211 RegExpCompiler* compiler,
1120 int characters_filled_in, 1212 int characters_filled_in,
1121 bool not_at_start); 1213 bool not_at_start);
1214 virtual void FillInBMInfo(
1215 int offset, BoyerMooreLookahead* bm, bool not_at_start) {
1216 alternatives_->at(1).node()->FillInBMInfo(offset, bm, not_at_start);
1217 }
1122 // For a negative lookahead we don't emit the quick check for the 1218 // For a negative lookahead we don't emit the quick check for the
1123 // alternative that is expected to fail. This is because quick check code 1219 // alternative that is expected to fail. This is because quick check code
1124 // starts by loading enough characters for the alternative that takes fewest 1220 // starts by loading enough characters for the alternative that takes fewest
1125 // characters, but on a negative lookahead the negative branch did not take 1221 // characters, but on a negative lookahead the negative branch did not take
1126 // part in that calculation (EatsAtLeast) so the assumptions don't hold. 1222 // part in that calculation (EatsAtLeast) so the assumptions don't hold.
1127 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } 1223 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; }
1128 virtual int ComputeFirstCharacterSet(int budget); 1224 virtual int ComputeFirstCharacterSet(int budget);
1129 }; 1225 };
1130 1226
1131 1227
1132 class LoopChoiceNode: public ChoiceNode { 1228 class LoopChoiceNode: public ChoiceNode {
1133 public: 1229 public:
1134 explicit LoopChoiceNode(bool body_can_be_zero_length) 1230 explicit LoopChoiceNode(bool body_can_be_zero_length)
1135 : ChoiceNode(2), 1231 : ChoiceNode(2),
1136 loop_node_(NULL), 1232 loop_node_(NULL),
1137 continue_node_(NULL), 1233 continue_node_(NULL),
1138 body_can_be_zero_length_(body_can_be_zero_length) { } 1234 body_can_be_zero_length_(body_can_be_zero_length) { }
1139 void AddLoopAlternative(GuardedAlternative alt); 1235 void AddLoopAlternative(GuardedAlternative alt);
1140 void AddContinueAlternative(GuardedAlternative alt); 1236 void AddContinueAlternative(GuardedAlternative alt);
1141 virtual void Emit(RegExpCompiler* compiler, Trace* trace); 1237 virtual void Emit(RegExpCompiler* compiler, Trace* trace);
1142 virtual int EatsAtLeast(int still_to_find, 1238 virtual int EatsAtLeast(int still_to_find,
1143 int recursion_depth, 1239 int recursion_depth,
1144 bool not_at_start); 1240 bool not_at_start);
1145 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 1241 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
1146 RegExpCompiler* compiler, 1242 RegExpCompiler* compiler,
1147 int characters_filled_in, 1243 int characters_filled_in,
1148 bool not_at_start); 1244 bool not_at_start);
1245 virtual void FillInBMInfo(
1246 int offset, BoyerMooreLookahead* bm, bool not_at_start);
1149 virtual int ComputeFirstCharacterSet(int budget); 1247 virtual int ComputeFirstCharacterSet(int budget);
1150 virtual LoopChoiceNode* Clone() { return new LoopChoiceNode(*this); } 1248 virtual LoopChoiceNode* Clone() { return new LoopChoiceNode(*this); }
1151 RegExpNode* loop_node() { return loop_node_; } 1249 RegExpNode* loop_node() { return loop_node_; }
1152 RegExpNode* continue_node() { return continue_node_; } 1250 RegExpNode* continue_node() { return continue_node_; }
1153 bool body_can_be_zero_length() { return body_can_be_zero_length_; } 1251 bool body_can_be_zero_length() { return body_can_be_zero_length_; }
1154 virtual void Accept(NodeVisitor* visitor); 1252 virtual void Accept(NodeVisitor* visitor);
1155 1253
1156 private: 1254 private:
1157 // AddAlternative is made private for loop nodes because alternatives 1255 // AddAlternative is made private for loop nodes because alternatives
1158 // should not be added freely, we need to keep track of which node 1256 // should not be added freely, we need to keep track of which node
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 num_registers(registers) {} 1549 num_registers(registers) {}
1452 const char* error_message; 1550 const char* error_message;
1453 Object* code; 1551 Object* code;
1454 int num_registers; 1552 int num_registers;
1455 }; 1553 };
1456 1554
1457 static CompilationResult Compile(RegExpCompileData* input, 1555 static CompilationResult Compile(RegExpCompileData* input,
1458 bool ignore_case, 1556 bool ignore_case,
1459 bool multiline, 1557 bool multiline,
1460 Handle<String> pattern, 1558 Handle<String> pattern,
1559 Handle<String> sample_subject,
1461 bool is_ascii); 1560 bool is_ascii);
1462 1561
1463 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); 1562 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case);
1464 }; 1563 };
1465 1564
1466 1565
1467 class OffsetsVector { 1566 class OffsetsVector {
1468 public: 1567 public:
1469 inline OffsetsVector(int num_registers, Isolate* isolate) 1568 inline OffsetsVector(int num_registers, Isolate* isolate)
1470 : offsets_vector_length_(num_registers) { 1569 : offsets_vector_length_(num_registers) {
(...skipping 22 matching lines...) Expand all
1493 int* vector_; 1592 int* vector_;
1494 int offsets_vector_length_; 1593 int offsets_vector_length_;
1495 1594
1496 friend class ExternalReference; 1595 friend class ExternalReference;
1497 }; 1596 };
1498 1597
1499 1598
1500 } } // namespace v8::internal 1599 } } // namespace v8::internal
1501 1600
1502 #endif // V8_JSREGEXP_H_ 1601 #endif // V8_JSREGEXP_H_
OLDNEW
« no previous file with comments | « no previous file | src/jsregexp.cc » ('j') | src/jsregexp.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698