| Index: src/jsregexp.cc
 | 
| diff --git a/src/jsregexp.cc b/src/jsregexp.cc
 | 
| index 51683682fdb3159dca2daa548947c6735e48c576..3517b11b468b010fce833e467bc07aa2e034b366 100644
 | 
| --- a/src/jsregexp.cc
 | 
| +++ b/src/jsregexp.cc
 | 
| @@ -231,13 +231,14 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
 | 
|  Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
 | 
|                                  Handle<String> subject,
 | 
|                                  int index,
 | 
| -                                Handle<JSArray> last_match_info) {
 | 
| +                                Handle<JSArray> last_match_info,
 | 
| +                                Zone* zone) {
 | 
|    switch (regexp->TypeTag()) {
 | 
|      case JSRegExp::ATOM:
 | 
|        return AtomExec(regexp, subject, index, last_match_info);
 | 
|      case JSRegExp::IRREGEXP: {
 | 
|        Handle<Object> result =
 | 
| -          IrregexpExec(regexp, subject, index, last_match_info);
 | 
| +          IrregexpExec(regexp, subject, index, last_match_info, zone);
 | 
|        ASSERT(!result.is_null() ||
 | 
|               regexp->GetIsolate()->has_pending_exception());
 | 
|        return result;
 | 
| @@ -344,7 +345,8 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
 | 
|  // If compilation fails, an exception is thrown and this function
 | 
|  // returns false.
 | 
|  bool RegExpImpl::EnsureCompiledIrregexp(
 | 
| -    Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii) {
 | 
| +    Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii,
 | 
| +    Zone* zone) {
 | 
|    Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii));
 | 
|  #ifdef V8_INTERPRETED_REGEXP
 | 
|    if (compiled_code->IsByteArray()) return true;
 | 
| @@ -360,7 +362,7 @@ bool RegExpImpl::EnsureCompiledIrregexp(
 | 
|      ASSERT(compiled_code->IsSmi());
 | 
|      return true;
 | 
|    }
 | 
| -  return CompileIrregexp(re, sample_subject, is_ascii);
 | 
| +  return CompileIrregexp(re, sample_subject, is_ascii, zone);
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -382,7 +384,8 @@ static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re,
 | 
|  
 | 
|  bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
 | 
|                                   Handle<String> sample_subject,
 | 
| -                                 bool is_ascii) {
 | 
| +                                 bool is_ascii,
 | 
| +                                 Zone* zone) {
 | 
|    // Compile the RegExp.
 | 
|    Isolate* isolate = re->GetIsolate();
 | 
|    ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
 | 
| @@ -433,7 +436,8 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
 | 
|                              flags.is_multiline(),
 | 
|                              pattern,
 | 
|                              sample_subject,
 | 
| -                            is_ascii);
 | 
| +                            is_ascii,
 | 
| +                            zone);
 | 
