Merge V8 5.3.332.45.  DO NOT MERGE

Test: Manual

FPIIM-449

Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index da72ecd..5624e3f 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -47,11 +47,12 @@
 #include "src/futex-emulation.h"
 #include "src/objects.h"
 #include "src/parsing/parser.h"
+#include "src/profiler/cpu-profiler.h"
 #include "src/unicode-inl.h"
 #include "src/utils.h"
 #include "src/vm-state.h"
 #include "test/cctest/heap/heap-tester.h"
-#include "test/cctest/heap/utils-inl.h"
+#include "test/cctest/heap/heap-utils.h"
 
 static const bool kLogThreading = false;
 
@@ -555,40 +556,19 @@
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);
 
   uint16_t* two_byte_string = AsciiToTwoByteString("s1");
-  Local<String> small_string =
+  Local<String> local_string =
       String::NewFromTwoByte(env->GetIsolate(), two_byte_string,
                              v8::NewStringType::kNormal)
           .ToLocalChecked();
   i::DeleteArray(two_byte_string);
 
-  // We should refuse to externalize small strings.
-  CHECK(!small_string->CanMakeExternal());
+  // We should refuse to externalize new space strings.
+  CHECK(!local_string->CanMakeExternal());
   // Trigger GCs so that the newly allocated string moves to old gen.
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in survivor space now
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in old gen now
   // Old space strings should be accepted.
-  CHECK(small_string->CanMakeExternal());
-
-  two_byte_string = AsciiToTwoByteString("small string 2");
-  small_string = String::NewFromTwoByte(env->GetIsolate(), two_byte_string,
-                                        v8::NewStringType::kNormal)
-                     .ToLocalChecked();
-  i::DeleteArray(two_byte_string);
-
-  const int buf_size = 10 * 1024;
-  char* buf = i::NewArray<char>(buf_size);
-  memset(buf, 'a', buf_size);
-  buf[buf_size - 1] = '\0';
-
-  two_byte_string = AsciiToTwoByteString(buf);
-  Local<String> large_string =
-      String::NewFromTwoByte(env->GetIsolate(), two_byte_string,
-                             v8::NewStringType::kNormal)
-          .ToLocalChecked();
-  i::DeleteArray(buf);
-  i::DeleteArray(two_byte_string);
-  // Large strings should be immediately accepted.
-  CHECK(large_string->CanMakeExternal());
+  CHECK(local_string->CanMakeExternal());
 }
 
 
@@ -600,23 +580,14 @@
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);
 
-  Local<String> small_string = v8_str("s1");
-  // We should refuse to externalize small strings.
-  CHECK(!small_string->CanMakeExternal());
+  Local<String> local_string = v8_str("s1");
+  // We should refuse to externalize new space strings.
+  CHECK(!local_string->CanMakeExternal());
   // Trigger GCs so that the newly allocated string moves to old gen.
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in survivor space now
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in old gen now
   // Old space strings should be accepted.
-  CHECK(small_string->CanMakeExternal());
-
-  const int buf_size = 10 * 1024;
-  char* buf = i::NewArray<char>(buf_size);
-  memset(buf, 'a', buf_size);
-  buf[buf_size - 1] = '\0';
-  Local<String> large_string = v8_str(buf);
-  i::DeleteArray(buf);
-  // Large strings should be immediately accepted.
-  CHECK(large_string->CanMakeExternal());
+  CHECK(local_string->CanMakeExternal());
 }
 
 
@@ -634,7 +605,7 @@
       "slice('abcdefghijklmnopqrstuvwxyz');"));
 
   // Trigger GCs so that the newly allocated string moves to old gen.
-  SimulateFullSpace(CcTest::heap()->old_space());
+  i::heap::SimulateFullSpace(CcTest::heap()->old_space());
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in survivor space now
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in old gen now
 
@@ -2827,16 +2798,15 @@
   CHECK(env->Global()
             ->Set(env.local(), v8_str("global"), global_proxy)
             .FromJust());
