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/lookup.cc b/src/lookup.cc
index 48da4fa..bad5a20 100644
--- a/src/lookup.cc
+++ b/src/lookup.cc
@@ -7,6 +7,7 @@
 #include "src/bootstrapper.h"
 #include "src/deoptimizer.h"
 #include "src/elements.h"
+#include "src/field-type.h"
 #include "src/isolate-inl.h"
 
 namespace v8 {
@@ -52,7 +53,7 @@
   has_property_ = false;
 
   JSReceiver* holder = *holder_;
-  Map* map = *holder_map_;
+  Map* map = holder->map();
 
   // Perform lookup on current holder.
   state_ = LookupInHolder(map, holder);
@@ -73,10 +74,7 @@
     state_ = LookupInHolder(map, holder);
   } while (!IsFound());
 
-  if (holder != *holder_) {
-    holder_ = handle(holder, isolate_);
-    holder_map_ = handle(map, isolate_);
-  }
+  if (holder != *holder_) holder_ = handle(holder, isolate_);
 }
 
 
@@ -85,7 +83,6 @@
   interceptor_state_ = interceptor_state;
   property_details_ = PropertyDetails::Empty();
   holder_ = initial_holder_;
-  holder_map_ = handle(holder_->map(), isolate_);
   number_ = DescriptorArray::kNotFound;
   Next();
 }
@@ -122,9 +119,10 @@
 
 Handle<JSObject> LookupIterator::GetStoreTarget() const {
   if (receiver_->IsJSGlobalProxy()) {
-    PrototypeIterator iter(isolate(), receiver_);
-    if (iter.IsAtEnd()) return Handle<JSGlobalProxy>::cast(receiver_);
-    return PrototypeIterator::GetCurrent<JSGlobalObject>(iter);
+    Object* prototype = JSGlobalProxy::cast(*receiver_)->map()->prototype();
+    if (!prototype->IsNull()) {
+      return handle(JSGlobalObject::cast(prototype), isolate_);
+    }
   }
   return Handle<JSObject>::cast(receiver_);
 }
@@ -140,21 +138,57 @@
 void LookupIterator::ReloadPropertyInformation() {
   state_ = BEFORE_PROPERTY;
   interceptor_state_ = InterceptorState::kUninitialized;
-  state_ = LookupInHolder(*holder_map_, *holder_);
-  DCHECK(IsFound() || holder_map_->is_dictionary_map());
+  state_ = LookupInHolder(holder_->map(), *holder_);
+  DCHECK(IsFound() || !holder_->HasFastProperties());
 }
 
+bool LookupIterator::HolderIsInContextIndex(uint32_t index) const {
+  DisallowHeapAllocation no_gc;
 
-void LookupIterator::ReloadHolderMap() {
-  DCHECK_EQ(DATA, state_);
-  DCHECK(IsElement());
-  DCHECK(JSObject::cast(*holder_)->HasFixedTypedArrayElements());
-  if (*holder_map_ != holder_->map()) {
-    holder_map_ = handle(holder_->map(), isolate_);
+  Object* context = heap()->native_contexts_list();
+  while (!context->IsUndefined()) {
+    Context* current_context = Context::cast(context);
+    if (current_context->get(index) == *holder_) {
+      return true;
+    }
+    context = current_context->get(Context::NEXT_CONTEXT_LINK);
+  }
+  return false;
+}
+
+void LookupIterator::UpdateProtector() {
+  if (!FLAG_harmony_species) return;
+
+  if (IsElement()) return;
+  if (isolate_->bootstrapper()->IsActive()) return;
+  if (!isolate_->IsArraySpeciesLookupChainIntact()) return;
+
+  if (*name_ == *isolate_->factory()->constructor_string()) {
+    // Setting the constructor property could change an instance's @@species
+    if (holder_->IsJSArray()) {
+      isolate_->CountUsage(
+          v8::Isolate::UseCounterFeature::kArrayInstanceConstructorModified);
+      isolate_->InvalidateArraySpeciesProtector();
+    } else if (holder_->map()->is_prototype_map()) {
+      // Setting the constructor of Array.prototype of any realm also needs
+      // to invalidate the species protector
+      if (HolderIsInContextIndex(Context::INITIAL_ARRAY_PROTOTYPE_INDEX)) {
+        isolate_->CountUsage(v8::Isolate::UseCounterFeature::
+                                 kArrayPrototypeConstructorModified);
+        isolate_->InvalidateArraySpeciesProtector();
+      }
+    }
+  } else if (*name_ == *isolate_->factory()->species_symbol()) {
+    // Setting the Symbol.species property of any Array constructor invalidates
+    // the species protector
+    if (HolderIsInContextIndex(Context::ARRAY_FUNCTION_INDEX)) {
+      isolate_->CountUsage(
+          v8::Isolate::UseCounterFeature::kArraySpeciesModified);
+      isolate_->InvalidateArraySpeciesProtector();
+    }
   }
 }
 
-
 void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
   DCHECK(state_ == DATA || state_ == ACCESSOR);
   DCHECK(HolderIsReceiverOrHiddenPrototype());
@@ -162,25 +196,38 @@
   Handle<JSObject> holder = GetHolder<JSObject>();
 
   if (IsElement()) {
-    ElementsKind kind = holder_map_->elements_kind();
+    ElementsKind kind = holder->GetElementsKind();
     ElementsKind to = value->OptimalElementsKind();
     if (IsHoleyElementsKind(kind)) to = GetHoleyElementsKind(to);
     to = GetMoreGeneralElementsKind(kind, to);
-    JSObject::TransitionElementsKind(holder, to);
-    holder_map_ = handle(holder->map(), isolate_);
+
+    if (kind != to) {
+      JSObject::TransitionElementsKind(holder, to);
+    }
 
     // Copy the backing store if it is copy-on-write.
     if (IsFastSmiOrObjectElementsKind(to)) {
       JSObject::EnsureWritableFastElements(holder);
     }
-
-  } else {
-    if (holder_map_->is_dictionary_map()) return;
-    holder_map_ =
-        Map::PrepareForDataProperty(holder_map_, descriptor_number(), value);
+    return;
   }
 
-  JSObject::MigrateToMap(holder, holder_map_);
+  if (!holder->HasFastProperties()) return;
+
+  Handle<Map> old_map(holder->map(), isolate_);
+  Handle<Map> new_map =
+      Map::PrepareForDataProperty(old_map, descriptor_number(), value);
+
+  if (old_map.is_identical_to(new_map)) {
+    // Update the property details if the representation was None.
+    if (representation().IsNone()) {
+      property_details_ =
+          new_map->instance_descriptors()->GetDetails(descriptor_number());
+    }
+    return;
+  }
+
+  JSObject::MigrateToMap(holder, new_map);
   ReloadPropertyInformation();
 }
 
@@ -196,16 +243,16 @@
     Handle<FixedArrayBase> elements(holder->elements());
     holder->GetElementsAccessor()->Reconfigure(holder, elements, number_, value,
                                                attributes);
-  } else if (holder_map_->is_dictionary_map()) {
+  } else if (!holder->HasFastProperties()) {
     PropertyDetails details(attributes, v8::internal::DATA, 0,
                             PropertyCellType::kMutable);
     JSObject::SetNormalizedProperty(holder, name(), value, details);
   } else {
-    holder_map_ = Map::ReconfigureExistingProperty(
-        holder_map_, descriptor_number(), i::kData, attributes);
-    holder_map_ =
-        Map::PrepareForDataProperty(holder_map_, descriptor_number(), value);
-    JSObject::MigrateToMap(holder, holder_map_);
+    Handle<Map> old_map(holder->map(), isolate_);
+    Handle<Map> new_map = Map::ReconfigureExistingProperty(
+        old_map, descriptor_number(), i::kData, attributes);
+    new_map = Map::PrepareForDataProperty(new_map, descriptor_number(), value);
+    JSObject::MigrateToMap(holder, new_map);
   }
 
   ReloadPropertyInformation();
@@ -218,54 +265,66 @@
 #endif
 }
 
-
+// Can only be called when the receiver is a JSObject. JSProxy has to be handled
+// via a trap. Adding properties to primitive values is not observable.
 void LookupIterator::PrepareTransitionToDataProperty(
-    Handle<Object> value, PropertyAttributes attributes,
-    Object::StoreFromKeyed store_mode) {
+    Handle<JSObject> receiver, Handle<Object> value,
+    PropertyAttributes attributes, Object::StoreFromKeyed store_mode) {
+  DCHECK(receiver.is_identical_to(GetStoreTarget()));
   if (state_ == TRANSITION) return;
   DCHECK(state_ != LookupIterator::ACCESSOR ||
          (GetAccessors()->IsAccessorInfo() &&
           AccessorInfo::cast(*GetAccessors())->is_special_data_property()));
   DCHECK_NE(INTEGER_INDEXED_EXOTIC, state_);
   DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype());
