| 417 | }; |
| 418 | |
| 419 | DFA::DFA(Prog* prog, Prog::MatchKind kind, int64_t max_mem) |
| 420 | : prog_(prog), |
| 421 | kind_(kind), |
| 422 | init_failed_(false), |
| 423 | q0_(NULL), |
| 424 | q1_(NULL), |
| 425 | mem_budget_(max_mem) { |
| 426 | if (ExtraDebug) |
| 427 | fprintf(stderr, "\nkind %d\n%s\n", kind_, prog_->DumpUnanchored().c_str()); |
| 428 | int nmark = 0; |
| 429 | if (kind_ == Prog::kLongestMatch) |
| 430 | nmark = prog_->size(); |
| 431 | // See DFA::AddToQueue() for why this is so. |
| 432 | int nstack = prog_->inst_count(kInstCapture) + |
| 433 | prog_->inst_count(kInstEmptyWidth) + |
| 434 | prog_->inst_count(kInstNop) + |
| 435 | nmark + 1; // + 1 for start inst |
| 436 | |
| 437 | // Account for space needed for DFA, q0, q1, stack. |
| 438 | mem_budget_ -= sizeof(DFA); |
| 439 | mem_budget_ -= (prog_->size() + nmark) * |
| 440 | (sizeof(int)+sizeof(int)) * 2; // q0, q1 |
| 441 | mem_budget_ -= nstack * sizeof(int); // stack |
| 442 | if (mem_budget_ < 0) { |
| 443 | init_failed_ = true; |
| 444 | return; |
| 445 | } |
| 446 | |
| 447 | state_budget_ = mem_budget_; |
| 448 | |
| 449 | // Make sure there is a reasonable amount of working room left. |
| 450 | // At minimum, the search requires room for two states in order |
| 451 | // to limp along, restarting frequently. We'll get better performance |
| 452 | // if there is room for a larger number of states, say 20. |
| 453 | // Note that a state stores list heads only, so we use the program |
| 454 | // list count for the upper bound, not the program size. |
| 455 | int nnext = prog_->bytemap_range() + 1; // + 1 for kByteEndText slot |
| 456 | int64_t one_state = sizeof(State) + nnext*sizeof(std::atomic<State*>) + |
| 457 | (prog_->list_count()+nmark)*sizeof(int); |
| 458 | if (state_budget_ < 20*one_state) { |
| 459 | init_failed_ = true; |
| 460 | return; |
| 461 | } |
| 462 | |
| 463 | q0_ = new Workq(prog_->size(), nmark); |
| 464 | q1_ = new Workq(prog_->size(), nmark); |
| 465 | stack_ = PODArray<int>(nstack); |
| 466 | } |
| 467 | |
| 468 | DFA::~DFA() { |
| 469 | delete q0_; |
nothing calls this directly
no test coverage detected