Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 4a572c8..a91058c 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -28,55 +28,61 @@
 #include <cstdlib>
 #include <sstream>
 
+#include "include/v8.h"
 #include "src/v8.h"
 
-#include "src/ast.h"
+#include "src/ast/ast.h"
 #include "src/char-predicates-inl.h"
-#include "src/jsregexp.h"
 #include "src/ostreams.h"
-#include "src/parser.h"
-#include "src/regexp-macro-assembler.h"
-#include "src/regexp-macro-assembler-irregexp.h"
+#include "src/regexp/jsregexp.h"
+#include "src/regexp/regexp-macro-assembler.h"
+#include "src/regexp/regexp-macro-assembler-irregexp.h"
+#include "src/regexp/regexp-parser.h"
+#include "src/splay-tree-inl.h"
 #include "src/string-stream.h"
-#include "src/zone-inl.h"
 #ifdef V8_INTERPRETED_REGEXP
-#include "src/interpreter-irregexp.h"
+#include "src/regexp/interpreter-irregexp.h"
 #else  // V8_INTERPRETED_REGEXP
 #include "src/macro-assembler.h"
 #if V8_TARGET_ARCH_ARM
 #include "src/arm/assembler-arm.h"  // NOLINT
 #include "src/arm/macro-assembler-arm.h"
-#include "src/arm/regexp-macro-assembler-arm.h"
+#include "src/regexp/arm/regexp-macro-assembler-arm.h"
 #endif
 #if V8_TARGET_ARCH_ARM64
 #include "src/arm64/assembler-arm64.h"
 #include "src/arm64/macro-assembler-arm64.h"
-#include "src/arm64/regexp-macro-assembler-arm64.h"
+#include "src/regexp/arm64/regexp-macro-assembler-arm64.h"
+#endif
+#if V8_TARGET_ARCH_PPC
+#include "src/ppc/assembler-ppc.h"
+#include "src/ppc/macro-assembler-ppc.h"
+#include "src/regexp/ppc/regexp-macro-assembler-ppc.h"
 #endif
 #if V8_TARGET_ARCH_MIPS
 #include "src/mips/assembler-mips.h"
 #include "src/mips/macro-assembler-mips.h"
-#include "src/mips/regexp-macro-assembler-mips.h"
+#include "src/regexp/mips/regexp-macro-assembler-mips.h"
 #endif
 #if V8_TARGET_ARCH_MIPS64
 #include "src/mips64/assembler-mips64.h"
 #include "src/mips64/macro-assembler-mips64.h"
-#include "src/mips64/regexp-macro-assembler-mips64.h"
+#include "src/regexp/mips64/regexp-macro-assembler-mips64.h"
 #endif
 #if V8_TARGET_ARCH_X64
+#include "src/regexp/x64/regexp-macro-assembler-x64.h"
 #include "src/x64/assembler-x64.h"
 #include "src/x64/macro-assembler-x64.h"
-#include "src/x64/regexp-macro-assembler-x64.h"
 #endif
 #if V8_TARGET_ARCH_IA32
 #include "src/ia32/assembler-ia32.h"
 #include "src/ia32/macro-assembler-ia32.h"
-#include "src/ia32/regexp-macro-assembler-ia32.h"
+#include "src/regexp/ia32/regexp-macro-assembler-ia32.h"
 #endif
 #if V8_TARGET_ARCH_X87
+#include "src/regexp/x87/regexp-macro-assembler-x87.h"
 #include "src/x87/assembler-x87.h"
 #include "src/x87/macro-assembler-x87.h"
-#include "src/x87/regexp-macro-assembler-x87.h"
 #endif
 #endif  // V8_INTERPRETED_REGEXP
 #include "test/cctest/cctest.h"
@@ -86,36 +92,40 @@
 
 static bool CheckParse(const char* input) {
   v8::HandleScope scope(CcTest::isolate());
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
   RegExpCompileData result;
   return v8::internal::RegExpParser::ParseRegExp(
-      &reader, false, &result, &zone);
+      CcTest::i_isolate(), &zone, &reader, false, false, &result);
 }
 
 
-static void CheckParseEq(const char* input, const char* expected) {
+static void CheckParseEq(const char* input, const char* expected,
+                         bool unicode = false) {
   v8::HandleScope scope(CcTest::isolate());
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
   RegExpCompileData result;
   CHECK(v8::internal::RegExpParser::ParseRegExp(
-      &reader, false, &result, &zone));
+      CcTest::i_isolate(), &zone, &reader, false, unicode, &result));
   CHECK(result.tree != NULL);
   CHECK(result.error.is_null());
   std::ostringstream os;
   result.tree->Print(os, &zone);
