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