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

Side by Side Diff: src/jsregexp.h

Issue 7374002: Refactor allocation policies. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 5 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 | « src/json-parser.h ('k') | src/jsregexp.cc » ('j') | 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-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 } 280 }
281 bool Contains(uc16 i) { return from_ <= i && i <= to_; } 281 bool Contains(uc16 i) { return from_ <= i && i <= to_; }
282 uc16 from() const { return from_; } 282 uc16 from() const { return from_; }
283 void set_from(uc16 value) { from_ = value; } 283 void set_from(uc16 value) { from_ = value; }
284 uc16 to() const { return to_; } 284 uc16 to() const { return to_; }
285 void set_to(uc16 value) { to_ = value; } 285 void set_to(uc16 value) { to_ = value; }
286 bool is_valid() { return from_ <= to_; } 286 bool is_valid() { return from_ <= to_; }
287 bool IsEverything(uc16 max) { return from_ == 0 && to_ >= max; } 287 bool IsEverything(uc16 max) { return from_ == 0 && to_ >= max; }
288 bool IsSingleton() { return (from_ == to_); } 288 bool IsSingleton() { return (from_ == to_); }
289 void AddCaseEquivalents(ZoneList<CharacterRange>* ranges, bool is_ascii); 289 void AddCaseEquivalents(ZoneList<CharacterRange>* ranges, bool is_ascii);
290 static void Split(ZoneList<CharacterRange>* base, 290 static void Split(Zone* zone,
291 ZoneList<CharacterRange>* base,
291 Vector<const uc16> overlay, 292 Vector<const uc16> overlay,
292 ZoneList<CharacterRange>** included, 293 ZoneList<CharacterRange>** included,
293 ZoneList<CharacterRange>** excluded); 294 ZoneList<CharacterRange>** excluded);
294 // Whether a range list is in canonical form: Ranges ordered by from value, 295 // Whether a range list is in canonical form: Ranges ordered by from value,
295 // and ranges non-overlapping and non-adjacent. 296 // and ranges non-overlapping and non-adjacent.
296 static bool IsCanonical(ZoneList<CharacterRange>* ranges); 297 static bool IsCanonical(ZoneList<CharacterRange>* ranges);
297 // Convert range list to canonical form. The characters covered by the ranges 298 // Convert range list to canonical form. The characters covered by the ranges
298 // will still be the same, but no character is in more than one range, and 299 // will still be the same, but no character is in more than one range, and
299 // adjacent ranges are merged. The resulting list may be shorter than the 300 // adjacent ranges are merged. The resulting list may be shorter than the
300 // original, but cannot be longer. 301 // original, but cannot be longer.
(...skipping 30 matching lines...) Expand all
331 uc16 from_; 332 uc16 from_;
332 uc16 to_; 333 uc16 to_;
333 }; 334 };
334 335
335 336
336 // A set of unsigned integers that behaves especially well on small 337 // A set of unsigned integers that behaves especially well on small
337 // integers (< 32). May do zone-allocation. 338 // integers (< 32). May do zone-allocation.
338 class OutSet: public ZoneObject { 339 class OutSet: public ZoneObject {
339 public: 340 public:
340 OutSet() : first_(0), remaining_(NULL), successors_(NULL) { } 341 OutSet() : first_(0), remaining_(NULL), successors_(NULL) { }
341 OutSet* Extend(unsigned value); 342 OutSet* Extend(Zone* zone, unsigned value);
342 bool Get(unsigned value); 343 bool Get(unsigned value);
343 static const unsigned kFirstLimit = 32; 344 static const unsigned kFirstLimit = 32;
344 345
345 private: 346 private:
346 // Destructively set a value in this set. In most cases you want 347 // Destructively set a value in this set. In most cases you want
347 // to use Extend instead to ensure that only one instance exists 348 // to use Extend instead to ensure that only one instance exists
348 // that contains the same values. 349 // that contains the same values.
349 void Set(unsigned value); 350 void Set(Zone* zone, unsigned value);
350 351
351 // The successors are a list of sets that contain the same values 352 // The successors are a list of sets that contain the same values
352 // as this set and the one more value that is not present in this 353 // as this set and the one more value that is not present in this
353 // set. 354 // set.
354 ZoneList<OutSet*>* successors() { return successors_; } 355 ZoneList<OutSet*>* successors() { return successors_; }
355 356
356 OutSet(uint32_t first, ZoneList<unsigned>* remaining) 357 OutSet(uint32_t first, ZoneList<unsigned>* remaining)
357 : first_(first), remaining_(remaining), successors_(NULL) { } 358 : first_(first), remaining_(remaining), successors_(NULL) { }
358 uint32_t first_; 359 uint32_t first_;
359 ZoneList<unsigned>* remaining_; 360 ZoneList<unsigned>* remaining_;
360 ZoneList<OutSet*>* successors_; 361 ZoneList<OutSet*>* successors_;
361 friend class Trace; 362 friend class Trace;
362 }; 363 };
363 364
364 365
365 // A mapping from integers, specified as ranges, to a set of integers. 366 // A mapping from integers, specified as ranges, to a set of integers.
366 // Used for mapping character ranges to choices. 367 // Used for mapping character ranges to choices.
367 class DispatchTable : public ZoneObject { 368 class DispatchTable : public ZoneObject {
368 public: 369 public:
369 class Entry { 370 class Entry {
370 public: 371 public:
371 Entry() : from_(0), to_(0), out_set_(NULL) { } 372 Entry() : from_(0), to_(0), out_set_(NULL) { }
372 Entry(uc16 from, uc16 to, OutSet* out_set) 373 Entry(uc16 from, uc16 to, OutSet* out_set)
373 : from_(from), to_(to), out_set_(out_set) { } 374 : from_(from), to_(to), out_set_(out_set) { }
374 uc16 from() { return from_; } 375 uc16 from() { return from_; }
375 uc16 to() { return to_; } 376 uc16 to() { return to_; }
376 void set_to(uc16 value) { to_ = value; } 377 void set_to(uc16 value) { to_ = value; }
377 void AddValue(int value) { out_set_ = out_set_->Extend(value); } 378 void AddValue(Zone* zone, int value) {
379 out_set_ = out_set_->Extend(zone, value);
380 }
378 OutSet* out_set() { return out_set_; } 381 OutSet* out_set() { return out_set_; }
379 private: 382 private:
380 uc16 from_; 383 uc16 from_;
381 uc16 to_; 384 uc16 to_;
382 OutSet* out_set_; 385 OutSet* out_set_;
383 }; 386 };
384 387
385 class Config { 388 class Config {
386 public: 389 public:
387 typedef uc16 Key; 390 typedef uc16 Key;
388 typedef Entry Value; 391 typedef Entry Value;
389 static const uc16 kNoKey; 392 static const uc16 kNoKey;
390 static const Entry kNoValue; 393 static const Entry kNoValue;
391 static inline int Compare(uc16 a, uc16 b) { 394 static inline int Compare(uc16 a, uc16 b) {
392 if (a == b) 395 if (a == b)
393 return 0; 396 return 0;
394 else if (a < b) 397 else if (a < b)
395 return -1; 398 return -1;
396 else 399 else
397 return 1; 400 return 1;
398 } 401 }
399 }; 402 };
400 403
404 explicit DispatchTable(Zone* zone) : zone_(zone), tree_(zone) {}
405
401 void AddRange(CharacterRange range, int value); 406 void AddRange(CharacterRange range, int value);
402 OutSet* Get(uc16 value); 407 OutSet* Get(uc16 value);
403 void Dump(); 408 void Dump();
404 409
405 template <typename Callback> 410 template <typename Callback>
406 void ForEach(Callback* callback) { return tree()->ForEach(callback); } 411 void ForEach(Callback* callback) { return tree()->ForEach(callback); }
407 private: 412 private:
408 // There can't be a static empty set since it allocates its 413 // There can't be a static empty set since it allocates its
409 // successors in a zone and caches them. 414 // successors in a zone and caches them.
410 OutSet* empty() { return &empty_; } 415 OutSet* empty() { return &empty_; }
416 Zone* zone_;
411 OutSet empty_; 417 OutSet empty_;
412 ZoneSplayTree<Config>* tree() { return &tree_; } 418 ZoneSplayTree<Config>* tree() { return &tree_; }
413 ZoneSplayTree<Config> tree_; 419 ZoneSplayTree<Config> tree_;
414 }; 420 };
415 421
416 422
417 #define FOR_EACH_NODE_TYPE(VISIT) \ 423 #define FOR_EACH_NODE_TYPE(VISIT) \
418 VISIT(End) \ 424 VISIT(End) \
419 VISIT(Action) \ 425 VISIT(Action) \
420 VISIT(Choice) \ 426 VISIT(Choice) \
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 bool visited: 1; 528 bool visited: 1;
523 }; 529 };
524 530
525 531
526 class SiblingList { 532 class SiblingList {
527 public: 533 public:
528 SiblingList() : list_(NULL) { } 534 SiblingList() : list_(NULL) { }
529 int length() { 535 int length() {
530 return list_ == NULL ? 0 : list_->length(); 536 return list_ == NULL ? 0 : list_->length();
531 } 537 }
532 void Ensure(RegExpNode* parent) { 538 void Ensure(Zone* zone, RegExpNode* parent) {
533 if (list_ == NULL) { 539 if (list_ == NULL) {
534 list_ = new ZoneList<RegExpNode*>(2); 540 list_ = ZoneList<RegExpNode*>::New(zone, 2);
535 list_->Add(parent); 541 list_->Add(parent);
536 } 542 }
537 } 543 }
538 void Add(RegExpNode* node) { list_->Add(node); } 544 void Add(RegExpNode* node) { list_->Add(node); }
539 RegExpNode* Get(int index) { return list_->at(index); } 545 RegExpNode* Get(int index) { return list_->at(index); }
540 private: 546 private:
541 ZoneList<RegExpNode*>* list_; 547 ZoneList<RegExpNode*>* list_;
542 }; 548 };
543 549
544 550
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 // the deferred actions in the current trace and generating a goto. 644 // the deferred actions in the current trace and generating a goto.
639 static const int kMaxCopiesCodeGenerated = 10; 645 static const int kMaxCopiesCodeGenerated = 10;
640 646
641 NodeInfo* info() { return &info_; } 647 NodeInfo* info() { return &info_; }
642 648
643 void AddSibling(RegExpNode* node) { siblings_.Add(node); } 649 void AddSibling(RegExpNode* node) { siblings_.Add(node); }
644 650
645 // Static version of EnsureSibling that expresses the fact that the 651 // Static version of EnsureSibling that expresses the fact that the
646 // result has the same type as the input. 652 // result has the same type as the input.
647 template <class C> 653 template <class C>
648 static C* EnsureSibling(C* node, NodeInfo* info, bool* cloned) { 654 static C* EnsureSibling(Zone* zone, C* node, NodeInfo* info, bool* cloned) {
649 return static_cast<C*>(node->EnsureSibling(info, cloned)); 655 return static_cast<C*>(node->EnsureSibling(zone, info, cloned));
650 } 656 }
651 657
652 SiblingList* siblings() { return &siblings_; } 658 SiblingList* siblings() { return &siblings_; }
653 void set_siblings(SiblingList* other) { siblings_ = *other; } 659 void set_siblings(SiblingList* other) { siblings_ = *other; }
654 660
655 // Return the set of possible next characters recognized by the regexp 661 // Return the set of possible next characters recognized by the regexp
656 // (or a safe subset, potentially the set of all characters). 662 // (or a safe subset, potentially the set of all characters).
657 ZoneList<CharacterRange>* FirstCharacterSet(); 663 ZoneList<CharacterRange>* FirstCharacterSet(Zone* zone);
658 664
659 // Compute (if possible within the budget of traversed nodes) the 665 // Compute (if possible within the budget of traversed nodes) the
660 // possible first characters of the input matched by this node and 666 // possible first characters of the input matched by this node and
661 // its continuation. Returns the remaining budget after the computation. 667 // its continuation. Returns the remaining budget after the computation.
662 // If the budget is spent, the result is negative, and the cached 668 // If the budget is spent, the result is negative, and the cached
663 // first_character_set_ value isn't set. 669 // first_character_set_ value isn't set.
664 virtual int ComputeFirstCharacterSet(int budget); 670 virtual int ComputeFirstCharacterSet(Zone* zone, int budget);
665 671
666 // Get and set the cached first character set value. 672 // Get and set the cached first character set value.
667 ZoneList<CharacterRange>* first_character_set() { 673 ZoneList<CharacterRange>* first_character_set() {
668 return first_character_set_; 674 return first_character_set_;
669 } 675 }
670 void set_first_character_set(ZoneList<CharacterRange>* character_set) { 676 void set_first_character_set(ZoneList<CharacterRange>* character_set) {
671 first_character_set_ = character_set; 677 first_character_set_ = character_set;
672 } 678 }
673 679
674 protected: 680 protected:
675 enum LimitResult { DONE, CONTINUE }; 681 enum LimitResult { DONE, CONTINUE };
676 static const int kComputeFirstCharacterSetFail = -1; 682 static const int kComputeFirstCharacterSetFail = -1;
677 683
678 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); 684 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace);
679 685
680 // Returns a sibling of this node whose interests and assumptions 686 // Returns a sibling of this node whose interests and assumptions
681 // match the ones in the given node info. If no sibling exists NULL 687 // match the ones in the given node info. If no sibling exists NULL
682 // is returned. 688 // is returned.
683 RegExpNode* TryGetSibling(NodeInfo* info); 689 RegExpNode* TryGetSibling(NodeInfo* info);
684 690
685 // Returns a sibling of this node whose interests match the ones in 691 // Returns a sibling of this node whose interests match the ones in
686 // the given node info. The info must not contain any assertions. 692 // the given node info. The info must not contain any assertions.
687 // If no node exists a new one will be created by cloning the current 693 // If no node exists a new one will be created by cloning the current
688 // node. The result will always be an instance of the same concrete 694 // node. The result will always be an instance of the same concrete
689 // class as this node. 695 // class as this node.
690 RegExpNode* EnsureSibling(NodeInfo* info, bool* cloned); 696 RegExpNode* EnsureSibling(Zone* zone, NodeInfo* info, bool* cloned);
691 697
692 // Returns a clone of this node initialized using the copy constructor 698 // Returns a clone of this node initialized using the copy constructor
693 // of its concrete class. Note that the node may have to be pre- 699 // of its concrete class. Note that the node may have to be pre-
694 // processed before it is on a usable state. 700 // processed before it is on a usable state.
695 virtual RegExpNode* Clone() = 0; 701 virtual RegExpNode* Clone() = 0;
696 702
697 private: 703 private:
698 static const int kFirstCharBudget = 10; 704 static const int kFirstCharBudget = 10;
699 Label label_; 705 Label label_;
700 NodeInfo info_; 706 NodeInfo info_;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 RegExpCompiler* compiler, 791 RegExpCompiler* compiler,
786 int filled_in, 792 int filled_in,
787 bool not_at_start) { 793 bool not_at_start) {
788 return on_success()->GetQuickCheckDetails( 794 return on_success()->GetQuickCheckDetails(
789 details, compiler, filled_in, not_at_start); 795 details, compiler, filled_in, not_at_start);
790 } 796 }
791 Type type() { return type_; } 797 Type type() { return type_; }
792 // TODO(erikcorry): We should allow some action nodes in greedy loops. 798 // TODO(erikcorry): We should allow some action nodes in greedy loops.
793 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; } 799 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
794 virtual ActionNode* Clone() { return new ActionNode(*this); } 800 virtual ActionNode* Clone() { return new ActionNode(*this); }
795 virtual int ComputeFirstCharacterSet(int budget); 801 virtual int ComputeFirstCharacterSet(Zone* zone, int budget);
796 private: 802 private:
797 union { 803 union {
798 struct { 804 struct {
799 int reg; 805 int reg;
800 int value; 806 int value;
801 } u_store_register; 807 } u_store_register;
802 struct { 808 struct {
803 int reg; 809 int reg;
804 } u_increment_register; 810 } u_increment_register;
805 struct { 811 struct {
(...skipping 23 matching lines...) Expand all
829 friend class DotPrinter; 835 friend class DotPrinter;
830 }; 836 };
831 837
832 838
833 class TextNode: public SeqRegExpNode { 839 class TextNode: public SeqRegExpNode {
834 public: 840 public:
835 TextNode(ZoneList<TextElement>* elms, 841 TextNode(ZoneList<TextElement>* elms,
836 RegExpNode* on_success) 842 RegExpNode* on_success)
837 : SeqRegExpNode(on_success), 843 : SeqRegExpNode(on_success),
838 elms_(elms) { } 844 elms_(elms) { }
839 TextNode(RegExpCharacterClass* that, 845 TextNode(Zone* zone,
846 RegExpCharacterClass* that,
840 RegExpNode* on_success) 847 RegExpNode* on_success)
841 : SeqRegExpNode(on_success), 848 : SeqRegExpNode(on_success),
842 elms_(new ZoneList<TextElement>(1)) { 849 elms_(ZoneList<TextElement>::New(zone, 1)) {
843 elms_->Add(TextElement::CharClass(that)); 850 elms_->Add(TextElement::CharClass(that));
844 } 851 }
845 virtual void Accept(NodeVisitor* visitor); 852 virtual void Accept(NodeVisitor* visitor);
846 virtual void Emit(RegExpCompiler* compiler, Trace* trace); 853 virtual void Emit(RegExpCompiler* compiler, Trace* trace);
847 virtual int EatsAtLeast(int still_to_find, 854 virtual int EatsAtLeast(int still_to_find,
848 int recursion_depth, 855 int recursion_depth,
849 bool not_at_start); 856 bool not_at_start);
850 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 857 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
851 RegExpCompiler* compiler, 858 RegExpCompiler* compiler,
852 int characters_filled_in, 859 int characters_filled_in,
853 bool not_at_start); 860 bool not_at_start);
854 ZoneList<TextElement>* elements() { return elms_; } 861 ZoneList<TextElement>* elements() { return elms_; }
855 void MakeCaseIndependent(bool is_ascii); 862 void MakeCaseIndependent(Zone* zone, bool is_ascii);
856 virtual int GreedyLoopTextLength(); 863 virtual int GreedyLoopTextLength();
857 virtual TextNode* Clone() { 864 virtual TextNode* Clone() {
858 TextNode* result = new TextNode(*this); 865 TextNode* result = new TextNode(*this);
859 result->CalculateOffsets(); 866 result->CalculateOffsets();
860 return result; 867 return result;
861 } 868 }
862 void CalculateOffsets(); 869 void CalculateOffsets();
863 virtual int ComputeFirstCharacterSet(int budget); 870 virtual int ComputeFirstCharacterSet(Zone* zone, int budget);
864 private: 871 private:
865 enum TextEmitPassType { 872 enum TextEmitPassType {
866 NON_ASCII_MATCH, // Check for characters that can't match. 873 NON_ASCII_MATCH, // Check for characters that can't match.
867 SIMPLE_CHARACTER_MATCH, // Case-dependent single character check. 874 SIMPLE_CHARACTER_MATCH, // Case-dependent single character check.
868 NON_LETTER_CHARACTER_MATCH, // Check characters that have no case equivs. 875 NON_LETTER_CHARACTER_MATCH, // Check characters that have no case equivs.
869 CASE_CHARACTER_MATCH, // Case-independent single character check. 876 CASE_CHARACTER_MATCH, // Case-independent single character check.
870 CHARACTER_CLASS_MATCH // Character class. 877 CHARACTER_CLASS_MATCH // Character class.
871 }; 878 };
872 static bool SkipPass(int pass, bool ignore_case); 879 static bool SkipPass(int pass, bool ignore_case);
873 static const int kFirstRealPass = SIMPLE_CHARACTER_MATCH; 880 static const int kFirstRealPass = SIMPLE_CHARACTER_MATCH;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 } 921 }
915 virtual void Accept(NodeVisitor* visitor); 922 virtual void Accept(NodeVisitor* visitor);
916 virtual void Emit(RegExpCompiler* compiler, Trace* trace); 923 virtual void Emit(RegExpCompiler* compiler, Trace* trace);
917 virtual int EatsAtLeast(int still_to_find, 924 virtual int EatsAtLeast(int still_to_find,
918 int recursion_depth, 925 int recursion_depth,
919 bool not_at_start); 926 bool not_at_start);
920 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 927 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
921 RegExpCompiler* compiler, 928 RegExpCompiler* compiler,
922 int filled_in, 929 int filled_in,
923 bool not_at_start); 930 bool not_at_start);
924 virtual int ComputeFirstCharacterSet(int budget); 931 virtual int ComputeFirstCharacterSet(Zone* zone, int budget);
925 virtual AssertionNode* Clone() { return new AssertionNode(*this); } 932 virtual AssertionNode* Clone() { return new AssertionNode(*this); }
926 AssertionNodeType type() { return type_; } 933 AssertionNodeType type() { return type_; }
927 void set_type(AssertionNodeType type) { type_ = type; } 934 void set_type(AssertionNodeType type) { type_ = type; }
928 private: 935 private:
929 AssertionNode(AssertionNodeType t, RegExpNode* on_success) 936 AssertionNode(AssertionNodeType t, RegExpNode* on_success)
930 : SeqRegExpNode(on_success), type_(t) { } 937 : SeqRegExpNode(on_success), type_(t) { }
931 AssertionNodeType type_; 938 AssertionNodeType type_;
932 }; 939 };
933 940
934 941
(...skipping 12 matching lines...) Expand all
947 virtual int EatsAtLeast(int still_to_find, 954 virtual int EatsAtLeast(int still_to_find,
948 int recursion_depth, 955 int recursion_depth,
949 bool not_at_start); 956 bool not_at_start);
950 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 957 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
951 RegExpCompiler* compiler, 958 RegExpCompiler* compiler,
952 int characters_filled_in, 959 int characters_filled_in,
953 bool not_at_start) { 960 bool not_at_start) {
954 return; 961 return;
955 } 962 }
956 virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); } 963 virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); }
957 virtual int ComputeFirstCharacterSet(int budget); 964 virtual int ComputeFirstCharacterSet(Zone* zone, int budget);
958 private: 965 private:
959 int start_reg_; 966 int start_reg_;
960 int end_reg_; 967 int end_reg_;
961 }; 968 };
962 969
963 970
964 class EndNode: public RegExpNode { 971 class EndNode: public RegExpNode {
965 public: 972 public:
966 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; 973 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS };
967 explicit EndNode(Action action) : action_(action) { } 974 explicit EndNode(Action action) : action_(action) { }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 private: 1025 private:
1019 int reg_; 1026 int reg_;
1020 Relation op_; 1027 Relation op_;
1021 int value_; 1028 int value_;
1022 }; 1029 };
1023 1030
1024 1031
1025 class GuardedAlternative { 1032 class GuardedAlternative {
1026 public: 1033 public:
1027 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { } 1034 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { }
1028 void AddGuard(Guard* guard); 1035 void AddGuard(Zone* zone, Guard* guard);
1029 RegExpNode* node() { return node_; } 1036 RegExpNode* node() { return node_; }
1030 void set_node(RegExpNode* node) { node_ = node; } 1037 void set_node(RegExpNode* node) { node_ = node; }
1031 ZoneList<Guard*>* guards() { return guards_; } 1038 ZoneList<Guard*>* guards() { return guards_; }
1032 1039
1033 private: 1040 private:
1034 RegExpNode* node_; 1041 RegExpNode* node_;
1035 ZoneList<Guard*>* guards_; 1042 ZoneList<Guard*>* guards_;
1036 }; 1043 };
1037 1044
1038 1045
1039 class AlternativeGeneration; 1046 class AlternativeGeneration;
1040 1047
1041 1048
1042 class ChoiceNode: public RegExpNode { 1049 class ChoiceNode: public RegExpNode {
1043 public: 1050 public:
1044 explicit ChoiceNode(int expected_size) 1051 ChoiceNode(Zone* zone, int expected_size)
1045 : alternatives_(new ZoneList<GuardedAlternative>(expected_size)), 1052 : alternatives_(ZoneList<GuardedAlternative>::New(zone, expected_size)),
1046 table_(NULL), 1053 table_(NULL),
1047 not_at_start_(false), 1054 not_at_start_(false),
1048 being_calculated_(false) { } 1055 being_calculated_(false) { }
1049 virtual void Accept(NodeVisitor* visitor); 1056 virtual void Accept(NodeVisitor* visitor);
1050 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } 1057 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); }
1051 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } 1058 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; }
1052 DispatchTable* GetTable(bool ignore_case); 1059 DispatchTable* GetTable(Zone* zone, bool ignore_case);
1053 virtual void Emit(RegExpCompiler* compiler, Trace* trace); 1060 virtual void Emit(RegExpCompiler* compiler, Trace* trace);
1054 virtual int EatsAtLeast(int still_to_find, 1061 virtual int EatsAtLeast(int still_to_find,
1055 int recursion_depth, 1062 int recursion_depth,
1056 bool not_at_start); 1063 bool not_at_start);
1057 int EatsAtLeastHelper(int still_to_find, 1064 int EatsAtLeastHelper(int still_to_find,
1058 int recursion_depth, 1065 int recursion_depth,
1059 RegExpNode* ignore_this_node, 1066 RegExpNode* ignore_this_node,
1060 bool not_at_start); 1067 bool not_at_start);
1061 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 1068 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
1062 RegExpCompiler* compiler, 1069 RegExpCompiler* compiler,
(...skipping 27 matching lines...) Expand all
1090 DispatchTable* table_; 1097 DispatchTable* table_;
1091 // If true, this node is never checked at the start of the input. 1098 // If true, this node is never checked at the start of the input.
1092 // Allows a new trace to start with at_start() set to false. 1099 // Allows a new trace to start with at_start() set to false.
1093 bool not_at_start_; 1100 bool not_at_start_;
1094 bool being_calculated_; 1101 bool being_calculated_;
1095 }; 1102 };
1096 1103
1097 1104
1098 class NegativeLookaheadChoiceNode: public ChoiceNode { 1105 class NegativeLookaheadChoiceNode: public ChoiceNode {
1099 public: 1106 public:
1100 explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail, 1107 explicit NegativeLookaheadChoiceNode(Zone* zone,
1108 GuardedAlternative this_must_fail,
1101 GuardedAlternative then_do_this) 1109 GuardedAlternative then_do_this)
1102 : ChoiceNode(2) { 1110 : ChoiceNode(zone, 2) {
1103 AddAlternative(this_must_fail); 1111 AddAlternative(this_must_fail);
1104 AddAlternative(then_do_this); 1112 AddAlternative(then_do_this);
1105 } 1113 }
1106 virtual int EatsAtLeast(int still_to_find, 1114 virtual int EatsAtLeast(int still_to_find,
1107 int recursion_depth, 1115 int recursion_depth,
1108 bool not_at_start); 1116 bool not_at_start);
1109 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 1117 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
1110 RegExpCompiler* compiler, 1118 RegExpCompiler* compiler,
1111 int characters_filled_in, 1119 int characters_filled_in,
1112 bool not_at_start); 1120 bool not_at_start);
1113 // For a negative lookahead we don't emit the quick check for the 1121 // For a negative lookahead we don't emit the quick check for the
1114 // alternative that is expected to fail. This is because quick check code 1122 // alternative that is expected to fail. This is because quick check code
1115 // starts by loading enough characters for the alternative that takes fewest 1123 // starts by loading enough characters for the alternative that takes fewest
1116 // characters, but on a negative lookahead the negative branch did not take 1124 // characters, but on a negative lookahead the negative branch did not take
1117 // part in that calculation (EatsAtLeast) so the assumptions don't hold. 1125 // part in that calculation (EatsAtLeast) so the assumptions don't hold.
1118 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } 1126 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; }
1119 virtual int ComputeFirstCharacterSet(int budget); 1127 virtual int ComputeFirstCharacterSet(Zone* zone, int budget);
1120 }; 1128 };
1121 1129
1122 1130
1123 class LoopChoiceNode: public ChoiceNode { 1131 class LoopChoiceNode: public ChoiceNode {
1124 public: 1132 public:
1125 explicit LoopChoiceNode(bool body_can_be_zero_length) 1133 LoopChoiceNode(Zone* zone, bool body_can_be_zero_length)
1126 : ChoiceNode(2), 1134 : ChoiceNode(zone, 2),
1127 loop_node_(NULL), 1135 loop_node_(NULL),
1128 continue_node_(NULL), 1136 continue_node_(NULL),
1129 body_can_be_zero_length_(body_can_be_zero_length) { } 1137 body_can_be_zero_length_(body_can_be_zero_length) { }
1130 void AddLoopAlternative(GuardedAlternative alt); 1138 void AddLoopAlternative(GuardedAlternative alt);
1131 void AddContinueAlternative(GuardedAlternative alt); 1139 void AddContinueAlternative(GuardedAlternative alt);
1132 virtual void Emit(RegExpCompiler* compiler, Trace* trace); 1140 virtual void Emit(RegExpCompiler* compiler, Trace* trace);
1133 virtual int EatsAtLeast(int still_to_find, 1141 virtual int EatsAtLeast(int still_to_find,
1134 int recursion_depth, 1142 int recursion_depth,
1135 bool not_at_start); 1143 bool not_at_start);
1136 virtual void GetQuickCheckDetails(QuickCheckDetails* details, 1144 virtual void GetQuickCheckDetails(QuickCheckDetails* details,
1137 RegExpCompiler* compiler, 1145 RegExpCompiler* compiler,
1138 int characters_filled_in, 1146 int characters_filled_in,
1139 bool not_at_start); 1147 bool not_at_start);
1140 virtual int ComputeFirstCharacterSet(int budget); 1148 virtual int ComputeFirstCharacterSet(Zone* zone, int budget);
1141 virtual LoopChoiceNode* Clone() { return new LoopChoiceNode(*this); } 1149 virtual LoopChoiceNode* Clone() { return new LoopChoiceNode(*this); }
1142 RegExpNode* loop_node() { return loop_node_; } 1150 RegExpNode* loop_node() { return loop_node_; }
1143 RegExpNode* continue_node() { return continue_node_; } 1151 RegExpNode* continue_node() { return continue_node_; }
1144 bool body_can_be_zero_length() { return body_can_be_zero_length_; } 1152 bool body_can_be_zero_length() { return body_can_be_zero_length_; }
1145 virtual void Accept(NodeVisitor* visitor); 1153 virtual void Accept(NodeVisitor* visitor);
1146 1154
1147 private: 1155 private:
1148 // AddAlternative is made private for loop nodes because alternatives 1156 // AddAlternative is made private for loop nodes because alternatives
1149 // should not be added freely, we need to keep track of which node 1157 // should not be added freely, we need to keep track of which node
1150 // goes back to the node itself. 1158 // goes back to the node itself.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 void set_loop_label(Label* label) { loop_label_ = label; } 1303 void set_loop_label(Label* label) { loop_label_ = label; }
1296 void set_characters_preloaded(int count) { characters_preloaded_ = count; } 1304 void set_characters_preloaded(int count) { characters_preloaded_ = count; }
1297 void set_bound_checked_up_to(int to) { bound_checked_up_to_ = to; } 1305 void set_bound_checked_up_to(int to) { bound_checked_up_to_ = to; }
1298 void set_flush_budget(int to) { flush_budget_ = to; } 1306 void set_flush_budget(int to) { flush_budget_ = to; }
1299 void set_quick_check_performed(QuickCheckDetails* d) { 1307 void set_quick_check_performed(QuickCheckDetails* d) {
1300 quick_check_performed_ = *d; 1308 quick_check_performed_ = *d;
1301 } 1309 }
1302 void InvalidateCurrentCharacter(); 1310 void InvalidateCurrentCharacter();
1303 void AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler); 1311 void AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler);
1304 private: 1312 private:
1305 int FindAffectedRegisters(OutSet* affected_registers); 1313 int FindAffectedRegisters(Zone* zone, OutSet* affected_registers);
1306 void PerformDeferredActions(RegExpMacroAssembler* macro, 1314 void PerformDeferredActions(Zone* zone,
1307 int max_register, 1315 RegExpMacroAssembler* macro,
1308 OutSet& affected_registers, 1316 int max_register,
1309 OutSet* registers_to_pop, 1317 OutSet& affected_registers,
1310 OutSet* registers_to_clear); 1318 OutSet* registers_to_pop,
1319 OutSet* registers_to_clear);
1311 void RestoreAffectedRegisters(RegExpMacroAssembler* macro, 1320 void RestoreAffectedRegisters(RegExpMacroAssembler* macro,
1312 int max_register, 1321 int max_register,
1313 OutSet& registers_to_pop, 1322 OutSet& registers_to_pop,
1314 OutSet& registers_to_clear); 1323 OutSet& registers_to_clear);
1315 int cp_offset_; 1324 int cp_offset_;
1316 DeferredAction* actions_; 1325 DeferredAction* actions_;
1317 Label* backtrack_; 1326 Label* backtrack_;
1318 RegExpNode* stop_node_; 1327 RegExpNode* stop_node_;
1319 Label* loop_label_; 1328 Label* loop_label_;
1320 int characters_preloaded_; 1329 int characters_preloaded_;
(...skipping 12 matching lines...) Expand all
1333 FOR_EACH_NODE_TYPE(DECLARE_VISIT) 1342 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
1334 #undef DECLARE_VISIT 1343 #undef DECLARE_VISIT
1335 virtual void VisitLoopChoice(LoopChoiceNode* that) { VisitChoice(that); } 1344 virtual void VisitLoopChoice(LoopChoiceNode* that) { VisitChoice(that); }
1336 }; 1345 };
1337 1346
1338 1347
1339 // Node visitor used to add the start set of the alternatives to the 1348 // Node visitor used to add the start set of the alternatives to the
1340 // dispatch table of a choice node. 1349 // dispatch table of a choice node.
1341 class DispatchTableConstructor: public NodeVisitor { 1350 class DispatchTableConstructor: public NodeVisitor {
1342 public: 1351 public:
1343 DispatchTableConstructor(DispatchTable* table, bool ignore_case) 1352 DispatchTableConstructor(Zone* zone, DispatchTable* table, bool ignore_case)
1344 : table_(table), 1353 : zone_(zone),
1354 table_(table),
1345 choice_index_(-1), 1355 choice_index_(-1),
1346 ignore_case_(ignore_case) { } 1356 ignore_case_(ignore_case) { }
1347 1357
1348 void BuildTable(ChoiceNode* node); 1358 void BuildTable(ChoiceNode* node);
1349 1359
1350 void AddRange(CharacterRange range) { 1360 void AddRange(CharacterRange range) {
1351 table()->AddRange(range, choice_index_); 1361 table()->AddRange(range, choice_index_);
1352 } 1362 }
1353 1363
1354 void AddInverse(ZoneList<CharacterRange>* ranges); 1364 void AddInverse(ZoneList<CharacterRange>* ranges);
1355 1365
1356 #define DECLARE_VISIT(Type) \ 1366 #define DECLARE_VISIT(Type) \
1357 virtual void Visit##Type(Type##Node* that); 1367 virtual void Visit##Type(Type##Node* that);
1358 FOR_EACH_NODE_TYPE(DECLARE_VISIT) 1368 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
1359 #undef DECLARE_VISIT 1369 #undef DECLARE_VISIT
1360 1370
1361 DispatchTable* table() { return table_; } 1371 DispatchTable* table() { return table_; }
1362 void set_choice_index(int value) { choice_index_ = value; } 1372 void set_choice_index(int value) { choice_index_ = value; }
1363 1373
1364 protected: 1374 protected:
1375 Zone* zone_;
1365 DispatchTable* table_; 1376 DispatchTable* table_;
1366 int choice_index_; 1377 int choice_index_;
1367 bool ignore_case_; 1378 bool ignore_case_;
1368 }; 1379 };
1369 1380
1370 1381
1371 // Assertion propagation moves information about assertions such as 1382 // Assertion propagation moves information about assertions such as
1372 // \b to the affected nodes. For instance, in /.\b./ information must 1383 // \b to the affected nodes. For instance, in /.\b./ information must
1373 // be propagated to the first '.' that whatever follows needs to know 1384 // be propagated to the first '.' that whatever follows needs to know
1374 // if it matched a word or a non-word, and to the second '.' that it 1385 // if it matched a word or a non-word, and to the second '.' that it
1375 // has to check if it succeeds a word or non-word. In this case the 1386 // has to check if it succeeds a word or non-word. In this case the
1376 // result will be something like: 1387 // result will be something like:
1377 // 1388 //
1378 // +-------+ +------------+ 1389 // +-------+ +------------+
1379 // | . | | . | 1390 // | . | | . |
1380 // +-------+ ---> +------------+ 1391 // +-------+ ---> +------------+
1381 // | word? | | check word | 1392 // | word? | | check word |
1382 // +-------+ +------------+ 1393 // +-------+ +------------+
1383 class Analysis: public NodeVisitor { 1394 class Analysis: public NodeVisitor {
1384 public: 1395 public:
1385 Analysis(bool ignore_case, bool is_ascii) 1396 Analysis(Zone* zone, bool ignore_case, bool is_ascii)
1386 : ignore_case_(ignore_case), 1397 : zone_(zone),
1398 ignore_case_(ignore_case),
1387 is_ascii_(is_ascii), 1399 is_ascii_(is_ascii),
1388 error_message_(NULL) { } 1400 error_message_(NULL) { }
1389 void EnsureAnalyzed(RegExpNode* node); 1401 void EnsureAnalyzed(RegExpNode* node);
1390 1402
1391 #define DECLARE_VISIT(Type) \ 1403 #define DECLARE_VISIT(Type) \
1392 virtual void Visit##Type(Type##Node* that); 1404 virtual void Visit##Type(Type##Node* that);
1393 FOR_EACH_NODE_TYPE(DECLARE_VISIT) 1405 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
1394 #undef DECLARE_VISIT 1406 #undef DECLARE_VISIT
1395 virtual void VisitLoopChoice(LoopChoiceNode* that); 1407 virtual void VisitLoopChoice(LoopChoiceNode* that);
1396 1408
1397 bool has_failed() { return error_message_ != NULL; } 1409 bool has_failed() { return error_message_ != NULL; }
1398 const char* error_message() { 1410 const char* error_message() {
1399 ASSERT(error_message_ != NULL); 1411 ASSERT(error_message_ != NULL);
1400 return error_message_; 1412 return error_message_;
1401 } 1413 }
1402 void fail(const char* error_message) { 1414 void fail(const char* error_message) {
1403 error_message_ = error_message; 1415 error_message_ = error_message;
1404 } 1416 }
1405 private: 1417 private:
1418 Zone* zone_;
1406 bool ignore_case_; 1419 bool ignore_case_;
1407 bool is_ascii_; 1420 bool is_ascii_;
1408 const char* error_message_; 1421 const char* error_message_;
1409 1422
1410 DISALLOW_IMPLICIT_CONSTRUCTORS(Analysis); 1423 DISALLOW_IMPLICIT_CONSTRUCTORS(Analysis);
1411 }; 1424 };
1412 1425
1413 1426
1414 struct RegExpCompileData { 1427 struct RegExpCompileData {
1415 RegExpCompileData() 1428 RegExpCompileData()
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 int* vector_; 1495 int* vector_;
1483 int offsets_vector_length_; 1496 int offsets_vector_length_;
1484 1497
1485 friend class ExternalReference; 1498 friend class ExternalReference;
1486 }; 1499 };
1487 1500
1488 1501
1489 } } // namespace v8::internal 1502 } } // namespace v8::internal
1490 1503
1491 #endif // V8_JSREGEXP_H_ 1504 #endif // V8_JSREGEXP_H_
OLDNEW
« no previous file with comments | « src/json-parser.h ('k') | src/jsregexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698