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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 delayed_weak_stack_.Add(it->second); | 165 delayed_weak_stack_.Add(it->second); |
166 } | 166 } |
167 delay_set_.erase(ret.first, ret.second); | 167 delay_set_.erase(ret.first, ret.second); |
168 } | 168 } |
169 intptr_t size = raw_obj->Size(); | 169 intptr_t size = raw_obj->Size(); |
170 // Check whether object should be promoted. | 170 // Check whether object should be promoted. |
171 if (scavenger_->survivor_end_ <= raw_addr) { | 171 if (scavenger_->survivor_end_ <= raw_addr) { |
172 // Not a survivor of a previous scavenge. Just copy the object into the | 172 // Not a survivor of a previous scavenge. Just copy the object into the |
173 // to space. | 173 // to space. |
174 new_addr = scavenger_->TryAllocate(size); | 174 new_addr = scavenger_->TryAllocate(size); |
| 175 if (HeapTrace::is_enabled()) { |
| 176 heap_->trace()->TraceCopy(raw_addr, new_addr); |
| 177 } |
175 } else { | 178 } else { |
176 // TODO(iposva): Experiment with less aggressive promotion. For example | 179 // TODO(iposva): Experiment with less aggressive promotion. For example |
177 // a coin toss determines if an object is promoted or whether it should | 180 // a coin toss determines if an object is promoted or whether it should |
178 // survive in this generation. | 181 // survive in this generation. |
179 // | 182 // |
180 // This object is a survivor of a previous scavenge. Attempt to promote | 183 // This object is a survivor of a previous scavenge. Attempt to promote |
181 // the object. | 184 // the object. |
182 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); | 185 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); |
183 if (new_addr != 0) { | 186 if (new_addr != 0) { |
184 // If promotion succeeded then we need to remember it so that it can | 187 // If promotion succeeded then we need to remember it so that it can |
185 // be traversed later. | 188 // be traversed later. |
186 scavenger_->PushToPromotedStack(new_addr); | 189 scavenger_->PushToPromotedStack(new_addr); |
187 bytes_promoted_ += size; | 190 bytes_promoted_ += size; |
| 191 if (HeapTrace::is_enabled()) { |
| 192 heap_->trace()->TracePromotion(raw_addr, new_addr); |
| 193 } |
188 } else if (!scavenger_->had_promotion_failure_) { | 194 } else if (!scavenger_->had_promotion_failure_) { |
189 // Signal a promotion failure and set the growth policy for | 195 // Signal a promotion failure and set the growth policy for |
190 // this, and all subsequent promotion allocations, to force | 196 // this, and all subsequent promotion allocations, to force |
191 // growth. | 197 // growth. |
192 scavenger_->had_promotion_failure_ = true; | 198 scavenger_->had_promotion_failure_ = true; |
193 growth_policy_ = PageSpace::kForceGrowth; | 199 growth_policy_ = PageSpace::kForceGrowth; |
194 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); | 200 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); |
195 if (new_addr != 0) { | 201 if (new_addr != 0) { |
196 scavenger_->PushToPromotedStack(new_addr); | 202 scavenger_->PushToPromotedStack(new_addr); |
197 bytes_promoted_ += size; | 203 bytes_promoted_ += size; |
| 204 if (HeapTrace::is_enabled()) { |
| 205 heap_->trace()->TracePromotion(raw_addr, new_addr); |
| 206 } |
198 } else { | 207 } else { |
199 // Promotion did not succeed. Copy into the to space | 208 // Promotion did not succeed. Copy into the to space |
200 // instead. | 209 // instead. |
201 new_addr = scavenger_->TryAllocate(size); | 210 new_addr = scavenger_->TryAllocate(size); |
| 211 if (HeapTrace::is_enabled()) { |
| 212 heap_->trace()->TraceCopy(raw_addr, new_addr); |
| 213 } |
202 } | 214 } |
203 } else { | 215 } else { |
204 ASSERT(growth_policy_ == PageSpace::kForceGrowth); | 216 ASSERT(growth_policy_ == PageSpace::kForceGrowth); |
205 // Promotion did not succeed. Copy into the to space instead. | 217 // Promotion did not succeed. Copy into the to space instead. |
206 new_addr = scavenger_->TryAllocate(size); | 218 new_addr = scavenger_->TryAllocate(size); |
| 219 if (HeapTrace::is_enabled()) { |
| 220 heap_->trace()->TraceCopy(raw_addr, new_addr); |
| 221 } |
207 } | 222 } |
208 } | 223 } |
209 // During a scavenge we always succeed to at least copy all of the | 224 // During a scavenge we always succeed to at least copy all of the |
210 // current objects to the to space. | 225 // current objects to the to space. |
211 ASSERT(new_addr != 0); | 226 ASSERT(new_addr != 0); |
212 // Copy the object to the new location. | 227 // Copy the object to the new location. |
213 memmove(reinterpret_cast<void*>(new_addr), | 228 memmove(reinterpret_cast<void*>(new_addr), |
214 reinterpret_cast<void*>(raw_addr), | 229 reinterpret_cast<void*>(raw_addr), |
215 size); | 230 size); |
216 // Remember forwarding address. | 231 // Remember forwarding address. |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 | 643 |
629 if (FLAG_verify_before_gc) { | 644 if (FLAG_verify_before_gc) { |
630 OS::PrintErr("Verifying before Scavenge..."); | 645 OS::PrintErr("Verifying before Scavenge..."); |
631 heap_->Verify(); | 646 heap_->Verify(); |
632 OS::PrintErr(" done.\n"); | 647 OS::PrintErr(" done.\n"); |
633 } | 648 } |
634 | 649 |
635 if (FLAG_verbose_gc) { | 650 if (FLAG_verbose_gc) { |
636 OS::PrintErr("Start scavenge for %s collection\n", gc_reason); | 651 OS::PrintErr("Start scavenge for %s collection\n", gc_reason); |
637 } | 652 } |
| 653 uword prev_first_obj_start = FirstObjectStart(); |
| 654 uword prev_top_addr = *(TopAddress()); |
638 Timer timer(FLAG_verbose_gc, "Scavenge"); | 655 Timer timer(FLAG_verbose_gc, "Scavenge"); |
639 timer.Start(); | 656 timer.Start(); |
640 | 657 |
641 intptr_t in_use_before = in_use(); | 658 intptr_t in_use_before = in_use(); |
642 | 659 |
643 // Setup the visitor and run a scavenge. | 660 // Setup the visitor and run a scavenge. |
644 ScavengerVisitor visitor(isolate, this); | 661 ScavengerVisitor visitor(isolate, this); |
645 Prologue(isolate, invoke_api_callbacks); | 662 Prologue(isolate, invoke_api_callbacks); |
646 IterateRoots(isolate, &visitor, !invoke_api_callbacks); | 663 IterateRoots(isolate, &visitor, !invoke_api_callbacks); |
647 ProcessToSpace(&visitor); | 664 ProcessToSpace(&visitor); |
(...skipping 25 matching lines...) Expand all Loading... |
673 (visitor.bytes_promoted() + KB2) / KB, | 690 (visitor.bytes_promoted() + KB2) / KB, |
674 promoted); | 691 promoted); |
675 } | 692 } |
676 | 693 |
677 if (FLAG_verify_after_gc) { | 694 if (FLAG_verify_after_gc) { |
678 OS::PrintErr("Verifying after Scavenge..."); | 695 OS::PrintErr("Verifying after Scavenge..."); |
679 heap_->Verify(); | 696 heap_->Verify(); |
680 OS::PrintErr(" done.\n"); | 697 OS::PrintErr(" done.\n"); |
681 } | 698 } |
682 | 699 |
| 700 if (HeapTrace::is_enabled()) { |
| 701 heap_->trace()->TraceDeathRange(prev_first_obj_start, prev_top_addr); |
| 702 } |
| 703 |
683 count_++; | 704 count_++; |
684 // Done scavenging. Reset the marker. | 705 // Done scavenging. Reset the marker. |
685 ASSERT(scavenging_); | 706 ASSERT(scavenging_); |
686 scavenging_ = false; | 707 scavenging_ = false; |
687 } | 708 } |
688 | 709 |
689 | 710 |
690 void Scavenger::WriteProtect(bool read_only) { | 711 void Scavenger::WriteProtect(bool read_only) { |
691 space_->Protect( | 712 space_->Protect( |
692 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); | 713 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); |
(...skipping 13 matching lines...) Expand all Loading... |
706 PeerTable::iterator it = peer_table_.find(raw_obj); | 727 PeerTable::iterator it = peer_table_.find(raw_obj); |
707 return (it == peer_table_.end()) ? NULL : it->second; | 728 return (it == peer_table_.end()) ? NULL : it->second; |
708 } | 729 } |
709 | 730 |
710 | 731 |
711 int64_t Scavenger::PeerCount() const { | 732 int64_t Scavenger::PeerCount() const { |
712 return static_cast<int64_t>(peer_table_.size()); | 733 return static_cast<int64_t>(peer_table_.size()); |
713 } | 734 } |
714 | 735 |
715 } // namespace dart | 736 } // namespace dart |
OLD | NEW |