Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE

This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.

FPIIM-449

Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/src/api-natives.cc b/src/api-natives.cc
index bc71e3e..3be2df0 100644
--- a/src/api-natives.cc
+++ b/src/api-natives.cc
@@ -16,8 +16,8 @@
 namespace {
 
 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
-                                        Handle<ObjectTemplateInfo> data);
-
+                                        Handle<ObjectTemplateInfo> data,
+                                        bool is_hidden_prototype);
 
 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
                                             Handle<FunctionTemplateInfo> data,
@@ -30,32 +30,36 @@
     return InstantiateFunction(isolate,
                                Handle<FunctionTemplateInfo>::cast(data), name);
   } else if (data->IsObjectTemplateInfo()) {
-    return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data));
+    return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data),
+                             false);
   } else {
     return data;
   }
 }
 
-
-MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
-                                           Handle<JSObject> object,
-                                           Handle<Name> name,
-                                           Handle<Object> getter,
-                                           Handle<Object> setter,
-                                           PropertyAttributes attributes) {
-  if (!getter->IsUndefined()) {
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate, getter,
-        InstantiateFunction(isolate,
-                            Handle<FunctionTemplateInfo>::cast(getter)),
-        Object);
-  }
-  if (!setter->IsUndefined()) {
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate, setter,
-        InstantiateFunction(isolate,
-                            Handle<FunctionTemplateInfo>::cast(setter)),
-        Object);
+MaybeHandle<Object> DefineAccessorProperty(
+    Isolate* isolate, Handle<JSObject> object, Handle<Name> name,
+    Handle<Object> getter, Handle<Object> setter, PropertyAttributes attributes,
+    bool force_instantiate) {
+  DCHECK(!getter->IsFunctionTemplateInfo() ||
+         !FunctionTemplateInfo::cast(*getter)->do_not_cache());
+  DCHECK(!setter->IsFunctionTemplateInfo() ||
+         !FunctionTemplateInfo::cast(*setter)->do_not_cache());
+  if (force_instantiate) {
+    if (getter->IsFunctionTemplateInfo()) {
+      ASSIGN_RETURN_ON_EXCEPTION(
+          isolate, getter,
+          InstantiateFunction(isolate,
+                              Handle<FunctionTemplateInfo>::cast(getter)),
+          Object);
+    }
+    if (setter->IsFunctionTemplateInfo()) {
+      ASSIGN_RETURN_ON_EXCEPTION(
+          isolate, setter,
+          InstantiateFunction(isolate,
+                              Handle<FunctionTemplateInfo>::cast(setter)),
+          Object);
+    }
   }
   RETURN_ON_EXCEPTION(isolate, JSObject::DefineAccessor(object, name, getter,
                                                         setter, attributes),
@@ -148,17 +152,78 @@
   return nullptr;
 }
 
+// Returns parent function template or null.
+FunctionTemplateInfo* GetParent(FunctionTemplateInfo* data) {
+  Object* parent = data->parent_template();
+  return parent->IsUndefined() ? nullptr : FunctionTemplateInfo::cast(parent);
+}
 
+// Starting from given object template's constructor walk up the inheritance
+// chain till a function template that has an instance template is found.
+ObjectTemplateInfo* GetParent(ObjectTemplateInfo* data) {
+  Object* maybe_ctor = data->constructor();
+  if (maybe_ctor->IsUndefined()) return nullptr;
+  FunctionTemplateInfo* ctor = FunctionTemplateInfo::cast(maybe_ctor);
+  while (true) {
+    ctor = GetParent(ctor);
+    if (ctor == nullptr) return nullptr;
+    Object* maybe_obj = ctor->instance_template();
+    if (!maybe_obj->IsUndefined()) return ObjectTemplateInfo::cast(maybe_obj);
+  }
+}
+
+template <typename TemplateInfoT>
 MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
-                                        Handle<TemplateInfo> data) {
+                                        Handle<TemplateInfoT> data,
+                                        bool is_hidden_prototype) {
+  HandleScope scope(isolate);
+  // Disable access checks while instantiating the object.
+  AccessCheckDisableScope access_check_scope(isolate, obj);
+
+  // Walk the inheritance chain and copy all accessors to current object.
+  int max_number_of_properties = 0;
+  TemplateInfoT* info = *data;
+  while (info != nullptr) {
+    if (!info->property_accessors()->IsUndefined()) {
+      Object* props = info->property_accessors();
+      if (!props->IsUndefined()) {
+        Handle<Object> props_handle(props, isolate);
+        NeanderArray props_array(props_handle);
+        max_number_of_properties += props_array.length();
+      }
+    }
+    info = GetParent(info);
+  }
+
+  if (max_number_of_properties > 0) {
+    int valid_descriptors = 0;
+    // Use a temporary FixedArray to accumulate unique accessors.
+    Handle<FixedArray> array =
+        isolate->factory()->NewFixedArray(max_number_of_properties);
+
+    info = *data;
+    while (info != nullptr) {
+      // Accumulate accessors.
+      if (!info->property_accessors()->IsUndefined()) {
+        Handle<Object> props(info->property_accessors(), isolate);
+        valid_descriptors =
+            AccessorInfo::AppendUnique(props, array, valid_descriptors);
+      }
+      info = GetParent(info);
+    }
+
+    // Install accumulated accessors.
+    for (int i = 0; i < valid_descriptors; i++) {
+      Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i)));
+      JSObject::SetAccessor(obj, accessor).Assert();
+    }
+  }
+
   auto property_list = handle(data->property_list(), isolate);
   if (property_list->IsUndefined()) return obj;
   // TODO(dcarney): just use a FixedArray here.
   NeanderArray properties(property_list);
   if (properties.length() == 0) return obj;