-  CHECK_EQ(expected, os.str().c_str());
+  if (strcmp(expected, os.str().c_str()) != 0) {
+    printf("%s | %s\n", expected, os.str().c_str());
+  }
+  CHECK_EQ(0, strcmp(expected, os.str().c_str()));
 }
 
 
 static bool CheckSimple(const char* input) {
   v8::HandleScope scope(CcTest::isolate());
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
   RegExpCompileData result;
   CHECK(v8::internal::RegExpParser::ParseRegExp(
-      &reader, false, &result, &zone));
+      CcTest::i_isolate(), &zone, &reader, false, false, &result));
   CHECK(result.tree != NULL);
   CHECK(result.error.is_null());
   return result.simple;
@@ -129,11 +139,11 @@
 
 static MinMaxPair CheckMinMaxMatch(const char* input) {
   v8::HandleScope scope(CcTest::isolate());
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
   RegExpCompileData result;
   CHECK(v8::internal::RegExpParser::ParseRegExp(
-      &reader, false, &result, &zone));
+      CcTest::i_isolate(), &zone, &reader, false, false, &result));
   CHECK(result.tree != NULL);
   CHECK(result.error.is_null());
   int min_match = result.tree->min_match();
@@ -151,7 +161,11 @@
     CHECK_EQ(max, min_max.max_match);                                          \
   }
 
