Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index a7a5c480f32cb374fcf43d6b4f9c02422684e382..680abc36ab24be64b8829aeba96155b647f98541 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -3164,32 +3164,30 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map, |
// respective prototypes. |
UpdatePrototypeUserRegistration(old_map, new_map, new_map->GetIsolate()); |
- if (object->HasFastProperties()) { |
- if (!new_map->is_dictionary_map()) { |
- MigrateFastToFast(object, new_map); |
- if (old_map->is_prototype_map()) { |
- DCHECK(!old_map->is_stable()); |
- DCHECK(new_map->is_stable()); |
- // Clear out the old descriptor array to avoid problems to sharing |
- // the descriptor array without using an explicit. |
- old_map->InitializeDescriptors( |
- old_map->GetHeap()->empty_descriptor_array(), |
- LayoutDescriptor::FastPointerLayout()); |
- // Ensure that no transition was inserted for prototype migrations. |
- DCHECK_EQ(0, TransitionArray::NumberOfTransitions( |
- old_map->raw_transitions())); |
- DCHECK(new_map->GetBackPointer()->IsUndefined()); |
- } |
- } else { |
- MigrateFastToSlow(object, new_map, expected_additional_properties); |
- } |
- } else { |
+ if (old_map->is_dictionary_map()) { |
// For slow-to-fast migrations JSObject::MigrateSlowToFast() |
// must be used instead. |
CHECK(new_map->is_dictionary_map()); |
// Slow-to-slow migration is trivial. |
object->set_map(*new_map); |
+ } else if (!new_map->is_dictionary_map()) { |
+ MigrateFastToFast(object, new_map); |
+ if (old_map->is_prototype_map()) { |
+ DCHECK(!old_map->is_stable()); |
+ DCHECK(new_map->is_stable()); |
+ // Clear out the old descriptor array to avoid problems to sharing |
+ // the descriptor array without using an explicit. |
+ old_map->InitializeDescriptors( |
+ old_map->GetHeap()->empty_descriptor_array(), |
+ LayoutDescriptor::FastPointerLayout()); |
+ // Ensure that no transition was inserted for prototype migrations. |
+ DCHECK_EQ( |
+ 0, TransitionArray::NumberOfTransitions(old_map->raw_transitions())); |
+ DCHECK(new_map->GetBackPointer()->IsUndefined()); |
+ } |
+ } else { |
+ MigrateFastToSlow(object, new_map, expected_additional_properties); |
} |
// Careful: Don't allocate here! |
@@ -4608,8 +4606,7 @@ Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value, |
Isolate* isolate = it->isolate(); |
- if (!receiver->map()->is_extensible() && |
- (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()))) { |
+ if (it->ExtendingNonExtensible(receiver)) { |
RETURN_FAILURE( |
isolate, should_throw, |
NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName())); |
@@ -4642,9 +4639,10 @@ Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value, |
} else { |
// Migrate to the most up-to-date map that will be able to store |value| |
// under it->name() with |attributes|. |
- it->PrepareTransitionToDataProperty(value, attributes, store_mode); |
+ it->PrepareTransitionToDataProperty(receiver, value, attributes, |
+ store_mode); |
DCHECK_EQ(LookupIterator::TRANSITION, it->state()); |
- it->ApplyTransitionToDataProperty(); |
+ it->ApplyTransitionToDataProperty(receiver); |
// TODO(verwaest): Encapsulate dictionary handling better. |
if (receiver->map()->is_dictionary_map()) { |
@@ -9930,28 +9928,32 @@ bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { |
return false; |
} |
+namespace { |
-// static |
-Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, |
- Handle<Object> value) { |
- // Dictionaries can store any property value. |
- if (map->is_dictionary_map()) return map; |
- |
- // Migrate to the newest map before storing the property. |
- map = Update(map); |
- |
- Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
- |
- if (descriptors->CanHoldValue(descriptor, *value)) return map; |
+Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor, |
+ Handle<Object> value) { |
+ if (map->instance_descriptors()->CanHoldValue(descriptor, *value)) return map; |
Isolate* isolate = map->GetIsolate(); |
PropertyAttributes attributes = |
- descriptors->GetDetails(descriptor).attributes(); |
+ map->instance_descriptors()->GetDetails(descriptor).attributes(); |
Representation representation = value->OptimalRepresentation(); |
Handle<FieldType> type = value->OptimalType(isolate, representation); |
- return ReconfigureProperty(map, descriptor, kData, attributes, representation, |
- type, FORCE_FIELD); |
+ return Map::ReconfigureProperty(map, descriptor, kData, attributes, |
+ representation, type, FORCE_FIELD); |
+} |
+ |
+} // namespace |
+ |
+// static |
+Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, |
+ Handle<Object> value) { |
+ // Dictionaries can store any property value. |
+ if (map->is_dictionary_map()) return map; |
+ |
+ // Update to the newest map before storing the property. |
+ return UpdateDescriptorForValue(Update(map), descriptor, value); |
} |
@@ -9975,7 +9977,7 @@ Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, |
->GetDetails(descriptor) |
.attributes()); |
- return Map::PrepareForDataProperty(transition, descriptor, value); |
+ return UpdateDescriptorForValue(transition, descriptor, value); |
} |
TransitionFlag flag = INSERT_TRANSITION; |