| 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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 // going to use for forwarding pointers. | 408 // going to use for forwarding pointers. |
| 409 ASSERT(Object::tags_offset() == 0); | 409 ASSERT(Object::tags_offset() == 0); |
| 410 | 410 |
| 411 // Set initial size resulting in a total of three different levels. | 411 // Set initial size resulting in a total of three different levels. |
| 412 const intptr_t initial_semi_capacity_in_words = max_semi_capacity_in_words / | 412 const intptr_t initial_semi_capacity_in_words = max_semi_capacity_in_words / |
| 413 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor); | 413 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor); |
| 414 to_ = SemiSpace::New(initial_semi_capacity_in_words); | 414 to_ = SemiSpace::New(initial_semi_capacity_in_words); |
| 415 if (to_ == NULL) { | 415 if (to_ == NULL) { |
| 416 FATAL("Out of memory.\n"); | 416 FATAL("Out of memory.\n"); |
| 417 } | 417 } |
| 418 UpdateMaxHeapCapacity(); | |
| 419 // Setup local fields. | 418 // Setup local fields. |
| 420 top_ = FirstObjectStart(); | 419 top_ = FirstObjectStart(); |
| 421 resolved_top_ = top_; | 420 resolved_top_ = top_; |
| 422 end_ = to_->end(); | 421 end_ = to_->end(); |
| 423 | 422 |
| 424 survivor_end_ = FirstObjectStart(); | 423 survivor_end_ = FirstObjectStart(); |
| 424 |
| 425 UpdateMaxHeapCapacity(); |
| 426 UpdateMaxHeapUsage(); |
| 427 UpdateGlobalMaxUsed(); |
| 425 } | 428 } |
| 426 | 429 |
| 427 | 430 |
| 428 Scavenger::~Scavenger() { | 431 Scavenger::~Scavenger() { |
| 429 ASSERT(!scavenging_); | 432 ASSERT(!scavenging_); |
| 430 to_->Delete(); | 433 to_->Delete(); |
| 431 } | 434 } |
| 432 | 435 |
| 433 | 436 |
| 434 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const { | 437 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 { | 497 { |
| 495 PageSpace* page_space = heap_->old_space(); | 498 PageSpace* page_space = heap_->old_space(); |
| 496 MonitorLocker ml(page_space->tasks_lock()); | 499 MonitorLocker ml(page_space->tasks_lock()); |
| 497 if (page_space->tasks() == 0) { | 500 if (page_space->tasks() == 0) { |
| 498 VerifyStoreBufferPointerVisitor verify_store_buffer_visitor(isolate, to_); | 501 VerifyStoreBufferPointerVisitor verify_store_buffer_visitor(isolate, to_); |
| 499 heap_->old_space()->VisitObjectPointers(&verify_store_buffer_visitor); | 502 heap_->old_space()->VisitObjectPointers(&verify_store_buffer_visitor); |
| 500 } | 503 } |
| 501 } | 504 } |
| 502 #endif // defined(DEBUG) | 505 #endif // defined(DEBUG) |
| 503 from->Delete(); | 506 from->Delete(); |
| 507 UpdateMaxHeapUsage(); |
| 508 UpdateGlobalMaxUsed(); |
| 504 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) { | 509 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) { |
| 505 (isolate->gc_epilogue_callback())(); | 510 (isolate->gc_epilogue_callback())(); |
| 506 } | 511 } |
| 507 } | 512 } |
| 508 | 513 |
| 509 | 514 |
| 510 void Scavenger::IterateStoreBuffers(Isolate* isolate, | 515 void Scavenger::IterateStoreBuffers(Isolate* isolate, |
| 511 ScavengerVisitor* visitor) { | 516 ScavengerVisitor* visitor) { |
| 512 // Iterating through the store buffers. | 517 // Iterating through the store buffers. |
| 513 // Grab the deduplication sets out of the isolate's consolidated store buffer. | 518 // Grab the deduplication sets out of the isolate's consolidated store buffer. |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 } | 718 } |
| 714 ASSERT(to_ != NULL); | 719 ASSERT(to_ != NULL); |
| 715 ASSERT(heap_ != NULL); | 720 ASSERT(heap_ != NULL); |
| 716 Isolate* isolate = heap_->isolate(); | 721 Isolate* isolate = heap_->isolate(); |
| 717 ASSERT(isolate != NULL); | 722 ASSERT(isolate != NULL); |
| 718 isolate->GetHeapNewCapacityMaxMetric()->SetValue( | 723 isolate->GetHeapNewCapacityMaxMetric()->SetValue( |
| 719 to_->size_in_words() * kWordSize); | 724 to_->size_in_words() * kWordSize); |
| 720 } | 725 } |
| 721 | 726 |
| 722 | 727 |
| 728 void Scavenger::UpdateMaxHeapUsage() { |
| 729 if (heap_ == NULL) { |
| 730 // Some unit tests. |
| 731 return; |
| 732 } |
| 733 ASSERT(to_ != NULL); |
| 734 ASSERT(heap_ != NULL); |
| 735 Isolate* isolate = heap_->isolate(); |
| 736 ASSERT(isolate != NULL); |
| 737 isolate->GetHeapNewUsedMaxMetric()->SetValue(UsedInWords() * kWordSize); |
| 738 } |
| 739 |
| 740 |
| 741 void Scavenger::UpdateGlobalMaxUsed() { |
| 742 if (heap_ == NULL) { |
| 743 // Some unit tests. |
| 744 return; |
| 745 } |
| 746 ASSERT(to_ != NULL); |
| 747 ASSERT(heap_ != NULL); |
| 748 Isolate* isolate = heap_->isolate(); |
| 749 ASSERT(isolate != NULL); |
| 750 // This is technically under-counting, but, we cannot safely query the |
| 751 // page space here. This is also updated whenever a page space GC occurs, |
| 752 // which will reflect the (larger) combined heap usage. |
| 753 isolate->GetHeapGlobalUsedMaxMetric()->SetValue( |
| 754 (static_cast<int64_t>(heap_->UsedInWords(Heap::kNew)) * kWordSize)); |
| 755 } |
| 756 |
| 757 |
| 723 uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak, | 758 uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak, |
| 724 ScavengerVisitor* visitor) { | 759 ScavengerVisitor* visitor) { |
| 725 // The fate of the weak property is determined by its key. | 760 // The fate of the weak property is determined by its key. |
| 726 RawObject* raw_key = raw_weak->ptr()->key_; | 761 RawObject* raw_key = raw_weak->ptr()->key_; |
| 727 if (raw_key->IsHeapObject() && raw_key->IsNewObject()) { | 762 if (raw_key->IsHeapObject() && raw_key->IsNewObject()) { |
| 728 uword raw_addr = RawObject::ToAddr(raw_key); | 763 uword raw_addr = RawObject::ToAddr(raw_key); |
| 729 uword header = *reinterpret_cast<uword*>(raw_addr); | 764 uword header = *reinterpret_cast<uword*>(raw_addr); |
| 730 if (!IsForwarding(header)) { | 765 if (!IsForwarding(header)) { |
| 731 // Key is white. Delay the weak property. | 766 // Key is white. Delay the weak property. |
| 732 visitor->DelayWeakProperty(raw_weak); | 767 visitor->DelayWeakProperty(raw_weak); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 } | 964 } |
| 930 | 965 |
| 931 | 966 |
| 932 void Scavenger::FreeExternal(intptr_t size) { | 967 void Scavenger::FreeExternal(intptr_t size) { |
| 933 ASSERT(size >= 0); | 968 ASSERT(size >= 0); |
| 934 external_size_ -= size; | 969 external_size_ -= size; |
| 935 ASSERT(external_size_ >= 0); | 970 ASSERT(external_size_ >= 0); |
| 936 } | 971 } |
| 937 | 972 |
| 938 } // namespace dart | 973 } // namespace dart |
| OLD | NEW |