-TEST(Parser) {
+
+void TestRegExpParser(bool lookbehind) {
+  FLAG_harmony_regexp_lookbehind = lookbehind;
+  FLAG_harmony_unicode_regexps = true;
+
   CHECK_PARSE_ERROR("?");
 
   CheckParseEq("abc", "'abc'");
@@ -183,6 +197,13 @@
   CheckParseEq("foo|(bar|baz)|quux", "(| 'foo' (^ (| 'bar' 'baz')) 'quux')");
   CheckParseEq("foo(?=bar)baz", "(: 'foo' (-> + 'bar') 'baz')");
   CheckParseEq("foo(?!bar)baz", "(: 'foo' (-> - 'bar') 'baz')");
+  if (lookbehind) {
+    CheckParseEq("foo(?<=bar)baz", "(: 'foo' (<- + 'bar') 'baz')");
+    CheckParseEq("foo(?<!bar)baz", "(: 'foo' (<- - 'bar') 'baz')");
+  } else {
+    CHECK_PARSE_ERROR("foo(?<=bar)baz");
+    CHECK_PARSE_ERROR("foo(?<!bar)baz");
+  }
   CheckParseEq("()", "(^ %)");
   CheckParseEq("(?=)", "(-> + %)");
   CheckParseEq("[]", "^[\\x00-\\uffff]");  // Doesn't compile on windows
@@ -254,14 +275,22 @@
   CheckParseEq("(a)\\1", "(: (^ 'a') (<- 1))");
   CheckParseEq("(a\\1)", "(^ 'a')");
   CheckParseEq("(\\1a)", "(^ 'a')");
+  CheckParseEq("(\\2)(\\1)", "(: (^ (<- 2)) (^ (<- 1)))");
   CheckParseEq("(?=a)?a", "'a'");
   CheckParseEq("(?=a){0,10}a", "'a'");
   CheckParseEq("(?=a){1,10}a", "(: (-> + 'a') 'a')");
   CheckParseEq("(?=a){9,10}a", "(: (-> + 'a') 'a')");
   CheckParseEq("(?!a)?a", "'a'");
-  CheckParseEq("\\1(a)", "(^ 'a')");
+  CheckParseEq("\\1(a)", "(: (<- 1) (^ 'a'))");
   CheckParseEq("(?!(a))\\1", "(: (-> - (^ 'a')) (<- 1))");
-  CheckParseEq("(?!\\1(a\\1)\\1)\\1", "(: (-> - (: (^ 'a') (<- 1))) (<- 1))");
+  CheckParseEq("(?!\\1(a\\1)\\1)\\1",
+               "(: (-> - (: (<- 1) (^ 'a') (<- 1))) (<- 1))");
+  CheckParseEq("\\1\\2(a(?:\\1(b\\1\\2))\\2)\\1",
+               "(: (<- 1) (<- 2) (^ (: 'a' (^ 'b') (<- 2))) (<- 1))");
+  if (lookbehind) {
+    CheckParseEq("\\1\\2(a(?<=\\1(b\\1\\2))\\2)\\1",
+                 "(: (<- 1) (<- 2) (^ (: 'a' (<- + (^ 'b')) (<- 2))) (<- 1))");
+  }
   CheckParseEq("[\\0]", "[\\x00]");
   CheckParseEq("[\\11]", "[\\x09]");
   CheckParseEq("[\\11a]", "[\\x09 a]");
@@ -278,6 +307,15 @@
   CheckParseEq("\\u003z", "'u003z'");
   CheckParseEq("foo[z]*", "(: 'foo' (# 0 - g [z]))");
 
+  // Unicode regexps
+  CheckParseEq("\\u{12345}", "'\\ud808\\udf45'", true);
+  CheckParseEq("\\u{12345}\\u{23456}", "(! '\\ud808\\udf45' '\\ud84d\\udc56')",
+               true);
+  CheckParseEq("\\u{12345}|\\u{23456}", "(| '\\ud808\\udf45' '\\ud84d\\udc56')",
+               true);
+  CheckParseEq("\\u{12345}{3}", "(# 3 3 g '\\ud808\\udf45')", true);
+  CheckParseEq("\\u{12345}*", "(# 0 - g '\\ud808\\udf45')", true);
+
   CHECK_SIMPLE("", false);
   CHECK_SIMPLE("a", true);
   CHECK_SIMPLE("a|b", false);
@@ -353,8 +391,8 @@
   CHECK_MIN_MAX("(?:ab)|cde", 2, 3);
   CHECK_MIN_MAX("(ab)", 2, 2);
   CHECK_MIN_MAX("(ab|cde)", 2, 3);
-  CHECK_MIN_MAX("(ab)\\1", 2, 4);
-  CHECK_MIN_MAX("(ab|cde)\\1", 2, 6);
+  CHECK_MIN_MAX("(ab)\\1", 2, RegExpTree::kInfinity);
+  CHECK_MIN_MAX("(ab|cde)\\1", 2, RegExpTree::kInfinity);
   CHECK_MIN_MAX("(?:ab)?", 0, 2);
   CHECK_MIN_MAX("(?:ab)*", 0, RegExpTree::kInfinity);
   CHECK_MIN_MAX("(?:ab)+", 2, RegExpTree::kInfinity);
@@ -392,6 +430,16 @@
 }
 
 
+TEST(ParserWithLookbehind) {
+  TestRegExpParser(true);  // Lookbehind enabled.
+}
+
+
+TEST(ParserWithoutLookbehind) {
+  TestRegExpParser(true);  // Lookbehind enabled.
+}
+
+
 TEST(ParserRegression) {
   CheckParseEq("[A-Z$-][x]", "(! [A-Z $ -] [x])");
   CheckParseEq("a{3,4*}", "(: 'a{3,' (# 0 - g '4') '}')");
@@ -402,15 +450,15 @@
 static void ExpectError(const char* input,
                         const char* expected) {
   v8::HandleScope scope(CcTest::isolate());
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
   RegExpCompileData result;
   CHECK(!v8::internal::RegExpParser::ParseRegExp(
-      &reader, false, &result, &zone));
+            CcTest::i_isolate(), &zone, &reader, false, false, &result));
   CHECK(result.tree == NULL);
   CHECK(!result.error.is_null());
-  SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS);
-  CHECK_EQ(expected, str.get());
+  v8::base::SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS);
+  CHECK_EQ(0, strcmp(expected, str.get()));
 }
 
 
@@ -471,7 +519,7 @@
 
 
 static void TestCharacterClassEscapes(uc16 c, bool (pred)(uc16 c)) {
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   ZoneList<CharacterRange>* ranges =
       new(&zone) ZoneList<CharacterRange>(2, &zone);
   CharacterRange::AddClassEscape(c, ranges, &zone);
@@ -497,29 +545,31 @@
 }
 
 
