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

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

Issue 2951333002: Moves the top_ and end_ words of the Scavenger into mutator thread. (Closed)
Patch Set: Created 3 years, 6 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
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 "vm/dart.h" 7 #include "vm/dart.h"
8 #include "vm/dart_api_state.h" 8 #include "vm/dart_api_state.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/lockers.h" 10 #include "vm/lockers.h"
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 Scavenger::Scavenger(Heap* heap, 330 Scavenger::Scavenger(Heap* heap,
331 intptr_t max_semi_capacity_in_words, 331 intptr_t max_semi_capacity_in_words,
332 uword object_alignment) 332 uword object_alignment)
333 : heap_(heap), 333 : heap_(heap),
334 max_semi_capacity_in_words_(max_semi_capacity_in_words), 334 max_semi_capacity_in_words_(max_semi_capacity_in_words),
335 object_alignment_(object_alignment), 335 object_alignment_(object_alignment),
336 scavenging_(false), 336 scavenging_(false),
337 delayed_weak_properties_(NULL), 337 delayed_weak_properties_(NULL),
338 gc_time_micros_(0), 338 gc_time_micros_(0),
339 collections_(0), 339 collections_(0),
340 external_size_(0) { 340 external_size_(0),
341 space_lock_(new Mutex()) {
341 // Verify assumptions about the first word in objects which the scavenger is 342 // Verify assumptions about the first word in objects which the scavenger is
342 // going to use for forwarding pointers. 343 // going to use for forwarding pointers.
343 ASSERT(Object::tags_offset() == 0); 344 ASSERT(Object::tags_offset() == 0);
344 345
345 // Set initial size resulting in a total of three different levels. 346 // Set initial size resulting in a total of three different levels.
346 const intptr_t initial_semi_capacity_in_words = 347 const intptr_t initial_semi_capacity_in_words =
347 max_semi_capacity_in_words / 348 max_semi_capacity_in_words /
348 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor); 349 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor);
349 to_ = SemiSpace::New(initial_semi_capacity_in_words); 350 to_ = SemiSpace::New(initial_semi_capacity_in_words);
350 if (to_ == NULL) { 351 if (to_ == NULL) {
351 OUT_OF_MEMORY(); 352 OUT_OF_MEMORY();
352 } 353 }
353 // Setup local fields. 354 // Setup local fields.
354 top_ = FirstObjectStart(); 355 top_ = FirstObjectStart();
355 resolved_top_ = top_; 356 resolved_top_ = top_;
356 end_ = to_->end(); 357 end_ = to_->end();
357 358
358 survivor_end_ = FirstObjectStart(); 359 survivor_end_ = FirstObjectStart();
359 360
360 UpdateMaxHeapCapacity(); 361 UpdateMaxHeapCapacity();
361 UpdateMaxHeapUsage(); 362 UpdateMaxHeapUsage();
362 } 363 }
363 364
364 365
365 Scavenger::~Scavenger() { 366 Scavenger::~Scavenger() {
366 ASSERT(!scavenging_); 367 ASSERT(!scavenging_);
367 to_->Delete(); 368 to_->Delete();
369 delete space_lock_;
368 } 370 }
369 371
370 372
371 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const { 373 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const {
372 if (stats_history_.Size() == 0) { 374 if (stats_history_.Size() == 0) {
373 return old_size_in_words; 375 return old_size_in_words;
374 } 376 }
375 double garbage = stats_history_.Get(0).GarbageFraction(); 377 double garbage = stats_history_.Get(0).GarbageFraction();
376 if (garbage < (FLAG_new_gen_garbage_threshold / 100.0)) { 378 if (garbage < (FLAG_new_gen_garbage_threshold / 100.0)) {
377 return Utils::Minimum(max_semi_capacity_in_words_, 379 return Utils::Minimum(max_semi_capacity_in_words_,
378 old_size_in_words * FLAG_new_gen_growth_factor); 380 old_size_in_words * FLAG_new_gen_growth_factor);
379 } else { 381 } else {
380 return old_size_in_words; 382 return old_size_in_words;
381 } 383 }
382 } 384 }
383 385
384 386
385 SemiSpace* Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) { 387 SemiSpace* Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) {
386 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) { 388 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
387 (isolate->gc_prologue_callback())(); 389 (isolate->gc_prologue_callback())();
388 } 390 }
389 isolate->PrepareForGC(); 391 isolate->PrepareForGC();
392
393 ASSERT(isolate->mutator_thread()->top() == top_);
394
390 // Flip the two semi-spaces so that to_ is always the space for allocating 395 // Flip the two semi-spaces so that to_ is always the space for allocating
391 // objects. 396 // objects.
392 SemiSpace* from = to_; 397 SemiSpace* from = to_;
393 to_ = SemiSpace::New(NewSizeInWords(from->size_in_words())); 398 to_ = SemiSpace::New(NewSizeInWords(from->size_in_words()));
394 if (to_ == NULL) { 399 if (to_ == NULL) {
395 // TODO(koda): We could try to recover (collect old space, wait for another 400 // TODO(koda): We could try to recover (collect old space, wait for another
396 // isolate to finish scavenge, etc.). 401 // isolate to finish scavenge, etc.).
397 OUT_OF_MEMORY(); 402 OUT_OF_MEMORY();
398 } 403 }
399 UpdateMaxHeapCapacity(); 404 UpdateMaxHeapCapacity();
400 top_ = FirstObjectStart(); 405 top_ = FirstObjectStart();
401 resolved_top_ = top_; 406 resolved_top_ = top_;
402 end_ = to_->end(); 407 end_ = to_->end();
408
409 isolate->mutator_thread()->set_top_offset(top_);
410 isolate->mutator_thread()->set_end_offset(end_);
411
403 return from; 412 return from;
404 } 413 }
405 414
406 415
407 void Scavenger::Epilogue(Isolate* isolate, 416 void Scavenger::Epilogue(Isolate* isolate,
408 SemiSpace* from, 417 SemiSpace* from,
409 bool invoke_api_callbacks) { 418 bool invoke_api_callbacks) {
410 // All objects in the to space have been copied from the from space at this 419 // All objects in the to space have been copied from the from space at this
411 // moment. 420 // moment.
421
422 isolate->mutator_thread()->set_top_offset(top_);
423 isolate->mutator_thread()->set_end_offset(end_);
424
412 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction(); 425 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction();
413 if (stats_history_.Size() >= 2) { 426 if (stats_history_.Size() >= 2) {
414 // Previous scavenge is only given half as much weight. 427 // Previous scavenge is only given half as much weight.
415 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction(); 428 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction();
416 avg_frac /= 1.0 + 0.5; // Normalize. 429 avg_frac /= 1.0 + 0.5; // Normalize.
417 } 430 }
418 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { 431 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) {
419 // Remember the limit to which objects have been copied. 432 // Remember the limit to which objects have been copied.
420 survivor_end_ = top_; 433 survivor_end_ = top_;
421 } else { 434 } else {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 } 551 }
539 552
540 553
541 void Scavenger::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) { 554 void Scavenger::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) {
542 isolate->VisitWeakPersistentHandles(visitor); 555 isolate->VisitWeakPersistentHandles(visitor);
543 } 556 }
544 557
545 558
546 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) { 559 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
547 // Iterate until all work has been drained. 560 // Iterate until all work has been drained.
561
562 ASSERT(Isolate::Current()->mutator_thread()->top() == top_);
563
548 while ((resolved_top_ < top_) || PromotedStackHasMore()) { 564 while ((resolved_top_ < top_) || PromotedStackHasMore()) {
549 while (resolved_top_ < top_) { 565 while (resolved_top_ < top_) {
550 RawObject* raw_obj = RawObject::FromAddr(resolved_top_); 566 RawObject* raw_obj = RawObject::FromAddr(resolved_top_);
551 intptr_t class_id = raw_obj->GetClassId(); 567 intptr_t class_id = raw_obj->GetClassId();
552 if (class_id != kWeakPropertyCid) { 568 if (class_id != kWeakPropertyCid) {
553 resolved_top_ += raw_obj->VisitPointersNonvirtual(visitor); 569 resolved_top_ += raw_obj->VisitPointersNonvirtual(visitor);
554 } else { 570 } else {
555 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); 571 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj);
556 resolved_top_ += ProcessWeakProperty(raw_weak, visitor); 572 resolved_top_ += ProcessWeakProperty(raw_weak, visitor);
557 } 573 }
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 732
717 // Advance to next weak property in the queue. 733 // Advance to next weak property in the queue.
718 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); 734 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
719 } 735 }
720 } 736 }
721 } 737 }
722 738
723 739
724 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { 740 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
725 uword cur = FirstObjectStart(); 741 uword cur = FirstObjectStart();
726 while (cur < top_) { 742 while (cur < top_) {
rmacnak 2017/06/22 22:31:50 top_ may be stale
danunez 2017/06/30 20:35:57 Right. top_ is now retrieved from the mutator thre
727 RawObject* raw_obj = RawObject::FromAddr(cur); 743 RawObject* raw_obj = RawObject::FromAddr(cur);
728 cur += raw_obj->VisitPointers(visitor); 744 cur += raw_obj->VisitPointers(visitor);
729 } 745 }
730 } 746 }
731 747
732 748
733 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { 749 void Scavenger::VisitObjects(ObjectVisitor* visitor) const {
734 uword cur = FirstObjectStart(); 750 uword cur = FirstObjectStart();
735 while (cur < top_) { 751 while (cur < top_) {
rmacnak 2017/06/22 22:31:50 top_ may be stale
danunez 2017/06/30 20:35:57 Right. top_ is now retrieved from the mutator thre
736 RawObject* raw_obj = RawObject::FromAddr(cur); 752 RawObject* raw_obj = RawObject::FromAddr(cur);
737 visitor->VisitObject(raw_obj); 753 visitor->VisitObject(raw_obj);
738 cur += raw_obj->Size(); 754 cur += raw_obj->Size();
739 } 755 }
740 } 756 }
741 757
742 758
743 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const { 759 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const {
744 set->AddRegion(to_->start(), to_->end()); 760 set->AddRegion(to_->start(), to_->end());
745 } 761 }
746 762
747 763
748 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const { 764 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const {
749 ASSERT(!scavenging_); 765 ASSERT(!scavenging_);
750 uword cur = FirstObjectStart(); 766 uword cur = FirstObjectStart();
751 if (visitor->VisitRange(cur, top_)) { 767 if (visitor->VisitRange(cur, top_)) {
rmacnak 2017/06/22 22:31:50 top_ may be stale
danunez 2017/06/30 20:35:57 Right. top_ is now retrieved from the mutator thre
752 while (cur < top_) { 768 while (cur < top_) {
753 RawObject* raw_obj = RawObject::FromAddr(cur); 769 RawObject* raw_obj = RawObject::FromAddr(cur);
754 uword next = cur + raw_obj->Size(); 770 uword next = cur + raw_obj->Size();
755 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) { 771 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) {
756 return raw_obj; // Found object, return it. 772 return raw_obj; // Found object, return it.
757 } 773 }
758 cur = next; 774 cur = next;
759 } 775 }
760 ASSERT(cur == top_); 776 ASSERT(cur == top_);
761 } 777 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 } 906 }
891 907
892 908
893 void Scavenger::FreeExternal(intptr_t size) { 909 void Scavenger::FreeExternal(intptr_t size) {
894 ASSERT(size >= 0); 910 ASSERT(size >= 0);
895 external_size_ -= size; 911 external_size_ -= size;
896 ASSERT(external_size_ >= 0); 912 ASSERT(external_size_ >= 0);
897 } 913 }
898 914
899 } // namespace dart 915 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698