-  HandleScope scope(isolate);
-  // Disable access checks while instantiating the object.
-  AccessCheckDisableScope access_check_scope(isolate, obj);
 
   int i = 0;
   for (int c = 0; c < data->number_of_properties(); c++) {
@@ -171,17 +236,16 @@
 
       if (kind == kData) {
         auto prop_data = handle(properties.get(i++), isolate);
-
         RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name,
                                                         prop_data, attributes),
                             JSObject);
       } else {
         auto getter = handle(properties.get(i++), isolate);
         auto setter = handle(properties.get(i++), isolate);
-        RETURN_ON_EXCEPTION(isolate,
-                            DefineAccessorProperty(isolate, obj, name, getter,
-                                                   setter, attributes),
-                            JSObject);
+        RETURN_ON_EXCEPTION(
+            isolate, DefineAccessorProperty(isolate, obj, name, getter, setter,
+                                            attributes, is_hidden_prototype),
+            JSObject);
       }
     } else {
       // Intrinsic data property --- Get appropriate value from the current
@@ -202,14 +266,28 @@
   return obj;
 }
 
+void CacheTemplateInstantiation(Isolate* isolate, Handle<Smi> serial_number,
+                                Handle<JSObject> object) {
+  auto cache = isolate->template_instantiations_cache();
+  auto new_cache = ObjectHashTable::Put(cache, serial_number, object);
+  isolate->native_context()->set_template_instantiations_cache(*new_cache);
+}
+
+void UncacheTemplateInstantiation(Isolate* isolate, Handle<Smi> serial_number) {
+  auto cache = isolate->template_instantiations_cache();
+  bool was_present = false;
+  auto new_cache = ObjectHashTable::Remove(cache, serial_number, &was_present);
+  DCHECK(was_present);
+  isolate->native_context()->set_template_instantiations_cache(*new_cache);
+}
 
 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
