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

Side by Side Diff: src/jsregexp.cc

Issue 14508: Interest propagation bugfix. (Closed)
Patch Set: Created 12 years 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
« no previous file with comments | « src/jsregexp.h ('k') | test/cctest/test-regexp.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 1578 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 1589
1590 1590
1591 #define DEFINE_ACCEPT(Type) \ 1591 #define DEFINE_ACCEPT(Type) \
1592 void Type##Node::Accept(NodeVisitor* visitor) { \ 1592 void Type##Node::Accept(NodeVisitor* visitor) { \
1593 visitor->Visit##Type(this); \ 1593 visitor->Visit##Type(this); \
1594 } 1594 }
1595 FOR_EACH_NODE_TYPE(DEFINE_ACCEPT) 1595 FOR_EACH_NODE_TYPE(DEFINE_ACCEPT)
1596 #undef DEFINE_ACCEPT 1596 #undef DEFINE_ACCEPT
1597 1597
1598 1598
1599 void LoopChoiceNode::Accept(NodeVisitor* visitor) {
1600 visitor->VisitLoopChoice(this);
1601 }
1602
1603
1599 // ------------------------------------------------------------------- 1604 // -------------------------------------------------------------------
1600 // Emit code. 1605 // Emit code.
1601 1606
1602 1607
1603 void ChoiceNode::GenerateGuard(RegExpMacroAssembler* macro_assembler, 1608 void ChoiceNode::GenerateGuard(RegExpMacroAssembler* macro_assembler,
1604 Guard* guard, 1609 Guard* guard,
1605 GenerationVariant* variant) { 1610 GenerationVariant* variant) {
1606 switch (guard->op()) { 1611 switch (guard->op()) {
1607 case Guard::LT: 1612 case Guard::LT:
1608 ASSERT(!variant->mentions_reg(guard->reg())); 1613 ASSERT(!variant->mentions_reg(guard->reg()));
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
2063 return kNodeIsTooComplexForGreedyLoops; 2068 return kNodeIsTooComplexForGreedyLoops;
2064 } 2069 }
2065 length += node_length; 2070 length += node_length;
2066 SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node); 2071 SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node);
2067 node = seq_node->on_success(); 2072 node = seq_node->on_success();
2068 } 2073 }
2069 return length; 2074 return length;
2070 } 2075 }
2071 2076
2072 2077
2078 void LoopChoiceNode::AddLoopAlternative(GuardedAlternative alt) {
2079 ASSERT_EQ(loop_node_, NULL);
2080 AddAlternative(alt);
2081 loop_node_ = alt.node();
2082 }
2083
2084
2085 void LoopChoiceNode::AddContinueAlternative(GuardedAlternative alt) {
2086 ASSERT_EQ(continue_node_, NULL);
2087 AddAlternative(alt);
2088 continue_node_ = alt.node();
2089 }
2090
2091
2073 bool LoopChoiceNode::Emit(RegExpCompiler* compiler, 2092 bool LoopChoiceNode::Emit(RegExpCompiler* compiler,
2074 GenerationVariant* variant) { 2093 GenerationVariant* variant) {
2075 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler(); 2094 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
2076 if (variant->stop_node() == this) { 2095 if (variant->stop_node() == this) {
2077 int text_length = GreedyLoopTextLength(&(alternatives_->at(0))); 2096 int text_length = GreedyLoopTextLength(&(alternatives_->at(0)));
2078 ASSERT(text_length != kNodeIsTooComplexForGreedyLoops); 2097 ASSERT(text_length != kNodeIsTooComplexForGreedyLoops);
2079 // Update the counter-based backtracking info on the stack. This is an 2098 // Update the counter-based backtracking info on the stack. This is an
2080 // optimization for greedy loops (see below). 2099 // optimization for greedy loops (see below).
2081 ASSERT(variant->cp_offset() == text_length); 2100 ASSERT(variant->cp_offset() == text_length);
2082 macro_assembler->AdvanceCurrentPosition(text_length); 2101 macro_assembler->AdvanceCurrentPosition(text_length);
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
2664 RegExpCompiler* compiler, 2683 RegExpCompiler* compiler,
2665 RegExpNode* on_success) { 2684 RegExpNode* on_success) {
2666 // x{f, t} becomes this: 2685 // x{f, t} becomes this:
2667 // 2686 //
2668 // (r++)<-. 2687 // (r++)<-.
2669 // | ` 2688 // | `
2670 // | (x) 2689 // | (x)
2671 // v ^ 2690 // v ^
2672 // (r=0)-->(?)---/ [if r < t] 2691 // (r=0)-->(?)---/ [if r < t]
2673 // | 2692 // |
2674 // [if r >= f] \----> ... 2693 // [if r >= f] \----> ...
Erik Corry 2008/12/17 13:14:41 Someone should build this in wrought iron and you
2675 // 2694 //
2676 // 2695 //
2677 // TODO(someone): clear captures on repetition and handle empty 2696 // TODO(someone): clear captures on repetition and handle empty
2678 // matches. 2697 // matches.
2679 bool has_min = min > 0; 2698 bool has_min = min > 0;
2680 bool has_max = max < RegExpTree::kInfinity; 2699 bool has_max = max < RegExpTree::kInfinity;
2681 bool needs_counter = has_min || has_max; 2700 bool needs_counter = has_min || has_max;
2682 int reg_ctr = needs_counter ? compiler->AllocateRegister() : -1; 2701 int reg_ctr = needs_counter ? compiler->AllocateRegister() : -1;
2683 ChoiceNode* center = new LoopChoiceNode(2); 2702 LoopChoiceNode* center = new LoopChoiceNode();
2684 RegExpNode* loop_return = needs_counter 2703 RegExpNode* loop_return = needs_counter
2685 ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center)) 2704 ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
2686 : static_cast<RegExpNode*>(center); 2705 : static_cast<RegExpNode*>(center);
2687 RegExpNode* body_node = body->ToNode(compiler, loop_return); 2706 RegExpNode* body_node = body->ToNode(compiler, loop_return);
2688 GuardedAlternative body_alt(body_node); 2707 GuardedAlternative body_alt(body_node);
2689 if (has_max) { 2708 if (has_max) {
2690 Guard* body_guard = new Guard(reg_ctr, Guard::LT, max); 2709 Guard* body_guard = new Guard(reg_ctr, Guard::LT, max);
2691 body_alt.AddGuard(body_guard); 2710 body_alt.AddGuard(body_guard);
2692 } 2711 }
2693 GuardedAlternative rest_alt(on_success); 2712 GuardedAlternative rest_alt(on_success);
2694 if (has_min) { 2713 if (has_min) {
2695 Guard* rest_guard = new Guard(reg_ctr, Guard::GEQ, min); 2714 Guard* rest_guard = new Guard(reg_ctr, Guard::GEQ, min);
2696 rest_alt.AddGuard(rest_guard); 2715 rest_alt.AddGuard(rest_guard);
2697 } 2716 }
2698 if (is_greedy) { 2717 if (is_greedy) {
2699 center->AddAlternative(body_alt); 2718 center->AddLoopAlternative(body_alt);
2700 center->AddAlternative(rest_alt); 2719 center->AddContinueAlternative(rest_alt);
2701 } else { 2720 } else {
2702 center->AddAlternative(rest_alt); 2721 center->AddContinueAlternative(rest_alt);
2703 center->AddAlternative(body_alt); 2722 center->AddLoopAlternative(body_alt);
2704 } 2723 }
2705 if (needs_counter) { 2724 if (needs_counter) {
2706 return ActionNode::SetRegister(reg_ctr, 0, center); 2725 return ActionNode::SetRegister(reg_ctr, 0, center);
2707 } else { 2726 } else {
2708 return center; 2727 return center;
2709 } 2728 }
2710 } 2729 }
2711 2730
2712 2731
2713 RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler, 2732 RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler,
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
3351 for (int i = 0; i < that->alternatives()->length(); i++) { 3370 for (int i = 0; i < that->alternatives()->length(); i++) {
3352 RegExpNode* node = that->alternatives()->at(i).node(); 3371 RegExpNode* node = that->alternatives()->at(i).node();
3353 EnsureAnalyzed(node); 3372 EnsureAnalyzed(node);
3354 // Anything the following nodes need to know has to be known by 3373 // Anything the following nodes need to know has to be known by
3355 // this node also, so it can pass it on. 3374 // this node also, so it can pass it on.
3356 info->AddFromFollowing(node->info()); 3375 info->AddFromFollowing(node->info());
3357 } 3376 }
3358 } 3377 }
3359 3378
3360 3379
3380 void AssertionPropagation::VisitLoopChoice(LoopChoiceNode* that) {
3381 NodeInfo* info = that->info();
3382 for (int i = 0; i < that->alternatives()->length(); i++) {
3383 RegExpNode* node = that->alternatives()->at(i).node();
3384 if (node != that->loop_node()) {
3385 EnsureAnalyzed(node);
3386 info->AddFromFollowing(node->info());
3387 }
3388 }
3389 // Check the loop last since it may need the value of this node
3390 // to get a correct result.
3391 EnsureAnalyzed(that->loop_node());
3392 info->AddFromFollowing(that->loop_node()->info());
3393 }
3394
3395
3361 void AssertionPropagation::VisitBackReference(BackReferenceNode* that) { 3396 void AssertionPropagation::VisitBackReference(BackReferenceNode* that) {
3362 EnsureAnalyzed(that->on_success()); 3397 EnsureAnalyzed(that->on_success());
3363 } 3398 }
3364 3399
3365 3400
3366 // ------------------------------------------------------------------- 3401 // -------------------------------------------------------------------
3367 // Assumption expansion 3402 // Assumption expansion
3368 3403
3369 3404
3370 RegExpNode* RegExpNode::EnsureExpanded(NodeInfo* info) { 3405 RegExpNode* RegExpNode::EnsureExpanded(NodeInfo* info) {
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
3857 EmbeddedVector<byte, 1024> codes; 3892 EmbeddedVector<byte, 1024> codes;
3858 RegExpMacroAssemblerIrregexp macro_assembler(codes); 3893 RegExpMacroAssemblerIrregexp macro_assembler(codes);
3859 return compiler.Assemble(&macro_assembler, 3894 return compiler.Assemble(&macro_assembler,
3860 node, 3895 node,
3861 data->capture_count, 3896 data->capture_count,
3862 pattern); 3897 pattern);
3863 } 3898 }
3864 3899
3865 3900
3866 }} // namespace v8::internal 3901 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jsregexp.h ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698