Chromium Code Reviews| 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 "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 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 462 while (!pending->IsEmpty()) { | 462 while (!pending->IsEmpty()) { |
| 463 RawObject* raw_object = pending->Pop(); | 463 RawObject* raw_object = pending->Pop(); |
| 464 if (raw_object->IsForwardingCorpse()) { | 464 if (raw_object->IsForwardingCorpse()) { |
| 465 // A source object in a become was a remembered object, but we do | 465 // A source object in a become was a remembered object, but we do |
| 466 // not visit the store buffer during become to remove it. | 466 // not visit the store buffer during become to remove it. |
| 467 continue; | 467 continue; |
| 468 } | 468 } |
| 469 ASSERT(raw_object->IsRemembered()); | 469 ASSERT(raw_object->IsRemembered()); |
| 470 raw_object->ClearRememberedBit(); | 470 raw_object->ClearRememberedBit(); |
| 471 visitor->VisitingOldObject(raw_object); | 471 visitor->VisitingOldObject(raw_object); |
| 472 raw_object->VisitPointers(visitor); | 472 raw_object->VisitPointersNonvirtual(visitor); |
| 473 } | 473 } |
| 474 pending->Reset(); | 474 pending->Reset(); |
| 475 // Return the emptied block for recycling (no need to check threshold). | 475 // Return the emptied block for recycling (no need to check threshold). |
| 476 isolate->store_buffer()->PushBlock(pending, StoreBuffer::kIgnoreThreshold); | 476 isolate->store_buffer()->PushBlock(pending, StoreBuffer::kIgnoreThreshold); |
| 477 pending = next; | 477 pending = next; |
| 478 } | 478 } |
| 479 heap_->RecordData(kStoreBufferEntries, total_count); | 479 heap_->RecordData(kStoreBufferEntries, total_count); |
| 480 heap_->RecordData(kDataUnused1, 0); | 480 heap_->RecordData(kDataUnused1, 0); |
| 481 heap_->RecordData(kDataUnused2, 0); | 481 heap_->RecordData(kDataUnused2, 0); |
| 482 // Done iterating through old objects remembered in the store buffers. | 482 // Done iterating through old objects remembered in the store buffers. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 543 } | 543 } |
| 544 | 544 |
| 545 | 545 |
| 546 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) { | 546 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) { |
| 547 // Iterate until all work has been drained. | 547 // Iterate until all work has been drained. |
| 548 while ((resolved_top_ < top_) || PromotedStackHasMore()) { | 548 while ((resolved_top_ < top_) || PromotedStackHasMore()) { |
| 549 while (resolved_top_ < top_) { | 549 while (resolved_top_ < top_) { |
| 550 RawObject* raw_obj = RawObject::FromAddr(resolved_top_); | 550 RawObject* raw_obj = RawObject::FromAddr(resolved_top_); |
| 551 intptr_t class_id = raw_obj->GetClassId(); | 551 intptr_t class_id = raw_obj->GetClassId(); |
| 552 if (class_id != kWeakPropertyCid) { | 552 if (class_id != kWeakPropertyCid) { |
| 553 resolved_top_ += raw_obj->VisitPointers(visitor); | 553 resolved_top_ += raw_obj->VisitPointersNonvirtual(visitor); |
| 554 } else { | 554 } else { |
| 555 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); | 555 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); |
| 556 resolved_top_ += ProcessWeakProperty(raw_weak, visitor); | 556 resolved_top_ += ProcessWeakProperty(raw_weak, visitor); |
| 557 } | 557 } |
| 558 } | 558 } |
| 559 { | 559 { |
| 560 // Visit all the promoted objects and update/scavenge their internal | 560 // Visit all the promoted objects and update/scavenge their internal |
| 561 // pointers. Potentially this adds more objects to the to space. | 561 // pointers. Potentially this adds more objects to the to space. |
| 562 while (PromotedStackHasMore()) { | 562 while (PromotedStackHasMore()) { |
| 563 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); | 563 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); |
| 564 // Resolve or copy all objects referred to by the current object. This | 564 // Resolve or copy all objects referred to by the current object. This |
| 565 // can potentially push more objects on this stack as well as add more | 565 // can potentially push more objects on this stack as well as add more |
| 566 // objects to be resolved in the to space. | 566 // objects to be resolved in the to space. |
| 567 ASSERT(!raw_object->IsRemembered()); | 567 ASSERT(!raw_object->IsRemembered()); |
| 568 visitor->VisitingOldObject(raw_object); | 568 visitor->VisitingOldObject(raw_object); |
| 569 raw_object->VisitPointers(visitor); | 569 raw_object->VisitPointersNonvirtual(visitor); |
| 570 } | 570 } |
| 571 visitor->VisitingOldObject(NULL); | 571 visitor->VisitingOldObject(NULL); |
| 572 } | 572 } |
| 573 { | 573 { |
| 574 // Finished this round of scavenging. Process the pending weak properties | 574 // Finished this round of scavenging. Process the pending weak properties |
| 575 // for which the keys have become reachable. Potentially this adds more | 575 // for which the keys have become reachable. Potentially this adds more |
| 576 // objects to the to space. | 576 // objects to the to space. |
| 577 RawWeakProperty* cur_weak = delayed_weak_properties_; | 577 RawWeakProperty* cur_weak = delayed_weak_properties_; |
| 578 delayed_weak_properties_ = NULL; | 578 delayed_weak_properties_ = NULL; |
| 579 while (cur_weak != NULL) { | 579 while (cur_weak != NULL) { |
| 580 uword next_weak = cur_weak->ptr()->next_; | 580 uword next_weak = cur_weak->ptr()->next_; |
| 581 // Promoted weak properties are not enqueued. So we can guarantee that | 581 // Promoted weak properties are not enqueued. So we can guarantee that |
| 582 // we do not need to think about store barriers here. | 582 // we do not need to think about store barriers here. |
| 583 ASSERT(cur_weak->IsNewObject()); | 583 ASSERT(cur_weak->IsNewObject()); |
| 584 RawObject* raw_key = cur_weak->ptr()->key_; | 584 RawObject* raw_key = cur_weak->ptr()->key_; |
| 585 ASSERT(raw_key->IsHeapObject()); | 585 ASSERT(raw_key->IsHeapObject()); |
| 586 // Key still points into from space even if the object has been | 586 // Key still points into from space even if the object has been |
| 587 // promoted to old space by now. The key will be updated accordingly | 587 // promoted to old space by now. The key will be updated accordingly |
| 588 // below when VisitPointers is run. | 588 // below when VisitPointers is run. |
| 589 ASSERT(raw_key->IsNewObject()); | 589 ASSERT(raw_key->IsNewObject()); |
| 590 uword raw_addr = RawObject::ToAddr(raw_key); | 590 uword raw_addr = RawObject::ToAddr(raw_key); |
| 591 ASSERT(visitor->from_->Contains(raw_addr)); | 591 ASSERT(visitor->from_->Contains(raw_addr)); |
| 592 uword header = *reinterpret_cast<uword*>(raw_addr); | 592 uword header = *reinterpret_cast<uword*>(raw_addr); |
| 593 // Reset the next pointer in the weak property. | 593 // Reset the next pointer in the weak property. |
| 594 cur_weak->ptr()->next_ = 0; | 594 cur_weak->ptr()->next_ = 0; |
| 595 if (IsForwarding(header)) { | 595 if (IsForwarding(header)) { |
| 596 cur_weak->VisitPointers(visitor); | 596 cur_weak->VisitPointersNonvirtual(visitor); |
|
erikcorry
2017/05/31 10:40:42
Probably not worth it.
| |
| 597 } else { | 597 } else { |
| 598 EnqueueWeakProperty(cur_weak); | 598 EnqueueWeakProperty(cur_weak); |
| 599 } | 599 } |
| 600 // Advance to next weak property in the queue. | 600 // Advance to next weak property in the queue. |
| 601 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); | 601 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); |
| 602 } | 602 } |
| 603 } | 603 } |
| 604 } | 604 } |
| 605 } | 605 } |
| 606 | 606 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 654 if (raw_key->IsHeapObject() && raw_key->IsNewObject()) { | 654 if (raw_key->IsHeapObject() && raw_key->IsNewObject()) { |
| 655 uword raw_addr = RawObject::ToAddr(raw_key); | 655 uword raw_addr = RawObject::ToAddr(raw_key); |
| 656 uword header = *reinterpret_cast<uword*>(raw_addr); | 656 uword header = *reinterpret_cast<uword*>(raw_addr); |
| 657 if (!IsForwarding(header)) { | 657 if (!IsForwarding(header)) { |
| 658 // Key is white. Enqueue the weak property. | 658 // Key is white. Enqueue the weak property. |
| 659 EnqueueWeakProperty(raw_weak); | 659 EnqueueWeakProperty(raw_weak); |
| 660 return raw_weak->Size(); | 660 return raw_weak->Size(); |
| 661 } | 661 } |
| 662 } | 662 } |
| 663 // Key is gray or black. Make the weak property black. | 663 // Key is gray or black. Make the weak property black. |
| 664 return raw_weak->VisitPointers(visitor); | 664 return raw_weak->VisitPointersNonvirtual(visitor); |
|
erikcorry
2017/05/31 10:40:42
Probably not worth it.
| |
| 665 } | 665 } |
| 666 | 666 |
| 667 | 667 |
| 668 void Scavenger::ProcessWeakReferences() { | 668 void Scavenger::ProcessWeakReferences() { |
| 669 // Rehash the weak tables now that we know which objects survive this cycle. | 669 // Rehash the weak tables now that we know which objects survive this cycle. |
| 670 for (int sel = 0; sel < Heap::kNumWeakSelectors; sel++) { | 670 for (int sel = 0; sel < Heap::kNumWeakSelectors; sel++) { |
| 671 WeakTable* table = | 671 WeakTable* table = |
| 672 heap_->GetWeakTable(Heap::kNew, static_cast<Heap::WeakSelector>(sel)); | 672 heap_->GetWeakTable(Heap::kNew, static_cast<Heap::WeakSelector>(sel)); |
| 673 heap_->SetWeakTable(Heap::kNew, static_cast<Heap::WeakSelector>(sel), | 673 heap_->SetWeakTable(Heap::kNew, static_cast<Heap::WeakSelector>(sel), |
| 674 WeakTable::NewFrom(table)); | 674 WeakTable::NewFrom(table)); |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 890 } | 890 } |
| 891 | 891 |
| 892 | 892 |
| 893 void Scavenger::FreeExternal(intptr_t size) { | 893 void Scavenger::FreeExternal(intptr_t size) { |
| 894 ASSERT(size >= 0); | 894 ASSERT(size >= 0); |
| 895 external_size_ -= size; | 895 external_size_ -= size; |
| 896 ASSERT(external_size_ >= 0); | 896 ASSERT(external_size_ >= 0); |
| 897 } | 897 } |
| 898 | 898 |
| 899 } // namespace dart | 899 } // namespace dart |
| OLD | NEW |