Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 4ca3d57de2c4b560384e2f8649e481ffd6953202..d5bcdd667875d252e60f32e2c86dd31a1c96037d 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -1900,99 +1900,127 @@ MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
| } |
| -void JSObject::AddFastProperty(Handle<JSObject> object, |
| - Handle<Name> name, |
| - Handle<Object> value, |
| - PropertyAttributes attributes, |
| - StoreFromKeyed store_mode, |
| - ValueType value_type, |
| - TransitionFlag flag) { |
| - CALL_HEAP_FUNCTION_VOID( |
| - object->GetIsolate(), |
| - object->AddFastProperty( |
| - *name, *value, attributes, store_mode, value_type, flag)); |
| +static MaybeObject* CopyAddFieldDescriptor(Map* map, |
| + Name* name, |
| + int index, |
| + PropertyAttributes attributes, |
| + Representation representation, |
| + TransitionFlag flag) { |
| + FieldDescriptor new_field_desc(name, index, attributes, representation); |
| + return map->CopyAddDescriptor(&new_field_desc, flag); |
| } |
| -MaybeObject* JSObject::AddFastProperty(Name* name, |
| - Object* value, |
| - PropertyAttributes attributes, |
| - StoreFromKeyed store_mode, |
| - ValueType value_type, |
| - TransitionFlag flag) { |
| - ASSERT(!IsJSGlobalProxy()); |
| +static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, |
| + Handle<Name> name, |
| + int index, |
| + PropertyAttributes attributes, |
| + Representation representation, |
| + TransitionFlag flag) { |
| + CALL_HEAP_FUNCTION(map->GetIsolate(), |
| + CopyAddFieldDescriptor( |
| + *map, *name, index, attributes, representation, flag), |
| + Map); |
| +} |
| + |
| + |
| +void JSObject::AddFastProperty(Handle<JSObject> object, |
|
Toon Verwaest
2013/09/11 13:11:32
Could we rename this to either JSObject::AddField
|
| + Handle<Name> name, |
| + Handle<Object> value, |
| + PropertyAttributes attributes, |
| + StoreFromKeyed store_mode, |
| + ValueType value_type, |
| + TransitionFlag flag) { |
| + ASSERT(!object->IsJSGlobalProxy()); |
| ASSERT(DescriptorArray::kNotFound == |
| - map()->instance_descriptors()->Search( |
| - name, map()->NumberOfOwnDescriptors())); |
| + object->map()->instance_descriptors()->Search( |
| + *name, object->map()->NumberOfOwnDescriptors())); |
| // 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 = GetHeap()->isolate(); |
| - if (!name->IsCacheable(isolate) || TooManyFastProperties(store_mode)) { |
| - MaybeObject* maybe_failure = |
| - NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| - if (maybe_failure->IsFailure()) return maybe_failure; |
| - return AddSlowProperty(name, value, attributes); |
| + Isolate* isolate = object->GetIsolate(); |
| + if (!name->IsCacheable(isolate) || |
| + object->TooManyFastProperties(store_mode)) { |
| + NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| + AddSlowProperty(object, name, value, attributes); |
| + return; |
| } |
| // Compute the new index for new field. |
| - int index = map()->NextFreePropertyIndex(); |
| + int index = object->map()->NextFreePropertyIndex(); |
| // Allocate new instance descriptors with (name, index) added |
| - if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
| + if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
| Representation representation = value->OptimalRepresentation(value_type); |
| + Handle<Map> new_map = CopyAddFieldDescriptor( |
| + handle(object->map()), name, index, attributes, representation, flag); |
| - FieldDescriptor new_field(name, index, attributes, representation); |
| - |
| - Map* new_map; |
| - MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag); |
| - if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| - |
| - int unused_property_fields = map()->unused_property_fields() - 1; |
| + int unused_property_fields = object->map()->unused_property_fields() - 1; |
|
Toon Verwaest
2013/09/11 13:11:32
Now that you created CopyAddFieldDescriptor, you c
|
| if (unused_property_fields < 0) { |
| unused_property_fields += kFieldsAdded; |
| } |
| new_map->set_unused_property_fields(unused_property_fields); |
| - return AddFastPropertyUsingMap(new_map, name, value, index, representation); |
| + CALL_HEAP_FUNCTION_VOID( |
| + isolate, |
| + object->AddFastPropertyUsingMap( |
| + *new_map, *name, *value, index, representation)); |
| } |
| -void JSObject::AddConstantProperty(Handle<JSObject> object, |
| - Handle<Name> name, |
| - Handle<Object> constant, |
| - PropertyAttributes attributes, |
| - TransitionFlag flag) { |
| - CALL_HEAP_FUNCTION_VOID( |
| - object->GetIsolate(), |
| - object->AddConstantProperty(*name, *constant, attributes, flag)); |
| +static MaybeObject* CopyAddConstantDescriptor(Map* map, |
| + Name* name, |
| + Object* value, |
| + PropertyAttributes attributes, |
| + TransitionFlag flag) { |
| + ConstantDescriptor new_constant_desc(name, value, attributes); |
| + return map->CopyAddDescriptor(&new_constant_desc, flag); |
| } |
| -MaybeObject* JSObject::AddConstantProperty( |
| - Name* name, |
| - Object* constant, |
| - PropertyAttributes attributes, |
| - TransitionFlag initial_flag) { |
| - // Allocate new instance descriptors with (name, constant) added |
| - ConstantDescriptor d(name, constant, attributes); |
| +static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map, |
| + Handle<Name> name, |
| + Handle<Object> value, |
| + PropertyAttributes attributes, |
| + TransitionFlag flag) { |
| + CALL_HEAP_FUNCTION(map->GetIsolate(), |
| + CopyAddConstantDescriptor( |
| + *map, *name, *value, attributes, flag), |
| + Map); |
| +} |
| + |
| +void JSObject::AddConstantProperty(Handle<JSObject> object, |
| + Handle<Name> name, |
| + Handle<Object> constant, |
| + PropertyAttributes attributes, |
| + TransitionFlag initial_flag) { |
| TransitionFlag flag = |
| // Do not add transitions to global objects. |
| - (IsGlobalObject() || |
| + (object->IsGlobalObject() || |
| // Don't add transitions to special properties with non-trivial |
| // attributes. |
| attributes != NONE) |
| ? OMIT_TRANSITION |
| : initial_flag; |
| - Map* new_map; |
| - MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); |
| - if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| + // Allocate new instance descriptors with (name, constant) added. |
| + Handle<Map> new_map = CopyAddConstantDescriptor( |
| + handle(object->map()), name, constant, attributes, flag); |
| - set_map(new_map); |
| - return constant; |
| + object->set_map(*new_map); |
| +} |
| + |
| + |
| +// TODO(mstarzinger): Temporary wrapper until handlified. |
| +static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict, |
| + Handle<Name> name, |
| + Handle<Object> value, |
| + PropertyDetails details) { |
| + CALL_HEAP_FUNCTION(dict->GetIsolate(), |
| + dict->Add(*name, *value, details), |
| + NameDictionary); |
| } |
| @@ -2000,49 +2028,30 @@ void JSObject::AddSlowProperty(Handle<JSObject> object, |
| Handle<Name> name, |
| Handle<Object> value, |
| PropertyAttributes attributes) { |
| - CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
| - object->AddSlowProperty(*name, *value, attributes)); |
| -} |
| - |
| - |
| -MaybeObject* JSObject::AddSlowProperty(Name* name, |
| - Object* value, |
| - PropertyAttributes attributes) { |
| - ASSERT(!HasFastProperties()); |
| - NameDictionary* dict = property_dictionary(); |
| - Object* store_value = value; |
| - if (IsGlobalObject()) { |
| + ASSERT(!object->HasFastProperties()); |
| + Isolate* isolate = object->GetIsolate(); |
| + Handle<NameDictionary> dict(object->property_dictionary()); |
| + if (object->IsGlobalObject()) { |
| // In case name is an orphaned property reuse the cell. |
| - int entry = dict->FindEntry(name); |
| + int entry = dict->FindEntry(*name); |
| if (entry != NameDictionary::kNotFound) { |
| - store_value = dict->ValueAt(entry); |
| - MaybeObject* maybe_type = |
| - PropertyCell::cast(store_value)->SetValueInferType(value); |
| - if (maybe_type->IsFailure()) return maybe_type; |
| + Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry))); |
| + PropertyCell::SetValueInferType(cell, value); |
| // Assign an enumeration index to the property and update |
| // SetNextEnumerationIndex. |
| int index = dict->NextEnumerationIndex(); |
| PropertyDetails details = PropertyDetails(attributes, NORMAL, index); |
| dict->SetNextEnumerationIndex(index + 1); |
| - dict->SetEntry(entry, name, store_value, details); |
| - return value; |
| - } |
| - Heap* heap = GetHeap(); |
| - { MaybeObject* maybe_store_value = |
| - heap->AllocatePropertyCell(value); |
| - if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
| + dict->SetEntry(entry, *name, *cell, details); |
| + return; |
| } |
| - MaybeObject* maybe_type = |
| - PropertyCell::cast(store_value)->SetValueInferType(value); |
| - if (maybe_type->IsFailure()) return maybe_type; |
| + Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value); |
| + PropertyCell::SetValueInferType(cell, value); |
| + value = cell; |
| } |
| PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
| - Object* result; |
| - { MaybeObject* maybe_result = dict->Add(name, store_value, details); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - if (dict != result) set_properties(NameDictionary::cast(result)); |
| - return value; |
| + Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details); |
| + if (*dict != *result) object->set_properties(*result); |
| } |
| @@ -3788,7 +3797,7 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, |
| } |
| -static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup, |
| +MaybeObject* JSObject::SetPropertyUsingTransition(LookupResult* lookup, |
| Handle<Name> name, |
| Handle<Object> value, |
| PropertyAttributes attributes) { |
| @@ -14491,17 +14500,6 @@ PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { |
| } |
| -// TODO(mstarzinger): Temporary wrapper until handlified. |
| -static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict, |
| - Handle<Name> name, |
| - Handle<Object> value, |
| - PropertyDetails details) { |
| - CALL_HEAP_FUNCTION(dict->GetIsolate(), |
| - dict->Add(*name, *value, details), |
| - NameDictionary); |
| -} |
| - |
| - |
| Handle<PropertyCell> GlobalObject::EnsurePropertyCell( |
| Handle<GlobalObject> global, |
| Handle<Name> name) { |
| @@ -16080,6 +16078,14 @@ Type* PropertyCell::UpdateType(Handle<PropertyCell> cell, |
| } |
| +void PropertyCell::SetValueInferType(Handle<PropertyCell> cell, |
| + Handle<Object> value, |
| + WriteBarrierMode mode) { |
| + CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(), |
| + cell->SetValueInferType(*value, mode)); |
| +} |
| + |
| + |
| MaybeObject* PropertyCell::SetValueInferType(Object* value, |
| WriteBarrierMode ignored) { |
| set_value(value, ignored); |