-  i::Handle<i::Object> original_hash;
+  int32_t hash1;
   if (set_in_js) {
     CompileRun("var m = new Set(); m.add(global);");
-    original_hash = i::Handle<i::Object>(i_global_proxy->GetHash(), i_isolate);
+    i::Object* original_hash = i_global_proxy->GetHash();
+    CHECK(original_hash->IsSmi());
+    hash1 = i::Smi::cast(original_hash)->value();
   } else {
-    original_hash = i::Handle<i::Object>(
-        i::Object::GetOrCreateHash(i_isolate, i_global_proxy));
+    hash1 = i::Object::GetOrCreateHash(i_isolate, i_global_proxy)->value();
   }
-  CHECK(original_hash->IsSmi());
-  int32_t hash1 = i::Handle<i::Smi>::cast(original_hash)->value();
   // Hash should be retained after being detached.
   env->DetachGlobal();
   int hash2 = global_proxy->GetIdentityHash();
@@ -13381,7 +13351,7 @@
   value =
       context->Global()->ObjectProtoToString(context.local()).ToLocalChecked();
   CHECK(value->IsString() &&
-        value->Equals(context.local(), v8_str("[object global]")).FromJust());
+        value->Equals(context.local(), v8_str("[object Object]")).FromJust());
 
   // Check ordinary object
   Local<Value> object =
@@ -13427,7 +13397,7 @@
   value =
       context->Global()->ObjectProtoToString(context.local()).ToLocalChecked();
   CHECK(value->IsString() &&
-        value->Equals(context.local(), v8_str("[object global]")).FromJust());
+        value->Equals(context.local(), v8_str("[object Object]")).FromJust());
 
   // Check ordinary object
   Local<Value> object = CompileRun("new Object()");
@@ -14610,9 +14580,8 @@
   test.RunTest();
 }
 
-
-static i::HashMap* code_map = NULL;
-static i::HashMap* jitcode_line_info = NULL;
+static v8::base::HashMap* code_map = NULL;
+static v8::base::HashMap* jitcode_line_info = NULL;
 static int saw_bar = 0;
 static int move_events = 0;
 
@@ -14672,7 +14641,7 @@
         CHECK(event->code_start != NULL);
         CHECK_NE(0, static_cast<int>(event->code_len));
         CHECK(event->name.str != NULL);
