Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 10971cfb7c53c8695f620f49129373c1f489e882..c8455d00e70e4f77d0d3475c4d9a5e395ff8ce32 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -1812,7 +1812,8 @@ static bool IsIdentifier(UnicodeCache* cache, Name* name) { |
| MaybeObject* JSObject::AddFastProperty(Name* name, |
| Object* value, |
| PropertyAttributes attributes, |
| - StoreFromKeyed store_mode) { |
| + StoreFromKeyed store_mode, |
| + ValueType value_type) { |
| ASSERT(!IsJSGlobalProxy()); |
| ASSERT(DescriptorArray::kNotFound == |
| map()->instance_descriptors()->Search( |
| @@ -1838,8 +1839,8 @@ MaybeObject* JSObject::AddFastProperty(Name* name, |
| int index = map()->NextFreePropertyIndex(); |
| // Allocate new instance descriptors with (name, index) added |
| - Representation representation = IsJSContextExtensionObject() |
| - ? Representation::Tagged() : value->OptimalRepresentation(); |
| + if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
| + Representation representation = value->OptimalRepresentation(value_type); |
| FieldDescriptor new_field(name, index, attributes, representation); |
| @@ -1956,7 +1957,8 @@ MaybeObject* JSObject::AddProperty(Name* name, |
| PropertyAttributes attributes, |
| StrictModeFlag strict_mode, |
| JSReceiver::StoreFromKeyed store_mode, |
| - ExtensibilityCheck extensibility_check) { |
| + ExtensibilityCheck extensibility_check, |
| + ValueType value_type) { |
| ASSERT(!IsJSGlobalProxy()); |
| Map* map_of_this = map(); |
| Heap* heap = GetHeap(); |
| @@ -1983,7 +1985,8 @@ MaybeObject* JSObject::AddProperty(Name* name, |
| JSFunction::cast(value), |
| attributes); |
| } else { |
| - result = AddFastProperty(name, value, attributes, store_mode); |
| + result = AddFastProperty( |
| + name, value, attributes, store_mode, value_type); |
| } |
| } else { |
| // Normalize the object to prevent very large instance descriptors. |
| @@ -2267,7 +2270,7 @@ bool Map::InstancesNeedRewriting(Map* target, |
| int limit = NumberOfOwnDescriptors(); |
| for (int i = 0; i < limit; i++) { |
| if (new_desc->GetDetails(i).representation().IsDouble() && |
| - old_desc->GetDetails(i).representation().IsSmi()) { |
| + !old_desc->GetDetails(i).representation().IsDouble()) { |
| return true; |
| } |
| } |
| @@ -2338,8 +2341,9 @@ MaybeObject* JSObject::MigrateToMap(Map* new_map) { |
| ? old_descriptors->GetValue(i) |
| : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); |
| if (FLAG_track_double_fields && |
| - old_details.representation().IsSmi() && |
| + !old_details.representation().IsDouble() && |
| details.representation().IsDouble()) { |
| + if (old_details.representation().IsNone()) value = Smi::FromInt(0); |
| // Objects must be allocated in the old object space, since the |
| // overall number of HeapNumbers needed for the conversion might |
| // exceed the capacity of new space, and we would fail repeatedly |
| @@ -2392,7 +2396,7 @@ MaybeObject* JSObject::GeneralizeFieldRepresentation( |
| MaybeObject* maybe_new_map = |
| map()->GeneralizeRepresentation(modify_index, new_representation); |
| if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| - ASSERT(map() != new_map || new_map->FindRootMap()->is_deprecated()); |
| + if (map() == new_map) return this; |
| return MigrateToMap(new_map); |
| } |
| @@ -2569,10 +2573,17 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, |
| Representation old_representation = |
| old_descriptors->GetDetails(modify_index).representation(); |
| - if (old_representation.IsNone()) { |
| - UNREACHABLE(); |
| + if (old_representation.IsNone() && |
|
danno
2013/06/06 13:07:32
Add comment:
"It's fine to transition from None to
Toon Verwaest
2013/06/06 13:22:26
Done.
|
| + !new_representation.IsNone() && |
| + !new_representation.IsDouble()) { |
| + if (FLAG_trace_generalization) { |
| + PrintF("initializing representation %i: %p -> %s\n", |
| + modify_index, |
| + static_cast<void*>(this), |
| + new_representation.Mnemonic()); |
| + } |
| old_descriptors->SetRepresentation(modify_index, new_representation); |
| - return this; |
| + return old_map; |
| } |
| int descriptors = old_map->NumberOfOwnDescriptors(); |
| @@ -2598,7 +2609,7 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, |
| updated_descriptors->GetDetails(modify_index).representation(); |
| if (new_representation.fits_into(updated_representation)) { |
| if (FLAG_trace_generalization && |
| - !(modify_index == 0 && new_representation.IsSmi())) { |
| + !(modify_index == 0 && new_representation.IsNone())) { |
| PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| PrintF("migrating to existing map %p(%s) -> %p(%s)\n", |
| static_cast<void*>(this), |
| @@ -2636,7 +2647,7 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, |
| old_descriptors->GetKey(descriptor), new_descriptors); |
| if (FLAG_trace_generalization && |
| - !(modify_index == 0 && new_representation.IsSmi())) { |
| + !(modify_index == 0 && new_representation.IsNone())) { |
| PrintF("migrating to new map %i: %p(%s) -> %p(%s) (%i steps)\n", |
| modify_index, |
| static_cast<void*>(this), |
| @@ -3928,10 +3939,12 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( |
| Handle<JSObject> object, |
| Handle<Name> key, |
| Handle<Object> value, |
| - PropertyAttributes attributes) { |
| + PropertyAttributes attributes, |
| + ValueType value_type) { |
| CALL_HEAP_FUNCTION( |
| object->GetIsolate(), |
| - object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes), |
| + object->SetLocalPropertyIgnoreAttributes( |
| + *key, *value, attributes, value_type), |
| Object); |
| } |
| @@ -3939,7 +3952,8 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( |
| MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| Name* name_raw, |
| Object* value_raw, |
| - PropertyAttributes attributes) { |
| + PropertyAttributes attributes, |
| + ValueType value_type) { |
| // Make sure that the top context does not change when doing callbacks or |
| // interceptor calls. |
| AssertNoContextChange ncc; |
| @@ -3965,13 +3979,16 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( |
| name_raw, |
| value_raw, |
| - attributes); |
| + attributes, |
| + value_type); |
| } |
| // Check for accessor in prototype chain removed here in clone. |
| if (!lookup.IsFound()) { |
| // Neither properties nor transitions found. |
| - return AddProperty(name_raw, value_raw, attributes, kNonStrictMode); |
| + return AddProperty( |
| + name_raw, value_raw, attributes, kNonStrictMode, |
| + MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, value_type); |
| } |
| // From this point on everything needs to be handlified. |
| @@ -3998,9 +4015,13 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| } |
| case FIELD: { |
| Representation representation = lookup.representation(); |
| - if (!value->FitsRepresentation(representation)) { |
| + Representation value_representation = value_type == FORCE_TAGGED |
| + ? Representation::Tagged() |
| + : value->OptimalRepresentation(); |
|
danno
2013/06/06 13:07:32
Just pass value_type into OptimalRepresentation()
Toon Verwaest
2013/06/06 13:22:26
Done.
|
| + if (value_type != PLACEHOLDER_VALUE && |
| + !value_representation.fits_into(representation)) { |
| MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation( |
| - lookup.GetDescriptorIndex(), value->OptimalRepresentation()); |
| + lookup.GetDescriptorIndex(), value_representation); |
| if (maybe_failure->IsFailure()) return maybe_failure; |
| DescriptorArray* desc = self->map()->instance_descriptors(); |
| int descriptor = lookup.GetDescriptorIndex(); |
| @@ -4041,9 +4062,13 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| if (details.type() == FIELD) { |
| if (attributes == details.attributes()) { |
| Representation representation = details.representation(); |
| - if (!value->FitsRepresentation(representation)) { |
| + Representation value_representation = value_type == FORCE_TAGGED |
| + ? Representation::Tagged() |
| + : value->OptimalRepresentation(); |
|
danno
2013/06/06 13:07:32
Same here.
Toon Verwaest
2013/06/06 13:22:26
Done.
|
| + if (value_type != PLACEHOLDER_VALUE && |
| + !value_representation.fits_into(representation)) { |
| MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( |
| - descriptor, value->OptimalRepresentation()); |
| + descriptor, value_representation); |
| if (!maybe_map->To(&transition_map)) return maybe_map; |
| Object* back = transition_map->GetBackPointer(); |
| if (back->IsMap()) { |