Index: src/jsregexp.cc |
diff --git a/src/jsregexp.cc b/src/jsregexp.cc |
index f88511f4a1d266c89984c4b46aa25bd6be642af2..9aa80beefc53be906100e87f40b70969a438858c 100644 |
--- a/src/jsregexp.cc |
+++ b/src/jsregexp.cc |
@@ -820,24 +820,24 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp, |
// the event that code generation is requested for an identical trace. |
-void RegExpTree::AppendToText(RegExpText* text) { |
+void RegExpTree::AppendToText(RegExpText* text, Zone* zone) { |
UNREACHABLE(); |
} |
-void RegExpAtom::AppendToText(RegExpText* text) { |
- text->AddElement(TextElement::Atom(this)); |
+void RegExpAtom::AppendToText(RegExpText* text, Zone* zone) { |
+ text->AddElement(TextElement::Atom(this), zone); |
} |
-void RegExpCharacterClass::AppendToText(RegExpText* text) { |
- text->AddElement(TextElement::CharClass(this)); |
+void RegExpCharacterClass::AppendToText(RegExpText* text, Zone* zone) { |
+ text->AddElement(TextElement::CharClass(this), zone); |
} |
-void RegExpText::AppendToText(RegExpText* text) { |
+void RegExpText::AppendToText(RegExpText* text, Zone* zone) { |
for (int i = 0; i < elements()->length(); i++) |
- text->AddElement(elements()->at(i)); |
+ text->AddElement(elements()->at(i), zone); |
} |
@@ -868,8 +868,8 @@ int TextElement::length() { |
DispatchTable* ChoiceNode::GetTable(bool ignore_case) { |
if (table_ == NULL) { |
- table_ = new DispatchTable(); |
- DispatchTableConstructor cons(table_, ignore_case); |
+ table_ = new(zone()) DispatchTable(zone()); |
+ DispatchTableConstructor cons(table_, ignore_case, zone()); |
cons.BuildTable(this); |
} |
return table_; |
@@ -966,7 +966,7 @@ class RegExpCompiler { |
current_expansion_factor_ = value; |
} |
- Zone* zone() { return zone_; } |
+ Zone* zone() const { return zone_; } |
static const int kNoRegister = -1; |
@@ -1014,7 +1014,7 @@ RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii, |
current_expansion_factor_(1), |
frequency_collator_(), |
zone_(zone) { |
- accept_ = new EndNode(EndNode::ACCEPT, zone); |
+ accept_ = new(zone) EndNode(EndNode::ACCEPT, zone); |
ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister); |
} |
@@ -1110,7 +1110,8 @@ bool Trace::GetStoredPosition(int reg, int* cp_offset) { |
} |
-int Trace::FindAffectedRegisters(OutSet* affected_registers) { |
+int Trace::FindAffectedRegisters(OutSet* affected_registers, |
+ Zone* zone) { |
int max_register = RegExpCompiler::kNoRegister; |
for (DeferredAction* action = actions_; |
action != NULL; |
@@ -1118,10 +1119,10 @@ int Trace::FindAffectedRegisters(OutSet* affected_registers) { |
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); |
+ affected_registers->Set(i, zone); |
if (range.to() > max_register) max_register = range.to(); |
} else { |
- affected_registers->Set(action->reg()); |
+ affected_registers->Set(action->reg(), zone); |
if (action->reg() > max_register) max_register = action->reg(); |
} |
} |
@@ -1150,7 +1151,8 @@ void Trace::PerformDeferredActions(RegExpMacroAssembler* assembler, |
int max_register, |
OutSet& affected_registers, |
OutSet* registers_to_pop, |
- OutSet* registers_to_clear) { |
+ OutSet* registers_to_clear, |
+ Zone* zone) { |
// The "+1" is to avoid a push_limit of zero if stack_limit_slack() is 1. |
const int push_limit = (assembler->stack_limit_slack() + 1) / 2; |
@@ -1256,9 +1258,9 @@ void Trace::PerformDeferredActions(RegExpMacroAssembler* assembler, |
} |
assembler->PushRegister(reg, stack_check); |
- registers_to_pop->Set(reg); |
+ registers_to_pop->Set(reg, zone); |
} else if (undo_action == CLEAR) { |
- registers_to_clear->Set(reg); |
+ registers_to_clear->Set(reg, zone); |
} |
// Perform the chronologically last action (or accumulated increment) |
// for the register. |
@@ -1304,14 +1306,16 @@ void Trace::Flush(RegExpCompiler* compiler, RegExpNode* successor) { |
assembler->PushCurrentPosition(); |
} |
- int max_register = FindAffectedRegisters(&affected_registers); |
+ int max_register = FindAffectedRegisters(&affected_registers, |
+ compiler->zone()); |
OutSet registers_to_pop; |
OutSet registers_to_clear; |
PerformDeferredActions(assembler, |
max_register, |
affected_registers, |
®isters_to_pop, |
- ®isters_to_clear); |
+ ®isters_to_clear, |
+ compiler->zone()); |
if (cp_offset_ != 0) { |
assembler->AdvanceCurrentPosition(cp_offset_); |
} |
@@ -1388,17 +1392,18 @@ void EndNode::Emit(RegExpCompiler* compiler, Trace* trace) { |
} |
-void GuardedAlternative::AddGuard(Guard* guard) { |
+void GuardedAlternative::AddGuard(Guard* guard, Zone* zone) { |
if (guards_ == NULL) |
- guards_ = new ZoneList<Guard*>(1); |
- guards_->Add(guard); |
+ guards_ = new(zone) ZoneList<Guard*>(1, zone); |
+ guards_->Add(guard, zone); |
} |
ActionNode* ActionNode::SetRegister(int reg, |
int val, |
RegExpNode* on_success) { |
- ActionNode* result = new ActionNode(SET_REGISTER, on_success); |
+ ActionNode* result = |
+ new(on_success->zone()) ActionNode(SET_REGISTER, on_success); |
result->data_.u_store_register.reg = reg; |
result->data_.u_store_register.value = val; |
return result; |
@@ -1406,7 +1411,8 @@ ActionNode* ActionNode::SetRegister(int reg, |
ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success) { |
- ActionNode* result = new ActionNode(INCREMENT_REGISTER, on_success); |
+ ActionNode* result = |
+ new(on_success->zone()) ActionNode(INCREMENT_REGISTER, on_success); |
result->data_.u_increment_register.reg = reg; |
return result; |
} |
@@ -1415,7 +1421,8 @@ ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success) { |
ActionNode* ActionNode::StorePosition(int reg, |
bool is_capture, |
RegExpNode* on_success) { |
- ActionNode* result = new ActionNode(STORE_POSITION, on_success); |
+ ActionNode* result = |
+ new(on_success->zone()) ActionNode(STORE_POSITION, on_success); |
result->data_.u_position_register.reg = reg; |
result->data_.u_position_register.is_capture = is_capture; |
return result; |
@@ -1424,7 +1431,8 @@ ActionNode* ActionNode::StorePosition(int reg, |
ActionNode* ActionNode::ClearCaptures(Interval range, |
RegExpNode* on_success) { |
- ActionNode* result = new ActionNode(CLEAR_CAPTURES, on_success); |
+ ActionNode* result = |
+ new(on_success->zone()) ActionNode(CLEAR_CAPTURES, on_success); |
result->data_.u_clear_captures.range_from = range.from(); |
result->data_.u_clear_captures.range_to = range.to(); |
return result; |
@@ -1434,7 +1442,8 @@ ActionNode* ActionNode::ClearCaptures(Interval range, |
ActionNode* ActionNode::BeginSubmatch(int stack_reg, |
int position_reg, |
RegExpNode* on_success) { |
- ActionNode* result = new ActionNode(BEGIN_SUBMATCH, on_success); |
+ ActionNode* result = |
+ new(on_success->zone()) ActionNode(BEGIN_SUBMATCH, on_success); |
result->data_.u_submatch.stack_pointer_register = stack_reg; |
result->data_.u_submatch.current_position_register = position_reg; |
return result; |
@@ -1446,7 +1455,8 @@ ActionNode* ActionNode::PositiveSubmatchSuccess(int stack_reg, |
int clear_register_count, |
int clear_register_from, |
RegExpNode* on_success) { |
- ActionNode* result = new ActionNode(POSITIVE_SUBMATCH_SUCCESS, on_success); |
+ ActionNode* result = |
+ new(on_success->zone()) ActionNode(POSITIVE_SUBMATCH_SUCCESS, on_success); |
result->data_.u_submatch.stack_pointer_register = stack_reg; |
result->data_.u_submatch.current_position_register = position_reg; |
result->data_.u_submatch.clear_register_count = clear_register_count; |
@@ -1459,7 +1469,8 @@ ActionNode* ActionNode::EmptyMatchCheck(int start_register, |
int repetition_register, |
int repetition_limit, |
RegExpNode* on_success) { |
- ActionNode* result = new ActionNode(EMPTY_MATCH_CHECK, on_success); |
+ ActionNode* result = |
+ new(on_success->zone()) ActionNode(EMPTY_MATCH_CHECK, on_success); |
result->data_.u_empty_match_check.start_register = start_register; |
result->data_.u_empty_match_check.repetition_register = repetition_register; |
result->data_.u_empty_match_check.repetition_limit = repetition_limit; |
@@ -2039,8 +2050,9 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, |
Label* on_failure, |
int cp_offset, |
bool check_offset, |
- bool preloaded) { |
- ZoneList<CharacterRange>* ranges = cc->ranges(); |
+ bool preloaded, |
+ Zone* zone) { |
+ ZoneList<CharacterRange>* ranges = cc->ranges(zone); |
if (!CharacterRange::IsCanonical(ranges)) { |
CharacterRange::Canonicalize(ranges); |
} |
@@ -2099,7 +2111,7 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, |
macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check_offset); |
} |
- if (cc->is_standard() && |
+ if (cc->is_standard(zone) && |
macro_assembler->CheckSpecialCharacterClass(cc->standard_type(), |
on_failure)) { |
return; |
@@ -2112,7 +2124,8 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, |
// entry at zero which goes to the failure label, but if there |
// was already one there we fall through for success on that entry. |
// Subsequent entries have alternating meaning (success/failure). |
- ZoneList<int>* range_boundaries = new ZoneList<int>(last_valid_range); |
+ ZoneList<int>* range_boundaries = |
+ new(zone) ZoneList<int>(last_valid_range, zone); |
bool zeroth_entry_is_failure = !cc->is_negated(); |
@@ -2122,9 +2135,9 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, |
ASSERT_EQ(i, 0); |
zeroth_entry_is_failure = !zeroth_entry_is_failure; |
} else { |
- range_boundaries->Add(range.from()); |
+ range_boundaries->Add(range.from(), zone); |
} |
- range_boundaries->Add(range.to() + 1); |
+ range_boundaries->Add(range.to() + 1, zone); |
} |
int end_index = range_boundaries->length() - 1; |
if (range_boundaries->at(end_index) > max_char) { |
@@ -2522,7 +2535,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(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 |
@@ -2707,7 +2720,7 @@ RegExpNode* TextNode::FilterASCII(int depth) { |
} else { |
ASSERT(elm.type == TextElement::CHAR_CLASS); |
RegExpCharacterClass* cc = elm.data.u_char_class; |
- ZoneList<CharacterRange>* ranges = cc->ranges(); |
+ ZoneList<CharacterRange>* ranges = cc->ranges(zone()); |
if (!CharacterRange::IsCanonical(ranges)) { |
CharacterRange::Canonicalize(ranges); |
} |
@@ -2775,13 +2788,13 @@ RegExpNode* ChoiceNode::FilterASCII(int depth) { |
// Only some of the nodes survived the filtering. We need to rebuild the |
// alternatives list. |
ZoneList<GuardedAlternative>* new_alternatives = |
- new ZoneList<GuardedAlternative>(surviving); |
+ new(zone()) ZoneList<GuardedAlternative>(surviving, zone()); |
for (int i = 0; i < choice_count; i++) { |
RegExpNode* replacement = |
alternatives_->at(i).node()->FilterASCII(depth - 1); |
if (replacement != NULL) { |
alternatives_->at(i).set_node(replacement); |
- new_alternatives->Add(alternatives_->at(i)); |
+ new_alternatives->Add(alternatives_->at(i), zone()); |
} |
} |
alternatives_ = new_alternatives; |
@@ -2938,7 +2951,7 @@ void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) { |
EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); |
if (eats_at_least >= 1) { |
BoyerMooreLookahead* bm = |
- new BoyerMooreLookahead(eats_at_least, compiler, zone()); |
+ new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone()); |
FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); |
if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; |
if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; |
@@ -3165,7 +3178,8 @@ void TextNode::TextEmitPass(RegExpCompiler* compiler, |
backtrack, |
cp_offset, |
*checked_up_to < cp_offset, |
- preloaded); |
+ preloaded, |
+ zone()); |
UpdateBoundsCheck(cp_offset, checked_up_to); |
} |
} |
@@ -3286,11 +3300,11 @@ void TextNode::MakeCaseIndependent(bool is_ascii) { |
RegExpCharacterClass* cc = elm.data.u_char_class; |
// None of the standard character classes 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); |
+ ranges->at(j).AddCaseEquivalents(ranges, is_ascii, zone()); |
} |
} |
} |
@@ -3313,7 +3327,7 @@ RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode( |
TextElement elm = elms_->at(0); |
if (elm.type != TextElement::CHAR_CLASS) return NULL; |
RegExpCharacterClass* node = elm.data.u_char_class; |
- ZoneList<CharacterRange>* ranges = node->ranges(); |
+ ZoneList<CharacterRange>* ranges = node->ranges(zone()); |
if (!CharacterRange::IsCanonical(ranges)) { |
CharacterRange::Canonicalize(ranges); |
} |
@@ -3435,13 +3449,13 @@ 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(int count, Zone* zone) |
+ : alt_gens_(count, zone) { |
for (int i = 0; i < count && i < kAFew; i++) { |
- alt_gens_.Add(a_few_alt_gens_ + i); |
+ alt_gens_.Add(a_few_alt_gens_ + i, zone); |
} |
for (int i = kAFew; i < count; i++) { |
- alt_gens_.Add(new AlternativeGeneration()); |
+ alt_gens_.Add(new AlternativeGeneration(), zone); |
} |
} |
~AlternativeGenerationList() { |
@@ -3527,9 +3541,9 @@ BoyerMooreLookahead::BoyerMooreLookahead( |
} else { |
max_char_ = String::kMaxUtf16CodeUnit; |
} |
- bitmaps_ = new ZoneList<BoyerMoorePositionInfo*>(length); |
+ bitmaps_ = new(zone) ZoneList<BoyerMoorePositionInfo*>(length, zone); |
for (int i = 0; i < length; i++) { |
- bitmaps_->Add(new BoyerMoorePositionInfo(zone)); |
+ bitmaps_->Add(new(zone) BoyerMoorePositionInfo(zone), zone); |
} |
} |
@@ -3875,7 +3889,9 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) { |
EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); |
if (eats_at_least >= 1) { |
BoyerMooreLookahead* bm = |
- new BoyerMooreLookahead(eats_at_least, compiler, zone()); |
+ new(zone()) BoyerMooreLookahead(eats_at_least, |
+ compiler, |
+ zone()); |
GuardedAlternative alt0 = alternatives_->at(0); |
alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); |
skip_was_emitted = bm->EmitSkipInstructions(macro_assembler); |
@@ -3897,7 +3913,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(choice_count, zone()); |
// 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. |
@@ -4377,6 +4393,7 @@ void DotPrinter::VisitChoice(ChoiceNode* that) { |
void DotPrinter::VisitText(TextNode* that) { |
+ Zone* zone = that->zone(); |
stream()->Add(" n%p [label=\"", that); |
for (int i = 0; i < that->elements()->length(); i++) { |
if (i > 0) stream()->Add(" "); |
@@ -4391,8 +4408,8 @@ 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); |
+ 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("]"); |
@@ -4550,15 +4567,16 @@ void RegExpEngine::DotPrint(const char* label, |
RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler, |
RegExpNode* on_success) { |
- ZoneList<TextElement>* elms = new ZoneList<TextElement>(1); |
- elms->Add(TextElement::Atom(this)); |
- return new TextNode(elms, on_success); |
+ ZoneList<TextElement>* elms = |
+ new(compiler->zone()) ZoneList<TextElement>(1, compiler->zone()); |
+ elms->Add(TextElement::Atom(this), compiler->zone()); |
+ return new(compiler->zone()) TextNode(elms, on_success); |
} |
RegExpNode* RegExpText::ToNode(RegExpCompiler* compiler, |
RegExpNode* on_success) { |
- return new TextNode(elements(), on_success); |
+ return new(compiler->zone()) TextNode(elements(), on_success); |
} |
@@ -4612,7 +4630,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_) { |
@@ -4621,31 +4639,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; |
} |
@@ -4655,7 +4673,7 @@ bool RegExpCharacterClass::is_standard() { |
RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler, |
RegExpNode* on_success) { |
- return new TextNode(this, on_success); |
+ return new(compiler->zone()) TextNode(this, on_success); |
} |
@@ -4663,7 +4681,8 @@ RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler, |
RegExpNode* on_success) { |
ZoneList<RegExpTree*>* alternatives = this->alternatives(); |
int length = alternatives->length(); |
- ChoiceNode* result = new ChoiceNode(length, compiler->zone()); |
+ ChoiceNode* result = |
+ new(compiler->zone()) ChoiceNode(length, compiler->zone()); |
for (int i = 0; i < length; i++) { |
GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler, |
on_success)); |
@@ -4756,6 +4775,8 @@ RegExpNode* RegExpQuantifier::ToNode(int min, |
int body_start_reg = RegExpCompiler::kNoRegister; |
Interval capture_registers = body->CaptureRegisters(); |
bool needs_capture_clearing = !capture_registers.is_empty(); |
+ Zone* zone = compiler->zone(); |
+ |
if (body_can_be_empty) { |
body_start_reg = compiler->AllocateRegister(); |
} else if (FLAG_regexp_optimization && !needs_capture_clearing) { |
@@ -4786,7 +4807,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, compiler->zone()); |
+ ChoiceNode* alternation = new(zone) ChoiceNode(2, zone); |
if (is_greedy) { |
alternation->AddAlternative( |
GuardedAlternative(body->ToNode(compiler, answer))); |
@@ -4809,8 +4830,8 @@ RegExpNode* RegExpQuantifier::ToNode(int min, |
int reg_ctr = needs_counter |
? compiler->AllocateRegister() |
: RegExpCompiler::kNoRegister; |
- LoopChoiceNode* center = new LoopChoiceNode(body->min_match() == 0, |
- compiler->zone()); |
+ LoopChoiceNode* center = new(zone) LoopChoiceNode(body->min_match() == 0, |
+ zone); |
if (not_at_start) center->set_not_at_start(); |
RegExpNode* loop_return = needs_counter |
? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center)) |
@@ -4835,13 +4856,14 @@ 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); |
+ Guard* body_guard = |
+ new(zone) Guard(reg_ctr, Guard::LT, max); |
+ body_alt.AddGuard(body_guard, zone); |
} |
GuardedAlternative rest_alt(on_success); |
if (has_min) { |
- Guard* rest_guard = new Guard(reg_ctr, Guard::GEQ, min); |
- rest_alt.AddGuard(rest_guard); |
+ Guard* rest_guard = new(compiler->zone()) Guard(reg_ctr, Guard::GEQ, min); |
+ rest_alt.AddGuard(rest_guard, zone); |
} |
if (is_greedy) { |
center->AddLoopAlternative(body_alt); |
@@ -4861,6 +4883,8 @@ RegExpNode* RegExpQuantifier::ToNode(int min, |
RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler, |
RegExpNode* on_success) { |
NodeInfo info; |
+ Zone* zone = compiler->zone(); |
+ |
switch (type()) { |
case START_OF_LINE: |
return AssertionNode::AfterNewline(on_success); |
@@ -4879,13 +4903,13 @@ 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, compiler->zone()); |
+ ChoiceNode* result = new(zone) ChoiceNode(2, zone); |
// Create a newline atom. |
ZoneList<CharacterRange>* newline_ranges = |
- new ZoneList<CharacterRange>(3); |
- CharacterRange::AddClassEscape('n', newline_ranges); |
- RegExpCharacterClass* newline_atom = new RegExpCharacterClass('n'); |
- TextNode* newline_matcher = new TextNode( |
+ new(zone) ZoneList<CharacterRange>(3, zone); |
+ CharacterRange::AddClassEscape('n', newline_ranges, zone); |
+ RegExpCharacterClass* newline_atom = new(zone) RegExpCharacterClass('n'); |
+ TextNode* newline_matcher = new(zone) TextNode( |
newline_atom, |
ActionNode::PositiveSubmatchSuccess(stack_pointer_register, |
position_register, |
@@ -4913,9 +4937,10 @@ RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler, |
RegExpNode* RegExpBackReference::ToNode(RegExpCompiler* compiler, |
RegExpNode* on_success) { |
- return new BackReferenceNode(RegExpCapture::StartRegister(index()), |
- RegExpCapture::EndRegister(index()), |
- on_success); |
+ return new(compiler->zone()) |
+ BackReferenceNode(RegExpCapture::StartRegister(index()), |
+ RegExpCapture::EndRegister(index()), |
+ on_success); |
} |
@@ -4960,18 +4985,20 @@ RegExpNode* RegExpLookahead::ToNode(RegExpCompiler* compiler, |
// for a negative lookahead. The NegativeLookaheadChoiceNode is a special |
// ChoiceNode that knows to ignore the first exit when calculating quick |
// checks. |
+ Zone* zone = compiler->zone(); |
+ |
GuardedAlternative body_alt( |
body()->ToNode( |
compiler, |
- success = new NegativeSubmatchSuccess(stack_pointer_register, |
- position_register, |
- register_count, |
- register_start, |
- compiler->zone()))); |
+ success = new(zone) NegativeSubmatchSuccess(stack_pointer_register, |
+ position_register, |
+ register_count, |
+ register_start, |
+ zone))); |
ChoiceNode* choice_node = |
- new NegativeLookaheadChoiceNode(body_alt, |
- GuardedAlternative(on_success), |
- compiler->zone()); |
+ new(zone) NegativeLookaheadChoiceNode(body_alt, |
+ GuardedAlternative(on_success), |
+ zone); |
return ActionNode::BeginSubmatch(stack_pointer_register, |
position_register, |
choice_node); |
@@ -5010,19 +5037,21 @@ RegExpNode* RegExpAlternative::ToNode(RegExpCompiler* compiler, |
static void AddClass(const int* elmv, |
int elmc, |
- ZoneList<CharacterRange>* ranges) { |
+ ZoneList<CharacterRange>* ranges, |
+ Zone* zone) { |
elmc--; |
ASSERT(elmv[elmc] == 0x10000); |
for (int i = 0; i < elmc; i += 2) { |
ASSERT(elmv[i] < elmv[i + 1]); |
- ranges->Add(CharacterRange(elmv[i], elmv[i + 1] - 1)); |
+ ranges->Add(CharacterRange(elmv[i], elmv[i + 1] - 1), zone); |
} |
} |
static void AddClassNegated(const int *elmv, |
int elmc, |
- ZoneList<CharacterRange>* ranges) { |
+ ZoneList<CharacterRange>* ranges, |
+ Zone* zone) { |
elmc--; |
ASSERT(elmv[elmc] == 0x10000); |
ASSERT(elmv[0] != 0x0000); |
@@ -5031,51 +5060,54 @@ static void AddClassNegated(const int *elmv, |
for (int i = 0; i < elmc; i += 2) { |
ASSERT(last <= elmv[i] - 1); |
ASSERT(elmv[i] < elmv[i + 1]); |
- ranges->Add(CharacterRange(last, elmv[i] - 1)); |
+ ranges->Add(CharacterRange(last, elmv[i] - 1), zone); |
last = elmv[i + 1]; |
} |
- ranges->Add(CharacterRange(last, String::kMaxUtf16CodeUnit)); |
+ ranges->Add(CharacterRange(last, String::kMaxUtf16CodeUnit), zone); |
} |
void CharacterRange::AddClassEscape(uc16 type, |
- ZoneList<CharacterRange>* ranges) { |
+ ZoneList<CharacterRange>* ranges, |
+ Zone* zone) { |
switch (type) { |
case 's': |
- AddClass(kSpaceRanges, kSpaceRangeCount, ranges); |
+ AddClass(kSpaceRanges, kSpaceRangeCount, ranges, zone); |
break; |
case 'S': |
- AddClassNegated(kSpaceRanges, kSpaceRangeCount, ranges); |
+ AddClassNegated(kSpaceRanges, kSpaceRangeCount, ranges, zone); |
break; |
case 'w': |
- AddClass(kWordRanges, kWordRangeCount, ranges); |
+ AddClass(kWordRanges, kWordRangeCount, ranges, zone); |
break; |
case 'W': |
- AddClassNegated(kWordRanges, kWordRangeCount, ranges); |
+ AddClassNegated(kWordRanges, kWordRangeCount, ranges, zone); |
break; |
case 'd': |
- AddClass(kDigitRanges, kDigitRangeCount, ranges); |
+ AddClass(kDigitRanges, kDigitRangeCount, ranges, zone); |
break; |
case 'D': |
- AddClassNegated(kDigitRanges, kDigitRangeCount, ranges); |
+ AddClassNegated(kDigitRanges, kDigitRangeCount, ranges, zone); |
break; |
case '.': |
AddClassNegated(kLineTerminatorRanges, |
kLineTerminatorRangeCount, |
- ranges); |
+ ranges, |
+ zone); |
break; |
// This is not a character range as defined by the spec but a |
// convenient shorthand for a character class that matches any |
// character. |
case '*': |
- ranges->Add(CharacterRange::Everything()); |
+ ranges->Add(CharacterRange::Everything(), zone); |
break; |
// This is the set of characters matched by the $ and ^ symbols |
// in multiline mode. |
case 'n': |
AddClass(kLineTerminatorRanges, |
kLineTerminatorRangeCount, |
- ranges); |
+ ranges, |
+ zone); |
break; |
default: |
UNREACHABLE(); |
@@ -5091,9 +5123,11 @@ Vector<const int> CharacterRange::GetWordBounds() { |
class CharacterRangeSplitter { |
public: |
CharacterRangeSplitter(ZoneList<CharacterRange>** included, |
- ZoneList<CharacterRange>** excluded) |
+ ZoneList<CharacterRange>** excluded, |
+ Zone* zone) |
: included_(included), |
- excluded_(excluded) { } |
+ excluded_(excluded), |
+ zone_(zone) { } |
void Call(uc16 from, DispatchTable::Entry entry); |
static const int kInBase = 0; |
@@ -5102,6 +5136,7 @@ class CharacterRangeSplitter { |
private: |
ZoneList<CharacterRange>** included_; |
ZoneList<CharacterRange>** excluded_; |
+ Zone* zone_; |
}; |
@@ -5110,31 +5145,33 @@ void CharacterRangeSplitter::Call(uc16 from, DispatchTable::Entry entry) { |
ZoneList<CharacterRange>** target = entry.out_set()->Get(kInOverlay) |
? included_ |
: excluded_; |
- if (*target == NULL) *target = new ZoneList<CharacterRange>(2); |
- (*target)->Add(CharacterRange(entry.from(), entry.to())); |
+ if (*target == NULL) *target = new(zone_) ZoneList<CharacterRange>(2, zone_); |
+ (*target)->Add(CharacterRange(entry.from(), entry.to()), zone_); |
} |
void CharacterRange::Split(ZoneList<CharacterRange>* base, |
Vector<const int> overlay, |
ZoneList<CharacterRange>** included, |
- ZoneList<CharacterRange>** excluded) { |
+ ZoneList<CharacterRange>** excluded, |
+ Zone* zone) { |
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); |
+ table.AddRange(base->at(i), CharacterRangeSplitter::kInBase, zone); |
for (int i = 0; i < overlay.length(); i += 2) { |
table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1), |
- CharacterRangeSplitter::kInOverlay); |
+ CharacterRangeSplitter::kInOverlay, zone); |
} |
- CharacterRangeSplitter callback(included, excluded); |
+ CharacterRangeSplitter callback(included, excluded, zone); |
table.ForEach(&callback); |
} |
void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges, |
- bool is_ascii) { |
+ bool is_ascii, |
+ Zone* zone) { |
Isolate* isolate = Isolate::Current(); |
uc16 bottom = from(); |
uc16 top = to(); |
@@ -5149,7 +5186,7 @@ void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges, |
for (int i = 0; i < length; i++) { |
uc32 chr = chars[i]; |
if (chr != bottom) { |
- ranges->Add(CharacterRange::Singleton(chars[i])); |
+ ranges->Add(CharacterRange::Singleton(chars[i]), zone); |
} |
} |
} else { |
@@ -5189,7 +5226,7 @@ void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges, |
uc16 range_from = c - (block_end - pos); |
uc16 range_to = c - (block_end - end); |
if (!(bottom <= range_from && range_to <= top)) { |
- ranges->Add(CharacterRange(range_from, range_to)); |
+ ranges->Add(CharacterRange(range_from, range_to), zone); |
} |
} |
pos = end + 1; |
@@ -5212,10 +5249,10 @@ bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) { |
} |
-ZoneList<CharacterRange>* CharacterSet::ranges() { |
+ZoneList<CharacterRange>* CharacterSet::ranges(Zone* zone) { |
if (ranges_ == NULL) { |
- ranges_ = new ZoneList<CharacterRange>(2); |
- CharacterRange::AddClassEscape(standard_set_type_, ranges_); |
+ ranges_ = new(zone) ZoneList<CharacterRange>(2, zone); |
+ CharacterRange::AddClassEscape(standard_set_type_, ranges_, zone); |
} |
return ranges_; |
} |
@@ -5344,7 +5381,8 @@ void CharacterRange::Canonicalize(ZoneList<CharacterRange>* character_ranges) { |
void CharacterRange::Negate(ZoneList<CharacterRange>* ranges, |
- ZoneList<CharacterRange>* negated_ranges) { |
+ ZoneList<CharacterRange>* negated_ranges, |
+ Zone* zone) { |
ASSERT(CharacterRange::IsCanonical(ranges)); |
ASSERT_EQ(0, negated_ranges->length()); |
int range_count = ranges->length(); |
@@ -5356,12 +5394,13 @@ void CharacterRange::Negate(ZoneList<CharacterRange>* ranges, |
} |
while (i < range_count) { |
CharacterRange range = ranges->at(i); |
- negated_ranges->Add(CharacterRange(from + 1, range.from() - 1)); |
+ negated_ranges->Add(CharacterRange(from + 1, range.from() - 1), zone); |
from = range.to(); |
i++; |
} |
if (from < String::kMaxUtf16CodeUnit) { |
- negated_ranges->Add(CharacterRange(from + 1, String::kMaxUtf16CodeUnit)); |
+ negated_ranges->Add(CharacterRange(from + 1, String::kMaxUtf16CodeUnit), |
+ zone); |
} |
} |
@@ -5370,33 +5409,33 @@ void CharacterRange::Negate(ZoneList<CharacterRange>* ranges, |
// Splay tree |
-OutSet* OutSet::Extend(unsigned value) { |
+OutSet* OutSet::Extend(unsigned value, Zone* zone) { |
if (Get(value)) |
return this; |
- if (successors() != NULL) { |
- for (int i = 0; i < successors()->length(); i++) { |
- OutSet* successor = successors()->at(i); |
+ if (successors(zone) != NULL) { |
+ for (int i = 0; i < successors(zone)->length(); i++) { |
+ OutSet* successor = successors(zone)->at(i); |
if (successor->Get(value)) |
return successor; |
} |
} else { |
- successors_ = new ZoneList<OutSet*>(2); |
+ successors_ = new(zone) ZoneList<OutSet*>(2, zone); |
} |
- OutSet* result = new OutSet(first_, remaining_); |
- result->Set(value); |
- successors()->Add(result); |
+ OutSet* result = new(zone) OutSet(first_, remaining_); |
+ result->Set(value, zone); |
+ successors(zone)->Add(result, zone); |
return result; |
} |
-void OutSet::Set(unsigned value) { |
+void OutSet::Set(unsigned value, Zone *zone) { |
if (value < kFirstLimit) { |
first_ |= (1 << value); |
} else { |
if (remaining_ == NULL) |
- remaining_ = new ZoneList<unsigned>(1); |
+ remaining_ = new(zone) ZoneList<unsigned>(1, zone); |
if (remaining_->is_empty() || !remaining_->Contains(value)) |
- remaining_->Add(value); |
+ remaining_->Add(value, zone); |
} |
} |
@@ -5415,13 +5454,15 @@ bool OutSet::Get(unsigned value) { |
const uc16 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar; |
-void DispatchTable::AddRange(CharacterRange full_range, int value) { |
+void DispatchTable::AddRange(CharacterRange full_range, int value, |
+ Zone* zone) { |
CharacterRange current = full_range; |
if (tree()->is_empty()) { |
// 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(value, zone))); |
return; |
} |
// First see if there is a range to the left of this one that |
@@ -5464,7 +5505,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(value, zone))); |
current.set_from(entry->from()); |
} |
ASSERT_EQ(current.from(), entry->from()); |
@@ -5482,7 +5523,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(value, zone); |
// Bail out if the last interval ended at 0xFFFF since otherwise |
// adding 1 will wrap around to 0. |
if (entry->to() == String::kMaxUtf16CodeUnit) |
@@ -5495,7 +5536,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(value, zone))); |
break; |
} |
} |
@@ -5695,7 +5736,7 @@ void TextNode::FillInBMInfo(int initial_offset, |
} 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()); |
if (char_class->is_negated()) { |
bm->SetAll(offset); |
} else { |
@@ -5815,7 +5856,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(that->zone()); |
if (tree->is_negated()) { |
AddInverse(ranges); |
} else { |
@@ -5879,7 +5920,7 @@ RegExpEngine::CompilationResult RegExpEngine::Compile( |
RegExpQuantifier::ToNode(0, |
RegExpTree::kInfinity, |
false, |
- new RegExpCharacterClass('*'), |
+ new(zone) RegExpCharacterClass('*'), |
&compiler, |
captured_body, |
data->contains_anchor); |
@@ -5887,10 +5928,10 @@ RegExpEngine::CompilationResult RegExpEngine::Compile( |
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, zone); |
+ ChoiceNode* first_step_node = new(zone) ChoiceNode(2, zone); |
first_step_node->AddAlternative(GuardedAlternative(captured_body)); |
first_step_node->AddAlternative(GuardedAlternative( |
- new TextNode(new RegExpCharacterClass('*'), loop_node))); |
+ new(zone) TextNode(new(zone) RegExpCharacterClass('*'), loop_node))); |
node = first_step_node; |
} else { |
node = loop_node; |
@@ -5903,7 +5944,7 @@ RegExpEngine::CompilationResult RegExpEngine::Compile( |
if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion); |
} |
- if (node == NULL) node = new EndNode(EndNode::BACKTRACK, zone); |
+ if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone); |
data->node = node; |
Analysis analysis(ignore_case, is_ascii); |
analysis.EnsureAnalyzed(node); |
@@ -5921,11 +5962,14 @@ RegExpEngine::CompilationResult RegExpEngine::Compile( |
: NativeRegExpMacroAssembler::UC16; |
#if V8_TARGET_ARCH_IA32 |
- RegExpMacroAssemblerIA32 macro_assembler(mode, (data->capture_count + 1) * 2); |
+ RegExpMacroAssemblerIA32 macro_assembler(mode, (data->capture_count + 1) * 2, |
+ zone); |
#elif V8_TARGET_ARCH_X64 |
- RegExpMacroAssemblerX64 macro_assembler(mode, (data->capture_count + 1) * 2); |
+ RegExpMacroAssemblerX64 macro_assembler(mode, (data->capture_count + 1) * 2, |
+ zone); |
#elif V8_TARGET_ARCH_ARM |
- RegExpMacroAssemblerARM macro_assembler(mode, (data->capture_count + 1) * 2); |
+ RegExpMacroAssemblerARM macro_assembler(mode, (data->capture_count + 1) * 2, |
+ zone); |
#elif V8_TARGET_ARCH_MIPS |
RegExpMacroAssemblerMIPS macro_assembler(mode, (data->capture_count + 1) * 2); |
#endif |