| Index: src/jsregexp.cc
|
| diff --git a/src/jsregexp.cc b/src/jsregexp.cc
|
| index 45a39ffbc2e8fee37ec64c8782b0525de9fc5b6c..7db89fba8e1bdc0a1bec7648b9bea1bc9b9ee917 100644
|
| --- a/src/jsregexp.cc
|
| +++ b/src/jsregexp.cc
|
| @@ -796,10 +796,10 @@ int TextElement::length() {
|
| }
|
|
|
|
|
| -DispatchTable* ChoiceNode::GetTable(bool ignore_case) {
|
| +DispatchTable* ChoiceNode::GetTable(Zone* zone, bool ignore_case) {
|
| if (table_ == NULL) {
|
| - table_ = new DispatchTable();
|
| - DispatchTableConstructor cons(table_, ignore_case);
|
| + table_ = new DispatchTable(zone);
|
| + DispatchTableConstructor cons(zone, table_, ignore_case);
|
| cons.BuildTable(this);
|
| }
|
| return table_;
|
| @@ -808,7 +808,13 @@ DispatchTable* ChoiceNode::GetTable(bool ignore_case) {
|
|
|
| class RegExpCompiler {
|
| public:
|
| - RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii);
|
| + RegExpCompiler(Isolate* isolate,
|
| + int capture_count,
|
| + bool ignore_case,
|
| + bool is_ascii);
|
| +
|
| + Isolate* isolate() { return isolate_; }
|
| + Zone* zone() { return isolate()->zone(); }
|
|
|
| int AllocateRegister() {
|
| if (next_register_ >= RegExpMacroAssembler::kMaxRegister) {
|
| @@ -850,6 +856,7 @@ class RegExpCompiler {
|
| static const int kNoRegister = -1;
|
|
|
| private:
|
| + Isolate* isolate_;
|
| EndNode* accept_;
|
| int next_register_;
|
| List<RegExpNode*>* work_list_;
|
| @@ -880,8 +887,12 @@ static RegExpEngine::CompilationResult IrregexpRegExpTooBig() {
|
|
|
| // Attempts to compile the regexp using an Irregexp code generator. Returns
|
| // a fixed array or a null handle depending on whether it succeeded.
|
| -RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii)
|
| - : next_register_(2 * (capture_count + 1)),
|
| +RegExpCompiler::RegExpCompiler(Isolate* isolate,
|
| + int capture_count,
|
| + bool ignore_case,
|
| + bool ascii)
|
| + : isolate_(isolate),
|
| + next_register_(2 * (capture_count + 1)),
|
| work_list_(NULL),
|
| recursion_depth_(0),
|
| ignore_case_(ignore_case),
|
| @@ -984,18 +995,19 @@ bool Trace::GetStoredPosition(int reg, int* cp_offset) {
|
| }
|
|
|
|
|
| -int Trace::FindAffectedRegisters(OutSet* affected_registers) {
|
| +int Trace::FindAffectedRegisters(Zone* zone, OutSet* affected_registers) {
|
| int max_register = RegExpCompiler::kNoRegister;
|
| for (DeferredAction* action = actions_;
|
| action != NULL;
|
| action = action->next()) {
|
| if (action->type() == ActionNode::CLEAR_CAPTURES) {
|
| Interval range = static_cast<DeferredClearCaptures*>(action)->range();
|
| - for (int i = range.from(); i <= range.to(); i++)
|
| - affected_registers->Set(i);
|
| + for (int i = range.from(); i <= range.to(); i++) {
|
| + affected_registers->Set(zone, i);
|
| + }
|
| if (range.to() > max_register) max_register = range.to();
|
| } else {
|
| - affected_registers->Set(action->reg());
|
| + affected_registers->Set(zone, action->reg());
|
| if (action->reg() > max_register) max_register = action->reg();
|
| }
|
| }
|
| @@ -1020,7 +1032,8 @@ void Trace::RestoreAffectedRegisters(RegExpMacroAssembler* assembler,
|
| }
|
|
|
|
|
| -void Trace::PerformDeferredActions(RegExpMacroAssembler* assembler,
|
| +void Trace::PerformDeferredActions(Zone* zone,
|
| + RegExpMacroAssembler* assembler,
|
| int max_register,
|
| OutSet& affected_registers,
|
| OutSet* registers_to_pop,
|
| @@ -1130,9 +1143,9 @@ void Trace::PerformDeferredActions(RegExpMacroAssembler* assembler,
|
| }
|
|
|
| assembler->PushRegister(reg, stack_check);
|
| - registers_to_pop->Set(reg);
|
| + registers_to_pop->Set(zone, reg);
|
| } else if (undo_action == CLEAR) {
|
| - registers_to_clear->Set(reg);
|
| + registers_to_clear->Set(zone, reg);
|
| }
|
| // Perform the chronologically last action (or accumulated increment)
|
| // for the register.
|
| @@ -1178,10 +1191,12 @@ void Trace::Flush(RegExpCompiler* compiler, RegExpNode* successor) {
|
| assembler->PushCurrentPosition();
|
| }
|
|
|
| - int max_register = FindAffectedRegisters(&affected_registers);
|
| + int max_register = FindAffectedRegisters(compiler->zone(),
|
| + &affected_registers);
|
| OutSet registers_to_pop;
|
| OutSet registers_to_clear;
|
| - PerformDeferredActions(assembler,
|
| + PerformDeferredActions(compiler->zone(),
|
| + assembler,
|
| max_register,
|
| affected_registers,
|
| ®isters_to_pop,
|
| @@ -1262,9 +1277,9 @@ void EndNode::Emit(RegExpCompiler* compiler, Trace* trace) {
|
| }
|
|
|
|
|
| -void GuardedAlternative::AddGuard(Guard* guard) {
|
| +void GuardedAlternative::AddGuard(Zone* zone, Guard* guard) {
|
| if (guards_ == NULL)
|
| - guards_ = new ZoneList<Guard*>(1);
|
| + guards_ = ZoneList<Guard*>::New(zone, 1);
|
| guards_->Add(guard);
|
| }
|
|
|
| @@ -1556,14 +1571,15 @@ static inline bool EmitAtomLetter(Isolate* isolate,
|
| }
|
|
|
|
|
| -static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
|
| +static void EmitCharClass(Zone* zone,
|
| + RegExpMacroAssembler* macro_assembler,
|
| RegExpCharacterClass* cc,
|
| bool ascii,
|
| Label* on_failure,
|
| int cp_offset,
|
| bool check_offset,
|
| bool preloaded) {
|
| - ZoneList<CharacterRange>* ranges = cc->ranges();
|
| + ZoneList<CharacterRange>* ranges = cc->ranges(zone);
|
| int max_char;
|
| if (ascii) {
|
| max_char = String::kMaxAsciiCharCode;
|
| @@ -1613,9 +1629,9 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
|
| macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check_offset);
|
| }
|
|
|
| - if (cc->is_standard() &&
|
| - macro_assembler->CheckSpecialCharacterClass(cc->standard_type(),
|
| - on_failure)) {
|
| + if (cc->is_standard(zone) &&
|
| + macro_assembler->CheckSpecialCharacterClass(cc->standard_type(),
|
| + on_failure)) {
|
| return;
|
| }
|
|
|
| @@ -1954,7 +1970,7 @@ void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
|
| RegExpCompiler* compiler,
|
| int characters_filled_in,
|
| bool not_at_start) {
|
| - Isolate* isolate = Isolate::Current();
|
| + Isolate* isolate = compiler->isolate();
|
| ASSERT(characters_filled_in < details->characters());
|
| int characters = details->characters();
|
| int char_mask;
|
| @@ -2032,7 +2048,7 @@ void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
|
| QuickCheckDetails::Position* pos =
|
| details->positions(characters_filled_in);
|
| RegExpCharacterClass* tree = elm.data.u_char_class;
|
| - ZoneList<CharacterRange>* ranges = tree->ranges();
|
| + ZoneList<CharacterRange>* ranges = tree->ranges(isolate->zone());
|
| if (tree->is_negated()) {
|
| // A quick check uses multi-character mask and compare. There is no
|
| // useful way to incorporate a negative char class into this scheme
|
| @@ -2486,7 +2502,7 @@ void TextNode::TextEmitPass(RegExpCompiler* compiler,
|
| Trace* trace,
|
| bool first_element_checked,
|
| int* checked_up_to) {
|
| - Isolate* isolate = Isolate::Current();
|
| + Isolate* isolate = compiler->isolate();
|
| RegExpMacroAssembler* assembler = compiler->macro_assembler();
|
| bool ascii = compiler->ascii();
|
| Label* backtrack = trace->backtrack();
|
| @@ -2538,7 +2554,8 @@ void TextNode::TextEmitPass(RegExpCompiler* compiler,
|
| if (first_element_checked && i == 0) continue;
|
| if (DeterminedAlready(quick_check, elm.cp_offset)) continue;
|
| RegExpCharacterClass* cc = elm.data.u_char_class;
|
| - EmitCharClass(assembler,
|
| + EmitCharClass(compiler->zone(),
|
| + assembler,
|
| cc,
|
| ascii,
|
| backtrack,
|
| @@ -2657,7 +2674,7 @@ void Trace::AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler) {
|
| }
|
|
|
|
|
| -void TextNode::MakeCaseIndependent(bool is_ascii) {
|
| +void TextNode::MakeCaseIndependent(Zone* zone, bool is_ascii) {
|
| int element_count = elms_->length();
|
| for (int i = 0; i < element_count; i++) {
|
| TextElement elm = elms_->at(i);
|
| @@ -2665,8 +2682,8 @@ void TextNode::MakeCaseIndependent(bool is_ascii) {
|
| RegExpCharacterClass* cc = elm.data.u_char_class;
|
| // None of the standard character classses is different in the case
|
| // independent case and it slows us down if we don't know that.
|
| - if (cc->is_standard()) continue;
|
| - ZoneList<CharacterRange>* ranges = cc->ranges();
|
| + if (cc->is_standard(zone)) continue;
|
| + ZoneList<CharacterRange>* ranges = cc->ranges(zone);
|
| int range_count = ranges->length();
|
| for (int j = 0; j < range_count; j++) {
|
| ranges->at(j).AddCaseEquivalents(ranges, is_ascii);
|
| @@ -2788,8 +2805,8 @@ class AlternativeGeneration: public Malloced {
|
| // size then it is on the stack, otherwise the excess is on the heap.
|
| class AlternativeGenerationList {
|
| public:
|
| - explicit AlternativeGenerationList(int count)
|
| - : alt_gens_(count) {
|
| + AlternativeGenerationList(Zone* zone, int count)
|
| + : alt_gens_(zone, count) {
|
| for (int i = 0; i < count && i < kAFew; i++) {
|
| alt_gens_.Add(a_few_alt_gens_ + i);
|
| }
|
| @@ -2965,7 +2982,7 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
|
| (current_trace->characters_preloaded() == preload_characters);
|
| bool preload_has_checked_bounds = preload_is_current;
|
|
|
| - AlternativeGenerationList alt_gens(choice_count);
|
| + AlternativeGenerationList alt_gens(compiler->zone(), choice_count);
|
|
|
| // For now we just call all choices one after the other. The idea ultimately
|
| // is to use the Dispatch table to try only the relevant ones.
|
| @@ -3425,11 +3442,11 @@ void DotPrinter::VisitChoice(ChoiceNode* that) {
|
| if (kPrintDispatchTable) {
|
| stream()->Add(" n%p [shape=Mrecord, label=\"", that);
|
| TableEntryHeaderPrinter header_printer(stream());
|
| - that->GetTable(ignore_case_)->ForEach(&header_printer);
|
| + that->GetTable(ZONE, ignore_case_)->ForEach(&header_printer);
|
| stream()->Add("\"]\n", that);
|
| PrintAttributes(that);
|
| TableEntryBodyPrinter body_printer(stream(), that);
|
| - that->GetTable(ignore_case_)->ForEach(&body_printer);
|
| + that->GetTable(ZONE, ignore_case_)->ForEach(&body_printer);
|
| } else {
|
| stream()->Add(" n%p [shape=Mrecord, label=\"?\"];\n", that);
|
| for (int i = 0; i < that->alternatives()->length(); i++) {
|
| @@ -3459,8 +3476,9 @@ void DotPrinter::VisitText(TextNode* that) {
|
| stream()->Add("[");
|
| if (node->is_negated())
|
| stream()->Add("^");
|
| - for (int j = 0; j < node->ranges()->length(); j++) {
|
| - CharacterRange range = node->ranges()->at(j);
|
| + Zone* zone = ZONE;
|
| + for (int j = 0; j < node->ranges(zone)->length(); j++) {
|
| + CharacterRange range = node->ranges(zone)->at(j);
|
| stream()->Add("%k-%k", range.from(), range.to());
|
| }
|
| stream()->Add("]");
|
| @@ -3641,7 +3659,7 @@ static const uc16 kLineTerminatorRanges[kLineTerminatorRangeCount] = { 0x000A,
|
|
|
| RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler,
|
| RegExpNode* on_success) {
|
| - ZoneList<TextElement>* elms = new ZoneList<TextElement>(1);
|
| + ZoneList<TextElement>* elms = ZoneList<TextElement>::New(compiler->zone(), 1);
|
| elms->Add(TextElement::Atom(this));
|
| return new TextNode(elms, on_success);
|
| }
|
| @@ -3697,7 +3715,7 @@ static bool CompareRanges(ZoneList<CharacterRange>* ranges,
|
| }
|
|
|
|
|
| -bool RegExpCharacterClass::is_standard() {
|
| +bool RegExpCharacterClass::is_standard(Zone* zone) {
|
| // TODO(lrn): Remove need for this function, by not throwing away information
|
| // along the way.
|
| if (is_negated_) {
|
| @@ -3706,31 +3724,31 @@ bool RegExpCharacterClass::is_standard() {
|
| if (set_.is_standard()) {
|
| return true;
|
| }
|
| - if (CompareRanges(set_.ranges(), kSpaceRanges, kSpaceRangeCount)) {
|
| + if (CompareRanges(set_.ranges(zone), kSpaceRanges, kSpaceRangeCount)) {
|
| set_.set_standard_set_type('s');
|
| return true;
|
| }
|
| - if (CompareInverseRanges(set_.ranges(), kSpaceRanges, kSpaceRangeCount)) {
|
| + if (CompareInverseRanges(set_.ranges(zone), kSpaceRanges, kSpaceRangeCount)) {
|
| set_.set_standard_set_type('S');
|
| return true;
|
| }
|
| - if (CompareInverseRanges(set_.ranges(),
|
| + if (CompareInverseRanges(set_.ranges(zone),
|
| kLineTerminatorRanges,
|
| kLineTerminatorRangeCount)) {
|
| set_.set_standard_set_type('.');
|
| return true;
|
| }
|
| - if (CompareRanges(set_.ranges(),
|
| + if (CompareRanges(set_.ranges(zone),
|
| kLineTerminatorRanges,
|
| kLineTerminatorRangeCount)) {
|
| set_.set_standard_set_type('n');
|
| return true;
|
| }
|
| - if (CompareRanges(set_.ranges(), kWordRanges, kWordRangeCount)) {
|
| + if (CompareRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) {
|
| set_.set_standard_set_type('w');
|
| return true;
|
| }
|
| - if (CompareInverseRanges(set_.ranges(), kWordRanges, kWordRangeCount)) {
|
| + if (CompareInverseRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) {
|
| set_.set_standard_set_type('W');
|
| return true;
|
| }
|
| @@ -3740,7 +3758,7 @@ bool RegExpCharacterClass::is_standard() {
|
|
|
| RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler,
|
| RegExpNode* on_success) {
|
| - return new TextNode(this, on_success);
|
| + return new TextNode(compiler->zone(), this, on_success);
|
| }
|
|
|
|
|
| @@ -3748,7 +3766,7 @@ RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler,
|
| RegExpNode* on_success) {
|
| ZoneList<RegExpTree*>* alternatives = this->alternatives();
|
| int length = alternatives->length();
|
| - ChoiceNode* result = new ChoiceNode(length);
|
| + ChoiceNode* result = new ChoiceNode(compiler->zone(), length);
|
| for (int i = 0; i < length; i++) {
|
| GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler,
|
| on_success));
|
| @@ -3871,7 +3889,7 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
|
| // Unroll the optional matches up to max.
|
| RegExpNode* answer = on_success;
|
| for (int i = 0; i < max; i++) {
|
| - ChoiceNode* alternation = new ChoiceNode(2);
|
| + ChoiceNode* alternation = new ChoiceNode(compiler->zone(), 2);
|
| if (is_greedy) {
|
| alternation->AddAlternative(
|
| GuardedAlternative(body->ToNode(compiler, answer)));
|
| @@ -3894,7 +3912,8 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
|
| int reg_ctr = needs_counter
|
| ? compiler->AllocateRegister()
|
| : RegExpCompiler::kNoRegister;
|
| - LoopChoiceNode* center = new LoopChoiceNode(body->min_match() == 0);
|
| + LoopChoiceNode* center = new LoopChoiceNode(compiler->zone(),
|
| + body->min_match() == 0);
|
| if (not_at_start) center->set_not_at_start();
|
| RegExpNode* loop_return = needs_counter
|
| ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
|
| @@ -3920,12 +3939,12 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
|
| GuardedAlternative body_alt(body_node);
|
| if (has_max) {
|
| Guard* body_guard = new Guard(reg_ctr, Guard::LT, max);
|
| - body_alt.AddGuard(body_guard);
|
| + body_alt.AddGuard(compiler->zone(), body_guard);
|
| }
|
| GuardedAlternative rest_alt(on_success);
|
| if (has_min) {
|
| Guard* rest_guard = new Guard(reg_ctr, Guard::GEQ, min);
|
| - rest_alt.AddGuard(rest_guard);
|
| + rest_alt.AddGuard(compiler->zone(), rest_guard);
|
| }
|
| if (is_greedy) {
|
| center->AddLoopAlternative(body_alt);
|
| @@ -3963,19 +3982,20 @@ RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler,
|
| int stack_pointer_register = compiler->AllocateRegister();
|
| int position_register = compiler->AllocateRegister();
|
| // The ChoiceNode to distinguish between a newline and end-of-input.
|
| - ChoiceNode* result = new ChoiceNode(2);
|
| + ChoiceNode* result = new ChoiceNode(compiler->zone(), 2);
|
| // Create a newline atom.
|
| ZoneList<CharacterRange>* newline_ranges =
|
| - new ZoneList<CharacterRange>(3);
|
| + ZoneList<CharacterRange>::New(compiler->zone(), 3);
|
| CharacterRange::AddClassEscape('n', newline_ranges);
|
| RegExpCharacterClass* newline_atom = new RegExpCharacterClass('n');
|
| TextNode* newline_matcher = new TextNode(
|
| - newline_atom,
|
| - ActionNode::PositiveSubmatchSuccess(stack_pointer_register,
|
| - position_register,
|
| - 0, // No captures inside.
|
| - -1, // Ignored if no captures.
|
| - on_success));
|
| + compiler->zone(),
|
| + newline_atom,
|
| + ActionNode::PositiveSubmatchSuccess(stack_pointer_register,
|
| + position_register,
|
| + 0, // No captures inside.
|
| + -1, // Ignored if no captures.
|
| + on_success));
|
| // Create an end-of-input matcher.
|
| RegExpNode* end_of_line = ActionNode::BeginSubmatch(
|
| stack_pointer_register,
|
| @@ -4052,7 +4072,8 @@ RegExpNode* RegExpLookahead::ToNode(RegExpCompiler* compiler,
|
| register_count,
|
| register_start)));
|
| ChoiceNode* choice_node =
|
| - new NegativeLookaheadChoiceNode(body_alt,
|
| + new NegativeLookaheadChoiceNode(compiler->zone(),
|
| + body_alt,
|
| GuardedAlternative(on_success));
|
| return ActionNode::BeginSubmatch(stack_pointer_register,
|
| position_register,
|
| @@ -4168,9 +4189,11 @@ Vector<const uc16> CharacterRange::GetWordBounds() {
|
|
|
| class CharacterRangeSplitter {
|
| public:
|
| - CharacterRangeSplitter(ZoneList<CharacterRange>** included,
|
| - ZoneList<CharacterRange>** excluded)
|
| - : included_(included),
|
| + CharacterRangeSplitter(Zone* zone,
|
| + ZoneList<CharacterRange>** included,
|
| + ZoneList<CharacterRange>** excluded)
|
| + : zone_(zone),
|
| + included_(included),
|
| excluded_(excluded) { }
|
| void Call(uc16 from, DispatchTable::Entry entry);
|
|
|
| @@ -4178,35 +4201,38 @@ class CharacterRangeSplitter {
|
| static const int kInOverlay = 1;
|
|
|
| private:
|
| + Zone* zone_;
|
| ZoneList<CharacterRange>** included_;
|
| ZoneList<CharacterRange>** excluded_;
|
| };
|
|
|
|
|
| -void CharacterRangeSplitter::Call(uc16 from, DispatchTable::Entry entry) {
|
| +void CharacterRangeSplitter::Call(uc16 from,
|
| + DispatchTable::Entry entry) {
|
| if (!entry.out_set()->Get(kInBase)) return;
|
| ZoneList<CharacterRange>** target = entry.out_set()->Get(kInOverlay)
|
| ? included_
|
| : excluded_;
|
| - if (*target == NULL) *target = new ZoneList<CharacterRange>(2);
|
| + if (*target == NULL) *target = ZoneList<CharacterRange>::New(zone_, 2);
|
| (*target)->Add(CharacterRange(entry.from(), entry.to()));
|
| }
|
|
|
|
|
| -void CharacterRange::Split(ZoneList<CharacterRange>* base,
|
| +void CharacterRange::Split(Zone* zone,
|
| + ZoneList<CharacterRange>* base,
|
| Vector<const uc16> overlay,
|
| ZoneList<CharacterRange>** included,
|
| ZoneList<CharacterRange>** excluded) {
|
| ASSERT_EQ(NULL, *included);
|
| ASSERT_EQ(NULL, *excluded);
|
| - DispatchTable table;
|
| + DispatchTable table(zone);
|
| for (int i = 0; i < base->length(); i++)
|
| table.AddRange(base->at(i), CharacterRangeSplitter::kInBase);
|
| for (int i = 0; i < overlay.length(); i += 2) {
|
| table.AddRange(CharacterRange(overlay[i], overlay[i+1]),
|
| CharacterRangeSplitter::kInOverlay);
|
| }
|
| - CharacterRangeSplitter callback(included, excluded);
|
| + CharacterRangeSplitter callback(zone, included, excluded);
|
| table.ForEach(&callback);
|
| }
|
|
|
| @@ -4371,9 +4397,9 @@ SetRelation CharacterRange::WordCharacterRelation(
|
| }
|
|
|
|
|
| -ZoneList<CharacterRange>* CharacterSet::ranges() {
|
| +ZoneList<CharacterRange>* CharacterSet::ranges(Zone* zone) {
|
| if (ranges_ == NULL) {
|
| - ranges_ = new ZoneList<CharacterRange>(2);
|
| + ranges_ = ZoneList<CharacterRange>::New(zone, 2);
|
| CharacterRange::AddClassEscape(standard_set_type_, ranges_);
|
| }
|
| return ranges_;
|
| @@ -4679,9 +4705,11 @@ RegExpNode* RegExpNode::TryGetSibling(NodeInfo* info) {
|
| }
|
|
|
|
|
| -RegExpNode* RegExpNode::EnsureSibling(NodeInfo* info, bool* cloned) {
|
| +RegExpNode* RegExpNode::EnsureSibling(Zone* zone,
|
| + NodeInfo* info,
|
| + bool* cloned) {
|
| ASSERT_EQ(false, *cloned);
|
| - siblings_.Ensure(this);
|
| + siblings_.Ensure(zone, this);
|
| RegExpNode* result = TryGetSibling(info);
|
| if (result != NULL) return result;
|
| result = this->Clone();
|
| @@ -4707,7 +4735,7 @@ static RegExpNode* PropagateToEndpoint(C* node, NodeInfo* info) {
|
| // Splay tree
|
|
|
|
|
| -OutSet* OutSet::Extend(unsigned value) {
|
| +OutSet* OutSet::Extend(Zone* zone, unsigned value) {
|
| if (Get(value))
|
| return this;
|
| if (successors() != NULL) {
|
| @@ -4717,21 +4745,21 @@ OutSet* OutSet::Extend(unsigned value) {
|
| return successor;
|
| }
|
| } else {
|
| - successors_ = new ZoneList<OutSet*>(2);
|
| + successors_ = ZoneList<OutSet*>::New(zone, 2);
|
| }
|
| - OutSet* result = new OutSet(first_, remaining_);
|
| - result->Set(value);
|
| + OutSet* result = new(zone) OutSet(first_, remaining_);
|
| + result->Set(zone, value);
|
| successors()->Add(result);
|
| return result;
|
| }
|
|
|
|
|
| -void OutSet::Set(unsigned value) {
|
| +void OutSet::Set(Zone* zone, unsigned value) {
|
| if (value < kFirstLimit) {
|
| first_ |= (1 << value);
|
| } else {
|
| if (remaining_ == NULL)
|
| - remaining_ = new ZoneList<unsigned>(1);
|
| + remaining_ = ZoneList<unsigned>::New(zone, 1);
|
| if (remaining_->is_empty() || !remaining_->Contains(value))
|
| remaining_->Add(value);
|
| }
|
| @@ -4759,7 +4787,9 @@ void DispatchTable::AddRange(CharacterRange full_range, int value) {
|
| // If this is the first range we just insert into the table.
|
| ZoneSplayTree<Config>::Locator loc;
|
| ASSERT_RESULT(tree()->Insert(current.from(), &loc));
|
| - loc.set_value(Entry(current.from(), current.to(), empty()->Extend(value)));
|
| + loc.set_value(Entry(current.from(),
|
| + current.to(),
|
| + empty()->Extend(zone_, value)));
|
| return;
|
| }
|
| // First see if there is a range to the left of this one that
|
| @@ -4802,7 +4832,7 @@ void DispatchTable::AddRange(CharacterRange full_range, int value) {
|
| ASSERT_RESULT(tree()->Insert(current.from(), &ins));
|
| ins.set_value(Entry(current.from(),
|
| entry->from() - 1,
|
| - empty()->Extend(value)));
|
| + empty()->Extend(zone_, value)));
|
| current.set_from(entry->from());
|
| }
|
| ASSERT_EQ(current.from(), entry->from());
|
| @@ -4820,7 +4850,7 @@ void DispatchTable::AddRange(CharacterRange full_range, int value) {
|
| // The overlapping range is now completely contained by the range
|
| // we're adding so we can just update it and move the start point
|
| // of the range we're adding just past it.
|
| - entry->AddValue(value);
|
| + entry->AddValue(zone_, value);
|
| // Bail out if the last interval ended at 0xFFFF since otherwise
|
| // adding 1 will wrap around to 0.
|
| if (entry->to() == String::kMaxUC16CharCode)
|
| @@ -4833,7 +4863,7 @@ void DispatchTable::AddRange(CharacterRange full_range, int value) {
|
| ASSERT_RESULT(tree()->Insert(current.from(), &ins));
|
| ins.set_value(Entry(current.from(),
|
| current.to(),
|
| - empty()->Extend(value)));
|
| + empty()->Extend(zone_, value)));
|
| break;
|
| }
|
| }
|
| @@ -4896,7 +4926,7 @@ void TextNode::CalculateOffsets() {
|
|
|
| void Analysis::VisitText(TextNode* that) {
|
| if (ignore_case_) {
|
| - that->MakeCaseIndependent(is_ascii_);
|
| + that->MakeCaseIndependent(zone_, is_ascii_);
|
| }
|
| EnsureAnalyzed(that->on_success());
|
| if (!has_failed()) {
|
| @@ -4960,7 +4990,7 @@ void Analysis::VisitAssertion(AssertionNode* that) {
|
| type == AssertionNode::AT_NON_BOUNDARY) {
|
| // Check if the following character is known to be a word character
|
| // or known to not be a word character.
|
| - ZoneList<CharacterRange>* following_chars = that->FirstCharacterSet();
|
| + ZoneList<CharacterRange>* following_chars = that->FirstCharacterSet(zone_);
|
|
|
| CharacterRange::Canonicalize(following_chars);
|
|
|
| @@ -4984,13 +5014,14 @@ void Analysis::VisitAssertion(AssertionNode* that) {
|
| }
|
|
|
|
|
| -ZoneList<CharacterRange>* RegExpNode::FirstCharacterSet() {
|
| +ZoneList<CharacterRange>* RegExpNode::FirstCharacterSet(Zone* zone) {
|
| if (first_character_set_ == NULL) {
|
| - if (ComputeFirstCharacterSet(kFirstCharBudget) < 0) {
|
| + if (ComputeFirstCharacterSet(zone, kFirstCharBudget) < 0) {
|
| // If we can't find an exact solution within the budget, we
|
| // set the value to the set of every character, i.e., all characters
|
| // are possible.
|
| - ZoneList<CharacterRange>* all_set = new ZoneList<CharacterRange>(1);
|
| + ZoneList<CharacterRange>* all_set =
|
| + ZoneList<CharacterRange>::New(zone, 1);
|
| all_set->Add(CharacterRange::Everything());
|
| first_character_set_ = all_set;
|
| }
|
| @@ -4999,13 +5030,13 @@ ZoneList<CharacterRange>* RegExpNode::FirstCharacterSet() {
|
| }
|
|
|
|
|
| -int RegExpNode::ComputeFirstCharacterSet(int budget) {
|
| +int RegExpNode::ComputeFirstCharacterSet(Zone* zone, int budget) {
|
| // Default behavior is to not be able to determine the first character.
|
| return kComputeFirstCharacterSetFail;
|
| }
|
|
|
|
|
| -int LoopChoiceNode::ComputeFirstCharacterSet(int budget) {
|
| +int LoopChoiceNode::ComputeFirstCharacterSet(Zone* zone, int budget) {
|
| budget--;
|
| if (budget >= 0) {
|
| // Find loop min-iteration. It's the value of the guarded choice node
|
| @@ -5024,18 +5055,19 @@ int LoopChoiceNode::ComputeFirstCharacterSet(int budget) {
|
| }
|
| }
|
|
|
| - budget = loop_node()->ComputeFirstCharacterSet(budget);
|
| + budget = loop_node()->ComputeFirstCharacterSet(zone, budget);
|
| if (budget >= 0) {
|
| ZoneList<CharacterRange>* character_set =
|
| loop_node()->first_character_set();
|
| if (body_can_be_zero_length() || min_repetition == 0) {
|
| - budget = continue_node()->ComputeFirstCharacterSet(budget);
|
| + budget = continue_node()->ComputeFirstCharacterSet(zone, budget);
|
| if (budget < 0) return budget;
|
| ZoneList<CharacterRange>* body_set =
|
| continue_node()->first_character_set();
|
| ZoneList<CharacterRange>* union_set =
|
| - new ZoneList<CharacterRange>(Max(character_set->length(),
|
| - body_set->length()));
|
| + ZoneList<CharacterRange>::New(zone,
|
| + Max(character_set->length(),
|
| + body_set->length()));
|
| CharacterRange::Merge(character_set,
|
| body_set,
|
| union_set,
|
| @@ -5050,12 +5082,13 @@ int LoopChoiceNode::ComputeFirstCharacterSet(int budget) {
|
| }
|
|
|
|
|
| -int NegativeLookaheadChoiceNode::ComputeFirstCharacterSet(int budget) {
|
| +int NegativeLookaheadChoiceNode::ComputeFirstCharacterSet(Zone* zone,
|
| + int budget) {
|
| budget--;
|
| if (budget >= 0) {
|
| GuardedAlternative successor = this->alternatives()->at(1);
|
| RegExpNode* successor_node = successor.node();
|
| - budget = successor_node->ComputeFirstCharacterSet(budget);
|
| + budget = successor_node->ComputeFirstCharacterSet(zone, budget);
|
| if (budget >= 0) {
|
| set_first_character_set(successor_node->first_character_set());
|
| }
|
| @@ -5068,12 +5101,12 @@ int NegativeLookaheadChoiceNode::ComputeFirstCharacterSet(int budget) {
|
| // default implementation that fails and returns all characters as possible.
|
|
|
|
|
| -int AssertionNode::ComputeFirstCharacterSet(int budget) {
|
| +int AssertionNode::ComputeFirstCharacterSet(Zone* zone, int budget) {
|
| budget -= 1;
|
| if (budget >= 0) {
|
| switch (type_) {
|
| case AT_END: {
|
| - set_first_character_set(new ZoneList<CharacterRange>(0));
|
| + set_first_character_set(ZoneList<CharacterRange>::New(zone, 0));
|
| break;
|
| }
|
| case AT_START:
|
| @@ -5083,7 +5116,7 @@ int AssertionNode::ComputeFirstCharacterSet(int budget) {
|
| case AFTER_NONWORD_CHARACTER:
|
| case AFTER_WORD_CHARACTER: {
|
| ASSERT_NOT_NULL(on_success());
|
| - budget = on_success()->ComputeFirstCharacterSet(budget);
|
| + budget = on_success()->ComputeFirstCharacterSet(zone, budget);
|
| if (budget >= 0) {
|
| set_first_character_set(on_success()->first_character_set());
|
| }
|
| @@ -5095,12 +5128,12 @@ int AssertionNode::ComputeFirstCharacterSet(int budget) {
|
| }
|
|
|
|
|
| -int ActionNode::ComputeFirstCharacterSet(int budget) {
|
| +int ActionNode::ComputeFirstCharacterSet(Zone* zone, int budget) {
|
| if (type_ == POSITIVE_SUBMATCH_SUCCESS) return kComputeFirstCharacterSetFail;
|
| budget--;
|
| if (budget >= 0) {
|
| ASSERT_NOT_NULL(on_success());
|
| - budget = on_success()->ComputeFirstCharacterSet(budget);
|
| + budget = on_success()->ComputeFirstCharacterSet(zone, budget);
|
| if (budget >= 0) {
|
| set_first_character_set(on_success()->first_character_set());
|
| }
|
| @@ -5109,7 +5142,7 @@ int ActionNode::ComputeFirstCharacterSet(int budget) {
|
| }
|
|
|
|
|
| -int BackReferenceNode::ComputeFirstCharacterSet(int budget) {
|
| +int BackReferenceNode::ComputeFirstCharacterSet(Zone* zone, int budget) {
|
| // We don't know anything about the first character of a backreference
|
| // at this point.
|
| // The potential first characters are the first characters of the capture,
|
| @@ -5120,7 +5153,7 @@ int BackReferenceNode::ComputeFirstCharacterSet(int budget) {
|
| }
|
|
|
|
|
| -int TextNode::ComputeFirstCharacterSet(int budget) {
|
| +int TextNode::ComputeFirstCharacterSet(Zone* zone, int budget) {
|
| budget--;
|
| if (budget >= 0) {
|
| ASSERT_NE(0, elements()->length());
|
| @@ -5129,13 +5162,13 @@ int TextNode::ComputeFirstCharacterSet(int budget) {
|
| RegExpAtom* atom = text.data.u_atom;
|
| ASSERT_NE(0, atom->length());
|
| uc16 first_char = atom->data()[0];
|
| - ZoneList<CharacterRange>* range = new ZoneList<CharacterRange>(1);
|
| + ZoneList<CharacterRange>* range = ZoneList<CharacterRange>::New(zone, 1);
|
| range->Add(CharacterRange(first_char, first_char));
|
| set_first_character_set(range);
|
| } else {
|
| ASSERT(text.type == TextElement::CHAR_CLASS);
|
| RegExpCharacterClass* char_class = text.data.u_char_class;
|
| - ZoneList<CharacterRange>* ranges = char_class->ranges();
|
| + ZoneList<CharacterRange>* ranges = char_class->ranges(zone);
|
| // TODO(lrn): Canonicalize ranges when they are created
|
| // instead of waiting until now.
|
| CharacterRange::Canonicalize(ranges);
|
| @@ -5149,7 +5182,7 @@ int TextNode::ComputeFirstCharacterSet(int budget) {
|
| }
|
| }
|
| ZoneList<CharacterRange>* negated_ranges =
|
| - new ZoneList<CharacterRange>(new_length);
|
| + ZoneList<CharacterRange>::New(zone, new_length);
|
| CharacterRange::Negate(ranges, negated_ranges);
|
| set_first_character_set(negated_ranges);
|
| } else {
|
| @@ -5201,7 +5234,7 @@ void AddDispatchRange::Call(uc32 from, DispatchTable::Entry entry) {
|
| void DispatchTableConstructor::VisitChoice(ChoiceNode* node) {
|
| if (node->being_calculated())
|
| return;
|
| - DispatchTable* table = node->GetTable(ignore_case_);
|
| + DispatchTable* table = node->GetTable(zone_, ignore_case_);
|
| AddDispatchRange adder(this);
|
| table->ForEach(&adder);
|
| }
|
| @@ -5255,7 +5288,7 @@ void DispatchTableConstructor::VisitText(TextNode* that) {
|
| }
|
| case TextElement::CHAR_CLASS: {
|
| RegExpCharacterClass* tree = elm.data.u_char_class;
|
| - ZoneList<CharacterRange>* ranges = tree->ranges();
|
| + ZoneList<CharacterRange>* ranges = tree->ranges(zone_);
|
| if (tree->is_negated()) {
|
| AddInverse(ranges);
|
| } else {
|
| @@ -5282,10 +5315,11 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(RegExpCompileData* data,
|
| bool is_multiline,
|
| Handle<String> pattern,
|
| bool is_ascii) {
|
| + Isolate* isolate = pattern->GetIsolate();
|
| if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) {
|
| return IrregexpRegExpTooBig();
|
| }
|
| - RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii);
|
| + RegExpCompiler compiler(isolate, data->capture_count, ignore_case, is_ascii);
|
| // Wrap the body of the regexp in capture #0.
|
| RegExpNode* captured_body = RegExpCapture::ToNode(data->tree,
|
| 0,
|
| @@ -5310,17 +5344,18 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(RegExpCompileData* data,
|
| if (data->contains_anchor) {
|
| // Unroll loop once, to take care of the case that might start
|
| // at the start of input.
|
| - ChoiceNode* first_step_node = new ChoiceNode(2);
|
| + ChoiceNode* first_step_node = new ChoiceNode(isolate->zone(), 2);
|
| first_step_node->AddAlternative(GuardedAlternative(captured_body));
|
| first_step_node->AddAlternative(GuardedAlternative(
|
| - new TextNode(new RegExpCharacterClass('*'), loop_node)));
|
| + new TextNode(isolate->zone(),
|
| + new RegExpCharacterClass('*'), loop_node)));
|
| node = first_step_node;
|
| } else {
|
| node = loop_node;
|
| }
|
| }
|
| data->node = node;
|
| - Analysis analysis(ignore_case, is_ascii);
|
| + Analysis analysis(isolate->zone(), ignore_case, is_ascii);
|
| analysis.EnsureAnalyzed(node);
|
| if (analysis.has_failed()) {
|
| const char* error_message = analysis.error_message();
|
|
|