| Index: src/objects.cc | 
| diff --git a/src/objects.cc b/src/objects.cc | 
| index 9edbdc9623475e24b2cfbc622a8f12a40c9eccde..e90d28f084f60b32fbfdbf1e26da5eb51341236e 100644 | 
| --- a/src/objects.cc | 
| +++ b/src/objects.cc | 
| @@ -530,56 +530,6 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object, | 
| } | 
|  | 
|  | 
| -Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 
| -                                                  Handle<Name> name, | 
| -                                                  DeleteMode mode) { | 
| -  DCHECK(!object->HasFastProperties()); | 
| -  Isolate* isolate = object->GetIsolate(); | 
| -  Handle<NameDictionary> dictionary(object->property_dictionary()); | 
| -  int entry = dictionary->FindEntry(name); | 
| -  if (entry != NameDictionary::kNotFound) { | 
| -    // If we have a global object set the cell to the hole. | 
| -    if (object->IsGlobalObject()) { | 
| -      PropertyDetails details = dictionary->DetailsAt(entry); | 
| -      if (!details.IsConfigurable()) { | 
| -        if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | 
| -        // When forced to delete global properties, we have to make a | 
| -        // map change to invalidate any ICs that think they can load | 
| -        // from the non-configurable cell without checking if it contains | 
| -        // the hole value. | 
| -        Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 
| -        DCHECK(new_map->is_dictionary_map()); | 
| -#if TRACE_MAPS | 
| -        if (FLAG_trace_maps) { | 
| -          PrintF("[TraceMaps: GlobalDeleteNormalized from= %p to= %p ]\n", | 
| -                 reinterpret_cast<void*>(object->map()), | 
| -                 reinterpret_cast<void*>(*new_map)); | 
| -        } | 
| -#endif | 
| -        JSObject::MigrateToMap(object, new_map); | 
| -        // Optimized code does not check for the hole value for non-configurable | 
| -        // properties. | 
| -        Deoptimizer::DeoptimizeGlobalObject(*object); | 
| -      } | 
| -      Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 
| -      Handle<Object> value = isolate->factory()->the_hole_value(); | 
| -      PropertyCell::SetValueInferType(cell, value); | 
| -      dictionary->DetailsAtPut(entry, details.AsDeleted()); | 
| -    } else { | 
| -      Handle<Object> deleted( | 
| -          NameDictionary::DeleteProperty(dictionary, entry, mode)); | 
| -      if (*deleted == isolate->heap()->true_value()) { | 
| -        Handle<NameDictionary> new_properties = | 
| -            NameDictionary::Shrink(dictionary, name); | 
| -        object->set_properties(*new_properties); | 
| -      } | 
| -      return deleted; | 
| -    } | 
| -  } | 
| -  return isolate->factory()->true_value(); | 
| -} | 
| - | 
| - | 
| MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, | 
| Handle<Object> object, | 
| Handle<Object> receiver, | 
| @@ -3543,8 +3493,9 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( | 
| } | 
|  | 
|  | 
| -MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( | 
| -    Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { | 
| +MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(Handle<JSProxy> proxy, | 
| +                                                       Handle<Name> name, | 
| +                                                       StrictMode strict_mode) { | 
| Isolate* isolate = proxy->GetIsolate(); | 
|  | 
| // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 
| @@ -3562,7 +3513,7 @@ MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( | 
| Object); | 
|  | 
| bool result_bool = result->BooleanValue(); | 
| -  if (mode == STRICT_DELETION && !result_bool) { | 
| +  if (strict_mode == STRICT && !result_bool) { | 
| Handle<Object> handler(proxy->handler(), isolate); | 
| Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( | 
| STATIC_CHAR_VECTOR("delete")); | 
| @@ -3575,11 +3526,12 @@ MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( | 
| } | 
|  | 
|  | 
| -MaybeHandle<Object> JSProxy::DeleteElementWithHandler( | 
| -    Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) { | 
| +MaybeHandle<Object> JSProxy::DeleteElementWithHandler(Handle<JSProxy> proxy, | 
| +                                                      uint32_t index, | 
| +                                                      StrictMode strict_mode) { | 
| Isolate* isolate = proxy->GetIsolate(); | 
| Handle<String> name = isolate->factory()->Uint32ToString(index); | 
| -  return JSProxy::DeletePropertyWithHandler(proxy, name, mode); | 
| +  return JSProxy::DeletePropertyWithHandler(proxy, name, strict_mode); | 
| } | 
|  | 
|  | 
| @@ -4857,15 +4809,16 @@ MaybeHandle<Object> JSObject::DeleteElementWithInterceptor( | 
| // Rebox CustomArguments::kReturnValueOffset before returning. | 
| return handle(*result_internal, isolate); | 
| } | 
| -  MaybeHandle<Object> delete_result = object->GetElementsAccessor()->Delete( | 
| -      object, index, NORMAL_DELETION); | 
| +  // TODO(verwaest): Shouldn't this be the mode that was passed in? | 
| +  MaybeHandle<Object> delete_result = | 
| +      object->GetElementsAccessor()->Delete(object, index, SLOPPY); | 
| return delete_result; | 
| } | 
|  | 
|  | 
| MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, | 
| uint32_t index, | 
| -                                            DeleteMode mode) { | 
| +                                            StrictMode strict_mode) { | 
| Isolate* isolate = object->GetIsolate(); | 
| Factory* factory = isolate->factory(); | 
|  | 
| @@ -4878,7 +4831,7 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, | 
| } | 
|  | 
| if (object->IsStringObjectWithCharacterAt(index)) { | 
| -    if (mode == STRICT_DELETION) { | 
| +    if (strict_mode == STRICT) { | 
| // Deleting a non-configurable property in strict mode. | 
| Handle<Object> name = factory->NewNumberFromUint(index); | 
| Handle<Object> args[2] = { name, object }; | 
| @@ -4895,7 +4848,7 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, | 
| DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 
| return DeleteElement( | 
| Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, | 
| -        mode); | 
| +        strict_mode); | 
| } | 
|  | 
| Handle<Object> old_value; | 
| @@ -4916,10 +4869,11 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, | 
|  | 
| // Skip interceptor if forcing deletion. | 
| MaybeHandle<Object> maybe_result; | 
| -  if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { | 
| +  if (object->HasIndexedInterceptor()) { | 
| maybe_result = DeleteElementWithInterceptor(object, index); | 
| } else { | 
| -    maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); | 
| +    maybe_result = | 
| +        object->GetElementsAccessor()->Delete(object, index, strict_mode); | 
| } | 
| Handle<Object> result; | 
| ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); | 
| @@ -4939,23 +4893,44 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, | 
| } | 
|  | 
|  | 
| +void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 
| +                                        Handle<Name> name) { | 
| +  DCHECK(!object->HasFastProperties()); | 
| +  Isolate* isolate = object->GetIsolate(); | 
| +  Handle<NameDictionary> dictionary(object->property_dictionary()); | 
| +  int entry = dictionary->FindEntry(name); | 
| +  DCHECK_NE(NameDictionary::kNotFound, entry); | 
| + | 
| +  // If we have a global object set the cell to the hole. | 
| +  if (object->IsGlobalObject()) { | 
| +    PropertyDetails details = dictionary->DetailsAt(entry); | 
| +    DCHECK(details.IsConfigurable()); | 
| +    Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 
| +    Handle<Object> value = isolate->factory()->the_hole_value(); | 
| +    PropertyCell::SetValueInferType(cell, value); | 
| +    dictionary->DetailsAtPut(entry, details.AsDeleted()); | 
| +    return; | 
| +  } | 
| + | 
| +  NameDictionary::DeleteProperty(dictionary, entry); | 
| +  Handle<NameDictionary> new_properties = | 
| +      NameDictionary::Shrink(dictionary, name); | 
| +  object->set_properties(*new_properties); | 
| +} | 
| + | 
| + | 
| MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 
| Handle<Name> name, | 
| -                                             DeleteMode delete_mode) { | 
| +                                             StrictMode strict_mode) { | 
| // ECMA-262, 3rd, 8.6.2.5 | 
| DCHECK(name->IsName()); | 
|  | 
| uint32_t index = 0; | 
| if (name->AsArrayIndex(&index)) { | 
| -    return DeleteElement(object, index, delete_mode); | 
| +    return DeleteElement(object, index, strict_mode); | 
| } | 
|  | 
| -  // Skip interceptors on FORCE_DELETION. | 
| -  LookupIterator::Configuration config = | 
| -      delete_mode == FORCE_DELETION ? LookupIterator::HIDDEN_SKIP_INTERCEPTOR | 
| -                                    : LookupIterator::HIDDEN; | 
| - | 
| -  LookupIterator it(object, name, config); | 
| +  LookupIterator it(object, name, LookupIterator::HIDDEN); | 
|  | 
| bool is_observed = object->map()->is_observed() && | 
| !it.isolate()->IsInternallyUsedPropertyName(name); | 
| @@ -4989,9 +4964,9 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 
| } | 
| // Fall through. | 
| case LookupIterator::ACCESSOR: { | 
| -        if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) { | 
| +        if (!it.IsConfigurable()) { | 
| // Fail if the property is not configurable. | 
| -          if (delete_mode == STRICT_DELETION) { | 
| +          if (strict_mode == STRICT) { | 
| Handle<Object> args[2] = {name, object}; | 
| THROW_NEW_ERROR(it.isolate(), | 
| NewTypeError("strict_delete_property", | 
| @@ -5011,9 +4986,9 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 
| !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { | 
| return it.isolate()->factory()->true_value(); | 
| } | 
| + | 
| NormalizeProperties(holder, mode, 0, "DeletingProperty"); | 
| -        Handle<Object> result = | 
| -            DeleteNormalizedProperty(holder, name, delete_mode); | 
| +        DeleteNormalizedProperty(holder, name); | 
| ReoptimizeIfPrototype(holder); | 
|  | 
| if (is_observed) { | 
| @@ -5022,7 +4997,7 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 
| EnqueueChangeRecord(object, "delete", name, old_value), Object); | 
| } | 
|  | 
| -        return result; | 
| +        return it.isolate()->factory()->true_value(); | 
| } | 
| } | 
| } | 
| @@ -5033,23 +5008,25 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 
|  | 
| MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, | 
| uint32_t index, | 
| -                                              DeleteMode mode) { | 
| +                                              StrictMode strict_mode) { | 
| if (object->IsJSProxy()) { | 
| -    return JSProxy::DeleteElementWithHandler( | 
| -        Handle<JSProxy>::cast(object), index, mode); | 
| +    return JSProxy::DeleteElementWithHandler(Handle<JSProxy>::cast(object), | 
| +                                             index, strict_mode); | 
| } | 
| -  return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, mode); | 
| +  return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, | 
| +                                 strict_mode); | 
| } | 
|  | 
|  | 
| MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, | 
| Handle<Name> name, | 
| -                                               DeleteMode mode) { | 
| +                                               StrictMode strict_mode) { | 
| if (object->IsJSProxy()) { | 
| -    return JSProxy::DeletePropertyWithHandler( | 
| -        Handle<JSProxy>::cast(object), name, mode); | 
| +    return JSProxy::DeletePropertyWithHandler(Handle<JSProxy>::cast(object), | 
| +                                              name, strict_mode); | 
| } | 
| -  return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode); | 
| +  return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, | 
| +                                  strict_mode); | 
| } | 
|  | 
|  | 
| @@ -14469,11 +14446,11 @@ Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 
|  | 
| template Handle<Object> | 
| Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::DeleteProperty( | 
| -    Handle<NameDictionary>, int, JSObject::DeleteMode); | 
| +    Handle<NameDictionary>, int); | 
|  | 
| template Handle<Object> | 
| -Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 
| -    DeleteProperty(Handle<SeededNumberDictionary>, int, JSObject::DeleteMode); | 
| +Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, | 
| +           uint32_t>::DeleteProperty(Handle<SeededNumberDictionary>, int); | 
|  | 
| template Handle<NameDictionary> | 
| HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >:: | 
| @@ -15451,17 +15428,12 @@ Handle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity( | 
| } | 
|  | 
|  | 
| -template<typename Derived, typename Shape, typename Key> | 
| +template <typename Derived, typename Shape, typename Key> | 
| Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( | 
| -    Handle<Derived> dictionary, | 
| -    int entry, | 
| -    JSObject::DeleteMode mode) { | 
| +    Handle<Derived> dictionary, int entry) { | 
| Factory* factory = dictionary->GetIsolate()->factory(); | 
| PropertyDetails details = dictionary->DetailsAt(entry); | 
| -  // Ignore attributes if forcing a deletion. | 
| -  if (!details.IsConfigurable() && mode != JSReceiver::FORCE_DELETION) { | 
| -    return factory->false_value(); | 
| -  } | 
| +  if (!details.IsConfigurable()) return factory->false_value(); | 
|  | 
| dictionary->SetEntry( | 
| entry, factory->the_hole_value(), factory->the_hole_value()); | 
|  |