Reduce work done in EatsAtLeast to a sane level.
Review URL: http://codereview.chromium.org/18753 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1165 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
4cebfa827b
commit
34b47563ff
@ -2034,39 +2034,40 @@ RegExpNode::LimitResult RegExpNode::LimitVersions(RegExpCompiler* compiler,
|
||||
}
|
||||
|
||||
|
||||
int ActionNode::EatsAtLeast(int recursion_depth) {
|
||||
int ActionNode::EatsAtLeast(int still_to_find, int recursion_depth) {
|
||||
if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
|
||||
if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input!
|
||||
return on_success()->EatsAtLeast(recursion_depth + 1);
|
||||
return on_success()->EatsAtLeast(still_to_find, recursion_depth + 1);
|
||||
}
|
||||
|
||||
|
||||
int AssertionNode::EatsAtLeast(int recursion_depth) {
|
||||
int AssertionNode::EatsAtLeast(int still_to_find, int recursion_depth) {
|
||||
if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
|
||||
return on_success()->EatsAtLeast(recursion_depth + 1);
|
||||
return on_success()->EatsAtLeast(still_to_find, recursion_depth + 1);
|
||||
}
|
||||
|
||||
|
||||
int BackReferenceNode::EatsAtLeast(int recursion_depth) {
|
||||
int BackReferenceNode::EatsAtLeast(int still_to_find, int recursion_depth) {
|
||||
if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
|
||||
return on_success()->EatsAtLeast(recursion_depth + 1);
|
||||
return on_success()->EatsAtLeast(still_to_find, recursion_depth + 1);
|
||||
}
|
||||
|
||||
|
||||
int TextNode::EatsAtLeast(int recursion_depth) {
|
||||
int TextNode::EatsAtLeast(int still_to_find, int recursion_depth) {
|
||||
int answer = Length();
|
||||
if (answer >= 4) return answer;
|
||||
if (answer >= still_to_find) return answer;
|
||||
if (recursion_depth > RegExpCompiler::kMaxRecursion) return answer;
|
||||
return answer + on_success()->EatsAtLeast(recursion_depth + 1);
|
||||
return answer + on_success()->EatsAtLeast(still_to_find - answer,
|
||||
recursion_depth + 1);
|
||||
}
|
||||
|
||||
|
||||
int NegativeLookaheadChoiceNode:: EatsAtLeast(int recursion_depth) {
|
||||
int NegativeLookaheadChoiceNode:: EatsAtLeast(int still_to_find, int recursion_depth) {
|
||||
if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
|
||||
// Alternative 0 is the negative lookahead, alternative 1 is what comes
|
||||
// afterwards.
|
||||
RegExpNode* node = alternatives_->at(1).node();
|
||||
return node->EatsAtLeast(recursion_depth + 1);
|
||||
return node->EatsAtLeast(still_to_find, recursion_depth + 1);
|
||||
}
|
||||
|
||||
|
||||
@ -2081,7 +2082,8 @@ void NegativeLookaheadChoiceNode::GetQuickCheckDetails(
|
||||
}
|
||||
|
||||
|
||||
int ChoiceNode::EatsAtLeastHelper(int recursion_depth,
|
||||
int ChoiceNode::EatsAtLeastHelper(int still_to_find,
|
||||
int recursion_depth,
|
||||
RegExpNode* ignore_this_node) {
|
||||
if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0;
|
||||
int min = 100;
|
||||
@ -2089,20 +2091,20 @@ int ChoiceNode::EatsAtLeastHelper(int recursion_depth,
|
||||
for (int i = 0; i < choice_count; i++) {
|
||||
RegExpNode* node = alternatives_->at(i).node();
|
||||
if (node == ignore_this_node) continue;
|
||||
int node_eats_at_least = node->EatsAtLeast(recursion_depth + 1);
|
||||
int node_eats_at_least = node->EatsAtLeast(still_to_find, recursion_depth + 1);
|
||||
if (node_eats_at_least < min) min = node_eats_at_least;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
|
||||
int LoopChoiceNode::EatsAtLeast(int recursion_depth) {
|
||||
return EatsAtLeastHelper(recursion_depth, loop_node_);
|
||||
int LoopChoiceNode::EatsAtLeast(int still_to_find, int recursion_depth) {
|
||||
return EatsAtLeastHelper(still_to_find, recursion_depth, loop_node_);
|
||||
}
|
||||
|
||||
|
||||
int ChoiceNode::EatsAtLeast(int recursion_depth) {
|
||||
return EatsAtLeastHelper(recursion_depth, NULL);
|
||||
int ChoiceNode::EatsAtLeast(int still_to_find, int recursion_depth) {
|
||||
return EatsAtLeastHelper(still_to_find, recursion_depth, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -2882,7 +2884,7 @@ bool LoopChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
|
||||
|
||||
|
||||
int ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler) {
|
||||
int preload_characters = EatsAtLeast(0);
|
||||
int preload_characters = EatsAtLeast(4, 0);
|
||||
#ifdef CAN_READ_UNALIGNED
|
||||
bool ascii = compiler->ascii();
|
||||
if (ascii) {
|
||||
|
@ -592,8 +592,10 @@ class RegExpNode: public ZoneObject {
|
||||
// false for failure.
|
||||
virtual bool Emit(RegExpCompiler* compiler, Trace* trace) = 0;
|
||||
// How many characters must this node consume at a minimum in order to
|
||||
// succeed.
|
||||
virtual int EatsAtLeast(int recursion_depth) = 0;
|
||||
// succeed. If we have found at least 'still_to_find' characters that
|
||||
// must be consumed there is no need to ask any following nodes whether
|
||||
// they are sure to eat any more characters.
|
||||
virtual int EatsAtLeast(int still_to_find, int recursion_depth) = 0;
|
||||
// Emits some quick code that checks whether the preloaded characters match.
|
||||
// Falls through on certain failure, jumps to the label on possible success.
|
||||
// If the node cannot make a quick check it does nothing and returns false.
|
||||
@ -737,7 +739,7 @@ class ActionNode: public SeqRegExpNode {
|
||||
RegExpNode* on_success);
|
||||
virtual void Accept(NodeVisitor* visitor);
|
||||
virtual bool Emit(RegExpCompiler* compiler, Trace* trace);
|
||||
virtual int EatsAtLeast(int recursion_depth);
|
||||
virtual int EatsAtLeast(int still_to_find, int recursion_depth);
|
||||
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
|
||||
RegExpCompiler* compiler,
|
||||
int filled_in) {
|
||||
@ -799,7 +801,7 @@ class TextNode: public SeqRegExpNode {
|
||||
}
|
||||
virtual void Accept(NodeVisitor* visitor);
|
||||
virtual bool Emit(RegExpCompiler* compiler, Trace* trace);
|
||||
virtual int EatsAtLeast(int recursion_depth);
|
||||
virtual int EatsAtLeast(int still_to_find, int recursion_depth);
|
||||
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
|
||||
RegExpCompiler* compiler,
|
||||
int characters_filled_in);
|
||||
@ -857,7 +859,7 @@ class AssertionNode: public SeqRegExpNode {
|
||||
}
|
||||
virtual void Accept(NodeVisitor* visitor);
|
||||
virtual bool Emit(RegExpCompiler* compiler, Trace* trace);
|
||||
virtual int EatsAtLeast(int recursion_depth);
|
||||
virtual int EatsAtLeast(int still_to_find, int recursion_depth);
|
||||
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
|
||||
RegExpCompiler* compiler,
|
||||
int filled_in) {
|
||||
@ -884,7 +886,7 @@ class BackReferenceNode: public SeqRegExpNode {
|
||||
int start_register() { return start_reg_; }
|
||||
int end_register() { return end_reg_; }
|
||||
virtual bool Emit(RegExpCompiler* compiler, Trace* trace);
|
||||
virtual int EatsAtLeast(int recursion_depth);
|
||||
virtual int EatsAtLeast(int still_to_find, int recursion_depth);
|
||||
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
|
||||
RegExpCompiler* compiler,
|
||||
int characters_filled_in) {
|
||||
@ -904,7 +906,7 @@ class EndNode: public RegExpNode {
|
||||
explicit EndNode(Action action) : action_(action) { }
|
||||
virtual void Accept(NodeVisitor* visitor);
|
||||
virtual bool Emit(RegExpCompiler* compiler, Trace* trace);
|
||||
virtual int EatsAtLeast(int recursion_depth) { return 0; }
|
||||
virtual int EatsAtLeast(int still_to_find, int recursion_depth) { return 0; }
|
||||
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
|
||||
RegExpCompiler* compiler,
|
||||
int characters_filled_in) {
|
||||
@ -985,8 +987,10 @@ class ChoiceNode: public RegExpNode {
|
||||
ZoneList<GuardedAlternative>* alternatives() { return alternatives_; }
|
||||
DispatchTable* GetTable(bool ignore_case);
|
||||
virtual bool Emit(RegExpCompiler* compiler, Trace* trace);
|
||||
virtual int EatsAtLeast(int recursion_depth);
|
||||
int EatsAtLeastHelper(int recursion_depth, RegExpNode* ignore_this_node);
|
||||
virtual int EatsAtLeast(int still_to_find, int recursion_depth);
|
||||
int EatsAtLeastHelper(int still_to_find,
|
||||
int recursion_depth,
|
||||
RegExpNode* ignore_this_node);
|
||||
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
|
||||
RegExpCompiler* compiler,
|
||||
int characters_filled_in);
|
||||
@ -1026,7 +1030,7 @@ class NegativeLookaheadChoiceNode: public ChoiceNode {
|
||||
AddAlternative(this_must_fail);
|
||||
AddAlternative(then_do_this);
|
||||
}
|
||||
virtual int EatsAtLeast(int recursion_depth);
|
||||
virtual int EatsAtLeast(int still_to_find, int recursion_depth);
|
||||
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
|
||||
RegExpCompiler* compiler,
|
||||
int characters_filled_in);
|
||||
@ -1049,7 +1053,7 @@ class LoopChoiceNode: public ChoiceNode {
|
||||
void AddLoopAlternative(GuardedAlternative alt);
|
||||
void AddContinueAlternative(GuardedAlternative alt);
|
||||
virtual bool Emit(RegExpCompiler* compiler, Trace* trace);
|
||||
virtual int EatsAtLeast(int recursion_depth); // Returns 0.
|
||||
virtual int EatsAtLeast(int still_to_find, int recursion_depth);
|
||||
virtual void GetQuickCheckDetails(QuickCheckDetails* details,
|
||||
RegExpCompiler* compiler,
|
||||
int characters_filled_in);
|
||||
|
Loading…
Reference in New Issue
Block a user