-static RegExpNode* Compile(const char* input, bool multiline, bool is_one_byte,
-                           Zone* zone) {
+static RegExpNode* Compile(const char* input, bool multiline, bool unicode,
+                           bool is_one_byte, Zone* zone) {
   Isolate* isolate = CcTest::i_isolate();
   FlatStringReader reader(isolate, CStrVector(input));
   RegExpCompileData compile_data;
-  if (!v8::internal::RegExpParser::ParseRegExp(&reader, multiline,
-                                               &compile_data, zone))
+  if (!v8::internal::RegExpParser::ParseRegExp(CcTest::i_isolate(), zone,
+                                               &reader, multiline, unicode,
+                                               &compile_data))
     return NULL;
-  Handle<String> pattern = isolate->factory()->
-      NewStringFromUtf8(CStrVector(input)).ToHandleChecked();
+  Handle<String> pattern = isolate->factory()
+                               ->NewStringFromUtf8(CStrVector(input))
+                               .ToHandleChecked();
   Handle<String> sample_subject =
       isolate->factory()->NewStringFromUtf8(CStrVector("")).ToHandleChecked();
-  RegExpEngine::Compile(&compile_data, false, false, multiline, false, pattern,
-                        sample_subject, is_one_byte, zone);
+  RegExpEngine::Compile(isolate, zone, &compile_data, false, false, multiline,
+                        false, pattern, sample_subject, is_one_byte);
   return compile_data.node;
 }
 
 
-static void Execute(const char* input, bool multiline, bool is_one_byte,
-                    bool dot_output = false) {
+static void Execute(const char* input, bool multiline, bool unicode,
+                    bool is_one_byte, bool dot_output = false) {
   v8::HandleScope scope(CcTest::isolate());
-  Zone zone(CcTest::i_isolate());
-  RegExpNode* node = Compile(input, multiline, is_one_byte, &zone);
+  Zone zone;
+  RegExpNode* node = Compile(input, multiline, unicode, is_one_byte, &zone);
   USE(node);
 #ifdef DEBUG
   if (dot_output) {
@@ -556,7 +606,7 @@
 
 TEST(SplayTreeSimple) {
   static const unsigned kLimit = 1000;
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   ZoneSplayTree<TestConfig> tree(&zone);
   bool seen[kLimit];
   for (unsigned i = 0; i < kLimit; i++) seen[i] = false;
@@ -566,7 +616,7 @@
   } while (false)
   for (int i = 0; i < 50; i++) {
     for (int j = 0; j < 50; j++) {
-      unsigned next = PseudoRandom(i, j) % kLimit;
+      int next = PseudoRandom(i, j) % kLimit;
       if (seen[next]) {
         // We've already seen this one.  Check the value and remove
         // it.
@@ -623,7 +673,7 @@
     }
   }
   // Enter test data into dispatch table.
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   DispatchTable table(&zone);
   for (int i = 0; i < kRangeCount; i++) {
     uc16* range = ranges[i];
@@ -686,6 +736,8 @@
 typedef RegExpMacroAssemblerARM ArchRegExpMacroAssembler;
 #elif V8_TARGET_ARCH_ARM64
 typedef RegExpMacroAssemblerARM64 ArchRegExpMacroAssembler;
+#elif V8_TARGET_ARCH_PPC
+typedef RegExpMacroAssemblerPPC ArchRegExpMacroAssembler;
 #elif V8_TARGET_ARCH_MIPS
 typedef RegExpMacroAssemblerMIPS ArchRegExpMacroAssembler;
 #elif V8_TARGET_ARCH_MIPS64
@@ -706,7 +758,7 @@
   }
  private:
   v8::HandleScope scope_;
-  v8::Handle<v8::Context> env_;
+  v8::Local<v8::Context> env_;
 };
 
 
@@ -733,9 +785,10 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 4, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+                             4);
 
   m.Succeed();
 
@@ -770,13 +823,14 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 4, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+                             4);
 
   Label fail, backtrack;
   m.PushBacktrack(&fail);
-  m.CheckNotAtStart(NULL);
+  m.CheckNotAtStart(0, NULL);
   m.LoadCurrentCharacter(2, NULL);
   m.CheckNotCharacter('o', NULL);
   m.LoadCurrentCharacter(1, NULL, false);
@@ -836,13 +890,14 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::UC16,
+                             4);
 
   Label fail, backtrack;
   m.PushBacktrack(&fail);
-  m.CheckNotAtStart(NULL);
+  m.CheckNotAtStart(0, NULL);
   m.LoadCurrentCharacter(2, NULL);
   m.CheckNotCharacter('o', NULL);
   m.LoadCurrentCharacter(1, NULL, false);
@@ -908,9 +963,10 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 0, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+                             0);
 
   Label fail;
   Label backtrack;
@@ -948,20 +1004,21 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 4, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+                             4);
 
   m.WriteCurrentPositionToRegister(0, 0);
   m.AdvanceCurrentPosition(2);
   m.WriteCurrentPositionToRegister(1, 0);
   Label nomatch;
