| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 452c1d62d5ec673f30d6e9cb4549c80ce80fba4e..6d74ec75504c1fa21c5dc290dd2781d5d7b7ebf3 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -2170,11 +2170,12 @@ MaybeObject* JSObject::SetPropertyPostInterceptor(
|
| }
|
|
|
|
|
| -MaybeObject* JSObject::ReplaceSlowProperty(Name* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| - NameDictionary* dictionary = property_dictionary();
|
| - int old_index = dictionary->FindEntry(name);
|
| +void JSObject::ReplaceSlowProperty(Handle<JSObject> object,
|
| + Handle<Name> name,
|
| + Handle<Object> value,
|
| + PropertyAttributes attributes) {
|
| + Handle<NameDictionary> dictionary(object->property_dictionary());
|
| + int old_index = dictionary->FindEntry(*name);
|
| int new_enumeration_index = 0; // 0 means "Use the next available index."
|
| if (old_index != -1) {
|
| // All calls to ReplaceSlowProperty have had all transitions removed.
|
| @@ -2182,7 +2183,7 @@ MaybeObject* JSObject::ReplaceSlowProperty(Name* name,
|
| }
|
|
|
| PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
|
| - return SetNormalizedProperty(name, value, new_details);
|
| + SetNormalizedProperty(object, name, value, new_details);
|
| }
|
|
|
|
|
| @@ -2390,6 +2391,17 @@ MaybeObject* JSObject::MigrateToMap(Map* new_map) {
|
| }
|
|
|
|
|
| +void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
|
| + int modify_index,
|
| + Representation new_representation,
|
| + StoreMode store_mode) {
|
| + CALL_HEAP_FUNCTION_VOID(
|
| + object->GetIsolate(),
|
| + object->GeneralizeFieldRepresentation(
|
| + modify_index, new_representation, store_mode));
|
| +}
|
| +
|
| +
|
| MaybeObject* JSObject::GeneralizeFieldRepresentation(
|
| int modify_index,
|
| Representation new_representation,
|
| @@ -2453,6 +2465,18 @@ MaybeObject* Map::CopyGeneralizeAllRepresentations(
|
| }
|
|
|
|
|
| +Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
|
| + int descriptor_index,
|
| + StoreMode store_mode,
|
| + PropertyAttributes attributes,
|
| + const char* reason) {
|
| + CALL_HEAP_FUNCTION(map->GetIsolate(),
|
| + map->CopyGeneralizeAllRepresentations(
|
| + descriptor_index, store_mode, attributes, reason),
|
| + Map);
|
| +}
|
| +
|
| +
|
| void Map::DeprecateTransitionTree() {
|
| if (!FLAG_track_fields) return;
|
| if (is_deprecated()) return;
|
| @@ -2732,6 +2756,20 @@ Map* Map::CurrentMapForDeprecated() {
|
| }
|
|
|
|
|
| +Handle<Object> JSObject::SetPropertyWithInterceptor(
|
| + Handle<JSObject> object,
|
| + Handle<Name> name,
|
| + Handle<Object> value,
|
| + PropertyAttributes attributes,
|
| + StrictModeFlag strict_mode) {
|
| + CALL_HEAP_FUNCTION(
|
| + object->GetIsolate(),
|
| + object->SetPropertyWithInterceptor(
|
| + *name, *value, attributes, strict_mode),
|
| + Object);
|
| +}
|
| +
|
| +
|
| MaybeObject* JSObject::SetPropertyWithInterceptor(
|
| Name* name,
|
| Object* value,
|
| @@ -3737,25 +3775,61 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map,
|
| }
|
|
|
|
|
| -static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup,
|
| - Handle<Name> name,
|
| - Handle<Object> value,
|
| - PropertyAttributes attributes) {
|
| - Map* transition_map = lookup->GetTransitionTarget();
|
| +void JSObject::AddProperty(Handle<JSObject> object,
|
| + Handle<Name> name,
|
| + Handle<Object> value,
|
| + PropertyAttributes attributes,
|
| + StrictModeFlag strict_mode,
|
| + StoreFromKeyed store_mode,
|
| + ExtensibilityCheck extensibility_check,
|
| + ValueType value_type,
|
| + StoreMode mode,
|
| + TransitionFlag flag) {
|
| + CALL_HEAP_FUNCTION_VOID(
|
| + object->GetIsolate(),
|
| + object->AddProperty(*name, *value, attributes, strict_mode, store_mode,
|
| + extensibility_check, value_type, mode, flag));
|
| +}
|
| +
|
| +
|
| +void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> map) {
|
| + CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), object->MigrateToMap(*map));
|
| +}
|
| +
|
| +
|
| +void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object,
|
| + Handle<Map> new_map,
|
| + Handle<Name> name,
|
| + Handle<Object> value,
|
| + int field_index,
|
| + Representation representation) {
|
| + CALL_HEAP_FUNCTION_VOID(
|
| + object->GetIsolate(),
|
| + object->AddFastPropertyUsingMap(
|
| + *new_map, *name, *value, field_index, representation));
|
| +}
|
| +
|
| +
|
| +void JSObject::SetPropertyUsingTransition(LookupResult* lookup,
|
| + Handle<Name> name,
|
| + Handle<Object> value,
|
| + PropertyAttributes attributes) {
|
| + Handle<JSObject> holder(lookup->holder());
|
| + Handle<Map> transition_map(lookup->GetTransitionTarget());
|
| int descriptor = transition_map->LastAdded();
|
|
|
| - DescriptorArray* descriptors = transition_map->instance_descriptors();
|
| + Handle<DescriptorArray> descriptors(transition_map->instance_descriptors());
|
| PropertyDetails details = descriptors->GetDetails(descriptor);
|
|
|
| if (details.type() == CALLBACKS || attributes != details.attributes()) {
|
| // AddProperty will either normalize the object, or create a new fast copy
|
| // of the map. If we get a fast copy of the map, all field representations
|
| // will be tagged since the transition is omitted.
|
| - return lookup->holder()->AddProperty(
|
| - *name, *value, attributes, kNonStrictMode,
|
| - JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
|
| - JSReceiver::OMIT_EXTENSIBILITY_CHECK,
|
| - JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
|
| + AddProperty(holder, name, value, attributes, kNonStrictMode,
|
| + JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
|
| + JSReceiver::OMIT_EXTENSIBILITY_CHECK,
|
| + JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
|
| + return;
|
| }
|
|
|
| // Keep the target CONSTANT if the same value is stored.
|
| @@ -3763,109 +3837,100 @@ static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup,
|
| // (value->IsUninitialized) as constant.
|
| if (details.type() == CONSTANT &&
|
| descriptors->GetValue(descriptor) == *value) {
|
| - lookup->holder()->set_map(transition_map);
|
| - return *value;
|
| + holder->set_map(*transition_map);
|
| + return;
|
| }
|
|
|
| Representation representation = details.representation();
|
|
|
| if (!value->FitsRepresentation(representation) ||
|
| details.type() == CONSTANT) {
|
| - MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
|
| - descriptor, value->OptimalRepresentation(), FORCE_FIELD);
|
| - if (!maybe_map->To(&transition_map)) return maybe_map;
|
| - Object* back = transition_map->GetBackPointer();
|
| + transition_map = Map::GeneralizeRepresentation(
|
| + transition_map, descriptor,
|
| + value->OptimalRepresentation(), FORCE_FIELD);
|
| + Handle<Object> back(transition_map->GetBackPointer(),
|
| + transition_map->GetIsolate());
|
| if (back->IsMap()) {
|
| - MaybeObject* maybe_failure =
|
| - lookup->holder()->MigrateToMap(Map::cast(back));
|
| - if (maybe_failure->IsFailure()) return maybe_failure;
|
| + MigrateToMap(holder, Handle<Map>::cast(back));
|
| }
|
| - descriptors = transition_map->instance_descriptors();
|
| + descriptors = handle(transition_map->instance_descriptors());
|
| representation = descriptors->GetDetails(descriptor).representation();
|
| }
|
|
|
| int field_index = descriptors->GetFieldIndex(descriptor);
|
| - return lookup->holder()->AddFastPropertyUsingMap(
|
| - transition_map, *name, *value, field_index, representation);
|
| + return AddFastPropertyUsingMap(
|
| + holder, transition_map, name, value, field_index, representation);
|
| }
|
|
|
|
|
| -static MaybeObject* SetPropertyToField(LookupResult* lookup,
|
| - Handle<Name> name,
|
| - Handle<Object> value) {
|
| +void JSObject::SetPropertyToField(LookupResult* lookup,
|
| + Handle<Name> name,
|
| + Handle<Object> value) {
|
| + Handle<JSObject> holder(lookup->holder());
|
| Representation representation = lookup->representation();
|
| +
|
| if (!value->FitsRepresentation(representation) ||
|
| lookup->type() == CONSTANT) {
|
| - MaybeObject* maybe_failure =
|
| - lookup->holder()->GeneralizeFieldRepresentation(
|
| - lookup->GetDescriptorIndex(),
|
| - value->OptimalRepresentation(),
|
| - FORCE_FIELD);
|
| - if (maybe_failure->IsFailure()) return maybe_failure;
|
| - DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
|
| + GeneralizeFieldRepresentation(
|
| + holder, lookup->GetDescriptorIndex(),
|
| + value->OptimalRepresentation(), FORCE_FIELD);
|
| + DescriptorArray* desc = holder->map()->instance_descriptors();
|
| int descriptor = lookup->GetDescriptorIndex();
|
| representation = desc->GetDetails(descriptor).representation();
|
| }
|
|
|
| + int field_index = lookup->GetFieldIndex().field_index();
|
| if (FLAG_track_double_fields && representation.IsDouble()) {
|
| - HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
|
| - lookup->GetFieldIndex().field_index()));
|
| + Handle<HeapNumber> storage(
|
| + HeapNumber::cast(holder->RawFastPropertyAt(field_index)));
|
| storage->set_value(value->Number());
|
| - return *value;
|
| + return;
|
| }
|
|
|
| - lookup->holder()->FastPropertyAtPut(
|
| - lookup->GetFieldIndex().field_index(), *value);
|
| - return *value;
|
| + holder->FastPropertyAtPut(field_index, *value);
|
| }
|
|
|
|
|
| -static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup,
|
| - Name* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| - JSObject* object = lookup->holder();
|
| +void JSObject::ConvertAndSetLocalProperty(LookupResult* lookup,
|
| + Handle<Name> name,
|
| + Handle<Object> value,
|
| + PropertyAttributes attributes) {
|
| + Handle<JSObject> object(lookup->holder());
|
| if (object->TooManyFastProperties()) {
|
| - MaybeObject* maybe_failure = object->NormalizeProperties(
|
| - CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (maybe_failure->IsFailure()) return maybe_failure;
|
| + NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
|
| }
|
|
|
| if (!object->HasFastProperties()) {
|
| - return object->ReplaceSlowProperty(name, value, attributes);
|
| + ReplaceSlowProperty(object, name, value, attributes);
|
| + return;
|
| }
|
|
|
| int descriptor_index = lookup->GetDescriptorIndex();
|
| if (lookup->GetAttributes() == attributes) {
|
| - MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation(
|
| - descriptor_index, Representation::Tagged(), FORCE_FIELD);
|
| - if (maybe_failure->IsFailure()) return maybe_failure;
|
| + GeneralizeFieldRepresentation(
|
| + object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
|
| } else {
|
| - Map* map;
|
| - MaybeObject* maybe_map = object->map()->CopyGeneralizeAllRepresentations(
|
| - descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
|
| - if (!maybe_map->To(&map)) return maybe_map;
|
| - MaybeObject* maybe_failure = object->MigrateToMap(map);
|
| - if (maybe_failure->IsFailure()) return maybe_failure;
|
| + Handle<Map> map = Map::CopyGeneralizeAllRepresentations(
|
| + handle(object->map()), descriptor_index, FORCE_FIELD,
|
| + attributes, "attributes mismatch");
|
| + MigrateToMap(object, map);
|
| }
|
|
|
| DescriptorArray* descriptors = object->map()->instance_descriptors();
|
| int index = descriptors->GetDetails(descriptor_index).field_index();
|
| - object->FastPropertyAtPut(index, value);
|
| - return value;
|
| + object->FastPropertyAtPut(index, *value);
|
| }
|
|
|
|
|
| -static MaybeObject* SetPropertyToFieldWithAttributes(
|
| - LookupResult* lookup,
|
| - Handle<Name> name,
|
| - Handle<Object> value,
|
| - PropertyAttributes attributes) {
|
| +void JSObject::SetPropertyToFieldWithAttributes(LookupResult* lookup,
|
| + Handle<Name> name,
|
| + Handle<Object> value,
|
| + PropertyAttributes attributes) {
|
| if (lookup->GetAttributes() == attributes) {
|
| - if (value->IsUninitialized()) return *value;
|
| - return SetPropertyToField(lookup, name, value);
|
| + if (value->IsUninitialized()) return;
|
| + SetPropertyToField(lookup, name, value);
|
| } else {
|
| - return ConvertAndSetLocalProperty(lookup, *name, *value, attributes);
|
| + ConvertAndSetLocalProperty(lookup, name, value, attributes);
|
| }
|
| }
|
|
|
| @@ -3953,30 +4018,33 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
|
|
|
| // This is a real property that is not read-only, or it is a
|
| // transition or null descriptor and there are no setters in the prototypes.
|
| - MaybeObject* result = *value;
|
| switch (lookup->type()) {
|
| case NORMAL:
|
| - result = lookup->holder()->SetNormalizedProperty(lookup, *value);
|
| + SetNormalizedProperty(handle(lookup->holder()), lookup, value);
|
| break;
|
| case FIELD:
|
| - result = SetPropertyToField(lookup, name, value);
|
| + SetPropertyToField(lookup, name, value);
|
| break;
|
| case CONSTANT:
|
| // Only replace the constant if necessary.
|
| - if (*value == lookup->GetConstant()) return *value;
|
| - result = SetPropertyToField(lookup, name, value);
|
| + if (*value != lookup->GetConstant()) {
|
| + SetPropertyToField(lookup, name, value);
|
| + }
|
| break;
|
| case CALLBACKS: {
|
| Object* callback_object = lookup->GetCallbackObject();
|
| return self->SetPropertyWithCallback(
|
| callback_object, *name, *value, lookup->holder(), strict_mode);
|
| }
|
| - case INTERCEPTOR:
|
| - result = lookup->holder()->SetPropertyWithInterceptor(
|
| - *name, *value, attributes, strict_mode);
|
| + case INTERCEPTOR: {
|
| + RETURN_IF_EMPTY_HANDLE(
|
| + isolate,
|
| + SetPropertyWithInterceptor(
|
| + handle(lookup->holder()), name, value, attributes, strict_mode));
|
| break;
|
| + }
|
| case TRANSITION: {
|
| - result = SetPropertyUsingTransition(lookup, name, value, attributes);
|
| + SetPropertyUsingTransition(lookup, name, value, attributes);
|
| break;
|
| }
|
| case HANDLER:
|
| @@ -3984,9 +4052,6 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
|
| UNREACHABLE();
|
| }
|
|
|
| - Handle<Object> hresult;
|
| - if (!result->ToHandle(&hresult, isolate)) return result;
|
| -
|
| if (FLAG_harmony_observation && self->map()->is_observed()) {
|
| if (lookup->IsTransition()) {
|
| EnqueueChangeRecord(self, "new", name, old_value);
|
| @@ -4002,7 +4067,7 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
|
| }
|
| }
|
|
|
| - return *hresult;
|
| + return *value;
|
| }
|
|
|
|
|
| @@ -4096,28 +4161,25 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
|
| }
|
|
|
| // Check of IsReadOnly removed from here in clone.
|
| - MaybeObject* result = *value;
|
| switch (lookup.type()) {
|
| case NORMAL:
|
| - result = self->ReplaceSlowProperty(*name, *value, attributes);
|
| + ReplaceSlowProperty(self, name, value, attributes);
|
| break;
|
| case FIELD:
|
| - result = SetPropertyToFieldWithAttributes(
|
| - &lookup, name, value, attributes);
|
| + SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
|
| break;
|
| case CONSTANT:
|
| // Only replace the constant if necessary.
|
| if (lookup.GetAttributes() != attributes ||
|
| *value != lookup.GetConstant()) {
|
| - result = SetPropertyToFieldWithAttributes(
|
| - &lookup, name, value, attributes);
|
| + SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
|
| }
|
| break;
|
| case CALLBACKS:
|
| - result = ConvertAndSetLocalProperty(&lookup, *name, *value, attributes);
|
| + ConvertAndSetLocalProperty(&lookup, name, value, attributes);
|
| break;
|
| case TRANSITION:
|
| - result = SetPropertyUsingTransition(&lookup, name, value, attributes);
|
| + SetPropertyUsingTransition(&lookup, name, value, attributes);
|
| break;
|
| case NONEXISTENT:
|
| case HANDLER:
|
| @@ -4125,9 +4187,6 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
|
| UNREACHABLE();
|
| }
|
|
|
| - Handle<Object> hresult;
|
| - if (!result->ToHandle(&hresult, isolate)) return result;
|
| -
|
| if (is_observed) {
|
| if (lookup.IsTransition()) {
|
| EnqueueChangeRecord(self, "new", name, old_value);
|
| @@ -4150,7 +4209,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
|
| }
|
| }
|
|
|
| - return *hresult;
|
| + return *value;
|
| }
|
|
|
|
|
|
|