-  // Can only be called when the receiver is a JSObject. JSProxy has to be
-  // handled via a trap. Adding properties to primitive values is not
-  // observable.
-  Handle<JSObject> receiver = GetStoreTarget();
 
-  if (!isolate()->IsInternallyUsedPropertyName(name()) &&
-      !receiver->map()->is_extensible()) {
+  Handle<Map> map(receiver->map(), isolate_);
+
+  // Dictionary maps can always have additional data properties.
+  if (map->is_dictionary_map()) {
+    state_ = TRANSITION;
+    if (map->IsJSGlobalObjectMap()) {
+      // Install a property cell.
+      auto cell = JSGlobalObject::EnsurePropertyCell(
+          Handle<JSGlobalObject>::cast(receiver), name());
+      DCHECK(cell->value()->IsTheHole());
+      transition_ = cell;
+    } else {
+      transition_ = map;
+    }
     return;
   }
 
-  auto transition = Map::TransitionToDataProperty(
-      handle(receiver->map(), isolate_), name_, value, attributes, store_mode);
+  Handle<Map> transition =
+      Map::TransitionToDataProperty(map, name_, value, attributes, store_mode);
   state_ = TRANSITION;
   transition_ = transition;
 
-  if (receiver->IsJSGlobalObject()) {
-    // Install a property cell.
-    InternalizeName();
-    auto cell = JSGlobalObject::EnsurePropertyCell(
-        Handle<JSGlobalObject>::cast(receiver), name());
-    DCHECK(cell->value()->IsTheHole());
-    transition_ = cell;
-  } else if (!transition->is_dictionary_map()) {
+  if (!transition->is_dictionary_map()) {
     property_details_ = transition->GetLastDescriptorDetails();
     has_property_ = true;
   }
 }
 
-
-void LookupIterator::ApplyTransitionToDataProperty() {
+void LookupIterator::ApplyTransitionToDataProperty(Handle<JSObject> receiver) {
   DCHECK_EQ(TRANSITION, state_);
 
-  Handle<JSObject> receiver = GetStoreTarget();
+  DCHECK(receiver.is_identical_to(GetStoreTarget()));
+
   if (receiver->IsJSGlobalObject()) return;
   holder_ = receiver;
-  holder_map_ = transition_map();
-  JSObject::MigrateToMap(receiver, holder_map_);
-  ReloadPropertyInformation();
+  Handle<Map> transition = transition_map();
+  bool simple_transition = transition->GetBackPointer() == receiver->map();
+  JSObject::MigrateToMap(receiver, transition);
+
+  if (simple_transition) {
+    int number = transition->LastAdded();
+    number_ = static_cast<uint32_t>(number);
+    property_details_ = transition->GetLastDescriptorDetails();
+    state_ = DATA;
+  } else {
+    ReloadPropertyInformation();
+  }
 }
 
 
@@ -283,7 +342,6 @@
     if (holder->HasFastProperties()) {
       JSObject::NormalizeProperties(Handle<JSObject>::cast(holder), mode, 0,
                                     "DeletingProperty");
-      holder_map_ = handle(holder->map(), isolate_);
       ReloadPropertyInformation();
     }
     // TODO(verwaest): Get rid of the name_ argument.
@@ -292,6 +350,7 @@
       JSObject::ReoptimizeIfPrototype(Handle<JSObject>::cast(holder));
     }
   }
+  state_ = NOT_FOUND;
 }
 
 
@@ -306,14 +365,14 @@
 
   if (!IsElement() && !receiver->map()->is_dictionary_map()) {
     holder_ = receiver;
-    holder_map_ = Map::TransitionToAccessorProperty(
-        handle(receiver->map(), isolate_), name_, component, accessor,
-        attributes);
-    JSObject::MigrateToMap(receiver, holder_map_);
+    Handle<Map> old_map(receiver->map(), isolate_);
+    Handle<Map> new_map = Map::TransitionToAccessorProperty(
+        old_map, name_, component, accessor, attributes);
+    JSObject::MigrateToMap(receiver, new_map);
 
     ReloadPropertyInformation();
 
-    if (!holder_map_->is_dictionary_map()) return;
+    if (!new_map->is_dictionary_map()) return;
   }
 
   Handle<AccessorPair> pair;
@@ -383,34 +442,29 @@
     JSObject::ReoptimizeIfPrototype(receiver);
   }
 
