| 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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 intptr_t bytes_promoted_; | 264 intptr_t bytes_promoted_; |
| 265 RawObject* visiting_old_object_; | 265 RawObject* visiting_old_object_; |
| 266 bool in_scavenge_pointer_; | 266 bool in_scavenge_pointer_; |
| 267 | 267 |
| 268 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); | 268 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); |
| 269 }; | 269 }; |
| 270 | 270 |
| 271 | 271 |
| 272 class ScavengerWeakVisitor : public HandleVisitor { | 272 class ScavengerWeakVisitor : public HandleVisitor { |
| 273 public: | 273 public: |
| 274 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) { | 274 explicit ScavengerWeakVisitor(Scavenger* scavenger) |
| 275 } | 275 : scavenger_(scavenger), heap_(scavenger->heap_) {} |
| 276 | 276 |
| 277 void VisitHandle(uword addr) { | 277 void VisitHandle(uword addr) { |
| 278 FinalizablePersistentHandle* handle = | 278 FinalizablePersistentHandle* handle = |
| 279 reinterpret_cast<FinalizablePersistentHandle*>(addr); | 279 reinterpret_cast<FinalizablePersistentHandle*>(addr); |
| 280 RawObject** p = handle->raw_addr(); | 280 RawObject** p = handle->raw_addr(); |
| 281 RawObject* before = *p; |
| 281 if (scavenger_->IsUnreachable(p)) { | 282 if (scavenger_->IsUnreachable(p)) { |
| 282 FinalizablePersistentHandle::Finalize(handle); | 283 handle->UpdateUnreachable(heap_); |
| 284 } else { |
| 285 handle->UpdateRelocated(before, heap_); |
| 283 } | 286 } |
| 284 } | 287 } |
| 285 | 288 |
| 286 private: | 289 private: |
| 287 Scavenger* scavenger_; | 290 Scavenger* scavenger_; |
| 291 Heap* heap_; |
| 288 | 292 |
| 289 DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor); | 293 DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor); |
| 290 }; | 294 }; |
| 291 | 295 |
| 292 | 296 |
| 293 // Visitor used to verify that all old->new references have been added to the | 297 // Visitor used to verify that all old->new references have been added to the |
| 294 // StoreBuffers. | 298 // StoreBuffers. |
| 295 class VerifyStoreBufferPointerVisitor : public ObjectPointerVisitor { | 299 class VerifyStoreBufferPointerVisitor : public ObjectPointerVisitor { |
| 296 public: | 300 public: |
| 297 VerifyStoreBufferPointerVisitor(Isolate* isolate, MemoryRegion* to) | 301 VerifyStoreBufferPointerVisitor(Isolate* isolate, MemoryRegion* to) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 313 }; | 317 }; |
| 314 | 318 |
| 315 | 319 |
| 316 Scavenger::Scavenger(Heap* heap, | 320 Scavenger::Scavenger(Heap* heap, |
| 317 intptr_t max_capacity_in_words, | 321 intptr_t max_capacity_in_words, |
| 318 uword object_alignment) | 322 uword object_alignment) |
| 319 : heap_(heap), | 323 : heap_(heap), |
| 320 object_alignment_(object_alignment), | 324 object_alignment_(object_alignment), |
| 321 scavenging_(false), | 325 scavenging_(false), |
| 322 gc_time_micros_(0), | 326 gc_time_micros_(0), |
| 323 collections_(0) { | 327 collections_(0), |
| 328 external_size_(0) { |
| 324 // Verify assumptions about the first word in objects which the scavenger is | 329 // Verify assumptions about the first word in objects which the scavenger is |
| 325 // going to use for forwarding pointers. | 330 // going to use for forwarding pointers. |
| 326 ASSERT(Object::tags_offset() == 0); | 331 ASSERT(Object::tags_offset() == 0); |
| 327 | 332 |
| 328 // Allocate the virtual memory for this scavenge heap. | 333 // Allocate the virtual memory for this scavenge heap. |
| 329 space_ = VirtualMemory::Reserve(max_capacity_in_words << kWordSizeLog2); | 334 space_ = VirtualMemory::Reserve(max_capacity_in_words << kWordSizeLog2); |
| 330 if (space_ == NULL) { | 335 if (space_ == NULL) { |
| 331 FATAL("Out of memory.\n"); | 336 FATAL("Out of memory.\n"); |
| 332 } | 337 } |
| 333 | 338 |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 had_promotion_failure_ = false; | 680 had_promotion_failure_ = false; |
| 676 Isolate* isolate = Isolate::Current(); | 681 Isolate* isolate = Isolate::Current(); |
| 677 NoHandleScope no_handles(isolate); | 682 NoHandleScope no_handles(isolate); |
| 678 | 683 |
| 679 if (FLAG_verify_before_gc) { | 684 if (FLAG_verify_before_gc) { |
| 680 OS::PrintErr("Verifying before Scavenge..."); | 685 OS::PrintErr("Verifying before Scavenge..."); |
| 681 heap_->Verify(); | 686 heap_->Verify(); |
| 682 OS::PrintErr(" done.\n"); | 687 OS::PrintErr(" done.\n"); |
| 683 } | 688 } |
| 684 | 689 |
| 690 // During from/to flip and promoted stack use, move external allocation |
| 691 // out of tospace temporarily. |
| 692 intptr_t saved_external = external_size_; |
| 693 FreeExternal(saved_external); |
| 694 |
| 685 // Setup the visitor and run a scavenge. | 695 // Setup the visitor and run a scavenge. |
| 686 ScavengerVisitor visitor(isolate, this); | 696 ScavengerVisitor visitor(isolate, this); |
| 687 Prologue(isolate, invoke_api_callbacks); | 697 Prologue(isolate, invoke_api_callbacks); |
| 688 IterateRoots(isolate, &visitor, !invoke_api_callbacks); | 698 IterateRoots(isolate, &visitor, !invoke_api_callbacks); |
| 689 int64_t start = OS::GetCurrentTimeMicros(); | 699 int64_t start = OS::GetCurrentTimeMicros(); |
| 690 ProcessToSpace(&visitor); | 700 ProcessToSpace(&visitor); |
| 691 int64_t middle = OS::GetCurrentTimeMicros(); | 701 int64_t middle = OS::GetCurrentTimeMicros(); |
| 692 IterateWeakReferences(isolate, &visitor); | 702 IterateWeakReferences(isolate, &visitor); |
| 703 // Done with promoted stack; restore external allocation. |
| 704 ASSERT(!PromotedStackHasMore()); |
| 705 AllocateExternal(saved_external); |
| 693 ScavengerWeakVisitor weak_visitor(this); | 706 ScavengerWeakVisitor weak_visitor(this); |
| 694 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); | 707 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); |
| 695 visitor.Finalize(); | 708 visitor.Finalize(); |
| 696 ProcessWeakTables(); | 709 ProcessWeakTables(); |
| 697 int64_t end = OS::GetCurrentTimeMicros(); | 710 int64_t end = OS::GetCurrentTimeMicros(); |
| 698 heap_->RecordTime(kProcessToSpace, middle - start); | 711 heap_->RecordTime(kProcessToSpace, middle - start); |
| 699 heap_->RecordTime(kIterateWeaks, end - middle); | 712 heap_->RecordTime(kIterateWeaks, end - middle); |
| 700 Epilogue(isolate, &visitor, invoke_api_callbacks); | 713 Epilogue(isolate, &visitor, invoke_api_callbacks); |
| 701 | 714 |
| 702 if (FLAG_verify_after_gc) { | 715 if (FLAG_verify_after_gc) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 723 space.AddProperty("id", "heaps/new"); | 736 space.AddProperty("id", "heaps/new"); |
| 724 space.AddProperty("name", "Scavenger"); | 737 space.AddProperty("name", "Scavenger"); |
| 725 space.AddProperty("user_name", "new"); | 738 space.AddProperty("user_name", "new"); |
| 726 space.AddProperty("collections", collections()); | 739 space.AddProperty("collections", collections()); |
| 727 space.AddProperty("used", UsedInWords() * kWordSize); | 740 space.AddProperty("used", UsedInWords() * kWordSize); |
| 728 space.AddProperty("capacity", CapacityInWords() * kWordSize); | 741 space.AddProperty("capacity", CapacityInWords() * kWordSize); |
| 729 space.AddProperty("time", RoundMicrosecondsToSeconds(gc_time_micros())); | 742 space.AddProperty("time", RoundMicrosecondsToSeconds(gc_time_micros())); |
| 730 } | 743 } |
| 731 | 744 |
| 732 | 745 |
| 746 void Scavenger::AllocateExternal(intptr_t size) { |
| 747 ASSERT(size >= 0); |
| 748 external_size_ += size; |
| 749 intptr_t remaining = end_ - top_; |
| 750 end_ -= Utils::Minimum(remaining, size); |
| 751 } |
| 752 |
| 753 |
| 754 void Scavenger::FreeExternal(intptr_t size) { |
| 755 ASSERT(size >= 0); |
| 756 external_size_ -= size; |
| 757 ASSERT(external_size_ >= 0); |
| 758 end_ = Utils::Minimum(to_->end(), end_ + size); |
| 759 } |
| 760 |
| 733 } // namespace dart | 761 } // namespace dart |
| OLD | NEW |