Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Protected Attributes | Friends | List of all members
dart::ChoiceNode Class Reference

#include <regexp.h>

Inheritance diagram for dart::ChoiceNode:
dart::RegExpNode dart::ZoneAllocated dart::LoopChoiceNode dart::NegativeLookaroundChoiceNode

Public Member Functions

 ChoiceNode (intptr_t expected_size, Zone *zone)
 
virtual void Accept (NodeVisitor *visitor)
 
void AddAlternative (GuardedAlternative node)
 
ZoneGrowableArray< GuardedAlternative > * alternatives ()
 
virtual void Emit (RegExpCompiler *compiler, Trace *trace)
 
virtual intptr_t EatsAtLeast (intptr_t still_to_find, intptr_t budget, bool not_at_start)
 
intptr_t EatsAtLeastHelper (intptr_t still_to_find, intptr_t budget, RegExpNode *ignore_this_node, bool not_at_start)
 
virtual void GetQuickCheckDetails (QuickCheckDetails *details, RegExpCompiler *compiler, intptr_t characters_filled_in, bool not_at_start)
 
virtual void FillInBMInfo (intptr_t offset, intptr_t budget, BoyerMooreLookahead *bm, bool not_at_start)
 
bool being_calculated ()
 
bool not_at_start ()
 
void set_not_at_start ()
 
void set_being_calculated (bool b)
 
virtual bool try_to_emit_quick_check_for_alternative (bool is_first)
 
virtual RegExpNodeFilterOneByte (intptr_t depth)
 
virtual bool read_backward ()
 
- Public Member Functions inherited from dart::RegExpNode
 RegExpNode (Zone *zone)
 
virtual ~RegExpNode ()
 
bool EmitQuickCheck (RegExpCompiler *compiler, Trace *bounds_check_trace, Trace *trace, bool preload_has_checked_bounds, BlockLabel *on_possible_success, QuickCheckDetails *details_return, bool fall_through_on_failure)
 
virtual intptr_t GreedyLoopTextLength ()
 
virtual RegExpNodeGetSuccessorOfOmnivorousTextNode (RegExpCompiler *compiler)
 
RegExpNodereplacement ()
 
RegExpNodeset_replacement (RegExpNode *replacement)
 
void SaveBMInfo (BoyerMooreLookahead *bm, bool not_at_start, intptr_t offset)
 
BlockLabellabel ()
 
NodeInfoinfo ()
 
BoyerMooreLookaheadbm_info (bool not_at_start)
 
Zonezone () const
 
- Public Member Functions inherited from dart::ZoneAllocated
 ZoneAllocated ()
 
void * operator new (size_t size)
 
void * operator new (size_t size, Zone *zone)
 
void operator delete (void *pointer)
 

Protected Member Functions

intptr_t GreedyLoopTextLengthForAlternative (const GuardedAlternative *alternative)
 
- Protected Member Functions inherited from dart::RegExpNode
LimitResult LimitVersions (RegExpCompiler *compiler, Trace *trace)
 
void set_bm_info (bool not_at_start, BoyerMooreLookahead *bm)
 

Protected Attributes

ZoneGrowableArray< GuardedAlternative > * alternatives_
 
- Protected Attributes inherited from dart::RegExpNode
RegExpNodereplacement_
 

Friends

class Analysis
 

Additional Inherited Members

- Static Public Attributes inherited from dart::RegExpNode
static constexpr intptr_t kNodeIsTooComplexForGreedyLoops = -1
 
static constexpr intptr_t kRecursionBudget = 200
 
static constexpr intptr_t kMaxCopiesCodeGenerated = 10
 
- Protected Types inherited from dart::RegExpNode
enum  LimitResult { DONE , CONTINUE }
 

Detailed Description

Definition at line 894 of file regexp.h.

Constructor & Destructor Documentation

◆ ChoiceNode()

dart::ChoiceNode::ChoiceNode ( intptr_t  expected_size,
Zone zone 
)
inlineexplicit

Definition at line 896 of file regexp.h.

897 : RegExpNode(zone),
899 ZoneGrowableArray<GuardedAlternative>(expected_size)),
900 not_at_start_(false),
901 being_calculated_(false) {}
ZoneGrowableArray< GuardedAlternative > * alternatives_
Definition regexp.h:937
Zone * zone() const
Definition regexp.h:483
RegExpNode(Zone *zone)
Definition regexp.h:386

Member Function Documentation

◆ Accept()

virtual void dart::ChoiceNode::Accept ( NodeVisitor visitor)
virtual

