OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/scavenger.h" | 5 #include "vm/scavenger.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 while (true) { | 492 while (true) { |
493 WeakReferenceSet* queue = state->delayed_weak_reference_sets(); | 493 WeakReferenceSet* queue = state->delayed_weak_reference_sets(); |
494 if (queue == NULL) { | 494 if (queue == NULL) { |
495 // The delay queue is empty therefore no clean-up is required. | 495 // The delay queue is empty therefore no clean-up is required. |
496 return; | 496 return; |
497 } | 497 } |
498 state->set_delayed_weak_reference_sets(NULL); | 498 state->set_delayed_weak_reference_sets(NULL); |
499 while (queue != NULL) { | 499 while (queue != NULL) { |
500 WeakReferenceSet* reference_set = WeakReferenceSet::Pop(&queue); | 500 WeakReferenceSet* reference_set = WeakReferenceSet::Pop(&queue); |
501 ASSERT(reference_set != NULL); | 501 ASSERT(reference_set != NULL); |
| 502 intptr_t num_keys = reference_set->num_keys(); |
| 503 intptr_t num_values = reference_set->num_values(); |
| 504 if ((num_keys == 1) && (num_values == 1) && |
| 505 reference_set->SingletonKeyEqualsValue()) { |
| 506 // We do not have to process sets that have just one key/value pair |
| 507 // and the key and value are identical. |
| 508 continue; |
| 509 } |
502 bool is_unreachable = true; | 510 bool is_unreachable = true; |
503 // Test each key object for reachability. If a key object is | 511 // Test each key object for reachability. If a key object is |
504 // reachable, all value objects should be scavenged. | 512 // reachable, all value objects should be scavenged. |
505 for (intptr_t k = 0; k < reference_set->num_keys(); ++k) { | 513 for (intptr_t k = 0; k < num_keys; ++k) { |
506 if (!IsUnreachable(reference_set->get_key(k))) { | 514 if (!IsUnreachable(reference_set->get_key(k))) { |
507 for (intptr_t v = 0; v < reference_set->num_values(); ++v) { | 515 for (intptr_t v = 0; v < num_values; ++v) { |
508 visitor->VisitPointer(reference_set->get_value(v)); | 516 visitor->VisitPointer(reference_set->get_value(v)); |
509 } | 517 } |
510 is_unreachable = false; | 518 is_unreachable = false; |
511 delete reference_set; | 519 // Since we have found a key object that is reachable and all |
| 520 // value objects have been marked we can break out of iterating |
| 521 // this set and move on to the next set. |
512 break; | 522 break; |
513 } | 523 } |
514 } | 524 } |
515 // If all key objects are unreachable put the reference on a | 525 // If all key objects are unreachable put the reference on a |
516 // delay queue. This reference will be revisited if another | 526 // delay queue. This reference will be revisited if another |
517 // reference is scavenged. | 527 // reference is scavenged. |
518 if (is_unreachable) { | 528 if (is_unreachable) { |
519 state->DelayWeakReferenceSet(reference_set); | 529 state->DelayWeakReferenceSet(reference_set); |
520 } | 530 } |
521 } | 531 } |
522 if ((resolved_top_ < top_) || PromotedStackHasMore()) { | 532 if ((resolved_top_ < top_) || PromotedStackHasMore()) { |
523 ProcessToSpace(visitor); | 533 ProcessToSpace(visitor); |
524 } else { | 534 } else { |
525 // Break out of the loop if there has been no forward process. | 535 // Break out of the loop if there has been no forward process. |
| 536 // All key objects in the weak reference sets are unreachable |
| 537 // so we reset the weak reference sets queue. |
| 538 state->set_delayed_weak_reference_sets(NULL); |
526 break; | 539 break; |
527 } | 540 } |
528 } | 541 } |
529 // Deallocate any unreachable references on the delay queue. | 542 ASSERT(state->delayed_weak_reference_sets() == NULL); |
530 if (state->delayed_weak_reference_sets() != NULL) { | 543 // All weak reference sets are zone allocated and unmarked references which |
531 WeakReferenceSet* queue = state->delayed_weak_reference_sets(); | 544 // were on the delay queue will be freed when the zone is released in the |
532 state->set_delayed_weak_reference_sets(NULL); | 545 // epilog callback. |
533 while (queue != NULL) { | |
534 delete WeakReferenceSet::Pop(&queue); | |
535 } | |
536 } | |
537 } | 546 } |
538 | 547 |
539 | 548 |
540 void Scavenger::IterateWeakRoots(Isolate* isolate, | 549 void Scavenger::IterateWeakRoots(Isolate* isolate, |
541 HandleVisitor* visitor, | 550 HandleVisitor* visitor, |
542 bool visit_prologue_weak_persistent_handles) { | 551 bool visit_prologue_weak_persistent_handles) { |
543 isolate->VisitWeakPersistentHandles(visitor, | 552 isolate->VisitWeakPersistentHandles(visitor, |
544 visit_prologue_weak_persistent_handles); | 553 visit_prologue_weak_persistent_handles); |
545 } | 554 } |
546 | 555 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 } | 758 } |
750 | 759 |
751 | 760 |
752 void Scavenger::FreeExternal(intptr_t size) { | 761 void Scavenger::FreeExternal(intptr_t size) { |
753 ASSERT(size >= 0); | 762 ASSERT(size >= 0); |
754 external_size_ -= size; | 763 external_size_ -= size; |
755 ASSERT(external_size_ >= 0); | 764 ASSERT(external_size_ >= 0); |
756 } | 765 } |
757 | 766 |
758 } // namespace dart | 767 } // namespace dart |
OLD | NEW |