Commit a021c6af authored by ishell's avatar ishell Committed by Commit bot

[field type tracking] Use breadth first traversal instead of recursion when updating field types.

... to avoid potential stack overflow when updating happens near the stack limit.

BUG=chromium:599440
LOG=Y

Review URL: https://codereview.chromium.org/1884653002

Cr-Commit-Position: refs/heads/master@{#35436}
parent 79b1ab61
......@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment