Merge cherrypicks of [6714499, 6716593, 6716594, 6716595, 6716596, 6716597, 6716977, 6718226, 6717773, 6716978, 6717663] into oc-m8-release

Change-Id: Idfbfb5f585853ef9055e044915146da53838e235
diff --git a/src/ast/ast-numbering.cc b/src/ast/ast-numbering.cc
index 499760d..811bd33 100644
--- a/src/ast/ast-numbering.cc
+++ b/src/ast/ast-numbering.cc
@@ -616,6 +616,8 @@
   if (statements == NULL) return;
   for (int i = 0; i < statements->length(); i++) {
     Visit(statements->at(i));
+    if (statements->at(i)->IsJump())
+        break;
   }
 }
 
diff --git a/src/builtins/builtins-string.cc b/src/builtins/builtins-string.cc
index 7cef567..04be7a3 100644
--- a/src/builtins/builtins-string.cc
+++ b/src/builtins/builtins-string.cc
@@ -139,6 +139,7 @@
   typedef std::function<Node*()> NodeFunction0;
   typedef std::function<Node*(Node* fn)> NodeFunction1;
   void MaybeCallFunctionAtSymbol(Node* const context, Node* const object,
+                                 Node* const maybe_string,
                                  Handle<Symbol> symbol,
                                  const NodeFunction0& regexp_call,
                                  const NodeFunction1& generic_call);
@@ -1189,8 +1190,9 @@
 }
 
 void StringBuiltinsAssembler::MaybeCallFunctionAtSymbol(
-    Node* const context, Node* const object, Handle<Symbol> symbol,
-    const NodeFunction0& regexp_call, const NodeFunction1& generic_call) {
+    Node* const context, Node* const object, Node* const maybe_string,
+    Handle<Symbol> symbol, const NodeFunction0& regexp_call,
+    const NodeFunction1& generic_call) {
   Label out(this);
 
   // Smis definitely don't have an attached symbol.
@@ -1220,9 +1222,15 @@
   }
 
   // Take the fast path for RegExps.