Implements dart::RegExpNode.

Reimplemented in dart::LoopChoiceNode.

◆ AddAlternative()

void dart::ChoiceNode::AddAlternative ( GuardedAlternative  node)
inline

Definition at line 903 of file regexp.h.

903{ alternatives()->Add(node); }
ZoneGrowableArray< GuardedAlternative > * alternatives()
Definition regexp.h:904

◆ alternatives()

ZoneGrowableArray< GuardedAlternative > * dart::ChoiceNode::alternatives ( )
inline

Definition at line 904 of file regexp.h.

904 {
905 return alternatives_;
906 }

◆ being_calculated()

bool dart::ChoiceNode::being_calculated ( )
inline

Definition at line 924 of file regexp.h.

924{ return being_calculated_; }

◆ EatsAtLeast()

intptr_t dart::ChoiceNode::EatsAtLeast ( intptr_t  still_to_find,
intptr_t  budget,
bool  not_at_start 
)
virtual

Implements dart::RegExpNode.

Reimplemented in dart::NegativeLookaroundChoiceNode, and dart::LoopChoiceNode.

Definition at line 1582 of file regexp.cc.

1584 {
1585 return EatsAtLeastHelper(still_to_find, budget, nullptr, not_at_start);
1586}
intptr_t EatsAtLeastHelper(intptr_t still_to_find, intptr_t budget, RegExpNode *ignore_this_node, bool not_at_start)
Definition regexp.cc:1557
bool not_at_start()
Definition regexp.h:925

◆ EatsAtLeastHelper()

intptr_t dart::ChoiceNode::EatsAtLeastHelper ( intptr_t  still_to_find,
intptr_t  budget,
RegExpNode ignore_this_node,
bool  not_at_start 
)

Definition at line 1557 of file regexp.cc.

1560 {
1561 if (budget <= 0) return 0;
1562 intptr_t min = 100;
1563 intptr_t choice_count = alternatives_->length();
1564 budget = (budget - 1) / choice_count;
1565 for (intptr_t i = 0; i < choice_count; i++) {
1566 RegExpNode* node = (*alternatives_)[i].node();
1567 if (node == ignore_this_node) continue;
1568 intptr_t node_eats_at_least =
1569 node->EatsAtLeast(still_to_find, budget, not_at_start);
1570 if (node_eats_at_least < min) min = node_eats_at_least;
1571 if (min == 0) return 0;
1572 }
1573 return min;
1574}
static float min(float r, float g, float b)
Definition hsl.cpp:48

◆ Emit()

void dart::ChoiceNode::Emit ( RegExpCompiler compiler,
Trace trace 
)
virtual

Implements dart::RegExpNode.

Reimplemented in dart::LoopChoiceNode.

Definition at line 3127 of file regexp.cc.

3127 {
3128 intptr_t choice_count = alternatives_->length();
3129
3130 if (choice_count == 1 && alternatives_->At(0).guards() == nullptr) {
3131 alternatives_->At(0).node()->Emit(compiler, trace);
3132 return;
3133 }
3134
3135 AssertGuardsMentionRegisters(trace);
3136
3137 LimitResult limit_result = LimitVersions(compiler, trace);
3138 if (limit_result == DONE) return;
3139 ASSERT(limit_result == CONTINUE);
3140
3141 // For loop nodes we already flushed (see LoopChoiceNode::Emit), but for
3142 // other choice nodes we only flush if we are out of code size budget.
3143 if (trace->flush_budget() == 0 && trace->actions() != nullptr) {
3144 trace->Flush(compiler, this);
3145 return;
3146 }
3147
3148 RecursionCheck rc(compiler);
3149
3150 PreloadState preload;
3151 preload.init();
3152 GreedyLoopState greedy_loop_state(not_at_start());
3153
3154 intptr_t text_length =
3156 AlternativeGenerationList alt_gens(choice_count);
3157
3158 if (choice_count > 1 && text_length != kNodeIsTooComplexForGreedyLoops) {
3159 trace = EmitGreedyLoop(compiler, trace, &alt_gens, &preload,
3160 &greedy_loop_state, text_length);
3161 } else {
3162 // TODO(erikcorry): Delete this. We don't need this label, but it makes us
3163 // match the traces produced pre-cleanup.
3164 BlockLabel second_choice;
3165 compiler->macro_assembler()->BindBlock(&second_choice);
3166
3167 preload.eats_at_least_ = EmitOptimizedUnanchoredSearch(compiler, trace);
3168
3169 EmitChoices(compiler, &alt_gens, 0, trace, &preload);
3170 }
3171
3172 // At this point we need to generate slow checks for the alternatives where
3173 // the quick check was inlined. We can recognize these because the associated
3174 // label was bound.
3175 intptr_t new_flush_budget = trace->flush_budget() / choice_count;
3176 for (intptr_t i = 0; i < choice_count; i++) {
3177 AlternativeGeneration* alt_gen = alt_gens.at(i);
3178 Trace new_trace(*trace);
3179 // If there are actions to be flushed we have to limit how many times
3180 // they are flushed. Take the budget of the parent trace and distribute
3181 // it fairly amongst the children.
3182 if (new_trace.actions() != nullptr) {
3183 new_trace.set_flush_budget(new_flush_budget);
3184 }
3185 bool next_expects_preload =
3186 i == choice_count - 1 ? false : alt_gens.at(i + 1)->expects_preload;
3187 EmitOutOfLineContinuation(compiler, &new_trace, alternatives_->At(i),
3188 alt_gen, preload.preload_characters_,
3189 next_expects_preload);
3190 }
3191}
intptr_t GreedyLoopTextLengthForAlternative(const GuardedAlternative *alternative)
Definition regexp.cc:2632
static constexpr intptr_t kNodeIsTooComplexForGreedyLoops
Definition regexp.h:422
LimitResult LimitVersions(RegExpCompiler *compiler, Trace *trace)
Definition regexp.cc:1431
#define ASSERT(E)

