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) { |