-  holder_map_ = handle(receiver->map(), isolate_);
   ReloadPropertyInformation();
 }
 
 
 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
   DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
-  return InternalHolderIsReceiverOrHiddenPrototype();
-}
-
-bool LookupIterator::InternalHolderIsReceiverOrHiddenPrototype() const {
   // Optimization that only works if configuration_ is not mutable.
   if (!check_prototype_chain()) return true;
   DisallowHeapAllocation no_gc;
   if (!receiver_->IsJSReceiver()) return false;
-  Object* current = *receiver_;
-  JSReceiver* holder = *holder_;
+  JSReceiver* current = JSReceiver::cast(*receiver_);
+  JSReceiver* object = *holder_;
+  if (current == object) return true;
+  if (!current->map()->has_hidden_prototype()) return false;
   // JSProxy do not occur as hidden prototypes.
-  if (current->IsJSProxy()) {
-    return JSReceiver::cast(current) == holder;
-  }
+  if (current->IsJSProxy()) return false;
   PrototypeIterator iter(isolate(), current,
-                         PrototypeIterator::START_AT_RECEIVER);
-  do {
-    if (iter.GetCurrent<JSReceiver>() == holder) return true;
-    DCHECK(!current->IsJSProxy());
+                         PrototypeIterator::START_AT_PROTOTYPE,
+                         PrototypeIterator::END_AT_NON_HIDDEN);
+  while (!iter.IsAtEnd()) {
+    if (iter.GetCurrent<JSReceiver>() == object) return true;
     iter.Advance();
-  } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
+  }
   return false;
 }
 
@@ -419,30 +473,22 @@
   Object* result = NULL;
   if (IsElement()) {
     Handle<JSObject> holder = GetHolder<JSObject>();
-    // TODO(verwaest): Optimize.
-    if (holder->IsStringObjectWithCharacterAt(index_)) {
-      Handle<JSValue> js_value = Handle<JSValue>::cast(holder);
-      Handle<String> string(String::cast(js_value->value()));
-      return factory()->LookupSingleCharacterStringFromCode(
-          String::Flatten(string)->Get(index_));
-    }
-
     ElementsAccessor* accessor = holder->GetElementsAccessor();
-    return accessor->Get(handle(holder->elements()), number_);
-  } else if (holder_map_->IsJSGlobalObjectMap()) {
+    return accessor->Get(holder, number_);
+  } else if (holder_->IsJSGlobalObject()) {
     Handle<JSObject> holder = GetHolder<JSObject>();
     result = holder->global_dictionary()->ValueAt(number_);
     DCHECK(result->IsPropertyCell());
     result = PropertyCell::cast(result)->value();
-  } else if (holder_map_->is_dictionary_map()) {
+  } else if (!holder_->HasFastProperties()) {
     result = holder_->property_dictionary()->ValueAt(number_);
   } else if (property_details_.type() == v8::internal::DATA) {
     Handle<JSObject> holder = GetHolder<JSObject>();
-    FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_);
+    FieldIndex field_index = FieldIndex::ForDescriptor(holder->map(), number_);
     return JSObject::FastPropertyAt(holder, property_details_.representation(),
                                     field_index);
   } else {
-    result = holder_map_->instance_descriptors()->GetValue(number_);
+    result = holder_->map()->instance_descriptors()->GetValue(number_);
   }
   return handle(result, isolate_);
 }
@@ -450,7 +496,7 @@
 
 int LookupIterator::GetAccessorIndex() const {
   DCHECK(has_property_);
-  DCHECK(!holder_map_->is_dictionary_map());
+  DCHECK(holder_->HasFastProperties());
   DCHECK_EQ(v8::internal::ACCESSOR_CONSTANT, property_details_.type());
   return descriptor_number();
 }
@@ -458,7 +504,7 @@
 
 int LookupIterator::GetConstantIndex() const {
   DCHECK(has_property_);
-  DCHECK(!holder_map_->is_dictionary_map());
+  DCHECK(holder_->HasFastProperties());
   DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type());
   DCHECK(!IsElement());
   return descriptor_number();
