| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index db4e29ba484e80b7901b95cda24862e1349abb2c..8254ee7e9efcab696058f80d976d832c5bb27f9e 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -3281,25 +3281,40 @@ void Map::UpdateFieldType(int descriptor, Handle<Name> name,
|
| Representation new_representation,
|
| Handle<Object> new_wrapped_type) {
|
| DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell());
|
| + // We store raw pointers in the queue, so no allocations are allowed.
|
| DisallowHeapAllocation no_allocation;
|
| PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
|
| if (details.type() != DATA) return;
|
| - Object* transitions = raw_transitions();
|
| - int num_transitions = TransitionArray::NumberOfTransitions(transitions);
|
| - for (int i = 0; i < num_transitions; ++i) {
|
| - Map* target = TransitionArray::GetTarget(transitions, i);
|
| - target->UpdateFieldType(descriptor, name, new_representation,
|
| - new_wrapped_type);
|
| - }
|
| - // It is allowed to change representation here only from None to something.
|
| - DCHECK(details.representation().Equals(new_representation) ||
|
| - details.representation().IsNone());
|
| -
|
| - // Skip if already updated the shared descriptor.
|
| - if (instance_descriptors()->GetValue(descriptor) == *new_wrapped_type) return;
|
| - DataDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor),
|
| - new_wrapped_type, details.attributes(), new_representation);
|
| - instance_descriptors()->Replace(descriptor, &d);
|
| +
|
| + Zone zone(GetIsolate()->allocator());
|
| + ZoneQueue<Map*> backlog(&zone);
|
| + backlog.push(this);
|
| +
|
| + while (!backlog.empty()) {
|
| + Map* current = backlog.front();
|
| + backlog.pop();
|
| +
|
| + Object* transitions = current->raw_transitions();
|
| + int num_transitions = TransitionArray::NumberOfTransitions(transitions);
|
| + for (int i = 0; i < num_transitions; ++i) {
|
| + Map* target = TransitionArray::GetTarget(transitions, i);
|
| + backlog.push(target);
|
| + }
|
| + DescriptorArray* descriptors = current->instance_descriptors();
|
| + PropertyDetails details = descriptors->GetDetails(descriptor);
|
| +
|
| + // It is allowed to change representation here only from None to something.
|
| + DCHECK(details.representation().Equals(new_representation) ||
|
| + details.representation().IsNone());
|
| +
|
| + // Skip if already updated the shared descriptor.
|
| + if (descriptors->GetValue(descriptor) != *new_wrapped_type) {
|
| + DataDescriptor d(name, descriptors->GetFieldIndex(descriptor),
|
| + new_wrapped_type, details.attributes(),
|
| + new_representation);
|
| + descriptors->Replace(descriptor, &d);
|
| + }
|
| + }
|
| }
|
|
|
| bool FieldTypeIsCleared(Representation rep, FieldType* type) {
|
|
|