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 <map> | 7 #include <map> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "vm/dart.h" | 10 #include "vm/dart.h" |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 504 // Key is white. Delay the weak property. | 504 // Key is white. Delay the weak property. |
| 505 visitor->DelayWeakProperty(raw_weak); | 505 visitor->DelayWeakProperty(raw_weak); |
| 506 return raw_weak->Size(); | 506 return raw_weak->Size(); |
| 507 } else { | 507 } else { |
| 508 // Key is gray or black. Make the weak property black. | 508 // Key is gray or black. Make the weak property black. |
| 509 return raw_weak->VisitPointers(visitor); | 509 return raw_weak->VisitPointers(visitor); |
| 510 } | 510 } |
| 511 } | 511 } |
| 512 | 512 |
| 513 | 513 |
| 514 void Scavenger::ProcessPeerReferents() { | |
| 515 std::map<RawObject*, void*>::iterator it = peer_.begin(); | |
| 516 while (it != peer_.end()) { | |
| 517 RawObject* raw_obj = it->first; | |
| 518 ASSERT(raw_obj->IsHeapObject()); | |
| 519 uword raw_addr = RawObject::ToAddr(raw_obj); | |
| 520 uword header = *reinterpret_cast<uword*>(raw_addr); | |
| 521 if (IsForwarding(header)) { | |
| 522 // The object has survived. If it has been copied to new space, | |
| 523 // update the table for the new location. If it has been copied | |
| 524 // to old space, move it to the old space table. | |
| 525 uword new_addr = ForwardedAddr(header); | |
| 526 raw_obj = RawObject::FromAddr(new_addr); | |
| 527 void* peer = it->second; | |
| 528 peer_.erase(it++); | |
| 529 heap_->SetPeer(raw_obj, peer); | |
|
Anton Muhin
2012/09/13 06:27:07
That looks sketchy, but I am not sure I remember S
cshapiro
2012/09/15 01:23:41
Modifying the map while traversing it should be ok
| |
| 530 } else { | |
| 531 // The object has become garbage. Remove its record. | |
| 532 peer_.erase(it++); | |
| 533 } | |
| 534 } | |
| 535 } | |
| 536 | |
| 537 | |
| 514 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 538 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
| 515 uword cur = FirstObjectStart(); | 539 uword cur = FirstObjectStart(); |
| 516 while (cur < top_) { | 540 while (cur < top_) { |
| 517 RawObject* raw_obj = RawObject::FromAddr(cur); | 541 RawObject* raw_obj = RawObject::FromAddr(cur); |
| 518 cur += raw_obj->VisitPointers(visitor); | 542 cur += raw_obj->VisitPointers(visitor); |
| 519 } | 543 } |
| 520 } | 544 } |
| 521 | 545 |
| 522 | 546 |
| 523 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { | 547 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 558 timer.Start(); | 582 timer.Start(); |
| 559 // Setup the visitor and run a scavenge. | 583 // Setup the visitor and run a scavenge. |
| 560 ScavengerVisitor visitor(isolate, this); | 584 ScavengerVisitor visitor(isolate, this); |
| 561 Prologue(isolate, invoke_api_callbacks); | 585 Prologue(isolate, invoke_api_callbacks); |
| 562 IterateRoots(isolate, &visitor, !invoke_api_callbacks); | 586 IterateRoots(isolate, &visitor, !invoke_api_callbacks); |
| 563 ProcessToSpace(&visitor); | 587 ProcessToSpace(&visitor); |
| 564 IterateWeakReferences(isolate, &visitor); | 588 IterateWeakReferences(isolate, &visitor); |
| 565 ScavengerWeakVisitor weak_visitor(this); | 589 ScavengerWeakVisitor weak_visitor(this); |
| 566 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); | 590 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); |
| 567 visitor.Finalize(); | 591 visitor.Finalize(); |
| 592 ProcessPeerReferents(); | |
| 568 Epilogue(isolate, invoke_api_callbacks); | 593 Epilogue(isolate, invoke_api_callbacks); |
| 569 timer.Stop(); | 594 timer.Stop(); |
| 570 if (FLAG_verbose_gc) { | 595 if (FLAG_verbose_gc) { |
| 571 OS::PrintErr("Scavenge[%d]: %"Pd64"us\n", | 596 OS::PrintErr("Scavenge[%d]: %"Pd64"us\n", |
| 572 count_, | 597 count_, |
| 573 timer.TotalElapsedTime()); | 598 timer.TotalElapsedTime()); |
| 574 } | 599 } |
| 575 | 600 |
| 576 if (FLAG_verify_after_gc) { | 601 if (FLAG_verify_after_gc) { |
| 577 OS::PrintErr("Verifying after Scavenge..."); | 602 OS::PrintErr("Verifying after Scavenge..."); |
| 578 heap_->Verify(); | 603 heap_->Verify(); |
| 579 OS::PrintErr(" done.\n"); | 604 OS::PrintErr(" done.\n"); |
| 580 } | 605 } |
| 581 | 606 |
| 582 count_++; | 607 count_++; |
| 583 // Done scavenging. Reset the marker. | 608 // Done scavenging. Reset the marker. |
| 584 ASSERT(scavenging_); | 609 ASSERT(scavenging_); |
| 585 scavenging_ = false; | 610 scavenging_ = false; |
| 586 } | 611 } |
| 587 | 612 |
| 588 | 613 |
| 589 void Scavenger::WriteProtect(bool read_only) { | 614 void Scavenger::WriteProtect(bool read_only) { |
| 590 space_->Protect( | 615 space_->Protect( |
| 591 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); | 616 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); |
| 592 } | 617 } |
| 593 | 618 |
| 619 | |
| 620 void Scavenger::SetPeer(RawObject* raw_obj, void* peer) { | |
|
Anton Muhin
2012/09/13 06:27:07
you've written this code once, maybe abstract away
| |
| 621 if (peer == NULL) { | |
| 622 peer_.erase(raw_obj); | |
| 623 } else { | |
| 624 peer_[raw_obj] = peer; | |
| 625 } | |
| 626 } | |
| 627 | |
| 628 | |
| 629 void* Scavenger::GetPeer(RawObject* raw_obj) { | |
| 630 std::map<RawObject*, void*>::iterator it = peer_.find(raw_obj); | |
| 631 return (it == peer_.end()) ? NULL : it->second; | |
| 632 } | |
| 633 | |
| 634 | |
| 635 int64_t Scavenger::PeerCount() const { | |
| 636 return static_cast<int64_t>(peer_.size()); | |
| 637 } | |
| 638 | |
| 594 } // namespace dart | 639 } // namespace dart |
| OLD | NEW |