@@ -467,22 +513,22 @@
 
 FieldIndex LookupIterator::GetFieldIndex() const {
   DCHECK(has_property_);
-  DCHECK(!holder_map_->is_dictionary_map());
+  DCHECK(holder_->HasFastProperties());
   DCHECK_EQ(v8::internal::DATA, property_details_.type());
   DCHECK(!IsElement());
+  Map* holder_map = holder_->map();
   int index =
-      holder_map_->instance_descriptors()->GetFieldIndex(descriptor_number());
+      holder_map->instance_descriptors()->GetFieldIndex(descriptor_number());
   bool is_double = representation().IsDouble();
-  return FieldIndex::ForPropertyIndex(*holder_map_, index, is_double);
+  return FieldIndex::ForPropertyIndex(holder_map, index, is_double);
 }
 
-
-Handle<HeapType> LookupIterator::GetFieldType() const {
+Handle<FieldType> LookupIterator::GetFieldType() const {
   DCHECK(has_property_);
-  DCHECK(!holder_map_->is_dictionary_map());
+  DCHECK(holder_->HasFastProperties());
   DCHECK_EQ(v8::internal::DATA, property_details_.type());
   return handle(
-      holder_map_->instance_descriptors()->GetFieldType(descriptor_number()),
+      holder_->map()->instance_descriptors()->GetFieldType(descriptor_number()),
       isolate_);
 }
 
@@ -516,53 +562,26 @@
   if (IsElement()) {
     Handle<JSObject> object = Handle<JSObject>::cast(holder);
     ElementsAccessor* accessor = object->GetElementsAccessor();
-    accessor->Set(object->elements(), number_, *value);
+    accessor->Set(object, number_, *value);
+  } else if (holder->HasFastProperties()) {
+    if (property_details_.type() == v8::internal::DATA) {
+      JSObject::cast(*holder)->WriteToField(descriptor_number(),
+                                            property_details_, *value);
+    } else {
+      DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type());
+    }
   } else if (holder->IsJSGlobalObject()) {
     Handle<GlobalDictionary> property_dictionary =
         handle(JSObject::cast(*holder)->global_dictionary());
     PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value,
                              property_details_);
-  } else if (holder_map_->is_dictionary_map()) {
+  } else {
     NameDictionary* property_dictionary = holder->property_dictionary();
     property_dictionary->ValueAtPut(dictionary_entry(), *value);
-  } else if (property_details_.type() == v8::internal::DATA) {
-    JSObject::cast(*holder)->WriteToField(descriptor_number(), *value);
-  } else {
-    DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type());
   }
 }
 
 
-bool LookupIterator::IsIntegerIndexedExotic(JSReceiver* holder) {
-  DCHECK(exotic_index_state_ != ExoticIndexState::kNotExotic);
-  if (exotic_index_state_ == ExoticIndexState::kExotic) return true;
-  if (!InternalHolderIsReceiverOrHiddenPrototype()) {
-    exotic_index_state_ = ExoticIndexState::kNotExotic;
-    return false;
-  }
-  DCHECK(exotic_index_state_ == ExoticIndexState::kUninitialized);
-  bool result = false;
-  // Compute and cache result.
-  if (IsElement()) {
-    result = index_ >= JSTypedArray::cast(holder)->length_value();
-  } else if (name()->IsString()) {
-    Handle<String> name_string = Handle<String>::cast(name());
-    if (name_string->length() != 0) {
-      result = IsSpecialIndex(isolate_->unicode_cache(), *name_string);
-    }
-  }
-  exotic_index_state_ =
-      result ? ExoticIndexState::kExotic : ExoticIndexState::kNotExotic;
-  return result;
-}
-
-
-void LookupIterator::InternalizeName() {
-  if (name_->IsUniqueName()) return;
-  name_ = factory()->InternalizeString(Handle<String>::cast(name_));
-}
-
-
 bool LookupIterator::HasInterceptor(Map* map) const {
   if (IsElement()) return map->has_indexed_interceptor();
   return map->has_named_interceptor();
@@ -591,21 +610,30 @@
   DisallowHeapAllocation no_gc;
   if (!map->prototype()->IsJSReceiver()) return NULL;
 
-  JSReceiver* next = JSReceiver::cast(map->prototype());
-  DCHECK(!next->map()->IsJSGlobalObjectMap() ||
-         next->map()->is_hidden_prototype());
+  DCHECK(!map->IsJSGlobalProxyMap() || map->has_hidden_prototype());
 
   if (!check_prototype_chain() &&
-      !(check_hidden() && next->map()->is_hidden_prototype()) &&
+      !(check_hidden() && map->has_hidden_prototype()) &&
       // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even
       // when not checking other hidden prototypes.
       !map->IsJSGlobalProxyMap()) {
     return NULL;
   }
 
-  return next;
+  return JSReceiver::cast(map->prototype());
 }
 