-        i::HashMap::Entry* entry = code_map->LookupOrInsert(
+        v8::base::HashMap::Entry* entry = code_map->LookupOrInsert(
             event->code_start, i::ComputePointerHash(event->code_start));
         entry->value = reinterpret_cast<void*>(event->code_len);
 
@@ -14691,7 +14660,8 @@
         // Compiler::RecordFunctionCompilation) and the line endings
         // calculations can cause a GC, which can move the newly created code
         // before its existence can be logged.
-        i::HashMap::Entry* entry = code_map->Lookup(event->code_start, hash);
+        v8::base::HashMap::Entry* entry =
+            code_map->Lookup(event->code_start, hash);
         if (entry != NULL) {
           ++move_events;
 
@@ -14718,7 +14688,7 @@
         DummyJitCodeLineInfo* line_info = new DummyJitCodeLineInfo();
         v8::JitCodeEvent* temp_event = const_cast<v8::JitCodeEvent*>(event);
         temp_event->user_data = line_info;
-        i::HashMap::Entry* entry = jitcode_line_info->LookupOrInsert(
+        v8::base::HashMap::Entry* entry = jitcode_line_info->LookupOrInsert(
             line_info, i::ComputePointerHash(line_info));
         entry->value = reinterpret_cast<void*>(line_info);
       }
@@ -14729,7 +14699,7 @@
     case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: {
         CHECK(event->user_data != NULL);
         uint32_t hash = i::ComputePointerHash(event->user_data);
-        i::HashMap::Entry* entry =
+        v8::base::HashMap::Entry* entry =
             jitcode_line_info->Lookup(event->user_data, hash);
         CHECK(entry != NULL);
         delete reinterpret_cast<DummyJitCodeLineInfo*>(event->user_data);
@@ -14739,7 +14709,7 @@
     case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: {
         CHECK(event->user_data != NULL);
         uint32_t hash = i::ComputePointerHash(event->user_data);
-        i::HashMap::Entry* entry =
+        v8::base::HashMap::Entry* entry =
             jitcode_line_info->Lookup(event->user_data, hash);
         CHECK(entry != NULL);
       }
@@ -14781,10 +14751,10 @@
 
   {
     v8::HandleScope scope(isolate);
-    i::HashMap code(MatchPointers);
+    v8::base::HashMap code(MatchPointers);
     code_map = &code;
 
-    i::HashMap lineinfo(MatchPointers);
+    v8::base::HashMap lineinfo(MatchPointers);
     jitcode_line_info = &lineinfo;
 
     saw_bar = 0;
@@ -14798,8 +14768,8 @@
     for (int i = 0; i < kIterations; ++i) {
       LocalContext env(isolate);
       i::AlwaysAllocateScope always_allocate(i_isolate);
-      SimulateFullSpace(i::FLAG_ignition ? heap->old_space()
-                                         : heap->code_space());
+      i::heap::SimulateFullSpace(i::FLAG_ignition ? heap->old_space()
+                                                  : heap->code_space());
       CompileRun(script);
 
       // Keep a strong reference to the code object in the handle scope.
@@ -14847,10 +14817,10 @@
     CompileRun(script);
 
     // Now get code through initial iteration.
-    i::HashMap code(MatchPointers);
+    v8::base::HashMap code(MatchPointers);
     code_map = &code;
 
-    i::HashMap lineinfo(MatchPointers);
+    v8::base::HashMap lineinfo(MatchPointers);
     jitcode_line_info = &lineinfo;
 
     isolate->SetJitCodeEventHandler(v8::kJitCodeEventEnumExisting,
@@ -14883,8 +14853,7 @@
            isolate->AdjustAmountOfExternalAllocatedMemory(kSize));
   CHECK_EQ(baseline,
            isolate->AdjustAmountOfExternalAllocatedMemory(-kSize));
-  const int64_t kTriggerGCSize =
-      v8::internal::Internals::kExternalAllocationLimit + 1;
+  const int64_t kTriggerGCSize = i::kExternalAllocationLimit + 1;
   CHECK_EQ(baseline + kTriggerGCSize,
            isolate->AdjustAmountOfExternalAllocatedMemory(kTriggerGCSize));
   CHECK_EQ(baseline,
@@ -14896,8 +14865,7 @@
   i::FLAG_incremental_marking = false;
   CcTest::InitializeVM();
 
-  const int64_t kTriggerGCSize =
-      v8::internal::Internals::kExternalAllocationLimit + 1;
+  const int64_t kTriggerGCSize = i::kExternalAllocationLimit + 1;
   v8::Isolate* isolate = CcTest::isolate();
   isolate->AdjustAmountOfExternalAllocatedMemory(kTriggerGCSize);
 }
@@ -15072,18 +15040,39 @@
   CHECK_EQ(1224744689038.0, date.As<v8::Date>()->ValueOf());
 }
 
+void CheckIsSymbolAt(v8::Isolate* isolate, v8::Local<v8::Array> properties,
+                     unsigned index, const char* name) {
+  v8::Local<v8::Context> context = isolate->GetCurrentContext();
+  v8::Local<v8::Value> value =
+      properties->Get(context, v8::Integer::New(isolate, index))
+          .ToLocalChecked();
+  CHECK(value->IsSymbol());
+  v8::String::Utf8Value symbol_name(Local<Symbol>::Cast(value)->Name());
+  CHECK_EQ(0, strcmp(name, *symbol_name));
+}
+
+void CheckStringArray(v8::Isolate* isolate, v8::Local<v8::Array> properties,
+                      unsigned length, const char* names[]) {
+  v8::Local<v8::Context> context = isolate->GetCurrentContext();
+  CHECK_EQ(length, properties->Length());
+  for (unsigned i = 0; i < length; i++) {
+    v8::Local<v8::Value> value =
+        properties->Get(context, v8::Integer::New(isolate, i)).ToLocalChecked();
+    if (names[i] == nullptr) {
+      DCHECK(value->IsSymbol());
+    } else {
+      v8::String::Utf8Value elm(value);
+      CHECK_EQ(0, strcmp(names[i], *elm));
+    }
+  }
+}
 
 void CheckProperties(v8::Isolate* isolate, v8::Local<v8::Value> val,
-                     unsigned elmc, const char* elmv[]) {
+                     unsigned length, const char* names[]) {
   v8::Local<v8::Context> context = isolate->GetCurrentContext();
   v8::Local<v8::Object> obj = val.As<v8::Object>();
   v8::Local<v8::Array> props = obj->GetPropertyNames(context).ToLocalChecked();
-  CHECK_EQ(elmc, props->Length());
-  for (unsigned i = 0; i < elmc; i++) {
-    v8::String::Utf8Value elm(
-        props->Get(context, v8::Integer::New(isolate, i)).ToLocalChecked());
-    CHECK_EQ(0, strcmp(elmv[i], *elm));
-  }
+  CheckStringArray(isolate, props, length, names);
 }
 
 
@@ -15194,6 +15183,97 @@
   }
 }
 
+THREADED_TEST(PropertyNames) {
+  LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
+  v8::HandleScope scope(isolate);
+  v8::Local<v8::Value> result = CompileRun(
+      "var result = {0: 0, 1: 1, a: 2, b: 3};"
+      "result[Symbol('symbol')] = true;"
+      "result.__proto__ = {2: 4, 3: 5, c: 6, d: 7};"
+      "result;");
+  v8::Local<v8::Object> object = result.As<v8::Object>();
+  v8::PropertyFilter default_filter =
+      static_cast<v8::PropertyFilter>(v8::ONLY_ENUMERABLE | v8::SKIP_SYMBOLS);
+  v8::PropertyFilter include_symbols_filter = v8::ONLY_ENUMERABLE;
+
+  v8::Local<v8::Array> properties =
+      object->GetPropertyNames(context.local()).ToLocalChecked();
+  const char* expected_properties1[] = {"0", "1", "a", "b", "2", "3", "c", "d"};
+  CheckStringArray(isolate, properties, 8, expected_properties1);
+
+  properties =
+      object
+          ->GetPropertyNames(context.local(),
+                             v8::KeyCollectionMode::kIncludePrototypes,
+                             default_filter, v8::IndexFilter::kIncludeIndices)
+          .ToLocalChecked();
+  CheckStringArray(isolate, properties, 8, expected_properties1);
+
+  properties = object
+                   ->GetPropertyNames(context.local(),
+                                      v8::KeyCollectionMode::kIncludePrototypes,
+                                      include_symbols_filter,
+                                      v8::IndexFilter::kIncludeIndices)
+                   .ToLocalChecked();
+  const char* expected_properties1_1[] = {"0", "1", "a", "b", nullptr,
+                                          "2", "3", "c", "d"};
+  CheckStringArray(isolate, properties, 9, expected_properties1_1);
+  CheckIsSymbolAt(isolate, properties, 4, "symbol");
+
+  properties =
+      object
+          ->GetPropertyNames(context.local(),
+                             v8::KeyCollectionMode::kIncludePrototypes,
+                             default_filter, v8::IndexFilter::kSkipIndices)
+          .ToLocalChecked();
+  const char* expected_properties2[] = {"a", "b", "c", "d"};
+  CheckStringArray(isolate, properties, 4, expected_properties2);
+
+  properties = object
+                   ->GetPropertyNames(context.local(),
+                                      v8::KeyCollectionMode::kIncludePrototypes,
+                                      include_symbols_filter,
+                                      v8::IndexFilter::kSkipIndices)
+                   .ToLocalChecked();
+  const char* expected_properties2_1[] = {"a", "b", nullptr, "c", "d"};
+  CheckStringArray(isolate, properties, 5, expected_properties2_1);
+  CheckIsSymbolAt(isolate, properties, 2, "symbol");
+
+  properties =
+      object
+          ->GetPropertyNames(context.local(), v8::KeyCollectionMode::kOwnOnly,
+                             default_filter, v8::IndexFilter::kIncludeIndices)
+          .ToLocalChecked();
+  const char* expected_properties3[] = {"0", "1", "a", "b"};
+  CheckStringArray(isolate, properties, 4, expected_properties3);
+
+  properties = object
+                   ->GetPropertyNames(
+                       context.local(), v8::KeyCollectionMode::kOwnOnly,
+                       include_symbols_filter, v8::IndexFilter::kIncludeIndices)
+                   .ToLocalChecked();
+  const char* expected_properties3_1[] = {"0", "1", "a", "b", nullptr};
+  CheckStringArray(isolate, properties, 5, expected_properties3_1);
+  CheckIsSymbolAt(isolate, properties, 4, "symbol");
+
+  properties =
+      object
+          ->GetPropertyNames(context.local(), v8::KeyCollectionMode::kOwnOnly,
+                             default_filter, v8::IndexFilter::kSkipIndices)
+          .ToLocalChecked();
+  const char* expected_properties4[] = {"a", "b"};
+  CheckStringArray(isolate, properties, 2, expected_properties4);
+
+  properties = object
+                   ->GetPropertyNames(
+                       context.local(), v8::KeyCollectionMode::kOwnOnly,
+                       include_symbols_filter, v8::IndexFilter::kSkipIndices)
+                   .ToLocalChecked();
+  const char* expected_properties4_1[] = {"a", "b", nullptr};
+  CheckStringArray(isolate, properties, 3, expected_properties4_1);
+  CheckIsSymbolAt(isolate, properties, 2, "symbol");
+}
 
 THREADED_TEST(AccessChecksReenabledCorrectly) {
   LocalContext context;
@@ -18462,7 +18542,6 @@
 
 
 THREADED_TEST(FunctionGetDebugName) {
-  i::FLAG_harmony_function_name = true;
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());
   const char* code =
@@ -19001,7 +19080,7 @@
   ++prologue_call_count_alloc;
 
   // Simulate full heap to see if we will reenter this callback
-  SimulateFullSpace(CcTest::heap()->new_space());
+  i::heap::SimulateFullSpace(CcTest::heap()->new_space());
 
   Local<Object> obj = Object::New(isolate);
   CHECK(!obj.IsEmpty());
@@ -19021,7 +19100,7 @@
   ++epilogue_call_count_alloc;
 
   // Simulate full heap to see if we will reenter this callback
-  SimulateFullSpace(CcTest::heap()->new_space());
+  i::heap::SimulateFullSpace(CcTest::heap()->new_space());
 
   Local<Object> obj = Object::New(isolate);
   CHECK(!obj.IsEmpty());
@@ -19997,7 +20076,6 @@
 
 
 TEST(RegExp) {
-  i::FLAG_harmony_unicode_regexps = true;
   LocalContext context;
   v8::HandleScope scope(context->GetIsolate());
 
@@ -21375,14 +21453,17 @@
   env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
 }
 
-
 #ifdef ENABLE_DISASSEMBLER
-static int probes_counter = 0;
-static int misses_counter = 0;
-static int updates_counter = 0;
+// FLAG_test_primary_stub_cache and FLAG_test_secondary_stub_cache are read
+// only when ENABLE_DISASSEMBLER is not defined.
 
+namespace {
 
-static int* LookupCounter(const char* name) {
+int probes_counter = 0;
+int misses_counter = 0;
+int updates_counter = 0;
+
+int* LookupCounter(const char* name) {
   if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) {
     return &probes_counter;
   } else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) {
@@ -21393,24 +21474,28 @@
   return NULL;
 }
 
+const char* kMegamorphicTestProgram =
+    "function CreateClass(name) {\n"
+    "  var src = \n"
+    "    `  function ${name}() {};` +\n"
+    "    `  ${name}.prototype.foo = function() {};` +\n"
+    "    `  ${name};\\n`;\n"
+    "  return (0, eval)(src);\n"
+    "}\n"
+    "function fooify(obj) { obj.foo(); };\n"
+    "var objs = [];\n"
+    "for (var i = 0; i < 6; i++) {\n"
+    "  var Class = CreateClass('Class' + i);\n"
+    "  var obj = new Class();\n"
+    "  objs.push(obj);\n"
+    "}\n"
+    "for (var i = 0; i < 10000; i++) {\n"
+    "  for (var obj of objs) {\n"
+    "    fooify(obj);\n"
+    "  }\n"
+    "}\n";
 
-static const char* kMegamorphicTestProgram =
-    "function ClassA() { };"
-    "function ClassB() { };"
-    "ClassA.prototype.foo = function() { };"
-    "ClassB.prototype.foo = function() { };"
-    "function fooify(obj) { obj.foo(); };"
-    "var a = new ClassA();"
-    "var b = new ClassB();"
-    "for (var i = 0; i < 10000; i++) {"
-    "  fooify(a);"
-    "  fooify(b);"
-    "}";
-#endif
-
-
-static void StubCacheHelper(bool primary) {
-#ifdef ENABLE_DISASSEMBLER
+void StubCacheHelper(bool primary) {
   i::FLAG_native_code_counters = true;
   if (primary) {
     i::FLAG_test_primary_stub_cache = true;
@@ -21418,36 +21503,47 @@
     i::FLAG_test_secondary_stub_cache = true;
   }
   i::FLAG_crankshaft = false;
-  LocalContext env;
-  env->GetIsolate()->SetCounterFunction(LookupCounter);
-  v8::HandleScope scope(env->GetIsolate());
-  int initial_probes = probes_counter;
-  int initial_misses = misses_counter;
-  int initial_updates = updates_counter;
-  CompileRun(kMegamorphicTestProgram);
-  int probes = probes_counter - initial_probes;
-  int misses = misses_counter - initial_misses;
-  int updates = updates_counter - initial_updates;
-  CHECK_LT(updates, 10);
-  CHECK_LT(misses, 10);
-  // TODO(verwaest): Update this test to overflow the degree of polymorphism
-  // before megamorphism. The number of probes will only work once we teach the
-  // serializer to embed references to counters in the stubs, given that the
-  // megamorphic_stub_cache_probes is updated in a snapshot-generated stub.
-  CHECK_GE(probes, 0);
-#endif
+  i::FLAG_turbo = false;
+  v8::Isolate::CreateParams create_params;
+  create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+  create_params.counter_lookup_callback = LookupCounter;
+  v8::Isolate* isolate = v8::Isolate::New(create_params);
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+
+  if (!i_isolate->snapshot_available()) {
+    // The test is valid only for no-snapshot mode.
+    v8::Isolate::Scope isolate_scope(isolate);
+    LocalContext env(isolate);
+    v8::HandleScope scope(isolate);
+
+    int initial_probes = probes_counter;
+    int initial_misses = misses_counter;
+    int initial_updates = updates_counter;
+    CompileRun(kMegamorphicTestProgram);
+    int probes = probes_counter - initial_probes;
+    int misses = misses_counter - initial_misses;
+    int updates = updates_counter - initial_updates;
+    const int kClassesCount = 6;
+    // Check that updates and misses counts are bounded.
+    CHECK_LE(kClassesCount, updates);
+    CHECK_LT(updates, kClassesCount * 3);
+    CHECK_LE(1, misses);
+    CHECK_LT(misses, kClassesCount * 2);
+    // 2 is for PREMONOMORPHIC and MONOMORPHIC states,
+    // 4 is for POLYMORPHIC states,
+    // and all the others probes are for MEGAMORPHIC state.
+    CHECK_EQ(10000 * kClassesCount - 2 - 4, probes);
+  }
+  isolate->Dispose();
 }
 
+}  // namespace
 
-TEST(SecondaryStubCache) {
-  StubCacheHelper(true);
-}
+UNINITIALIZED_TEST(PrimaryStubCache) { StubCacheHelper(true); }
 
+UNINITIALIZED_TEST(SecondaryStubCache) { StubCacheHelper(false); }
 
-TEST(PrimaryStubCache) {
-  StubCacheHelper(false);
-}
-
+#endif  // ENABLE_DISASSEMBLER
 
 #ifdef DEBUG
 static int cow_arrays_created_runtime = 0;
@@ -22053,6 +22149,20 @@
   ExpectString("JSON.stringify(obj)", *utf8);
 }
 
+THREADED_TEST(JSONStringifyObjectWithGap) {
+  LocalContext context;
+  HandleScope scope(context->GetIsolate());
+  Local<Value> value =
+      v8::JSON::Parse(context.local(), v8_str("{\"x\":42}")).ToLocalChecked();
+  Local<Object> obj = value->ToObject(context.local()).ToLocalChecked();
+  Local<Object> global = context->Global();
+  global->Set(context.local(), v8_str("obj"), obj).FromJust();
+  Local<String> json =
+      v8::JSON::Stringify(context.local(), obj, v8_str("*")).ToLocalChecked();
+  v8::String::Utf8Value utf8(json);
+  ExpectString("JSON.stringify(obj, null,  '*')", *utf8);
+}
+
 #if V8_OS_POSIX && !V8_OS_NACL
 class ThreadInterruptTest {
  public:
@@ -23413,6 +23523,88 @@
   CHECK_EQ(13, line_number);
 }
 
+TEST(ScriptPositionInfo) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  const char* url = "http://www.foo.com/foo.js";
+  v8::ScriptOrigin origin(v8_str(url), v8::Integer::New(isolate, 13));
+  v8::ScriptCompiler::Source script_source(v8_str("var foo;\n"
+                                                  "var bar;\n"
+                                                  "var fisk = foo + bar;\n"),
+                                           origin);
+  Local<Script> script =
+      v8::ScriptCompiler::Compile(env.local(), &script_source).ToLocalChecked();
+
+  i::Handle<i::SharedFunctionInfo> obj = i::Handle<i::SharedFunctionInfo>::cast(
+      v8::Utils::OpenHandle(*script->GetUnboundScript()));
+  CHECK(obj->script()->IsScript());
+
+  i::Handle<i::Script> script1(i::Script::cast(obj->script()));
+
+  v8::internal::Script::PositionInfo info;
+
+  // With offset.
+
+  // Behave as if 0 was passed if position is negative.
+  CHECK(script1->GetPositionInfo(-1, &info, script1->WITH_OFFSET));
+  CHECK_EQ(13, info.line);
+  CHECK_EQ(0, info.column);
+  CHECK_EQ(0, info.line_start);
+  CHECK_EQ(8, info.line_end);
+
+  CHECK(script1->GetPositionInfo(0, &info, script1->WITH_OFFSET));
+  CHECK_EQ(13, info.line);
+  CHECK_EQ(0, info.column);
+  CHECK_EQ(0, info.line_start);
+  CHECK_EQ(8, info.line_end);
+
+  CHECK(script1->GetPositionInfo(8, &info, script1->WITH_OFFSET));
+  CHECK_EQ(13, info.line);
+  CHECK_EQ(8, info.column);
+  CHECK_EQ(0, info.line_start);
+  CHECK_EQ(8, info.line_end);
+
+  CHECK(script1->GetPositionInfo(9, &info, script1->WITH_OFFSET));
+  CHECK_EQ(14, info.line);
+  CHECK_EQ(0, info.column);
+  CHECK_EQ(9, info.line_start);
+  CHECK_EQ(17, info.line_end);
+
+  // Fail when position is larger than script size.
+  CHECK(!script1->GetPositionInfo(220384, &info, script1->WITH_OFFSET));
+
+  // Without offset.
+
+  // Behave as if 0 was passed if position is negative.
+  CHECK(script1->GetPositionInfo(-1, &info, script1->NO_OFFSET));
+  CHECK_EQ(0, info.line);
+  CHECK_EQ(0, info.column);
+  CHECK_EQ(0, info.line_start);
+  CHECK_EQ(8, info.line_end);
+
+  CHECK(script1->GetPositionInfo(0, &info, script1->NO_OFFSET));
+  CHECK_EQ(0, info.line);
+  CHECK_EQ(0, info.column);
+  CHECK_EQ(0, info.line_start);
+  CHECK_EQ(8, info.line_end);
+
+  CHECK(script1->GetPositionInfo(8, &info, script1->NO_OFFSET));
+  CHECK_EQ(0, info.line);
+  CHECK_EQ(8, info.column);
+  CHECK_EQ(0, info.line_start);
+  CHECK_EQ(8, info.line_end);
+
+  CHECK(script1->GetPositionInfo(9, &info, script1->NO_OFFSET));
+  CHECK_EQ(1, info.line);
+  CHECK_EQ(0, info.column);
+  CHECK_EQ(9, info.line_start);
+  CHECK_EQ(17, info.line_end);
+
+  // Fail when position is larger than script size.
+  CHECK(!script1->GetPositionInfo(220384, &info, script1->NO_OFFSET));
+}
+
 void CheckMagicComments(Local<Script> script, const char* expected_source_url,
                         const char* expected_source_mapping_url) {
   if (expected_source_url != NULL) {