Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 5a1daa2fc201301b311fc25f3ae28bcbf5784075..fdcbbdedac325d14a8b30829cd91ce7a96469d42 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -1824,48 +1824,100 @@ String* JSReceiver::constructor_name() { |
| } |
| -void JSObject::AddFastProperty(Handle<JSObject> object, |
| - Handle<Name> name, |
| - Handle<Object> value, |
| - PropertyAttributes attributes, |
| - StoreFromKeyed store_mode, |
| - ValueType value_type, |
| - TransitionFlag flag) { |
| - ASSERT(!object->IsJSGlobalProxy()); |
| +MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, |
| + Handle<Name> name, |
| + Handle<HeapType> type, |
| + PropertyAttributes attributes, |
| + Representation representation, |
| + TransitionFlag flag) { |
| ASSERT(DescriptorArray::kNotFound == |
| - object->map()->instance_descriptors()->Search( |
| - *name, object->map()->NumberOfOwnDescriptors())); |
| + map->instance_descriptors()->Search( |
| + *name, map->NumberOfOwnDescriptors())); |
| + |
| + // Ensure the descriptor array does not get too big. |
| + if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { |
| + return MaybeHandle<Map>(); |
| + } |
| // Normalize the object if the name is an actual name (not the |
| // hidden strings) and is not a real identifier. |
| // Normalize the object if it will have too many fast properties. |
| - Isolate* isolate = object->GetIsolate(); |
| - if (!name->IsCacheable(isolate) || |
| - object->TooManyFastProperties(store_mode)) { |
| - NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| - AddSlowProperty(object, name, value, attributes); |
| - return; |
| - } |
| - |
| - // Allocate new instance descriptors with (name, index) added |
| - if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
| - Representation representation = value->OptimalRepresentation(value_type); |
| + Isolate* isolate = map->GetIsolate(); |
| + if (!name->IsCacheable(isolate)) return Handle<Map>(); |
|
Igor Sheludko
2014/04/15 15:02:39
MaybeHandle<>
|
| // Compute the new index for new field. |
| - int index = object->map()->NextFreePropertyIndex(); |
| + int index = map->NextFreePropertyIndex(); |
| + |
| + if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { |
| + representation = Representation::Tagged(); |
|
Igor Sheludko
2014/04/15 15:02:39
Shouldn't we update type here as well?
|
| + } |
| - Handle<HeapType> type = value->OptimalType(isolate, representation); |
| FieldDescriptor new_field_desc(name, index, type, attributes, representation); |
| - Handle<Map> new_map = Map::CopyAddDescriptor( |
| - handle(object->map()), &new_field_desc, flag); |
| + Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); |
| int unused_property_fields = new_map->unused_property_fields() - 1; |
| if (unused_property_fields < 0) { |
| unused_property_fields += JSObject::kFieldsAdded; |
| } |
| new_map->set_unused_property_fields(unused_property_fields); |
| + return new_map; |
| +} |
| + |
| + |
| +MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map, |
| + Handle<Name> name, |
| + Handle<Object> constant, |
| + PropertyAttributes attributes, |
| + TransitionFlag flag) { |
| + // Ensure the descriptor array does not get too big. |
| + if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { |
| + return MaybeHandle<Map>(); |
| + } |
| + |
| + // Allocate new instance descriptors with (name, constant) added. |
| + ConstantDescriptor new_constant_desc(name, constant, attributes); |
| + return Map::CopyAddDescriptor(map, &new_constant_desc, flag); |
| +} |
| + |
| + |
| +void JSObject::AddFastProperty(Handle<JSObject> object, |
| + Handle<Name> name, |
| + Handle<Object> value, |
| + PropertyAttributes attributes, |
| + StoreFromKeyed store_mode, |
| + ValueType value_type, |
| + TransitionFlag flag) { |
| + ASSERT(!object->IsJSGlobalProxy()); |
| + |
| + MaybeHandle<Map> maybe_map; |
| + if (value->IsJSFunction()) { |
| + maybe_map = Map::CopyWithConstant( |
| + handle(object->map()), name, value, attributes, flag); |
| + } else if (object->TooManyFastProperties(store_mode)) { |
| + NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| + return; |
| + } else { |
|
Igor Sheludko
2014/04/15 15:02:39
I think you can now write here:
} else if (!obje
|
| + Isolate* isolate = object->GetIsolate(); |
| + Representation representation = value->OptimalRepresentation(value_type); |
| + maybe_map = Map::CopyWithField( |
| + handle(object->map(), isolate), name, |
| + value->OptimalType(isolate, representation), |
| + attributes, representation, flag); |
| + } |
| + |
| + Handle<Map> new_map; |
| + if (!maybe_map.ToHandle(&new_map)) { |
| + NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| + return; |
| + } |
| JSObject::MigrateToMap(object, new_map); |
| + PropertyDetails details = new_map->GetLastDescriptorDetails(); |
| + if (details.type() != FIELD) return; |
| + |
| + Representation representation = details.representation(); |
| + int index = details.field_index(); |
| + |
| if (representation.IsDouble()) { |
| // Nothing more to be done. |
| if (value->IsUninitialized()) return; |
| @@ -1877,24 +1929,6 @@ void JSObject::AddFastProperty(Handle<JSObject> object, |
| } |
| -void JSObject::AddConstantProperty(Handle<JSObject> object, |
| - Handle<Name> name, |
| - Handle<Object> constant, |
| - PropertyAttributes attributes, |
| - TransitionFlag initial_flag) { |
| - ASSERT(!object->IsGlobalObject()); |
| - // Don't add transitions to special properties with non-trivial attributes. |
| - TransitionFlag flag = attributes != NONE ? OMIT_TRANSITION : initial_flag; |
|
Igor Sheludko
2014/04/15 15:02:39
This code is lost.
|
| - |
| - // Allocate new instance descriptors with (name, constant) added. |
| - ConstantDescriptor new_constant_desc(name, constant, attributes); |
| - Handle<Map> new_map = Map::CopyAddDescriptor( |
| - handle(object->map()), &new_constant_desc, flag); |
| - |
| - JSObject::MigrateToMap(object, new_map); |
| -} |
| - |
| - |
| void JSObject::AddSlowProperty(Handle<JSObject> object, |
| Handle<Name> name, |
| Handle<Object> value, |
| @@ -1959,25 +1993,11 @@ MaybeHandle<Object> JSObject::AddProperty( |
| } |
| if (object->HasFastProperties()) { |
| - // Ensure the descriptor array does not get too big. |
| - if (object->map()->NumberOfOwnDescriptors() <= kMaxNumberOfDescriptors) { |
| - // TODO(verwaest): Support other constants. |
| - // if (mode == ALLOW_AS_CONSTANT && |
| - // !value->IsTheHole() && |
| - // !value->IsConsString()) { |
| - if (value->IsJSFunction()) { |
| - AddConstantProperty(object, name, value, attributes, transition_flag); |
| - } else { |
| - AddFastProperty(object, name, value, attributes, store_mode, |
| - value_type, transition_flag); |
| - } |
| - } else { |
| - // Normalize the object to prevent very large instance descriptors. |
| - // This eliminates unwanted N^2 allocation and lookup behavior. |
| - NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| - AddSlowProperty(object, name, value, attributes); |
| - } |
| - } else { |
| + AddFastProperty(object, name, value, attributes, store_mode, |
| + value_type, transition_flag); |
| + } |
| + |
| + if (!object->HasFastProperties()) { |
| AddSlowProperty(object, name, value, attributes); |
| } |
| @@ -6613,15 +6633,6 @@ static bool TryAccessorTransition(Handle<JSObject> self, |
| } |
| -static Handle<Map> CopyInsertDescriptor(Handle<Map> map, |
| - Handle<Name> name, |
| - Handle<AccessorPair> accessors, |
| - PropertyAttributes attributes) { |
| - CallbacksDescriptor new_accessors_desc(name, accessors, attributes); |
| - return Map::CopyInsertDescriptor(map, &new_accessors_desc, INSERT_TRANSITION); |
| -} |
| - |
| - |
| bool JSObject::DefineFastAccessor(Handle<JSObject> object, |
| Handle<Name> name, |
| AccessorComponent component, |
| @@ -6686,8 +6697,11 @@ bool JSObject::DefineFastAccessor(Handle<JSObject> object, |
| ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors)) |
| : isolate->factory()->NewAccessorPair(); |
| accessors->set(component, *accessor); |
| - Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()), |
| - name, accessors, attributes); |
| + |
| + CallbacksDescriptor new_accessors_desc(name, accessors, attributes); |
| + Handle<Map> new_map = Map::CopyInsertDescriptor( |
| + handle(object->map()), &new_accessors_desc, INSERT_TRANSITION); |
| + |
| JSObject::MigrateToMap(object, new_map); |
| return true; |
| } |