| 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.
|
| }
|
|
|
|
|
|
|