|    if (result.error_message != NULL) {
 | 
|      // Unable to compile regexp.
 | 
|      Handle<String> error_message =
 | 
| @@ -498,12 +502,13 @@ void RegExpImpl::IrregexpInitialize(Handle<JSRegExp> re,
 | 
|  
 | 
|  
 | 
|  int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
 | 
| -                                Handle<String> subject) {
 | 
| +                                Handle<String> subject,
 | 
| +                                Zone* zone) {
 | 
|    if (!subject->IsFlat()) FlattenString(subject);
 | 
|  
 | 
|    // Check the asciiness of the underlying storage.
 | 
|    bool is_ascii = subject->IsAsciiRepresentationUnderneath();
 | 
| -  if (!EnsureCompiledIrregexp(regexp, subject, is_ascii)) return -1;
 | 
| +  if (!EnsureCompiledIrregexp(regexp, subject, is_ascii, zone)) return -1;
 | 
|  
 | 
|  #ifdef V8_INTERPRETED_REGEXP
 | 
|    // Byte-code regexp needs space allocated for all its registers.
 | 
| @@ -536,7 +541,8 @@ int RegExpImpl::IrregexpExecRaw(
 | 
|      Handle<JSRegExp> regexp,
 | 
|      Handle<String> subject,
 | 
|      int index,
 | 
| -    Vector<int> output) {
 | 
| +    Vector<int> output,
 | 
| +    Zone* zone) {
 | 
|    Isolate* isolate = regexp->GetIsolate();
 | 
|  
 | 
|    Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate);
 | 
| @@ -550,7 +556,7 @@ int RegExpImpl::IrregexpExecRaw(
 | 
|  #ifndef V8_INTERPRETED_REGEXP
 | 
|    ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
 | 
|    do {
 | 
| -    EnsureCompiledIrregexp(regexp, subject, is_ascii);
 | 
| +    EnsureCompiledIrregexp(regexp, subject, is_ascii, zone);
 | 
|      Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate);
 | 
|      NativeRegExpMacroAssembler::Result res =
 | 
|          NativeRegExpMacroAssembler::Match(code,
 | 
| @@ -576,7 +582,7 @@ int RegExpImpl::IrregexpExecRaw(
 | 
|      // the, potentially, different subject (the string can switch between
 | 
|      // being internal and external, and even between being ASCII and UC16,
 | 
|      // but the characters are always the same).
 | 
| -    IrregexpPrepare(regexp, subject);
 | 
| +    IrregexpPrepare(regexp, subject, zone);
 | 
|      is_ascii = subject->IsAsciiRepresentationUnderneath();
 | 
|    } while (true);
 | 
|    UNREACHABLE();
 | 
| @@ -611,7 +617,8 @@ int RegExpImpl::IrregexpExecRaw(
 | 
|  Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
 | 
|                                          Handle<String> subject,
 | 
|                                          int previous_index,
 | 
| -                                        Handle<JSArray> last_match_info) {
 | 
| +                                        Handle<JSArray> last_match_info,
 | 
| +                                        Zone* zone) {
 | 
|    Isolate* isolate = jsregexp->GetIsolate();
 | 
|    ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP);
 | 
|  
 | 
| @@ -625,7 +632,7 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
 | 
|    }
 | 
|  #endif
 | 
|  #endif
 | 
| -  int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject);
 | 
| +  int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject, zone);
 | 
|    if (required_registers < 0) {
 | 
|      // Compiling failed with an exception.
 | 
|      ASSERT(isolate->has_pending_exception());
 | 
| @@ -636,7 +643,8 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
 | 
|  
 | 
|    int res = RegExpImpl::IrregexpExecRaw(
 | 
|        jsregexp, subject, previous_index, Vector<int>(registers.vector(),
 | 
| -                                                     registers.length()));
 | 
| +                                                     registers.length()),
 | 
| +                                        zone);
 | 
|    if (res == RE_SUCCESS) {
 | 
|      int capture_register_count =
 | 
|          (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2;
 | 
| @@ -917,7 +925,8 @@ class FrequencyCollator {
 | 
|  
 | 
|  class RegExpCompiler {
 | 
|   public:
 | 
| -  RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii);
 | 
| +  RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii,
 | 
| +                 Zone* zone);
 | 
|  
 | 
|    int AllocateRegister() {
 | 
|      if (next_register_ >= RegExpMacroAssembler::kMaxRegister) {
 | 
| @@ -957,6 +966,8 @@ class RegExpCompiler {
 | 
|      current_expansion_factor_ = value;
 | 
|    }
 | 
|  
 | 
| +  Zone* zone() { return zone_; }
 | 
| +
 | 
|    static const int kNoRegister = -1;
 | 
|  
 | 
|   private:
 | 
| @@ -970,6 +981,7 @@ class RegExpCompiler {
 | 
|    bool reg_exp_too_big_;
 | 
|    int current_expansion_factor_;
 | 
|    FrequencyCollator frequency_collator_;
 | 
| +  Zone* zone_;
 | 
|  };
 | 
|  
 | 
|  
 | 
| @@ -991,7 +1003,8 @@ 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)
 | 
| +RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii,
 | 
| +                               Zone* zone)
 | 
|      : next_register_(2 * (capture_count + 1)),
 | 
|        work_list_(NULL),
 | 
|        recursion_depth_(0),
 | 
| @@ -999,8 +1012,9 @@ RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii)
 | 
|        ascii_(ascii),
 | 
|        reg_exp_too_big_(false),
 | 
|        current_expansion_factor_(1),
 | 
| -      frequency_collator_() {
 | 
| -  accept_ = new EndNode(EndNode::ACCEPT);
 | 
| +      frequency_collator_(),
 | 
| +      zone_(zone) {
 | 
| +  accept_ = new EndNode(EndNode::ACCEPT, zone);
 | 
|    ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister);
 | 
|  }
 | 
|  
 | 
| @@ -2917,7 +2931,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);
 | 
| +          new BoyerMooreLookahead(eats_at_least, compiler, zone());
 | 
