Index: runtime/vm/scavenger.cc |
=================================================================== |
--- runtime/vm/scavenger.cc (revision 35211) |
+++ runtime/vm/scavenger.cc (working copy) |
@@ -499,16 +499,26 @@ |
while (queue != NULL) { |
WeakReferenceSet* reference_set = WeakReferenceSet::Pop(&queue); |
ASSERT(reference_set != NULL); |
+ intptr_t num_keys = reference_set->num_keys(); |
+ intptr_t num_values = reference_set->num_values(); |
+ if ((num_keys == 1) && (num_values == 1) && |
+ reference_set->SingletonKeyEqualsValue()) { |
+ // We do not have to process sets that have just one key/value pair |
+ // and the key and value are identical. |
+ continue; |
+ } |
bool is_unreachable = true; |
// Test each key object for reachability. If a key object is |
// reachable, all value objects should be scavenged. |
- for (intptr_t k = 0; k < reference_set->num_keys(); ++k) { |
+ for (intptr_t k = 0; k < num_keys; ++k) { |
if (!IsUnreachable(reference_set->get_key(k))) { |
- for (intptr_t v = 0; v < reference_set->num_values(); ++v) { |
+ for (intptr_t v = 0; v < num_values; ++v) { |
visitor->VisitPointer(reference_set->get_value(v)); |
} |
is_unreachable = false; |
- delete reference_set; |
+ // Since we have found a key object that is reachable and all |
+ // value objects have been marked we can break out of iterating |
+ // this set and move on to the next set. |
break; |
} |
} |
@@ -523,17 +533,16 @@ |
ProcessToSpace(visitor); |
} else { |
// Break out of the loop if there has been no forward process. |
+ // All key objects in the weak reference sets are unreachable |
+ // so we reset the weak reference sets queue. |
+ state->set_delayed_weak_reference_sets(NULL); |
break; |
} |
} |
- // Deallocate any unreachable references on the delay queue. |
- if (state->delayed_weak_reference_sets() != NULL) { |
- WeakReferenceSet* queue = state->delayed_weak_reference_sets(); |
- state->set_delayed_weak_reference_sets(NULL); |
- while (queue != NULL) { |
- delete WeakReferenceSet::Pop(&queue); |
- } |
- } |
+ ASSERT(state->delayed_weak_reference_sets() == NULL); |
+ // All weak reference sets are zone allocated and unmarked references which |
+ // were on the delay queue will be freed when the zone is released in the |
+ // epilog callback. |
} |