-  m.CheckNotBackReference(0, &nomatch);
+  m.CheckNotBackReference(0, false, &nomatch);
   m.Fail();
   m.Bind(&nomatch);
   m.AdvanceCurrentPosition(2);
   Label missing_match;
-  m.CheckNotBackReference(0, &missing_match);
+  m.CheckNotBackReference(0, false, &missing_match);
   m.WriteCurrentPositionToRegister(2, 0);
   m.Succeed();
   m.Bind(&missing_match);
@@ -997,20 +1054,21 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::UC16,
+                             4);
 
   m.WriteCurrentPositionToRegister(0, 0);
   m.AdvanceCurrentPosition(2);
   m.WriteCurrentPositionToRegister(1, 0);
   Label nomatch;
-  m.CheckNotBackReference(0, &nomatch);
+  m.CheckNotBackReference(0, false, &nomatch);
   m.Fail();
   m.Bind(&nomatch);
   m.AdvanceCurrentPosition(2);
   Label missing_match;
-  m.CheckNotBackReference(0, &missing_match);
+  m.CheckNotBackReference(0, false, &missing_match);
   m.WriteCurrentPositionToRegister(2, 0);
   m.Succeed();
   m.Bind(&missing_match);
@@ -1049,12 +1107,13 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 0, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+                             0);
 
   Label not_at_start, newline, fail;
-  m.CheckNotAtStart(&not_at_start);
+  m.CheckNotAtStart(0, &not_at_start);
   // Check that prevchar = '\n' and current = 'f'.
   m.CheckCharacter('\n', &newline);
   m.Bind(&fail);
@@ -1108,9 +1167,10 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 4, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+                             4);
 
   Label fail, succ;
 
@@ -1118,16 +1178,16 @@
   m.WriteCurrentPositionToRegister(2, 0);
   m.AdvanceCurrentPosition(3);
   m.WriteCurrentPositionToRegister(3, 0);
-  m.CheckNotBackReferenceIgnoreCase(2, &fail);  // Match "AbC".
-  m.CheckNotBackReferenceIgnoreCase(2, &fail);  // Match "ABC".
+  m.CheckNotBackReferenceIgnoreCase(2, false, &fail);  // Match "AbC".
+  m.CheckNotBackReferenceIgnoreCase(2, false, &fail);  // Match "ABC".
   Label expected_fail;
-  m.CheckNotBackReferenceIgnoreCase(2, &expected_fail);
+  m.CheckNotBackReferenceIgnoreCase(2, false, &expected_fail);
   m.Bind(&fail);
   m.Fail();
 
   m.Bind(&expected_fail);
   m.AdvanceCurrentPosition(3);  // Skip "xYz"
-  m.CheckNotBackReferenceIgnoreCase(2, &succ);
+  m.CheckNotBackReferenceIgnoreCase(2, false, &succ);
   m.Fail();
 
   m.Bind(&succ);
@@ -1166,9 +1226,10 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 6, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+                             6);
 
   uc16 foo_chars[3] = {'f', 'o', 'o'};
   Vector<const uc16> foo(foo_chars, 3);
@@ -1267,9 +1328,10 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 0, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+                             0);
 
   Label loop;
   m.Bind(&loop);
@@ -1305,9 +1367,10 @@
   ContextInitializer initializer;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
-  Zone zone(isolate);
+  Zone zone;
 
-  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 2, &zone);
+  ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+                             2);
 
   // At least 2048, to ensure the allocated space for registers
   // span one full page.
@@ -1316,7 +1379,7 @@
   m.WriteCurrentPositionToRegister(0, 0);
   m.WriteCurrentPositionToRegister(1, 1);
   Label done;
-  m.CheckNotBackReference(0, &done);  // Performs a system-stack push.
+  m.CheckNotBackReference(0, false, &done);  // Performs a system-stack push.
   m.Bind(&done);
   m.PushRegister(large_number, RegExpMacroAssembler::kNoStackLimitCheck);
   m.PopRegister(1);
@@ -1352,8 +1415,9 @@
 
 TEST(MacroAssembler) {
   byte codes[1024];
-  Zone zone(CcTest::i_isolate());
-  RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024), &zone);
+  Zone zone;
+  RegExpMacroAssemblerIrregexp m(CcTest::i_isolate(), Vector<byte>(codes, 1024),
+                                 &zone);
   // ^f(o)o.
   Label start, fail, backtrack;
 