|        FillInBMInfo(0, 0, 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;
 | 
| @@ -3498,7 +3512,7 @@ void BoyerMoorePositionInfo::SetAll() {
 | 
|  
 | 
|  
 | 
|  BoyerMooreLookahead::BoyerMooreLookahead(
 | 
| -    int length, RegExpCompiler* compiler)
 | 
| +    int length, RegExpCompiler* compiler, Zone* zone)
 | 
|      : length_(length),
 | 
|        compiler_(compiler) {
 | 
|    if (compiler->ascii()) {
 | 
| @@ -3508,7 +3522,7 @@ BoyerMooreLookahead::BoyerMooreLookahead(
 | 
|    }
 | 
|    bitmaps_ = new ZoneList<BoyerMoorePositionInfo*>(length);
 | 
|    for (int i = 0; i < length; i++) {
 | 
| -    bitmaps_->Add(new BoyerMoorePositionInfo());
 | 
| +    bitmaps_->Add(new BoyerMoorePositionInfo(zone));
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -3854,7 +3868,7 @@ 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);
 | 
| +                new BoyerMooreLookahead(eats_at_least, compiler, zone());
 | 
|              GuardedAlternative alt0 = alternatives_->at(0);
 | 
|              alt0.node()->FillInBMInfo(0, 0, bm, not_at_start);
 | 
|              skip_was_emitted = bm->EmitSkipInstructions(macro_assembler);
 | 
| @@ -4642,7 +4656,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(length, compiler->zone());
 | 
|    for (int i = 0; i < length; i++) {
 | 
|      GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler,
 | 
|                                                                 on_success));
 | 
| @@ -4765,7 +4779,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(2, compiler->zone());
 | 
|            if (is_greedy) {
 | 
|              alternation->AddAlternative(
 | 
|                  GuardedAlternative(body->ToNode(compiler, answer)));
 | 
| @@ -4788,7 +4802,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(body->min_match() == 0,
 | 
| +                                              compiler->zone());
 | 
|    if (not_at_start) center->set_not_at_start();
 | 
|    RegExpNode* loop_return = needs_counter
 | 
|        ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
 | 
| @@ -4857,7 +4872,7 @@ 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(2, compiler->zone());
 | 
|        // Create a newline atom.
 | 
|        ZoneList<CharacterRange>* newline_ranges =
 | 
|            new ZoneList<CharacterRange>(3);
 | 
| @@ -4944,10 +4959,12 @@ RegExpNode* RegExpLookahead::ToNode(RegExpCompiler* compiler,
 | 
|              success = new NegativeSubmatchSuccess(stack_pointer_register,
 | 
|                                                    position_register,
 | 
|                                                    register_count,
 | 
| -                                                  register_start)));
 | 
| +                                                  register_start,
 | 
| +                                                  compiler->zone())));
 | 
|      ChoiceNode* choice_node =
 | 
|          new NegativeLookaheadChoiceNode(body_alt,
 | 
| -                                        GuardedAlternative(on_success));
 | 
| +                                        GuardedAlternative(on_success),
 | 
| +                                        compiler->zone());
 | 
|      return ActionNode::BeginSubmatch(stack_pointer_register,
 | 
|                                       position_register,
 | 
|                                       choice_node);
 | 
| @@ -5814,11 +5831,12 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
 | 
|      bool is_multiline,
 | 
|      Handle<String> pattern,
 | 
|      Handle<String> sample_subject,
 | 
| -    bool is_ascii) {
 | 
| +    bool is_ascii,
 | 
| +    Zone* zone) {
 | 
|    if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) {
 | 
|      return IrregexpRegExpTooBig();
 | 
|    }
 | 
| -  RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii);
 | 
| +  RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii, zone);
 | 
|  
 | 
|    // Sample some characters from the middle of the string.
 | 
|    static const int kSampleSize = 128;
 | 
| @@ -5856,7 +5874,7 @@ 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);
 | 
| +      ChoiceNode* first_step_node = new ChoiceNode(2, zone);
 | 
|        first_step_node->AddAlternative(GuardedAlternative(captured_body));
 | 
|        first_step_node->AddAlternative(GuardedAlternative(
 | 
|            new TextNode(new RegExpCharacterClass('*'), loop_node)));
 | 
| @@ -5872,7 +5890,7 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
 | 
|      if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
 | 
|    }
 | 
|  
 | 
| -  if (node == NULL) node = new EndNode(EndNode::BACKTRACK);
 | 
| +  if (node == NULL) node = new EndNode(EndNode::BACKTRACK, zone);
 | 
|    data->node = node;
 | 
|    Analysis analysis(ignore_case, is_ascii);
 | 
|    analysis.EnsureAnalyzed(node);
 | 
| 
 |