Upgrade to 3.29

Update V8 to 3.29.88.17 and update makefiles to support building on
all the relevant platforms.

Bug: 17370214

Change-Id: Ia3407c157fd8d72a93e23d8318ccaf6ecf77fa4e
diff --git a/src/mips/regexp-macro-assembler-mips.cc b/src/mips/regexp-macro-assembler-mips.cc
index ae4da93..dbc12a0 100644
--- a/src/mips/regexp-macro-assembler-mips.cc
+++ b/src/mips/regexp-macro-assembler-mips.cc
@@ -1,41 +1,19 @@
 // Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
-#include "v8.h"
+#include "src/v8.h"
 
-#if defined(V8_TARGET_ARCH_MIPS)
+#if V8_TARGET_ARCH_MIPS
 
-#include "unicode.h"
-#include "log.h"
-#include "code-stubs.h"
-#include "regexp-stack.h"
-#include "macro-assembler.h"
-#include "regexp-macro-assembler.h"
-#include "mips/regexp-macro-assembler-mips.h"
+#include "src/code-stubs.h"
+#include "src/log.h"
+#include "src/macro-assembler.h"
+#include "src/regexp-macro-assembler.h"
+#include "src/regexp-stack.h"
+#include "src/unicode.h"
+
+#include "src/mips/regexp-macro-assembler-mips.h"
 
 namespace v8 {
 namespace internal {
@@ -43,44 +21,49 @@
 #ifndef V8_INTERPRETED_REGEXP
 /*
  * This assembler uses the following register assignment convention
+ * - t7 : Temporarily stores the index of capture start after a matching pass
+ *        for a global regexp.
  * - t1 : Pointer to current code object (Code*) including heap object tag.
  * - t2 : Current position in input, as negative offset from end of string.
  *        Please notice that this is the byte offset, not the character offset!
  * - t3 : Currently loaded character. Must be loaded using
  *        LoadCurrentCharacter before using any of the dispatch methods.
- * - t4 : points to tip of backtrack stack
+ * - t4 : Points to tip of backtrack stack
  * - t5 : Unused.
  * - t6 : End of input (points to byte after last character in input).
  * - fp : Frame pointer. Used to access arguments, local variables and
  *         RegExp registers.
- * - sp : points to tip of C stack.
+ * - sp : Points to tip of C stack.
  *
  * The remaining registers are free for computations.
  * Each call to a public method should retain this convention.
  *
  * The stack will have the following structure:
  *
- *  - fp[56]  direct_call  (if 1, direct call from JavaScript code,
+ *  - fp[64]  Isolate* isolate   (address of the current isolate)
+ *  - fp[60]  direct_call  (if 1, direct call from JavaScript code,
  *                          if 0, call through the runtime system).
- *  - fp[52]  stack_area_base (High end of the memory area to use as
+ *  - fp[56]  stack_area_base (High end of the memory area to use as
  *                             backtracking stack).
+ *  - fp[52]  capture array size (may fit multiple sets of matches)
  *  - fp[48]  int* capture_array (int[num_saved_registers_], for output).
  *  - fp[44]  secondary link/return address used by native call.
  *  --- sp when called ---
- *  - fp[40]  return address (lr).
- *  - fp[36]  old frame pointer (r11).
+ *  - fp[40]  return address      (lr).
+ *  - fp[36]  old frame pointer   (r11).
  *  - fp[0..32]  backup of registers s0..s7.
  *  --- frame pointer ----
- *  - fp[-4]  end of input       (Address of end of string).
- *  - fp[-8]  start of input     (Address of first character in string).
+ *  - fp[-4]  end of input       (address of end of string).
+ *  - fp[-8]  start of input     (address of first character in string).
  *  - fp[-12] start index        (character index of start).
  *  - fp[-16] void* input_string (location of a handle containing the string).
- *  - fp[-20] Offset of location before start of input (effectively character
+ *  - fp[-20] success counter    (only for global regexps to count matches).
+ *  - fp[-24] Offset of location before start of input (effectively character
  *            position -1). Used to initialize capture registers to a
  *            non-position.
- *  - fp[-24] At start (if 1, we are starting at the start of the
+ *  - fp[-28] At start (if 1, we are starting at the start of the
  *    string, otherwise 0)
- *  - fp[-28] register 0         (Only positions must be stored in the first
+ *  - fp[-32] register 0         (Only positions must be stored in the first
  *  -         register 1          num_saved_registers_ registers)
  *  -         ...
  *  -         register num_registers-1
@@ -114,8 +97,10 @@
 
 RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(
     Mode mode,
-    int registers_to_save)
-    : masm_(new MacroAssembler(Isolate::Current(), NULL, kRegExpCodeSize)),
+    int registers_to_save,
+    Zone* zone)
+    : NativeRegExpMacroAssembler(zone),
+      masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)),
       mode_(mode),
       num_registers_(registers_to_save),
       num_saved_registers_(registers_to_save),
@@ -125,7 +110,7 @@
       backtrack_label_(),
       exit_label_(),
       internal_failure_label_() {
-  ASSERT_EQ(0, registers_to_save % 2);
+  DCHECK_EQ(0, registers_to_save % 2);
   __ jmp(&entry_label_);   // We'll write the entry code later.
   // If the code gets too big or corrupted, an internal exception will be
   // raised, and we will exit right away.
@@ -158,14 +143,14 @@
 void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) {
   if (by != 0) {
     __ Addu(current_input_offset(),
-           current_input_offset(), Operand(by * char_size()));
+            current_input_offset(), Operand(by * char_size()));
   }
 }
 
 
 void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) {
-  ASSERT(reg >= 0);
-  ASSERT(reg < num_registers_);
+  DCHECK(reg >= 0);
+  DCHECK(reg < num_registers_);
   if (by != 0) {
     __ lw(a0, register_location(reg));
     __ Addu(a0, a0, Operand(by));
@@ -201,8 +186,8 @@
 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
   Label not_at_start;
   // Did we start the match at the start of the string at all?
-  __ lw(a0, MemOperand(frame_pointer(), kAtStart));
-  BranchOrBacktrack(&not_at_start, eq, a0, Operand(zero_reg));
+  __ lw(a0, MemOperand(frame_pointer(), kStartIndex));
+  BranchOrBacktrack(&not_at_start, ne, a0, Operand(zero_reg));
 
   // If we did, are we still at the start of the input?
   __ lw(a1, MemOperand(frame_pointer(), kInputStart));
@@ -214,8 +199,8 @@
 
 void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) {
   // Did we start the match at the start of the string at all?
-  __ lw(a0, MemOperand(frame_pointer(), kAtStart));
-  BranchOrBacktrack(on_not_at_start, eq, a0, Operand(zero_reg));
+  __ lw(a0, MemOperand(frame_pointer(), kStartIndex));
+  BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg));
   // If we did, are we still at the start of the input?
   __ lw(a1, MemOperand(frame_pointer(), kInputStart));
   __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
@@ -228,55 +213,6 @@
 }
 
 
-void RegExpMacroAssemblerMIPS::CheckCharacters(Vector<const uc16> str,
-                                              int cp_offset,
-                                              Label* on_failure,
-                                              bool check_end_of_string) {
-  if (on_failure == NULL) {
-    // Instead of inlining a backtrack for each test, (re)use the global
-    // backtrack target.
-    on_failure = &backtrack_label_;
-  }
-
-  if (check_end_of_string) {
-    // Is last character of required match inside string.
-    CheckPosition(cp_offset + str.length() - 1, on_failure);
-  }
-
-  __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
-  if (cp_offset != 0) {
-    int byte_offset = cp_offset * char_size();
-    __ Addu(a0, a0, Operand(byte_offset));
-  }
-
-  // a0 : Address of characters to match against str.
-  int stored_high_byte = 0;
-  for (int i = 0; i < str.length(); i++) {
-    if (mode_ == ASCII) {
-      __ lbu(a1, MemOperand(a0, 0));
-      __ addiu(a0, a0, char_size());
-      ASSERT(str[i] <= String::kMaxAsciiCharCode);
-      BranchOrBacktrack(on_failure, ne, a1, Operand(str[i]));
-    } else {
-      __ lhu(a1, MemOperand(a0, 0));
-      __ addiu(a0, a0, char_size());
-      uc16 match_char = str[i];
-      int match_high_byte = (match_char >> 8);
-      if (match_high_byte == 0) {
-        BranchOrBacktrack(on_failure, ne, a1, Operand(str[i]));
-      } else {
-        if (match_high_byte != stored_high_byte) {
-          __ li(a2, Operand(match_high_byte));
-          stored_high_byte = match_high_byte;
-        }
-        __ Addu(a3, a2, Operand(match_char & 0xff));
-        BranchOrBacktrack(on_failure, ne, a1, Operand(a3));
-      }
-    }
-  }
-}
-
-
 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
   Label backtrack_non_equal;
   __ lw(a0, MemOperand(backtrack_stackpointer(), 0));
@@ -305,7 +241,7 @@
   // Check that there are enough characters left in the input.
   BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg));
 
-  if (mode_ == ASCII) {
+  if (mode_ == LATIN1) {
     Label success;
     Label fail;
     Label loop_check;
@@ -334,7 +270,13 @@
     __ Or(t0, t0, Operand(0x20));  // Also convert input character.
     __ Branch(&fail, ne, t0, Operand(a3));
     __ Subu(a3, a3, Operand('a'));
-    __ Branch(&fail, hi, a3, Operand('z' - 'a'));  // Is a3 a lowercase letter?
+    __ Branch(&loop_check, ls, a3, Operand('z' - 'a'));
+    // Latin-1: Check for values in range [224,254] but not 247.
+    __ Subu(a3, a3, Operand(224 - 'a'));
+    // Weren't Latin-1 letters.
+    __ Branch(&fail, hi, a3, Operand(254 - 224));
+    // Check for 247.
+    __ Branch(&fail, eq, a3, Operand(247 - 224));
 
     __ bind(&loop_check);
     __ Branch(&loop, lt, a0, Operand(a1));
@@ -347,7 +289,7 @@
     // Compute new value of character position after the matched part.
     __ Subu(current_input_offset(), a2, end_of_input_address());
   } else {
-    ASSERT(mode_ == UC16);
+    DCHECK(mode_ == UC16);
     // Put regexp engine registers on stack.
     RegList regexp_registers_to_retain = current_input_offset().bit() |
         current_character().bit() | backtrack_stackpointer().bit();
@@ -375,7 +317,7 @@
     // Address of current input position.
     __ Addu(a1, current_input_offset(), Operand(end_of_input_address()));
     // Isolate.
-    __ li(a3, Operand(ExternalReference::isolate_address()));
+    __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
 
     {
       AllowExternalCallThatCantCauseGC scope(masm_);
@@ -423,13 +365,13 @@
 
   Label loop;
   __ bind(&loop);
-  if (mode_ == ASCII) {
+  if (mode_ == LATIN1) {
     __ lbu(a3, MemOperand(a0, 0));
     __ addiu(a0, a0, char_size());
     __ lbu(t0, MemOperand(a2, 0));
     __ addiu(a2, a2, char_size());
   } else {
-    ASSERT(mode_ == UC16);
+    DCHECK(mode_ == UC16);
     __ lhu(a3, MemOperand(a0, 0));
     __ addiu(a0, a0, char_size());
     __ lhu(t0, MemOperand(a2, 0));
@@ -444,32 +386,27 @@
 }
 
 
-void RegExpMacroAssemblerMIPS::CheckNotRegistersEqual(int reg1,
-                                                      int reg2,
-                                                      Label* on_not_equal) {
-  UNIMPLEMENTED_MIPS();
-}
-
-
 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c,
-                                                Label* on_not_equal) {
+                                                 Label* on_not_equal) {
   BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c));
 }
 
 
 void RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(uint32_t c,
-                                                     uint32_t mask,
-                                                     Label* on_equal) {
+                                                      uint32_t mask,
+                                                      Label* on_equal) {
   __ And(a0, current_character(), Operand(mask));
-  BranchOrBacktrack(on_equal, eq, a0, Operand(c));
+  Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
+  BranchOrBacktrack(on_equal, eq, a0, rhs);
 }
 
 
 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(uint32_t c,
-                                                        uint32_t mask,
-                                                        Label* on_not_equal) {
+                                                         uint32_t mask,
+                                                         Label* on_not_equal) {
   __ And(a0, current_character(), Operand(mask));
-  BranchOrBacktrack(on_not_equal, ne, a0, Operand(c));
+  Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
+  BranchOrBacktrack(on_not_equal, ne, a0, rhs);
 }
 
 
@@ -478,45 +415,79 @@
     uc16 minus,
     uc16 mask,
     Label* on_not_equal) {
-  UNIMPLEMENTED_MIPS();
+  DCHECK(minus < String::kMaxUtf16CodeUnit);
+  __ Subu(a0, current_character(), Operand(minus));
+  __ And(a0, a0, Operand(mask));
+  BranchOrBacktrack(on_not_equal, ne, a0, Operand(c));
+}
+
+
+void RegExpMacroAssemblerMIPS::CheckCharacterInRange(
+    uc16 from,
+    uc16 to,
+    Label* on_in_range) {
+  __ Subu(a0, current_character(), Operand(from));
+  // Unsigned lower-or-same condition.
+  BranchOrBacktrack(on_in_range, ls, a0, Operand(to - from));
+}
+
+
+void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange(
+    uc16 from,
+    uc16 to,
+    Label* on_not_in_range) {
+  __ Subu(a0, current_character(), Operand(from));
+  // Unsigned higher condition.
+  BranchOrBacktrack(on_not_in_range, hi, a0, Operand(to - from));
+}
+
+
+void RegExpMacroAssemblerMIPS::CheckBitInTable(
+    Handle<ByteArray> table,
+    Label* on_bit_set) {
+  __ li(a0, Operand(table));
+  if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) {
+    __ And(a1, current_character(), Operand(kTableSize - 1));
+    __ Addu(a0, a0, a1);
+  } else {
+    __ Addu(a0, a0, current_character());
+  }
+
+  __ lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize));
+  BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg));
 }
 
 
 bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type,
-                                                         Label* on_no_match) {
+                                                          Label* on_no_match) {
   // Range checks (c in min..max) are generally implemented by an unsigned
   // (c - min) <= (max - min) check.
   switch (type) {
   case 's':
     // Match space-characters.
-    if (mode_ == ASCII) {
-      // ASCII space characters are '\t'..'\r' and ' '.
+    if (mode_ == LATIN1) {
+      // One byte space characters are '\t'..'\r', ' ' and \u00a0.
       Label success;
       __ Branch(&success, eq, current_character(), Operand(' '));
       // Check range 0x09..0x0d.
       __ Subu(a0, current_character(), Operand('\t'));
-      BranchOrBacktrack(on_no_match, hi, a0, Operand('\r' - '\t'));
+      __ Branch(&success, ls, a0, Operand('\r' - '\t'));
+      // \u00a0 (NBSP).
+      BranchOrBacktrack(on_no_match, ne, a0, Operand(0x00a0 - '\t'));
       __ bind(&success);
       return true;
     }
     return false;
   case 'S':
-    // Match non-space characters.
-    if (mode_ == ASCII) {
-      // ASCII space characters are '\t'..'\r' and ' '.
-      BranchOrBacktrack(on_no_match, eq, current_character(), Operand(' '));
-      __ Subu(a0, current_character(), Operand('\t'));
-      BranchOrBacktrack(on_no_match, ls, a0, Operand('\r' - '\t'));
-      return true;
-    }
+    // The emitted code for generic character classes is good enough.
     return false;
   case 'd':
-    // Match ASCII digits ('0'..'9').
+    // Match Latin1 digits ('0'..'9').
     __ Subu(a0, current_character(), Operand('0'));
     BranchOrBacktrack(on_no_match, hi, a0, Operand('9' - '0'));
     return true;
   case 'D':
-    // Match non ASCII-digits.
+    // Match non Latin1-digits.
     __ Subu(a0, current_character(), Operand('0'));
     BranchOrBacktrack(on_no_match, ls, a0, Operand('9' - '0'));
     return true;
@@ -540,7 +511,7 @@
     __ Xor(a0, current_character(), Operand(0x01));
     // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c.
     __ Subu(a0, a0, Operand(0x0b));
-    if (mode_ == ASCII) {
+    if (mode_ == LATIN1) {
       BranchOrBacktrack(on_no_match, hi, a0, Operand(0x0c - 0x0b));
     } else {
       Label done;
@@ -555,8 +526,8 @@
     return true;
   }
   case 'w': {
-    if (mode_ != ASCII) {
-      // Table is 128 entries, so all ASCII characters can be tested.
+    if (mode_ != LATIN1) {
+      // Table is 256 entries, so all Latin1 characters can be tested.
       BranchOrBacktrack(on_no_match, hi, current_character(), Operand('z'));
     }
     ExternalReference map = ExternalReference::re_word_character_map();
@@ -568,8 +539,8 @@
   }
   case 'W': {
     Label done;
-    if (mode_ != ASCII) {
-      // Table is 128 entries, so all ASCII characters can be tested.
+    if (mode_ != LATIN1) {
+      // Table is 256 entries, so all Latin1 characters can be tested.
       __ Branch(&done, hi, current_character(), Operand('z'));
     }
     ExternalReference map = ExternalReference::re_word_character_map();
@@ -577,7 +548,7 @@
     __ Addu(a0, a0, current_character());
     __ lbu(a0, MemOperand(a0, 0));
     BranchOrBacktrack(on_no_match, ne, a0, Operand(zero_reg));
-    if (mode_ != ASCII) {
+    if (mode_ != LATIN1) {
       __ bind(&done);
     }
     return true;
@@ -599,6 +570,7 @@
 
 
 Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
+  Label return_v0;
   if (masm_->has_exception()) {
     // If the code gets corrupted due to long regular expressions and lack of
     // space on trampolines, an internal exception flag is set. If this case
@@ -628,8 +600,9 @@
     // Set frame pointer in space for it if this is not a direct call
     // from generated code.
     __ Addu(frame_pointer(), sp, Operand(4 * kPointerSize));
+    __ mov(a0, zero_reg);
+    __ push(a0);  // Make room for success counter and initialize it to 0.
     __ push(a0);  // Make room for "position - 1" constant (value irrelevant).
-    __ push(a0);  // Make room for "at start" constant (value irrelevant).
 
     // Check if we have space on the stack for registers.
     Label stack_limit_hit;
@@ -648,12 +621,12 @@
     // Exit with OutOfMemory exception. There is not enough space on the stack
     // for our working registers.
     __ li(v0, Operand(EXCEPTION));
-    __ jmp(&exit_label_);
+    __ jmp(&return_v0);
 
     __ bind(&stack_limit_hit);
     CallCheckStackGuardState(a0);
     // If returned value is non-zero, we exit with the returned value as result.
-    __ Branch(&exit_label_, ne, v0, Operand(zero_reg));
+    __ Branch(&return_v0, ne, v0, Operand(zero_reg));
 
     __ bind(&stack_ok);
     // Allocate space on stack for registers.
@@ -674,39 +647,44 @@
     // position registers.
     __ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
 
-    // Determine whether the start index is zero, that is at the start of the
-    // string, and store that value in a local variable.
-    __ mov(t5, a1);
-    __ li(a1, Operand(1));
-    __ Movn(a1, zero_reg, t5);
-    __ sw(a1, MemOperand(frame_pointer(), kAtStart));
+    // Initialize code pointer register
+    __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
 
+    Label load_char_start_regexp, start_regexp;
+    // Load newline if index is at start, previous character otherwise.
+    __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
+    __ li(current_character(), Operand('\n'));
+    __ jmp(&start_regexp);
+
+    // Global regexp restarts matching here.
+    __ bind(&load_char_start_regexp);
+    // Load previous char as initial value of current character register.
+    LoadCurrentCharacterUnchecked(-1, 1);
+    __ bind(&start_regexp);
+
+    // Initialize on-stack registers.
     if (num_saved_registers_ > 0) {  // Always is, if generated from a regexp.
       // Fill saved registers with initial value = start offset - 1.
-
-      // Address of register 0.
-      __ Addu(a1, frame_pointer(), Operand(kRegisterZero));
-      __ li(a2, Operand(num_saved_registers_));
-      Label init_loop;
-      __ bind(&init_loop);
-      __ sw(a0, MemOperand(a1));
-      __ Addu(a1, a1, Operand(-kPointerSize));
-      __ Subu(a2, a2, Operand(1));
-      __ Branch(&init_loop, ne, a2, Operand(zero_reg));
+      if (num_saved_registers_ > 8) {
+        // Address of register 0.
+        __ Addu(a1, frame_pointer(), Operand(kRegisterZero));
+        __ li(a2, Operand(num_saved_registers_));
+        Label init_loop;
+        __ bind(&init_loop);
+        __ sw(a0, MemOperand(a1));
+        __ Addu(a1, a1, Operand(-kPointerSize));
+        __ Subu(a2, a2, Operand(1));
+        __ Branch(&init_loop, ne, a2, Operand(zero_reg));
+      } else {
+        for (int i = 0; i < num_saved_registers_; i++) {
+          __ sw(a0, register_location(i));
+        }
+      }
     }
 
     // Initialize backtrack stack pointer.
     __ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
-    // Initialize code pointer register
-    __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
-    // Load previous char as initial value of current character register.
-    Label at_start;
-    __ lw(a0, MemOperand(frame_pointer(), kAtStart));
-    __ Branch(&at_start, ne, a0, Operand(zero_reg));
-    LoadCurrentCharacterUnchecked(-1, 1);  // Load previous char.
-    __ jmp(&start_label_);
-    __ bind(&at_start);
-    __ li(current_character(), Operand('\n'));
+
     __ jmp(&start_label_);
 
 
@@ -728,13 +706,17 @@
         __ Addu(a1, a1, Operand(a2));
         // a1 is length of string in characters.
 
-        ASSERT_EQ(0, num_saved_registers_ % 2);
+        DCHECK_EQ(0, num_saved_registers_ % 2);
         // Always an even number of capture registers. This allows us to
         // unroll the loop once to add an operation between a load of a register
         // and the following use of that register.
         for (int i = 0; i < num_saved_registers_; i += 2) {
           __ lw(a2, register_location(i));
           __ lw(a3, register_location(i + 1));
+          if (i == 0 && global_with_zero_length_check()) {
+            // Keep capture start in a4 for the zero-length check later.
+            __ mov(t7, a2);
+          }
           if (mode_ == UC16) {
             __ sra(a2, a2, 1);
             __ Addu(a2, a2, a1);
@@ -750,10 +732,57 @@
           __ Addu(a0, a0, kPointerSize);
         }
       }
-      __ li(v0, Operand(SUCCESS));
+
+      if (global()) {
+        // Restart matching if the regular expression is flagged as global.
+        __ lw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
+        __ lw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
+        __ lw(a2, MemOperand(frame_pointer(), kRegisterOutput));
+        // Increment success counter.
+        __ Addu(a0, a0, 1);
+        __ sw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
+        // Capture results have been stored, so the number of remaining global
+        // output registers is reduced by the number of stored captures.
+        __ Subu(a1, a1, num_saved_registers_);
+        // Check whether we have enough room for another set of capture results.
+        __ mov(v0, a0);
+        __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
+
+        __ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
+        // Advance the location for output.
+        __ Addu(a2, a2, num_saved_registers_ * kPointerSize);
+        __ sw(a2, MemOperand(frame_pointer(), kRegisterOutput));
+
+        // Prepare a0 to initialize registers with its value in the next run.
+        __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
+
+        if (global_with_zero_length_check()) {
+          // Special case for zero-length matches.
+          // t7: capture start index
+          // Not a zero-length match, restart.
+          __ Branch(
+              &load_char_start_regexp, ne, current_input_offset(), Operand(t7));
+          // Offset from the end is zero if we already reached the end.
+          __ Branch(&exit_label_, eq, current_input_offset(),
+                    Operand(zero_reg));
+          // Advance current position after a zero-length match.
+          __ Addu(current_input_offset(),
+                  current_input_offset(),
+                  Operand((mode_ == UC16) ? 2 : 1));
+        }
+
+        __ Branch(&load_char_start_regexp);
+      } else {
+        __ li(v0, Operand(SUCCESS));
+      }
     }
     // Exit and return v0.
     __ bind(&exit_label_);
+    if (global()) {
+      __ lw(v0, MemOperand(frame_pointer(), kSuccessfulCaptures));
+    }
+
+    __ bind(&return_v0);
     // Skip sp past regexp registers and local variables..
     __ mov(sp, frame_pointer());
     // Restore registers s0..s7 and return (restoring ra to pc).
@@ -779,7 +808,7 @@
       __ MultiPop(regexp_registers_to_retain);
       // If returning non-zero, we should end execution with the given
       // result as return value.
-      __ Branch(&exit_label_, ne, v0, Operand(zero_reg));
+      __ Branch(&return_v0, ne, v0, Operand(zero_reg));
 
       // String might have moved: Reload end of string from frame.
       __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
@@ -801,7 +830,7 @@
       __ PrepareCallCFunction(num_arguments, a0);
       __ mov(a0, backtrack_stackpointer());
       __ Addu(a1, frame_pointer(), Operand(kStackHighEnd));
-      __ li(a2, Operand(ExternalReference::isolate_address()));
+      __ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate())));
       ExternalReference grow_stack =
           ExternalReference::re_grow_stack(masm_->isolate());
       __ CallCFunction(grow_stack, num_arguments);
@@ -823,16 +852,15 @@
       __ bind(&exit_with_exception);
       // Exit with Result EXCEPTION(-1) to signal thrown exception.
       __ li(v0, Operand(EXCEPTION));
-      __ jmp(&exit_label_);
+      __ jmp(&return_v0);
     }
   }
 
   CodeDesc code_desc;
   masm_->GetCode(&code_desc);
-  Handle<Code> code = FACTORY->NewCode(code_desc,
-                                       Code::ComputeFlags(Code::REGEXP),
-                                       masm_->CodeObject());
-  LOG(Isolate::Current(), RegExpCodeCreateEvent(*code, *source));
+  Handle<Code> code = isolate()->factory()->NewCode(
+      code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject());
+  LOG(masm_->isolate(), RegExpCodeCreateEvent(*code, *source));
   return Handle<HeapObject>::cast(code);
 }
 
@@ -848,23 +876,23 @@
 
 
 void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg,
-                                           int comparand,
-                                           Label* if_ge) {
+                                            int comparand,
+                                            Label* if_ge) {
   __ lw(a0, register_location(reg));
     BranchOrBacktrack(if_ge, ge, a0, Operand(comparand));
 }
 
 
 void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg,
-                                           int comparand,
-                                           Label* if_lt) {
+                                            int comparand,
+                                            Label* if_lt) {
   __ lw(a0, register_location(reg));
   BranchOrBacktrack(if_lt, lt, a0, Operand(comparand));
 }
 
 
 void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg,
-                                              Label* if_eq) {
+                                               Label* if_eq) {
   __ lw(a0, register_location(reg));
   BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset()));
 }
@@ -877,11 +905,11 @@
 
 
 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
-                                                   Label* on_end_of_input,
-                                                   bool check_bounds,
-                                                   int characters) {
-  ASSERT(cp_offset >= -1);      // ^ and \b can look behind one character.
-  ASSERT(cp_offset < (1<<30));  // Be sane! (And ensure negation works).
+                                                    Label* on_end_of_input,
+                                                    bool check_bounds,
+                                                    int characters) {
+  DCHECK(cp_offset >= -1);      // ^ and \b can look behind one character.
+  DCHECK(cp_offset < (1<<30));  // Be sane! (And ensure negation works).
   if (check_bounds) {
     CheckPosition(cp_offset + characters - 1, on_end_of_input);
   }
@@ -905,6 +933,7 @@
     int target = label->pos();
     __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
   } else {
+    Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
     Label after_constant;
     __ Branch(&after_constant);
     int offset = masm_->pc_offset();
@@ -930,7 +959,7 @@
 
 
 void RegExpMacroAssemblerMIPS::PushRegister(int register_index,
-                                           StackCheckFlag check_stack_limit) {
+                                            StackCheckFlag check_stack_limit) {
   __ lw(a0, register_location(register_index));
   Push(a0);
   if (check_stack_limit) CheckStackLimit();
@@ -965,19 +994,20 @@
 
 
 void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) {
-  ASSERT(register_index >= num_saved_registers_);  // Reserved for positions!
+  DCHECK(register_index >= num_saved_registers_);  // Reserved for positions!
   __ li(a0, Operand(to));
   __ sw(a0, register_location(register_index));
 }
 
 
-void RegExpMacroAssemblerMIPS::Succeed() {
+bool RegExpMacroAssemblerMIPS::Succeed() {
   __ jmp(&success_label_);
+  return global();
 }
 
 
 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg,
-                                                             int cp_offset) {
+                                                              int cp_offset) {
   if (cp_offset == 0) {
     __ sw(current_input_offset(), register_location(reg));
   } else {
@@ -988,7 +1018,7 @@
 
 
 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) {
-  ASSERT(reg_from <= reg_to);
+  DCHECK(reg_from <= reg_to);
   __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
   for (int reg = reg_from; reg <= reg_to; reg++) {
     __ sw(a0, register_location(reg));
@@ -1003,18 +1033,64 @@
 }
 
 
+bool RegExpMacroAssemblerMIPS::CanReadUnaligned() {
+  return false;
+}
+
+
 // Private methods:
 
 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) {
-  static const int num_arguments = 3;
-  __ PrepareCallCFunction(num_arguments, scratch);
+  int stack_alignment = base::OS::ActivationFrameAlignment();
+
+  // Align the stack pointer and save the original sp value on the stack.
+  __ mov(scratch, sp);
+  __ Subu(sp, sp, Operand(kPointerSize));
+  DCHECK(base::bits::IsPowerOfTwo32(stack_alignment));
+  __ And(sp, sp, Operand(-stack_alignment));
+  __ sw(scratch, MemOperand(sp));
+
   __ mov(a2, frame_pointer());
   // Code* of self.
   __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE);
-  // a0 becomes return address pointer.
+
+  // We need to make room for the return address on the stack.
+  DCHECK(IsAligned(stack_alignment, kPointerSize));
+  __ Subu(sp, sp, Operand(stack_alignment));
+
+  // Stack pointer now points to cell where return address is to be written.
+  // Arguments are in registers, meaning we teat the return address as
+  // argument 5. Since DirectCEntryStub will handleallocating space for the C
+  // argument slots, we don't need to care about that here. This is how the
+  // stack will look (sp meaning the value of sp at this moment):
+  // [sp + 3] - empty slot if needed for alignment.
+  // [sp + 2] - saved sp.
+  // [sp + 1] - second word reserved for return value.
+  // [sp + 0] - first word reserved for return value.
+
+  // a0 will point to the return address, placed by DirectCEntry.
+  __ mov(a0, sp);
+
   ExternalReference stack_guard_check =
       ExternalReference::re_check_stack_guard_state(masm_->isolate());
-  CallCFunctionUsingStub(stack_guard_check, num_arguments);
+  __ li(t9, Operand(stack_guard_check));
+  DirectCEntryStub stub(isolate());
+  stub.GenerateCall(masm_, t9);
+
+  // DirectCEntryStub allocated space for the C argument slots so we have to
+  // drop them with the return address from the stack with loading saved sp.
+  // At this point stack must look:
+  // [sp + 7] - empty slot if needed for alignment.
+  // [sp + 6] - saved sp.
+  // [sp + 5] - second word reserved for return value.
+  // [sp + 4] - first word reserved for return value.
+  // [sp + 3] - C argument slot.
+  // [sp + 2] - C argument slot.
+  // [sp + 1] - C argument slot.
+  // [sp + 0] - C argument slot.
+  __ lw(sp, MemOperand(sp, stack_alignment + kCArgsSlotsSize));
+
+  __ li(code_pointer(), Operand(masm_->CodeObject()));
 }
 
 
@@ -1029,8 +1105,8 @@
                                                    Code* re_code,
                                                    Address re_frame) {
   Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate);
-  ASSERT(isolate == Isolate::Current());
-  if (isolate->stack_guard()->IsStackOverflow()) {
+  StackLimitCheck check(isolate);
+  if (check.JsHasOverflowed()) {
     isolate->StackOverflow();
     return EXCEPTION;
   }
@@ -1050,13 +1126,13 @@
 
   Handle<String> subject(frame_entry<String*>(re_frame, kInputString));
   // Current string.
-  bool is_ascii = subject->IsAsciiRepresentationUnderneath();
+  bool is_one_byte = subject->IsOneByteRepresentationUnderneath();
 
-  ASSERT(re_code->instruction_start() <= *return_address);
-  ASSERT(*return_address <=
+  DCHECK(re_code->instruction_start() <= *return_address);
+  DCHECK(*return_address <=
       re_code->instruction_start() + re_code->instruction_size());
 
-  MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
+  Object* result = isolate->stack_guard()->HandleInterrupts();
 
   if (*code_handle != re_code) {  // Return address no longer valid.
     int delta = code_handle->address() - re_code->address();
@@ -1081,8 +1157,8 @@
   }
 
   // String might have changed.
-  if (subject_tmp->IsAsciiRepresentation() != is_ascii) {
-    // If we changed between an ASCII and an UC16 string, the specialized
+  if (subject_tmp->IsOneByteRepresentation() != is_one_byte) {
+    // If we changed between an Latin1 and an UC16 string, the specialized
     // code cannot be used, and we need to restart regexp matching from
     // scratch (including, potentially, compiling a new version of the code).
     return RETRY;
@@ -1092,7 +1168,7 @@
   // be a sequential or external string with the same content.
   // Update the start and end pointers in the stack frame to the current
   // location (whether it has actually moved or not).
-  ASSERT(StringShape(*subject_tmp).IsSequential() ||
+  DCHECK(StringShape(*subject_tmp).IsSequential() ||
       StringShape(*subject_tmp).IsExternal());
 
   // The original start address of the characters to match.
@@ -1124,7 +1200,7 @@
 
 
 MemOperand RegExpMacroAssemblerMIPS::register_location(int register_index) {
-  ASSERT(register_index < (1<<30));
+  DCHECK(register_index < (1<<30));
   if (num_registers_ <= register_index) {
     num_registers_ = register_index + 1;
   }
@@ -1134,7 +1210,7 @@
 
 
 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset,
-                                            Label* on_outside_input) {
+                                             Label* on_outside_input) {
   BranchOrBacktrack(on_outside_input,
                     ge,
                     current_input_offset(),
@@ -1162,8 +1238,10 @@
 }
 
 
-void RegExpMacroAssemblerMIPS::SafeCall(Label* to, Condition cond, Register rs,
-                                           const Operand& rt) {
+void RegExpMacroAssemblerMIPS::SafeCall(Label* to,
+                                        Condition cond,
+                                        Register rs,
+                                        const Operand& rt) {
   __ BranchAndLink(to, cond, rs, rt);
 }
 
@@ -1183,7 +1261,7 @@
 
 
 void RegExpMacroAssemblerMIPS::Push(Register source) {
-  ASSERT(!source.is(backtrack_stackpointer()));
+  DCHECK(!source.is(backtrack_stackpointer()));
   __ Addu(backtrack_stackpointer(),
           backtrack_stackpointer(),
           Operand(-kPointerSize));
@@ -1192,7 +1270,7 @@
 
 
 void RegExpMacroAssemblerMIPS::Pop(Register target) {
-  ASSERT(!target.is(backtrack_stackpointer()));
+  DCHECK(!target.is(backtrack_stackpointer()));
   __ lw(target, MemOperand(backtrack_stackpointer()));
   __ Addu(backtrack_stackpointer(), backtrack_stackpointer(), kPointerSize);
 }
@@ -1218,58 +1296,27 @@
 }
 
 
-void RegExpMacroAssemblerMIPS::CallCFunctionUsingStub(
-    ExternalReference function,
-    int num_arguments) {
-  // Must pass all arguments in registers. The stub pushes on the stack.
-  ASSERT(num_arguments <= 4);
-  __ li(code_pointer(), Operand(function));
-  RegExpCEntryStub stub;
-  __ CallStub(&stub);
-  if (OS::ActivationFrameAlignment() != 0) {
-    __ lw(sp, MemOperand(sp, 16));
-  }
-  __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
-}
-
-
 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset,
-                                                            int characters) {
+                                                             int characters) {
   Register offset = current_input_offset();
   if (cp_offset != 0) {
-    __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size()));
-    offset = a0;
+    // t7 is not being used to store the capture start index at this point.
+    __ Addu(t7, current_input_offset(), Operand(cp_offset * char_size()));
+    offset = t7;
   }
   // We assume that we cannot do unaligned loads on MIPS, so this function
   // must only be used to load a single character at a time.
-  ASSERT(characters == 1);
+  DCHECK(characters == 1);
   __ Addu(t5, end_of_input_address(), Operand(offset));
-  if (mode_ == ASCII) {
+  if (mode_ == LATIN1) {
     __ lbu(current_character(), MemOperand(t5, 0));
   } else {
-    ASSERT(mode_ == UC16);
+    DCHECK(mode_ == UC16);
     __ lhu(current_character(), MemOperand(t5, 0));
   }
 }
 
 
-void RegExpCEntryStub::Generate(MacroAssembler* masm_) {
-  int stack_alignment = OS::ActivationFrameAlignment();
-  if (stack_alignment < kPointerSize) stack_alignment = kPointerSize;
-  // Stack is already aligned for call, so decrement by alignment
-  // to make room for storing the return address.
-  __ Subu(sp, sp, Operand(stack_alignment + kCArgsSlotsSize));
-  const int return_address_offset = kCArgsSlotsSize;
-  __ Addu(a0, sp, return_address_offset);
-  __ sw(ra, MemOperand(a0, 0));
-  __ mov(t9, t1);
-  __ Call(t9);
-  __ lw(ra, MemOperand(sp, return_address_offset));
-  __ Addu(sp, sp, Operand(stack_alignment + kCArgsSlotsSize));
-  __ Jump(ra);
-}
-
-
 #undef __
 
 #endif  // V8_INTERPRETED_REGEXP