Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(351)

Side by Side Diff: runtime/vm/scavenger.cc

Issue 1283093002: - Remove the from field from the the Scavenger class. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/scavenger.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 } 71 }
72 72
73 private: 73 private:
74 bool* _addr; 74 bool* _addr;
75 bool _value; 75 bool _value;
76 }; 76 };
77 77
78 78
79 class ScavengerVisitor : public ObjectPointerVisitor { 79 class ScavengerVisitor : public ObjectPointerVisitor {
80 public: 80 public:
81 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) 81 explicit ScavengerVisitor(Isolate* isolate,
82 Scavenger* scavenger,
83 SemiSpace* from)
82 : ObjectPointerVisitor(isolate), 84 : ObjectPointerVisitor(isolate),
83 thread_(Thread::Current()), 85 thread_(Thread::Current()),
84 scavenger_(scavenger), 86 scavenger_(scavenger),
85 from_start_(scavenger_->from_->start()), 87 from_(from),
86 from_size_(scavenger_->from_->end() - scavenger_->from_->start()),
87 heap_(scavenger->heap_), 88 heap_(scavenger->heap_),
88 vm_heap_(Dart::vm_isolate()->heap()), 89 vm_heap_(Dart::vm_isolate()->heap()),
89 page_space_(scavenger->heap_->old_space()), 90 page_space_(scavenger->heap_->old_space()),
90 delayed_weak_stack_(), 91 delayed_weak_stack_(),
91 bytes_promoted_(0), 92 bytes_promoted_(0),
92 visiting_old_object_(NULL), 93 visiting_old_object_(NULL),
93 in_scavenge_pointer_(false) { } 94 in_scavenge_pointer_(false) { }
94 95
95 void VisitPointers(RawObject** first, RawObject** last) { 96 void VisitPointers(RawObject** first, RawObject** last) {
96 for (RawObject** current = first; current <= last; current++) { 97 for (RawObject** current = first; current <= last; current++) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 BoolScope bs(&in_scavenge_pointer_, true); 151 BoolScope bs(&in_scavenge_pointer_, true);
151 #endif 152 #endif
152 153
153 RawObject* raw_obj = *p; 154 RawObject* raw_obj = *p;
154 155
155 if (raw_obj->IsSmiOrOldObject()) { 156 if (raw_obj->IsSmiOrOldObject()) {
156 return; 157 return;
157 } 158 }
158 159
159 // The scavenger is only interested in objects located in the from space. 160 // The scavenger is only interested in objects located in the from space.
160 // 161 ASSERT(from_->Contains(RawObject::ToAddr(raw_obj)));
koda 2015/08/12 01:22:33 You could rearrange and use "raw_addr" here; it mi
Ivan Posva 2015/08/14 20:19:32 Done.
161 // We are using address math here and relying on the unsigned underflow
162 // in the code below to avoid having two checks.
163 uword obj_offset = reinterpret_cast<uword>(raw_obj) - from_start_;
164 if (obj_offset > from_size_) {
165 ASSERT(scavenger_->to_->Contains(RawObject::ToAddr(raw_obj)));
166 return;
167 }
168 162
169 uword raw_addr = RawObject::ToAddr(raw_obj); 163 uword raw_addr = RawObject::ToAddr(raw_obj);
170 // Read the header word of the object and determine if the object has 164 // Read the header word of the object and determine if the object has
171 // already been copied. 165 // already been copied.
172 uword header = *reinterpret_cast<uword*>(raw_addr); 166 uword header = *reinterpret_cast<uword*>(raw_addr);
173 uword new_addr = 0; 167 uword new_addr = 0;
174 if (IsForwarding(header)) { 168 if (IsForwarding(header)) {
175 // Get the new location of the object. 169 // Get the new location of the object.
176 new_addr = ForwardedAddr(header); 170 new_addr = ForwardedAddr(header);
177 } else { 171 } else {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 *p = new_obj; 229 *p = new_obj;
236 // Update the store buffer as needed. 230 // Update the store buffer as needed.
237 if (visiting_old_object_ != NULL) { 231 if (visiting_old_object_ != NULL) {
238 VerifiedMemory::Accept(reinterpret_cast<uword>(p), sizeof(*p)); 232 VerifiedMemory::Accept(reinterpret_cast<uword>(p), sizeof(*p));
239 UpdateStoreBuffer(p, new_obj); 233 UpdateStoreBuffer(p, new_obj);
240 } 234 }
241 } 235 }
242 236
243 Thread* thread_; 237 Thread* thread_;
244 Scavenger* scavenger_; 238 Scavenger* scavenger_;
245 uword from_start_; 239 SemiSpace* from_;
246 uword from_size_;
247 Heap* heap_; 240 Heap* heap_;
248 Heap* vm_heap_; 241 Heap* vm_heap_;
249 PageSpace* page_space_; 242 PageSpace* page_space_;
250 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; 243 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
251 DelaySet delay_set_; 244 DelaySet delay_set_;
252 GrowableArray<RawObject*> delayed_weak_stack_; 245 GrowableArray<RawObject*> delayed_weak_stack_;
253 // TODO(cshapiro): use this value to compute survival statistics for 246 // TODO(cshapiro): use this value to compute survival statistics for
254 // new space growth policy. 247 // new space growth policy.
255 intptr_t bytes_promoted_; 248 intptr_t bytes_promoted_;
256 RawObject* visiting_old_object_; 249 RawObject* visiting_old_object_;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 // going to use for forwarding pointers. 408 // going to use for forwarding pointers.
416 ASSERT(Object::tags_offset() == 0); 409 ASSERT(Object::tags_offset() == 0);
417 410
418 // Set initial size resulting in a total of three different levels. 411 // Set initial size resulting in a total of three different levels.
419 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 /
420 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor); 413 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor);
421 to_ = SemiSpace::New(initial_semi_capacity_in_words); 414 to_ = SemiSpace::New(initial_semi_capacity_in_words);
422 if (to_ == NULL) { 415 if (to_ == NULL) {
423 FATAL("Out of memory.\n"); 416 FATAL("Out of memory.\n");
424 } 417 }
425 from_ = NULL;
426 418
427 // Setup local fields. 419 // Setup local fields.
428 top_ = FirstObjectStart(); 420 top_ = FirstObjectStart();
429 resolved_top_ = top_; 421 resolved_top_ = top_;
430 end_ = to_->end(); 422 end_ = to_->end();
431 423
432 survivor_end_ = FirstObjectStart(); 424 survivor_end_ = FirstObjectStart();
433 } 425 }
434 426
435 427
436 Scavenger::~Scavenger() { 428 Scavenger::~Scavenger() {
437 ASSERT(!scavenging_); 429 ASSERT(!scavenging_);
438 ASSERT(from_ == NULL);
439 to_->Delete(); 430 to_->Delete();
440 } 431 }
441 432
442 433
443 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const { 434 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const {
444 if (stats_history_.Size() == 0) { 435 if (stats_history_.Size() == 0) {
445 return old_size_in_words; 436 return old_size_in_words;
446 } 437 }
447 double garbage = stats_history_.Get(0).GarbageFraction(); 438 double garbage = stats_history_.Get(0).GarbageFraction();
448 if (garbage < (FLAG_new_gen_garbage_threshold / 100.0)) { 439 if (garbage < (FLAG_new_gen_garbage_threshold / 100.0)) {
449 return Utils::Minimum(max_semi_capacity_in_words_, 440 return Utils::Minimum(max_semi_capacity_in_words_,
450 old_size_in_words * FLAG_new_gen_growth_factor); 441 old_size_in_words * FLAG_new_gen_growth_factor);
451 } else { 442 } else {
452 return old_size_in_words; 443 return old_size_in_words;
453 } 444 }
454 } 445 }
455 446
456 447
457 void Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) { 448 SemiSpace* Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) {
458 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) { 449 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
459 (isolate->gc_prologue_callback())(); 450 (isolate->gc_prologue_callback())();
460 } 451 }
461 Thread::PrepareForGC(); 452 Thread::PrepareForGC();
462 // Flip the two semi-spaces so that to_ is always the space for allocating 453 // Flip the two semi-spaces so that to_ is always the space for allocating
463 // objects. 454 // objects.
464 from_ = to_; 455 SemiSpace* from = to_;
465 to_ = SemiSpace::New(NewSizeInWords(from_->size_in_words())); 456 to_ = SemiSpace::New(NewSizeInWords(from->size_in_words()));
466 if (to_ == NULL) { 457 if (to_ == NULL) {
467 // TODO(koda): We could try to recover (collect old space, wait for another 458 // TODO(koda): We could try to recover (collect old space, wait for another
468 // isolate to finish scavenge, etc.). 459 // isolate to finish scavenge, etc.).
469 FATAL("Out of memory.\n"); 460 FATAL("Out of memory.\n");
470 } 461 }
471 top_ = FirstObjectStart(); 462 top_ = FirstObjectStart();
472 resolved_top_ = top_; 463 resolved_top_ = top_;
473 end_ = to_->end(); 464 end_ = to_->end();
465 return from;
474 } 466 }
475 467
476 468
477 void Scavenger::Epilogue(Isolate* isolate, 469 void Scavenger::Epilogue(Isolate* isolate,
470 SemiSpace* from,
478 bool invoke_api_callbacks) { 471 bool invoke_api_callbacks) {
479 // All objects in the to space have been copied from the from space at this 472 // All objects in the to space have been copied from the from space at this
480 // moment. 473 // moment.
481 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction(); 474 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction();
482 if (stats_history_.Size() >= 2) { 475 if (stats_history_.Size() >= 2) {
483 // Previous scavenge is only given half as much weight. 476 // Previous scavenge is only given half as much weight.
484 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction(); 477 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction();
485 avg_frac /= 1.0 + 0.5; // Normalize. 478 avg_frac /= 1.0 + 0.5; // Normalize.
486 } 479 }
487 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { 480 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) {
(...skipping 11 matching lines...) Expand all
499 // being spawned. 492 // being spawned.
500 { 493 {
501 PageSpace* page_space = heap_->old_space(); 494 PageSpace* page_space = heap_->old_space();
502 MonitorLocker ml(page_space->tasks_lock()); 495 MonitorLocker ml(page_space->tasks_lock());
503 if (page_space->tasks() == 0) { 496 if (page_space->tasks() == 0) {
504 VerifyStoreBufferPointerVisitor verify_store_buffer_visitor(isolate, to_); 497 VerifyStoreBufferPointerVisitor verify_store_buffer_visitor(isolate, to_);
505 heap_->old_space()->VisitObjectPointers(&verify_store_buffer_visitor); 498 heap_->old_space()->VisitObjectPointers(&verify_store_buffer_visitor);
506 } 499 }
507 } 500 }
508 #endif // defined(DEBUG) 501 #endif // defined(DEBUG)
509 from_->Delete(); 502 from->Delete();
510 from_ = NULL;
511 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) { 503 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) {
512 (isolate->gc_epilogue_callback())(); 504 (isolate->gc_epilogue_callback())();
513 } 505 }
514 } 506 }
515 507
516 508
517 void Scavenger::IterateStoreBuffers(Isolate* isolate, 509 void Scavenger::IterateStoreBuffers(Isolate* isolate,
518 ScavengerVisitor* visitor) { 510 ScavengerVisitor* visitor) {
519 // Iterating through the store buffers. 511 // Iterating through the store buffers.
520 // Grab the deduplication sets out of the isolate's consolidated store buffer. 512 // Grab the deduplication sets out of the isolate's consolidated store buffer.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 568
577 bool Scavenger::IsUnreachable(RawObject** p) { 569 bool Scavenger::IsUnreachable(RawObject** p) {
578 RawObject* raw_obj = *p; 570 RawObject* raw_obj = *p;
579 if (!raw_obj->IsHeapObject()) { 571 if (!raw_obj->IsHeapObject()) {
580 return false; 572 return false;
581 } 573 }
582 if (!raw_obj->IsNewObject()) { 574 if (!raw_obj->IsNewObject()) {
583 return false; 575 return false;
584 } 576 }
585 uword raw_addr = RawObject::ToAddr(raw_obj); 577 uword raw_addr = RawObject::ToAddr(raw_obj);
586 if (!from_->Contains(raw_addr)) { 578 if (to_->Contains(raw_addr)) {
587 return false; 579 return false;
588 } 580 }
589 uword header = *reinterpret_cast<uword*>(raw_addr); 581 uword header = *reinterpret_cast<uword*>(raw_addr);
590 if (IsForwarding(header)) { 582 if (IsForwarding(header)) {
591 uword new_addr = ForwardedAddr(header); 583 uword new_addr = ForwardedAddr(header);
592 *p = RawObject::FromAddr(new_addr); 584 *p = RawObject::FromAddr(new_addr);
593 return false; 585 return false;
594 } 586 }
595 return true; 587 return true;
596 } 588 }
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) { 802 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) {
811 OS::PrintErr("Verifying before Scavenge..."); 803 OS::PrintErr("Verifying before Scavenge...");
812 heap_->Verify(kForbidMarked); 804 heap_->Verify(kForbidMarked);
813 OS::PrintErr(" done.\n"); 805 OS::PrintErr(" done.\n");
814 } 806 }
815 807
816 // Prepare for a scavenge. 808 // Prepare for a scavenge.
817 SpaceUsage usage_before = GetCurrentUsage(); 809 SpaceUsage usage_before = GetCurrentUsage();
818 intptr_t promo_candidate_words = 810 intptr_t promo_candidate_words =
819 (survivor_end_ - FirstObjectStart()) / kWordSize; 811 (survivor_end_ - FirstObjectStart()) / kWordSize;
820 Prologue(isolate, invoke_api_callbacks); 812 SemiSpace* from = Prologue(isolate, invoke_api_callbacks);
821 // The API prologue/epilogue may create/destroy zones, so we must not 813 // The API prologue/epilogue may create/destroy zones, so we must not
822 // depend on zone allocations surviving beyond the epilogue callback. 814 // depend on zone allocations surviving beyond the epilogue callback.
823 { 815 {
824 StackZone zone(isolate); 816 StackZone zone(isolate);
825 // Setup the visitor and run the scavenge. 817 // Setup the visitor and run the scavenge.
826 ScavengerVisitor visitor(isolate, this); 818 ScavengerVisitor visitor(isolate, this, from);
827 page_space->AcquireDataLock(); 819 page_space->AcquireDataLock();
828 const bool prologue_weak_are_strong = !invoke_api_callbacks; 820 const bool prologue_weak_are_strong = !invoke_api_callbacks;
829 IterateRoots(isolate, &visitor, prologue_weak_are_strong); 821 IterateRoots(isolate, &visitor, prologue_weak_are_strong);
830 int64_t start = OS::GetCurrentTimeMicros(); 822 int64_t start = OS::GetCurrentTimeMicros();
831 ProcessToSpace(&visitor); 823 ProcessToSpace(&visitor);
832 int64_t middle = OS::GetCurrentTimeMicros(); 824 int64_t middle = OS::GetCurrentTimeMicros();
833 IterateWeakReferences(isolate, &visitor); 825 IterateWeakReferences(isolate, &visitor);
834 ScavengerWeakVisitor weak_visitor(this, prologue_weak_are_strong); 826 ScavengerWeakVisitor weak_visitor(this, prologue_weak_are_strong);
835 // Include the prologue weak handles, since we must process any promotion. 827 // Include the prologue weak handles, since we must process any promotion.
836 const bool visit_prologue_weak_handles = true; 828 const bool visit_prologue_weak_handles = true;
837 IterateWeakRoots(isolate, &weak_visitor, visit_prologue_weak_handles); 829 IterateWeakRoots(isolate, &weak_visitor, visit_prologue_weak_handles);
838 visitor.Finalize(); 830 visitor.Finalize();
839 ProcessWeakTables(); 831 ProcessWeakTables();
840 page_space->ReleaseDataLock(); 832 page_space->ReleaseDataLock();
841 833
842 // Scavenge finished. Run accounting. 834 // Scavenge finished. Run accounting.
843 int64_t end = OS::GetCurrentTimeMicros(); 835 int64_t end = OS::GetCurrentTimeMicros();
844 heap_->RecordTime(kProcessToSpace, middle - start); 836 heap_->RecordTime(kProcessToSpace, middle - start);
845 heap_->RecordTime(kIterateWeaks, end - middle); 837 heap_->RecordTime(kIterateWeaks, end - middle);
846 stats_history_.Add( 838 stats_history_.Add(
847 ScavengeStats(start, end, 839 ScavengeStats(start, end,
848 usage_before, GetCurrentUsage(), 840 usage_before, GetCurrentUsage(),
849 promo_candidate_words, 841 promo_candidate_words,
850 visitor.bytes_promoted() >> kWordSizeLog2)); 842 visitor.bytes_promoted() >> kWordSizeLog2));
851 } 843 }
852 Epilogue(isolate, invoke_api_callbacks); 844 Epilogue(isolate, from, invoke_api_callbacks);
853 845
854 // TODO(koda): Make verification more compatible with concurrent sweep. 846 // TODO(koda): Make verification more compatible with concurrent sweep.
855 if (FLAG_verify_after_gc && !FLAG_concurrent_sweep) { 847 if (FLAG_verify_after_gc && !FLAG_concurrent_sweep) {
856 OS::PrintErr("Verifying after Scavenge..."); 848 OS::PrintErr("Verifying after Scavenge...");
857 heap_->Verify(kForbidMarked); 849 heap_->Verify(kForbidMarked);
858 OS::PrintErr(" done.\n"); 850 OS::PrintErr(" done.\n");
859 } 851 }
860 852
861 // Done scavenging. Reset the marker. 853 // Done scavenging. Reset the marker.
862 ASSERT(scavenging_); 854 ASSERT(scavenging_);
863 scavenging_ = false; 855 scavenging_ = false;
864 } 856 }
865 857
866 858
867 void Scavenger::WriteProtect(bool read_only) { 859 void Scavenger::WriteProtect(bool read_only) {
868 ASSERT(!scavenging_); 860 ASSERT(!scavenging_);
869 ASSERT(from_ == NULL);
870 to_->WriteProtect(read_only); 861 to_->WriteProtect(read_only);
871 } 862 }
872 863
873 864
874 void Scavenger::PrintToJSONObject(JSONObject* object) const { 865 void Scavenger::PrintToJSONObject(JSONObject* object) const {
875 Isolate* isolate = Isolate::Current(); 866 Isolate* isolate = Isolate::Current();
876 ASSERT(isolate != NULL); 867 ASSERT(isolate != NULL);
877 JSONObject space(object, "new"); 868 JSONObject space(object, "new");
878 space.AddProperty("type", "HeapSpace"); 869 space.AddProperty("type", "HeapSpace");
879 space.AddProperty("name", "new"); 870 space.AddProperty("name", "new");
(...skipping 23 matching lines...) Expand all
903 } 894 }
904 895
905 896
906 void Scavenger::FreeExternal(intptr_t size) { 897 void Scavenger::FreeExternal(intptr_t size) {
907 ASSERT(size >= 0); 898 ASSERT(size >= 0);
908 external_size_ -= size; 899 external_size_ -= size;
909 ASSERT(external_size_ >= 0); 900 ASSERT(external_size_ >= 0);
910 } 901 }
911 902
912 } // namespace dart 903 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scavenger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698