-                                        Handle<ObjectTemplateInfo> data) {
+                                        Handle<ObjectTemplateInfo> info,
+                                        bool is_hidden_prototype) {
   // Enter a new scope.  Recursion could otherwise create a lot of handles.
   HandleScope scope(isolate);
   // Fast path.
   Handle<JSObject> result;
-  auto info = Handle<ObjectTemplateInfo>::cast(data);
   auto constructor = handle(info->constructor(), isolate);
   Handle<JSFunction> cons;
   if (constructor->IsUndefined()) {
@@ -219,39 +297,42 @@
     ASSIGN_RETURN_ON_EXCEPTION(
         isolate, cons, InstantiateFunction(isolate, cons_templ), JSFunction);
   }
+  auto serial_number = handle(Smi::cast(info->serial_number()), isolate);
+  if (serial_number->value()) {
+    // Probe cache.
+    auto cache = isolate->template_instantiations_cache();
+    Object* boilerplate = cache->Lookup(serial_number);
+    if (boilerplate->IsJSObject()) {
+      result = handle(JSObject::cast(boilerplate), isolate);
+      ASSIGN_RETURN_ON_EXCEPTION(
+          isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject);
+      return scope.CloseAndEscape(result);
+    }
+  }
   auto object = isolate->factory()->NewJSObject(cons);
   ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, result, ConfigureInstance(isolate, object, info), JSFunction);
+      isolate, result,
+      ConfigureInstance(isolate, object, info, is_hidden_prototype),
+      JSFunction);
   // TODO(dcarney): is this necessary?
   JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject");
+
+  if (serial_number->value()) {
+    CacheTemplateInstantiation(isolate, serial_number, result);
+    ASSIGN_RETURN_ON_EXCEPTION(
+        isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject);
+  }
   return scope.CloseAndEscape(result);
 }
 
 