+  // There's two conditions: {object} needs to be a fast regexp, and
+  // {maybe_string} must be a string (we can't call ToString on the fast path
+  // since it may mutate {object}).
   {
     Label stub_call(this), slow_lookup(this);
 
+    GotoIf(TaggedIsSmi(maybe_string), &slow_lookup);
+    GotoIfNot(IsString(maybe_string), &slow_lookup);
+
     RegExpBuiltinsAssembler regexp_asm(state());
     regexp_asm.BranchIfFastRegExp(context, object, object_map, &stub_call,
                                   &slow_lookup);
@@ -1267,7 +1275,7 @@
   // Redirect to replacer method if {search[@@replace]} is not undefined.
 
   MaybeCallFunctionAtSymbol(
-      context, search, isolate()->factory()->replace_symbol(),
+      context, search, receiver, isolate()->factory()->replace_symbol(),
       [=]() {
         Callable tostring_callable = CodeFactory::ToString(isolate());
         Node* const subject_string =
@@ -1435,7 +1443,7 @@
   // Redirect to splitter method if {separator[@@split]} is not undefined.
 
   MaybeCallFunctionAtSymbol(
-      context, separator, isolate()->factory()->split_symbol(),
+      context, separator, receiver, isolate()->factory()->split_symbol(),
       [=]() {
         Callable tostring_callable = CodeFactory::ToString(isolate());
         Node* const subject_string =
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
index 8fef2f0..d563e1d 100644
--- a/src/compiler/access-info.cc
+++ b/src/compiler/access-info.cc
@@ -231,7 +231,8 @@
   MapTransitionList transitions(maps.length());
   for (Handle<Map> map : maps) {
     if (Map::TryUpdate(map).ToHandle(&map)) {
-      Map* transition_target =
+      Map* transition_target = map->is_stable() ?
+          nullptr :
           map->FindElementsKindTransitionedMap(&possible_transition_targets);
       if (transition_target == nullptr) {
         receiver_maps.Add(map);
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index ed1a04a..09003ca 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -1431,7 +1431,7 @@
           return Type::String();
         case kStringIndexOf:
         case kStringLastIndexOf:
-          return Type::Range(-1.0, String::kMaxLength - 1.0, t->zone());
+          return Type::Range(-1.0, String::kMaxLength, t->zone());
         case kStringEndsWith:
         case kStringIncludes:
           return Type::Boolean();
diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
index d55bb37..df7b02f 100644
--- a/src/crankshaft/hydrogen.cc
+++ b/src/crankshaft/hydrogen.cc
@@ -7176,7 +7176,8 @@
   // Get transition target for each map (NULL == no transition).
   for (int i = 0; i < maps->length(); ++i) {
     Handle<Map> map = maps->at(i);
-    Map* transitioned_map =
+    Map* transitioned_map = map->is_stable() ?
+        nullptr :
         map->FindElementsKindTransitionedMap(&possible_transitioned_maps);
     if (transitioned_map != nullptr) {
       transition_target.Add(handle(transitioned_map));
diff --git a/src/objects.cc b/src/objects.cc
index 9f9a628..d5b7777 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -12670,6 +12670,53 @@
   map->StartInobjectSlackTracking();
 }
 
+namespace {
+bool FastInitializeDerivedMap(Isolate* isolate, Handle<JSFunction> new_target,
+                              Handle<JSFunction> constructor,
+                              Handle<Map> constructor_initial_map) {
+  // Check that |function|'s initial map still in sync with the |constructor|,
+  // otherwise we must create a new initial map for |function|.
+  if (new_target->has_initial_map() &&
+      new_target->initial_map()->GetConstructor() == *constructor) {
+    DCHECK(new_target->instance_prototype()->IsJSReceiver());
+    return true;
+  }
+  // Create a new map with the size and number of in-object properties
+  // suggested by |function|.
+
+  // Link initial map and constructor function if the new.target is actually a
+  // subclass constructor.
+  if (!IsDerivedConstructor(new_target->shared()->kind())) return false;
+
+  Handle<Object> prototype(new_target->instance_prototype(), isolate);
+  InstanceType instance_type = constructor_initial_map->instance_type();
+  DCHECK(CanSubclassHaveInobjectProperties(instance_type));
+
+  int internal_fields =
+      JSObject::GetInternalFieldCount(*constructor_initial_map);
+  int pre_allocated = constructor_initial_map->GetInObjectProperties() -
+                      constructor_initial_map->unused_property_fields();
+  int instance_size;
+  int in_object_properties;
+  new_target->CalculateInstanceSizeForDerivedClass(
+      instance_type, internal_fields, &instance_size,
+      &in_object_properties);
+
+  int unused_property_fields = in_object_properties - pre_allocated;
+  Handle<Map> map =
+      Map::CopyInitialMap(constructor_initial_map, instance_size,
+                          in_object_properties, unused_property_fields);
+  map->set_new_target_is_base(false);
+
+  JSFunction::SetInitialMap(new_target, map, prototype);
+  map->SetConstructor(*constructor);
+  map->set_construction_counter(Map::kNoSlackTracking);
+  map->StartInobjectSlackTracking();
+
+  return true;
+}
+
+}  // namespace
 
 // static
 MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
@@ -12688,42 +12735,10 @@
 
     // Check that |function|'s initial map still in sync with the |constructor|,
     // otherwise we must create a new initial map for |function|.
-    if (function->has_initial_map() &&
-        function->initial_map()->GetConstructor() == *constructor) {
+    if (FastInitializeDerivedMap(isolate, function, constructor,
+                                 constructor_initial_map)) {
       return handle(function->initial_map(), isolate);
     }
-
-    // Create a new map with the size and number of in-object properties
-    // suggested by |function|.
-
-    // Link initial map and constructor function if the new.target is actually a
-    // subclass constructor.
-    if (IsDerivedConstructor(function->shared()->kind())) {
-      Handle<Object> prototype(function->instance_prototype(), isolate);
-      InstanceType instance_type = constructor_initial_map->instance_type();
-      DCHECK(CanSubclassHaveInobjectProperties(instance_type));
-      int internal_fields =
-          JSObject::GetInternalFieldCount(*constructor_initial_map);
-      int pre_allocated = constructor_initial_map->GetInObjectProperties() -
-                          constructor_initial_map->unused_property_fields();
-      int instance_size;
-      int in_object_properties;
-      function->CalculateInstanceSizeForDerivedClass(
-          instance_type, internal_fields, &instance_size,
-          &in_object_properties);
-
-      int unused_property_fields = in_object_properties - pre_allocated;
-      Handle<Map> map =
-          Map::CopyInitialMap(constructor_initial_map, instance_size,
-                              in_object_properties, unused_property_fields);
-      map->set_new_target_is_base(false);
-
-      JSFunction::SetInitialMap(function, map, prototype);
-      map->SetConstructor(*constructor);
-      map->set_construction_counter(Map::kNoSlackTracking);
-      map->StartInobjectSlackTracking();
-      return map;
-    }
   }
 
   // Slow path, new.target is either a proxy or can't cache the map.
@@ -13371,15 +13386,17 @@
                                              int* instance_size,
                                              int* in_object_properties) {
   int header_size = JSObject::GetHeaderSize(instance_type);
-  DCHECK_LE(requested_internal_fields,
-            (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2);
+  int max_nof_fields =
+      (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2;
+  CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties);
+  *in_object_properties = Min(requested_in_object_properties, max_nof_fields);
+  CHECK_LE(requested_internal_fields, max_nof_fields - *in_object_properties);
   *instance_size =
-      Min(header_size +
-              ((requested_internal_fields + requested_in_object_properties)
-               << kPointerSizeLog2),
-          JSObject::kMaxInstanceSize);
-  *in_object_properties = ((*instance_size - header_size) >> kPointerSizeLog2) -
-                          requested_internal_fields;
+      header_size +
+      ((requested_internal_fields + *in_object_properties) << kPointerSizeLog2);
+  CHECK_EQ(*in_object_properties,
+           ((*instance_size - header_size) >> kPointerSizeLog2) -
+               requested_internal_fields);
 }
 
 
@@ -13404,7 +13421,13 @@
     if (!current->IsJSFunction()) break;
     JSFunction* func = JSFunction::cast(current);
     SharedFunctionInfo* shared = func->shared();
-    expected_nof_properties += shared->expected_nof_properties();
+    int count = shared->expected_nof_properties();
+    // Check that the estimate is sane.
+    if (expected_nof_properties <= JSObject::kMaxInObjectProperties - count) {
+      expected_nof_properties += count;
+    } else {
+      expected_nof_properties = JSObject::kMaxInObjectProperties;
+    }
     if (!IsDerivedConstructor(shared->kind())) {
       break;
     }
diff --git a/src/objects.h b/src/objects.h
index 04d3d38..289f5fc 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2544,6 +2544,9 @@
   static const int kHeaderSize = kElementsOffset + kPointerSize;
 
   STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
+  static const int kMaxInObjectProperties =
+      (kMaxInstanceSize - kHeaderSize) >> kPointerSizeLog2;
+  STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors);
 
   typedef FlexibleBodyDescriptor<JSReceiver::kPropertiesOffset> BodyDescriptor;