@@ -1364,7 +1428,7 @@
   m.Fail();
   m.Bind(&start);
   m.PushBacktrack(&fail);
-  m.CheckNotAtStart(NULL);
+  m.CheckNotAtStart(0, NULL);
   m.LoadCurrentCharacter(0, NULL);
   m.CheckNotCharacter('f', NULL);
   m.LoadCurrentCharacter(1, NULL);
@@ -1419,7 +1483,7 @@
   static const int kLimit = 1000;
   static const int kRangeCount = 16;
   for (int t = 0; t < 10; t++) {
-    Zone zone(CcTest::i_isolate());
+    Zone zone;
     ZoneList<CharacterRange>* ranges =
         new(&zone) ZoneList<CharacterRange>(kRangeCount, &zone);
     for (int i = 0; i < kRangeCount; i++) {
@@ -1440,7 +1504,7 @@
       CHECK_EQ(is_on, set->Get(0) == false);
     }
   }
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   ZoneList<CharacterRange>* ranges =
       new(&zone) ZoneList<CharacterRange>(1, &zone);
   ranges->Add(CharacterRange(0xFFF0, 0xFFFE), &zone);
@@ -1467,8 +1531,8 @@
 
 TEST(LatinCanonicalize) {
   unibrow::Mapping<unibrow::Ecma262UnCanonicalize> un_canonicalize;
-  for (char lower = 'a'; lower <= 'z'; lower++) {
-    char upper = lower + ('A' - 'a');
+  for (unibrow::uchar lower = 'a'; lower <= 'z'; lower++) {
+    unibrow::uchar upper = lower + ('A' - 'a');
     CHECK_EQ(canonicalize(lower), canonicalize(upper));
     unibrow::uchar uncanon[unibrow::Ecma262UnCanonicalize::kMaxWidth];
     int length = un_canonicalize.get(lower, '\0', uncanon);
@@ -1551,13 +1615,13 @@
 }
 
 
-static void TestRangeCaseIndependence(CharacterRange input,
+static void TestRangeCaseIndependence(Isolate* isolate, CharacterRange input,
                                       Vector<CharacterRange> expected) {
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   int count = expected.length();
   ZoneList<CharacterRange>* list =
       new(&zone) ZoneList<CharacterRange>(count, &zone);
-  input.AddCaseEquivalents(list, false, &zone);
+  input.AddCaseEquivalents(isolate, &zone, list, false);
   CHECK_EQ(count, list->length());
   for (int i = 0; i < list->length(); i++) {
     CHECK_EQ(expected[i].from(), list->at(i).from());
@@ -1566,39 +1630,41 @@
 }
 
 
-static void TestSimpleRangeCaseIndependence(CharacterRange input,
+static void TestSimpleRangeCaseIndependence(Isolate* isolate,
+                                            CharacterRange input,
                                             CharacterRange expected) {
   EmbeddedVector<CharacterRange, 1> vector;
   vector[0] = expected;
-  TestRangeCaseIndependence(input, vector);
+  TestRangeCaseIndependence(isolate, input, vector);
 }
 
 
 TEST(CharacterRangeCaseIndependence) {
-  TestSimpleRangeCaseIndependence(CharacterRange::Singleton('a'),
+  Isolate* isolate = CcTest::i_isolate();
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange::Singleton('a'),
                                   CharacterRange::Singleton('A'));
-  TestSimpleRangeCaseIndependence(CharacterRange::Singleton('z'),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange::Singleton('z'),
                                   CharacterRange::Singleton('Z'));
-  TestSimpleRangeCaseIndependence(CharacterRange('a', 'z'),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange('a', 'z'),
                                   CharacterRange('A', 'Z'));
-  TestSimpleRangeCaseIndependence(CharacterRange('c', 'f'),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange('c', 'f'),
                                   CharacterRange('C', 'F'));
-  TestSimpleRangeCaseIndependence(CharacterRange('a', 'b'),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange('a', 'b'),
                                   CharacterRange('A', 'B'));
-  TestSimpleRangeCaseIndependence(CharacterRange('y', 'z'),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange('y', 'z'),
                                   CharacterRange('Y', 'Z'));
-  TestSimpleRangeCaseIndependence(CharacterRange('a' - 1, 'z' + 1),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange('a' - 1, 'z' + 1),
                                   CharacterRange('A', 'Z'));
-  TestSimpleRangeCaseIndependence(CharacterRange('A', 'Z'),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange('A', 'Z'),
                                   CharacterRange('a', 'z'));
-  TestSimpleRangeCaseIndependence(CharacterRange('C', 'F'),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange('C', 'F'),
                                   CharacterRange('c', 'f'));
-  TestSimpleRangeCaseIndependence(CharacterRange('A' - 1, 'Z' + 1),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange('A' - 1, 'Z' + 1),
                                   CharacterRange('a', 'z'));
   // Here we need to add [l-z] to complete the case independence of
   // [A-Za-z] but we expect [a-z] to be added since we always add a
   // whole block at a time.
-  TestSimpleRangeCaseIndependence(CharacterRange('A', 'k'),
+  TestSimpleRangeCaseIndependence(isolate, CharacterRange('A', 'k'),
                                   CharacterRange('a', 'z'));
 }
 
@@ -1616,7 +1682,7 @@
 
 
 TEST(CharClassDifference) {
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   ZoneList<CharacterRange>* base =
       new(&zone) ZoneList<CharacterRange>(1, &zone);
   base->Add(CharacterRange::Everything(), &zone);
@@ -1643,7 +1709,7 @@
 
 
 TEST(CanonicalizeCharacterSets) {
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   ZoneList<CharacterRange>* list =
       new(&zone) ZoneList<CharacterRange>(4, &zone);
   CharacterSet set(list);
@@ -1652,26 +1718,26 @@
   list->Add(CharacterRange(30, 40), &zone);
   list->Add(CharacterRange(50, 60), &zone);
   set.Canonicalize();
-  DCHECK_EQ(3, list->length());
-  DCHECK_EQ(10, list->at(0).from());
-  DCHECK_EQ(20, list->at(0).to());
-  DCHECK_EQ(30, list->at(1).from());
-  DCHECK_EQ(40, list->at(1).to());
-  DCHECK_EQ(50, list->at(2).from());
-  DCHECK_EQ(60, list->at(2).to());
+  CHECK_EQ(3, list->length());
+  CHECK_EQ(10, list->at(0).from());
+  CHECK_EQ(20, list->at(0).to());
+  CHECK_EQ(30, list->at(1).from());
+  CHECK_EQ(40, list->at(1).to());
+  CHECK_EQ(50, list->at(2).from());
+  CHECK_EQ(60, list->at(2).to());
 
   list->Rewind(0);
   list->Add(CharacterRange(10, 20), &zone);
   list->Add(CharacterRange(50, 60), &zone);
   list->Add(CharacterRange(30, 40), &zone);
   set.Canonicalize();
-  DCHECK_EQ(3, list->length());
-  DCHECK_EQ(10, list->at(0).from());
-  DCHECK_EQ(20, list->at(0).to());
-  DCHECK_EQ(30, list->at(1).from());
-  DCHECK_EQ(40, list->at(1).to());
-  DCHECK_EQ(50, list->at(2).from());
-  DCHECK_EQ(60, list->at(2).to());
+  CHECK_EQ(3, list->length());
+  CHECK_EQ(10, list->at(0).from());
+  CHECK_EQ(20, list->at(0).to());
+  CHECK_EQ(30, list->at(1).from());
+  CHECK_EQ(40, list->at(1).to());
+  CHECK_EQ(50, list->at(2).from());
+  CHECK_EQ(60, list->at(2).to());
 
   list->Rewind(0);
   list->Add(CharacterRange(30, 40), &zone);
@@ -1680,31 +1746,31 @@
   list->Add(CharacterRange(100, 100), &zone);
   list->Add(CharacterRange(1, 1), &zone);
   set.Canonicalize();
-  DCHECK_EQ(5, list->length());
-  DCHECK_EQ(1, list->at(0).from());
-  DCHECK_EQ(1, list->at(0).to());
-  DCHECK_EQ(10, list->at(1).from());
-  DCHECK_EQ(20, list->at(1).to());
-  DCHECK_EQ(25, list->at(2).from());
-  DCHECK_EQ(25, list->at(2).to());
-  DCHECK_EQ(30, list->at(3).from());
-  DCHECK_EQ(40, list->at(3).to());
-  DCHECK_EQ(100, list->at(4).from());
-  DCHECK_EQ(100, list->at(4).to());
+  CHECK_EQ(5, list->length());
+  CHECK_EQ(1, list->at(0).from());
+  CHECK_EQ(1, list->at(0).to());
+  CHECK_EQ(10, list->at(1).from());
+  CHECK_EQ(20, list->at(1).to());
+  CHECK_EQ(25, list->at(2).from());
+  CHECK_EQ(25, list->at(2).to());
+  CHECK_EQ(30, list->at(3).from());
+  CHECK_EQ(40, list->at(3).to());
+  CHECK_EQ(100, list->at(4).from());
+  CHECK_EQ(100, list->at(4).to());
 
   list->Rewind(0);
   list->Add(CharacterRange(10, 19), &zone);
   list->Add(CharacterRange(21, 30), &zone);
   list->Add(CharacterRange(20, 20), &zone);
   set.Canonicalize();
-  DCHECK_EQ(1, list->length());
-  DCHECK_EQ(10, list->at(0).from());
-  DCHECK_EQ(30, list->at(0).to());
+  CHECK_EQ(1, list->length());
+  CHECK_EQ(10, list->at(0).from());
+  CHECK_EQ(30, list->at(0).to());
 }
 
 
 TEST(CharacterRangeMerge) {
-  Zone zone(CcTest::i_isolate());
+  Zone zone;
   ZoneList<CharacterRange> l1(4, &zone);
   ZoneList<CharacterRange> l2(4, &zone);
   // Create all combinations of intersections of ranges, both singletons and
@@ -1781,8 +1847,8 @@
     offset += 9;
   }
 
-  DCHECK(CharacterRange::IsCanonical(&l1));
-  DCHECK(CharacterRange::IsCanonical(&l2));
+  CHECK(CharacterRange::IsCanonical(&l1));
+  CHECK(CharacterRange::IsCanonical(&l2));
 
   ZoneList<CharacterRange> first_only(4, &zone);
   ZoneList<CharacterRange> second_only(4, &zone);
@@ -1793,3 +1859,82 @@
 TEST(Graph) {
   Execute("\\b\\w+\\b", false, true, true);
 }
+
+
+namespace {
+
+int* global_use_counts = NULL;
+
+void MockUseCounterCallback(v8::Isolate* isolate,
+                            v8::Isolate::UseCounterFeature feature) {
+  ++global_use_counts[feature];
+}
+}
+
+
+// Test that ES2015 RegExp compatibility fixes are in place, that they
+// are not overly broad, and the appropriate UseCounters are incremented
+TEST(UseCountRegExp) {
+  i::FLAG_harmony_regexps = true;
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  LocalContext env;
+  int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
+  global_use_counts = use_counts;
+  CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
+
+  // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it
+  v8::Local<v8::Value> resultSticky = CompileRun("RegExp.prototype.sticky");
+  CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+  CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+  CHECK(resultSticky->IsUndefined());
+
+  // re.sticky has approriate value and doesn't touch UseCounter
+  v8::Local<v8::Value> resultReSticky = CompileRun("/a/.sticky");
+  CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+  CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+  CHECK(resultReSticky->IsFalse());
+
+  // When the getter is caleld on another object, throw an exception
+  // and don't increment the UseCounter
+  v8::Local<v8::Value> resultStickyError = CompileRun(
+      "var exception;"
+      "try { "
+      "  Object.getOwnPropertyDescriptor(RegExp.prototype, 'sticky')"
+      "      .get.call(null);"
+      "} catch (e) {"
+      "  exception = e;"
+      "}"
+      "exception");
+  CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+  CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+  CHECK(resultStickyError->IsObject());
+
+  // RegExp.prototype.toString() returns '/(?:)/' as a compatibility fix;
+  // a UseCounter is incremented to track it.
+  v8::Local<v8::Value> resultToString =
+      CompileRun("RegExp.prototype.toString().length");
+  CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+  CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+  CHECK(resultToString->IsInt32());
+  CHECK_EQ(6,
+           resultToString->Int32Value(isolate->GetCurrentContext()).FromJust());
+
+  // .toString() works on normal RegExps
+  v8::Local<v8::Value> resultReToString = CompileRun("/a/.toString().length");
+  CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+  CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+  CHECK(resultReToString->IsInt32());
+  CHECK_EQ(
+      3, resultReToString->Int32Value(isolate->GetCurrentContext()).FromJust());
+
+  // .toString() throws on non-RegExps that aren't RegExp.prototype
+  v8::Local<v8::Value> resultToStringError = CompileRun(
+      "var exception;"
+      "try { RegExp.prototype.toString.call(null) }"
+      "catch (e) { exception = e; }"
+      "exception");
+  CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+  CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+  CHECK(resultToStringError->IsObject());
+}