-void CacheFunction(Isolate* isolate, Handle<Smi> serial_number,
-                   Handle<JSFunction> function) {
-  auto cache = isolate->function_cache();
-  auto new_cache = ObjectHashTable::Put(cache, serial_number, function);
-  isolate->native_context()->set_function_cache(*new_cache);
-}
-
-
-void UncacheFunction(Isolate* isolate, Handle<Smi> serial_number) {
-  auto cache = isolate->function_cache();
-  bool was_present = false;
-  auto new_cache = ObjectHashTable::Remove(cache, serial_number, &was_present);
-  DCHECK(was_present);
-  isolate->native_context()->set_function_cache(*new_cache);
-}
-
-
 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
                                             Handle<FunctionTemplateInfo> data,
                                             Handle<Name> name) {
   auto serial_number = handle(Smi::cast(data->serial_number()), isolate);
-  // Probe cache.
-  if (!data->do_not_cache()) {
-    auto cache = isolate->function_cache();
+  if (serial_number->value()) {
+    // Probe cache.
+    auto cache = isolate->template_instantiations_cache();
     Object* element = cache->Lookup(serial_number);
     if (element->IsJSFunction()) {
       return handle(JSFunction::cast(element), isolate);
@@ -268,7 +349,8 @@
       ASSIGN_RETURN_ON_EXCEPTION(
           isolate, prototype,
           InstantiateObject(isolate,
-                            Handle<ObjectTemplateInfo>::cast(prototype_templ)),
+                            Handle<ObjectTemplateInfo>::cast(prototype_templ),
+                            data->hidden_prototype()),
           JSFunction);
     }
     auto parent = handle(data->parent_template(), isolate);
@@ -296,15 +378,16 @@
   if (!name.is_null() && name->IsString()) {
     function->shared()->set_name(*name);
   }
-  if (!data->do_not_cache()) {
+  if (serial_number->value()) {
     // Cache the function.
-    CacheFunction(isolate, serial_number, function);
+    CacheTemplateInstantiation(isolate, serial_number, function);
   }
-  auto result = ConfigureInstance(isolate, function, data);
+  auto result =
+      ConfigureInstance(isolate, function, data, data->hidden_prototype());
   if (result.is_null()) {
     // Uncache on error.
-    if (!data->do_not_cache()) {
-      UncacheFunction(isolate, serial_number);
+    if (serial_number->value()) {
+      UncacheTemplateInstantiation(isolate, serial_number);
     }
     return MaybeHandle<JSFunction>();
   }
@@ -364,23 +447,7 @@
     Handle<ObjectTemplateInfo> data) {
   Isolate* isolate = data->GetIsolate();
   InvokeScope invoke_scope(isolate);
-  return ::v8::internal::InstantiateObject(isolate, data);
-}
-
-
-MaybeHandle<FunctionTemplateInfo> ApiNatives::ConfigureInstance(
-    Isolate* isolate, Handle<FunctionTemplateInfo> desc,
-    Handle<JSObject> instance) {
-  // Configure the instance by adding the properties specified by the
-  // instance template.
-  if (desc->instance_template()->IsUndefined()) return desc;
-  InvokeScope invoke_scope(isolate);
-  Handle<ObjectTemplateInfo> instance_template(
-      ObjectTemplateInfo::cast(desc->instance_template()), isolate);
-  RETURN_ON_EXCEPTION(isolate, ::v8::internal::ConfigureInstance(
-                                   isolate, instance, instance_template),
-                      FunctionTemplateInfo);
-  return desc;
+  return ::v8::internal::InstantiateObject(isolate, data, false);
 }
 
 
@@ -527,11 +594,6 @@
     map->set_is_undetectable();
   }
 
-  // Mark as hidden for the __proto__ accessor if needed.
-  if (obj->hidden_prototype()) {
-    map->set_is_hidden_prototype();
-  }
-
   // Mark as needs_access_check if needed.
   if (obj->needs_access_check()) {
     map->set_is_access_check_needed(true);
@@ -548,73 +610,7 @@
   // Mark instance as callable in the map.
   if (!obj->instance_call_handler()->IsUndefined()) {
     map->set_is_callable();
-    map->set_is_constructor();
-  }
-
-  // Recursively copy parent instance templates' accessors,
-  // 'data' may be modified.
-  int max_number_of_additional_properties = 0;
-  int max_number_of_static_properties = 0;
-  FunctionTemplateInfo* info = *obj;
-  while (true) {
-    if (!info->instance_template()->IsUndefined()) {
-      Object* props = ObjectTemplateInfo::cast(info->instance_template())
-                          ->property_accessors();
-      if (!props->IsUndefined()) {
-        Handle<Object> props_handle(props, isolate);
-        NeanderArray props_array(props_handle);
-        max_number_of_additional_properties += props_array.length();
-      }
-    }
-    if (!info->property_accessors()->IsUndefined()) {
-      Object* props = info->property_accessors();
-      if (!props->IsUndefined()) {
-        Handle<Object> props_handle(props, isolate);
-        NeanderArray props_array(props_handle);
-        max_number_of_static_properties += props_array.length();
-      }
-    }
-    Object* parent = info->parent_template();
-    if (parent->IsUndefined()) break;
-    info = FunctionTemplateInfo::cast(parent);
-  }
-
-  Map::EnsureDescriptorSlack(map, max_number_of_additional_properties);
-
-  // Use a temporary FixedArray to acculumate static accessors
-  int valid_descriptors = 0;
-  Handle<FixedArray> array;
-  if (max_number_of_static_properties > 0) {
-    array = isolate->factory()->NewFixedArray(max_number_of_static_properties);
-  }
-
-  while (true) {
-    // Install instance descriptors
-    if (!obj->instance_template()->IsUndefined()) {
-      Handle<ObjectTemplateInfo> instance = Handle<ObjectTemplateInfo>(
-          ObjectTemplateInfo::cast(obj->instance_template()), isolate);
-      Handle<Object> props =
-          Handle<Object>(instance->property_accessors(), isolate);
-      if (!props->IsUndefined()) {
-        Map::AppendCallbackDescriptors(map, props);
-      }
-    }
-    // Accumulate static accessors
-    if (!obj->property_accessors()->IsUndefined()) {
-      Handle<Object> props = Handle<Object>(obj->property_accessors(), isolate);
-      valid_descriptors =
-          AccessorInfo::AppendUnique(props, array, valid_descriptors);
-    }
-    // Climb parent chain
-    Handle<Object> parent = Handle<Object>(obj->parent_template(), isolate);
-    if (parent->IsUndefined()) break;
-    obj = Handle<FunctionTemplateInfo>::cast(parent);
-  }
-
-  // Install accumulated static accessors
-  for (int i = 0; i < valid_descriptors; i++) {
-    Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i)));
-    JSObject::SetAccessor(result, accessor).Assert();
+    map->set_is_constructor(true);
   }
 
   DCHECK(result->shared()->IsApiFunction());