◆ FillInBMInfo()

void dart::ChoiceNode::FillInBMInfo ( intptr_t  offset,
intptr_t  budget,
BoyerMooreLookahead bm,
bool  not_at_start 
)
virtual

Reimplemented from dart::RegExpNode.

Reimplemented in dart::NegativeLookaroundChoiceNode, and dart::LoopChoiceNode.

Definition at line 5185 of file regexp.cc.

5188 {
5189 ZoneGrowableArray<GuardedAlternative>* alts = alternatives();
5190 budget = (budget - 1) / alts->length();
5191 for (intptr_t i = 0; i < alts->length(); i++) {
5192 GuardedAlternative& alt = (*alts)[i];
5193 if (alt.guards() != nullptr && alt.guards()->length() != 0) {
5194 bm->SetRest(offset); // Give up trying to fill in info.
5196 return;
5197 }
5198 alt.node()->FillInBMInfo(offset, budget, bm, not_at_start);
5199 }
5201}
void SaveBMInfo(BoyerMooreLookahead *bm, bool not_at_start, intptr_t offset)
Definition regexp.h:465
Point offset

◆ FilterOneByte()

RegExpNode * dart::ChoiceNode::FilterOneByte ( intptr_t  depth)
virtual

Reimplemented from dart::RegExpNode.

Reimplemented in dart::NegativeLookaroundChoiceNode, and dart::LoopChoiceNode.

Definition at line 2049 of file regexp.cc.

2049 {
2050 if (info()->replacement_calculated) return replacement();
2051 if (depth < 0) return this;
2052 if (info()->visited) return this;
2053 VisitMarker marker(info());
2054 intptr_t choice_count = alternatives_->length();
2055
2056 for (intptr_t i = 0; i < choice_count; i++) {
2057 GuardedAlternative alternative = alternatives_->At(i);
2058 if (alternative.guards() != nullptr &&
2059 alternative.guards()->length() != 0) {
2060 set_replacement(this);
2061 return this;
2062 }
2063 }
2064
2065 intptr_t surviving = 0;
2066 RegExpNode* survivor = nullptr;
2067 for (intptr_t i = 0; i < choice_count; i++) {
2068 GuardedAlternative alternative = alternatives_->At(i);
2069 RegExpNode* replacement = alternative.node()->FilterOneByte(depth - 1);
2070 ASSERT(replacement != this); // No missing EMPTY_MATCH_CHECK.
2071 if (replacement != nullptr) {
2072 (*alternatives_)[i].set_node(replacement);
2073 surviving++;
2074 survivor = replacement;
2075 }
2076 }
2077 if (surviving < 2) return set_replacement(survivor);
2078
2079 set_replacement(this);
2080 if (surviving == choice_count) {
2081 return this;
2082 }
2083 // Only some of the nodes survived the filtering. We need to rebuild the
2084 // alternatives list.
2085 ZoneGrowableArray<GuardedAlternative>* new_alternatives =
2086 new (Z) ZoneGrowableArray<GuardedAlternative>(surviving);
2087 for (intptr_t i = 0; i < choice_count; i++) {
2089 (*alternatives_)[i].node()->FilterOneByte(depth - 1);
2090 if (replacement != nullptr) {
2091 (*alternatives_)[i].set_node(replacement);
2092 new_alternatives->Add((*alternatives_)[i]);
2093 }
2094 }
2095 alternatives_ = new_alternatives;
2096 return this;
2097}
static const char marker[]
#define Z
NodeInfo * info()
Definition regexp.h:477
virtual RegExpNode * FilterOneByte(intptr_t depth)
Definition regexp.h:449
RegExpNode * set_replacement(RegExpNode *replacement)
Definition regexp.h:455
RegExpNode * replacement()
Definition regexp.h:451

