OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_JSREGEXP_H_ | 5 #ifndef V8_JSREGEXP_H_ |
6 #define V8_JSREGEXP_H_ | 6 #define V8_JSREGEXP_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/assembler.h" | 9 #include "src/assembler.h" |
10 #include "src/zone-inl.h" | 10 #include "src/zone-inl.h" |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 TextElement(TextType text_type, RegExpTree* tree) | 438 TextElement(TextType text_type, RegExpTree* tree) |
439 : cp_offset_(-1), text_type_(text_type), tree_(tree) {} | 439 : cp_offset_(-1), text_type_(text_type), tree_(tree) {} |
440 | 440 |
441 int cp_offset_; | 441 int cp_offset_; |
442 TextType text_type_; | 442 TextType text_type_; |
443 RegExpTree* tree_; | 443 RegExpTree* tree_; |
444 }; | 444 }; |
445 | 445 |
446 | 446 |
447 class Trace; | 447 class Trace; |
448 | 448 struct PreloadState; |
| 449 class GreedyLoopState; |
| 450 class AlternativeGenerationList; |
449 | 451 |
450 struct NodeInfo { | 452 struct NodeInfo { |
451 NodeInfo() | 453 NodeInfo() |
452 : being_analyzed(false), | 454 : being_analyzed(false), |
453 been_analyzed(false), | 455 been_analyzed(false), |
454 follows_word_interest(false), | 456 follows_word_interest(false), |
455 follows_newline_interest(false), | 457 follows_newline_interest(false), |
456 follows_start_interest(false), | 458 follows_start_interest(false), |
457 at_end(false), | 459 at_end(false), |
458 visited(false), | 460 visited(false), |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 bool not_at_start); | 1071 bool not_at_start); |
1070 virtual void FillInBMInfo(int offset, | 1072 virtual void FillInBMInfo(int offset, |
1071 int budget, | 1073 int budget, |
1072 BoyerMooreLookahead* bm, | 1074 BoyerMooreLookahead* bm, |
1073 bool not_at_start); | 1075 bool not_at_start); |
1074 | 1076 |
1075 bool being_calculated() { return being_calculated_; } | 1077 bool being_calculated() { return being_calculated_; } |
1076 bool not_at_start() { return not_at_start_; } | 1078 bool not_at_start() { return not_at_start_; } |
1077 void set_not_at_start() { not_at_start_ = true; } | 1079 void set_not_at_start() { not_at_start_ = true; } |
1078 void set_being_calculated(bool b) { being_calculated_ = b; } | 1080 void set_being_calculated(bool b) { being_calculated_ = b; } |
1079 virtual bool try_to_emit_quick_check_for_alternative(int i) { return true; } | 1081 virtual bool try_to_emit_quick_check_for_alternative(bool is_first) { |
| 1082 return true; |
| 1083 } |
1080 virtual RegExpNode* FilterASCII(int depth, bool ignore_case); | 1084 virtual RegExpNode* FilterASCII(int depth, bool ignore_case); |
1081 | 1085 |
1082 protected: | 1086 protected: |
1083 int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative); | 1087 int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative); |
1084 ZoneList<GuardedAlternative>* alternatives_; | 1088 ZoneList<GuardedAlternative>* alternatives_; |
1085 | 1089 |
1086 private: | 1090 private: |
1087 friend class DispatchTableConstructor; | 1091 friend class DispatchTableConstructor; |
1088 friend class Analysis; | 1092 friend class Analysis; |
1089 void GenerateGuard(RegExpMacroAssembler* macro_assembler, | 1093 void GenerateGuard(RegExpMacroAssembler* macro_assembler, |
1090 Guard* guard, | 1094 Guard* guard, |
1091 Trace* trace); | 1095 Trace* trace); |
1092 int CalculatePreloadCharacters(RegExpCompiler* compiler, int eats_at_least); | 1096 int CalculatePreloadCharacters(RegExpCompiler* compiler, int eats_at_least); |
1093 void EmitOutOfLineContinuation(RegExpCompiler* compiler, | 1097 void EmitOutOfLineContinuation(RegExpCompiler* compiler, |
1094 Trace* trace, | 1098 Trace* trace, |
1095 GuardedAlternative alternative, | 1099 GuardedAlternative alternative, |
1096 AlternativeGeneration* alt_gen, | 1100 AlternativeGeneration* alt_gen, |
1097 int preload_characters, | 1101 int preload_characters, |
1098 bool next_expects_preload); | 1102 bool next_expects_preload); |
| 1103 void SetUpPreLoad(RegExpCompiler* compiler, |
| 1104 Trace* current_trace, |
| 1105 PreloadState* preloads); |
| 1106 void AssertGuardsMentionRegisters(Trace* trace); |
| 1107 int EmitOptimizedUnanchoredSearch(RegExpCompiler* compiler, Trace* trace); |
| 1108 Trace* EmitGreedyLoop(RegExpCompiler* compiler, |
| 1109 Trace* trace, |
| 1110 AlternativeGenerationList* alt_gens, |
| 1111 PreloadState* preloads, |
| 1112 GreedyLoopState* greedy_loop_state, |
| 1113 int text_length); |
| 1114 void EmitChoices(RegExpCompiler* compiler, |
| 1115 AlternativeGenerationList* alt_gens, |
| 1116 int first_choice, |
| 1117 Trace* trace, |
| 1118 bool is_greedy_loop, |
| 1119 PreloadState* preloads); |
1099 DispatchTable* table_; | 1120 DispatchTable* table_; |
1100 // If true, this node is never checked at the start of the input. | 1121 // 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. | 1122 // Allows a new trace to start with at_start() set to false. |
1102 bool not_at_start_; | 1123 bool not_at_start_; |
1103 bool being_calculated_; | 1124 bool being_calculated_; |
1104 }; | 1125 }; |
1105 | 1126 |
1106 | 1127 |
1107 class NegativeLookaheadChoiceNode: public ChoiceNode { | 1128 class NegativeLookaheadChoiceNode: public ChoiceNode { |
1108 public: | 1129 public: |
(...skipping 15 matching lines...) Expand all Loading... |
1124 bool not_at_start) { | 1145 bool not_at_start) { |
1125 alternatives_->at(1).node()->FillInBMInfo( | 1146 alternatives_->at(1).node()->FillInBMInfo( |
1126 offset, budget - 1, bm, not_at_start); | 1147 offset, budget - 1, bm, not_at_start); |
1127 if (offset == 0) set_bm_info(not_at_start, bm); | 1148 if (offset == 0) set_bm_info(not_at_start, bm); |
1128 } | 1149 } |
1129 // For a negative lookahead we don't emit the quick check for the | 1150 // For a negative lookahead we don't emit the quick check for the |
1130 // alternative that is expected to fail. This is because quick check code | 1151 // alternative that is expected to fail. This is because quick check code |
1131 // starts by loading enough characters for the alternative that takes fewest | 1152 // starts by loading enough characters for the alternative that takes fewest |
1132 // characters, but on a negative lookahead the negative branch did not take | 1153 // characters, but on a negative lookahead the negative branch did not take |
1133 // part in that calculation (EatsAtLeast) so the assumptions don't hold. | 1154 // part in that calculation (EatsAtLeast) so the assumptions don't hold. |
1134 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } | 1155 virtual bool try_to_emit_quick_check_for_alternative(bool is_first) { |
| 1156 return !is_first; |
| 1157 } |
1135 virtual RegExpNode* FilterASCII(int depth, bool ignore_case); | 1158 virtual RegExpNode* FilterASCII(int depth, bool ignore_case); |
1136 }; | 1159 }; |
1137 | 1160 |
1138 | 1161 |
1139 class LoopChoiceNode: public ChoiceNode { | 1162 class LoopChoiceNode: public ChoiceNode { |
1140 public: | 1163 public: |
1141 explicit LoopChoiceNode(bool body_can_be_zero_length, Zone* zone) | 1164 explicit LoopChoiceNode(bool body_can_be_zero_length, Zone* zone) |
1142 : ChoiceNode(2, zone), | 1165 : ChoiceNode(2, zone), |
1143 loop_node_(NULL), | 1166 loop_node_(NULL), |
1144 continue_node_(NULL), | 1167 continue_node_(NULL), |
1145 body_can_be_zero_length_(body_can_be_zero_length) { } | 1168 body_can_be_zero_length_(body_can_be_zero_length) |
| 1169 { } |
1146 void AddLoopAlternative(GuardedAlternative alt); | 1170 void AddLoopAlternative(GuardedAlternative alt); |
1147 void AddContinueAlternative(GuardedAlternative alt); | 1171 void AddContinueAlternative(GuardedAlternative alt); |
1148 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 1172 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
1149 virtual int EatsAtLeast(int still_to_find, int budget, bool not_at_start); | 1173 virtual int EatsAtLeast(int still_to_find, int budget, bool not_at_start); |
1150 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 1174 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
1151 RegExpCompiler* compiler, | 1175 RegExpCompiler* compiler, |
1152 int characters_filled_in, | 1176 int characters_filled_in, |
1153 bool not_at_start); | 1177 bool not_at_start); |
1154 virtual void FillInBMInfo(int offset, | 1178 virtual void FillInBMInfo(int offset, |
1155 int budget, | 1179 int budget, |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 } | 1310 } |
1287 } | 1311 } |
1288 | 1312 |
1289 void SetAll(int map_number) { | 1313 void SetAll(int map_number) { |
1290 bitmaps_->at(map_number)->SetAll(); | 1314 bitmaps_->at(map_number)->SetAll(); |
1291 } | 1315 } |
1292 | 1316 |
1293 void SetRest(int from_map) { | 1317 void SetRest(int from_map) { |
1294 for (int i = from_map; i < length_; i++) SetAll(i); | 1318 for (int i = from_map; i < length_; i++) SetAll(i); |
1295 } | 1319 } |
1296 bool EmitSkipInstructions(RegExpMacroAssembler* masm); | 1320 void EmitSkipInstructions(RegExpMacroAssembler* masm); |
1297 | 1321 |
1298 private: | 1322 private: |
1299 // This is the value obtained by EatsAtLeast. If we do not have at least this | 1323 // This is the value obtained by EatsAtLeast. If we do not have at least this |
1300 // many characters left in the sample string then the match is bound to fail. | 1324 // many characters left in the sample string then the match is bound to fail. |
1301 // Therefore it is OK to read a character this far ahead of the current match | 1325 // Therefore it is OK to read a character this far ahead of the current match |
1302 // point. | 1326 // point. |
1303 int length_; | 1327 int length_; |
1304 RegExpCompiler* compiler_; | 1328 RegExpCompiler* compiler_; |
1305 // 0x7f for ASCII, 0xffff for UTF-16. | 1329 // 0x7f for ASCII, 0xffff for UTF-16. |
1306 int max_char_; | 1330 int max_char_; |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1479 RegExpNode* stop_node_; | 1503 RegExpNode* stop_node_; |
1480 Label* loop_label_; | 1504 Label* loop_label_; |
1481 int characters_preloaded_; | 1505 int characters_preloaded_; |
1482 int bound_checked_up_to_; | 1506 int bound_checked_up_to_; |
1483 QuickCheckDetails quick_check_performed_; | 1507 QuickCheckDetails quick_check_performed_; |
1484 int flush_budget_; | 1508 int flush_budget_; |
1485 TriBool at_start_; | 1509 TriBool at_start_; |
1486 }; | 1510 }; |
1487 | 1511 |
1488 | 1512 |
| 1513 class GreedyLoopState { |
| 1514 public: |
| 1515 explicit GreedyLoopState(bool not_at_start); |
| 1516 |
| 1517 Label* label() { return &label_; } |
| 1518 Trace* counter_backtrack_trace() { return &counter_backtrack_trace_; } |
| 1519 |
| 1520 private: |
| 1521 Label label_; |
| 1522 Trace counter_backtrack_trace_; |
| 1523 }; |
| 1524 |
| 1525 |
| 1526 struct PreloadState { |
| 1527 static const int kEatsAtLeastNotYetInitialized = -1; |
| 1528 bool preload_is_current_; |
| 1529 bool preload_has_checked_bounds_; |
| 1530 int preload_characters_; |
| 1531 int eats_at_least_; |
| 1532 void init() { |
| 1533 eats_at_least_ = kEatsAtLeastNotYetInitialized; |
| 1534 } |
| 1535 }; |
| 1536 |
| 1537 |
1489 class NodeVisitor { | 1538 class NodeVisitor { |
1490 public: | 1539 public: |
1491 virtual ~NodeVisitor() { } | 1540 virtual ~NodeVisitor() { } |
1492 #define DECLARE_VISIT(Type) \ | 1541 #define DECLARE_VISIT(Type) \ |
1493 virtual void Visit##Type(Type##Node* that) = 0; | 1542 virtual void Visit##Type(Type##Node* that) = 0; |
1494 FOR_EACH_NODE_TYPE(DECLARE_VISIT) | 1543 FOR_EACH_NODE_TYPE(DECLARE_VISIT) |
1495 #undef DECLARE_VISIT | 1544 #undef DECLARE_VISIT |
1496 virtual void VisitLoopChoice(LoopChoiceNode* that) { VisitChoice(that); } | 1545 virtual void VisitLoopChoice(LoopChoiceNode* that) { VisitChoice(that); } |
1497 }; | 1546 }; |
1498 | 1547 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 Handle<String> sample_subject, | 1665 Handle<String> sample_subject, |
1617 bool is_ascii, Zone* zone); | 1666 bool is_ascii, Zone* zone); |
1618 | 1667 |
1619 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); | 1668 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); |
1620 }; | 1669 }; |
1621 | 1670 |
1622 | 1671 |
1623 } } // namespace v8::internal | 1672 } } // namespace v8::internal |
1624 | 1673 |
1625 #endif // V8_JSREGEXP_H_ | 1674 #endif // V8_JSREGEXP_H_ |
OLD | NEW |