+LookupIterator::State LookupIterator::NotFound(JSReceiver* const holder) const {
+  DCHECK(!IsElement());
+  if (!holder->IsJSTypedArray() || !name_->IsString()) return NOT_FOUND;
+
+  Handle<String> name_string = Handle<String>::cast(name_);
+  if (name_string->length() == 0) return NOT_FOUND;
+
+  return IsSpecialIndex(isolate_->unicode_cache(), *name_string)
+             ? INTEGER_INDEXED_EXOTIC
+             : NOT_FOUND;
+}
 
 LookupIterator::State LookupIterator::LookupInHolder(Map* const map,
                                                      JSReceiver* const holder) {
@@ -617,51 +645,32 @@
   switch (state_) {
     case NOT_FOUND:
       if (map->IsJSProxyMap()) {
-        // Do not leak private property names.
         if (IsElement() || !name_->IsPrivate()) return JSPROXY;
       }
-      if (map->is_access_check_needed() &&
-          (IsElement() || !isolate_->IsInternallyUsedPropertyName(name_))) {
-        return ACCESS_CHECK;
+      if (map->is_access_check_needed()) {
+        if (IsElement() || !name_->IsPrivate()) return ACCESS_CHECK;
       }
     // Fall through.
     case ACCESS_CHECK:
-      if (exotic_index_state_ != ExoticIndexState::kNotExotic &&
-          holder->IsJSTypedArray() && IsIntegerIndexedExotic(holder)) {
-        return INTEGER_INDEXED_EXOTIC;
-      }
       if (check_interceptor() && HasInterceptor(map) &&
           !SkipInterceptor(JSObject::cast(holder))) {
-        // Do not leak private property names.
-        if (!name_.is_null() && name_->IsPrivate()) return NOT_FOUND;
-        return INTERCEPTOR;
+        if (IsElement() || !name_->IsPrivate()) return INTERCEPTOR;
       }
     // Fall through.
     case INTERCEPTOR:
       if (IsElement()) {
-        // TODO(verwaest): Optimize.
-        if (holder->IsStringObjectWithCharacterAt(index_)) {
-          PropertyAttributes attributes =
-              static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
-          property_details_ = PropertyDetails(attributes, v8::internal::DATA, 0,
-                                              PropertyCellType::kNoCell);
-        } else {
-          JSObject* js_object = JSObject::cast(holder);
-          if (js_object->elements() == isolate()->heap()->empty_fixed_array()) {
-            return NOT_FOUND;
-          }
-
-          ElementsAccessor* accessor = js_object->GetElementsAccessor();
-          FixedArrayBase* backing_store = js_object->elements();
-          number_ =
-              accessor->GetEntryForIndex(js_object, backing_store, index_);
-          if (number_ == kMaxUInt32) return NOT_FOUND;
-          property_details_ = accessor->GetDetails(backing_store, number_);
+        JSObject* js_object = JSObject::cast(holder);
+        ElementsAccessor* accessor = js_object->GetElementsAccessor();
+        FixedArrayBase* backing_store = js_object->elements();
+        number_ = accessor->GetEntryForIndex(js_object, backing_store, index_);
+        if (number_ == kMaxUInt32) {
+          return holder->IsJSTypedArray() ? INTEGER_INDEXED_EXOTIC : NOT_FOUND;
         }
+        property_details_ = accessor->GetDetails(js_object, number_);
       } else if (!map->is_dictionary_map()) {
         DescriptorArray* descriptors = map->instance_descriptors();
-        int number = descriptors->SearchWithCache(*name_, map);
-        if (number == DescriptorArray::kNotFound) return NOT_FOUND;
+        int number = descriptors->SearchWithCache(isolate_, *name_, map);
+        if (number == DescriptorArray::kNotFound) return NotFound(holder);
         number_ = static_cast<uint32_t>(number);
         property_details_ = descriptors->GetDetails(number_);
       } else if (map->IsJSGlobalObjectMap()) {
@@ -676,7 +685,7 @@
       } else {
         NameDictionary* dict = holder->property_dictionary();
         int number = dict->FindEntry(name_);
-        if (number == NameDictionary::kNotFound) return NOT_FOUND;
+        if (number == NameDictionary::kNotFound) return NotFound(holder);
         number_ = static_cast<uint32_t>(number);
         property_details_ = dict->DetailsAt(number_);
       }