◆ GetQuickCheckDetails()

void dart::ChoiceNode::GetQuickCheckDetails ( QuickCheckDetails details,
RegExpCompiler compiler,
intptr_t  characters_filled_in,
bool  not_at_start 
)
virtual

Implements dart::RegExpNode.

Reimplemented in dart::NegativeLookaroundChoiceNode, and dart::LoopChoiceNode.

Definition at line 2143 of file regexp.cc.

2146 {
2147 not_at_start = (not_at_start || not_at_start_);
2148 intptr_t choice_count = alternatives_->length();
2149 ASSERT(choice_count > 0);
2150 (*alternatives_)[0].node()->GetQuickCheckDetails(
2151 details, compiler, characters_filled_in, not_at_start);
2152 for (intptr_t i = 1; i < choice_count; i++) {
2153 QuickCheckDetails new_details(details->characters());
2154 RegExpNode* node = (*alternatives_)[i].node();
2155 node->GetQuickCheckDetails(&new_details, compiler, characters_filled_in,
2156 not_at_start);
2157 // Here we merge the quick match details of the two branches.
2158 details->Merge(&new_details, characters_filled_in);
2159 }
2160}

◆ GreedyLoopTextLengthForAlternative()

intptr_t dart::ChoiceNode::GreedyLoopTextLengthForAlternative ( const GuardedAlternative alternative)
protected

Definition at line 2632 of file regexp.cc.

2633 {
2634 intptr_t length = 0;
2635 RegExpNode* node = alternative->node();
2636 // Later we will generate code for all these text nodes using recursion
2637 // so we have to limit the max number.
2638 intptr_t recursion_depth = 0;
2639 while (node != this) {
2640 if (recursion_depth++ > RegExpCompiler::kMaxRecursion) {
2642 }
2643 intptr_t node_length = node->GreedyLoopTextLength();
2644 if (node_length == kNodeIsTooComplexForGreedyLoops) {
2646 }
2647 length += node_length;
2648 SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node);
2649 node = seq_node->on_success();
2650 }
2651 return read_backward() ? -length : length;
2652}
virtual bool read_backward()
Definition regexp.h:932
static constexpr intptr_t kMaxRecursion
Definition regexp.cc:336
size_t length

◆ not_at_start()

bool dart::ChoiceNode::not_at_start ( )
inline

Definition at line 925 of file regexp.h.

925{ return not_at_start_; }

◆ read_backward()

virtual bool dart::ChoiceNode::read_backward ( )
inlinevirtual

Reimplemented in dart::LoopChoiceNode.

Definition at line 932 of file regexp.h.

932{ return false; }

◆ set_being_calculated()

void dart::ChoiceNode::set_being_calculated ( bool  b)
inline

Definition at line 927 of file regexp.h.

927{ being_calculated_ = b; }
static bool b

◆ set_not_at_start()

void dart::ChoiceNode::set_not_at_start ( )
inline

Definition at line 926 of file regexp.h.

926{ not_at_start_ = true; }

◆ try_to_emit_quick_check_for_alternative()

virtual bool dart::ChoiceNode::try_to_emit_quick_check_for_alternative ( bool  is_first)
inlinevirtual

Reimplemented in dart::NegativeLookaroundChoiceNode.

Definition at line 928 of file regexp.h.

928 {
929 return true;
930 }

Friends And Related Symbol Documentation

◆ Analysis

friend class Analysis
friend

Definition at line 940 of file regexp.h.

Member Data Documentation

◆ alternatives_

ZoneGrowableArray<GuardedAlternative>* dart::ChoiceNode::alternatives_
protected

Definition at line 937 of file regexp.h.


The documentation for this class was generated from the following files: