Chromium Code Reviews| Index: runtime/vm/scavenger.cc |
| diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc |
| index 49eafb53e51ebb6a28ceaf9eaaa483cf6d3e139e..246343b8f1eacfc13b29d0c95cc11c52bb007d1f 100644 |
| --- a/runtime/vm/scavenger.cc |
| +++ b/runtime/vm/scavenger.cc |
| @@ -511,6 +511,30 @@ uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak, |
| } |
| +void Scavenger::ProcessPeerReferents() { |
| + std::map<RawObject*, void*>::iterator it = peer_.begin(); |
| + while (it != peer_.end()) { |
| + RawObject* raw_obj = it->first; |
| + ASSERT(raw_obj->IsHeapObject()); |
| + uword raw_addr = RawObject::ToAddr(raw_obj); |
| + uword header = *reinterpret_cast<uword*>(raw_addr); |
| + if (IsForwarding(header)) { |
| + // The object has survived. If it has been copied to new space, |
| + // update the table for the new location. If it has been copied |
| + // to old space, move it to the old space table. |
| + uword new_addr = ForwardedAddr(header); |
| + raw_obj = RawObject::FromAddr(new_addr); |
| + void* peer = it->second; |
| + peer_.erase(it++); |
| + 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
|
| + } else { |
| + // The object has become garbage. Remove its record. |
| + peer_.erase(it++); |
| + } |
| + } |
| +} |
| + |
| + |
| void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
| uword cur = FirstObjectStart(); |
| while (cur < top_) { |
| @@ -565,6 +589,7 @@ void Scavenger::Scavenge(bool invoke_api_callbacks, const char* gc_reason) { |
| ScavengerWeakVisitor weak_visitor(this); |
| IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); |
| visitor.Finalize(); |
| + ProcessPeerReferents(); |
| Epilogue(isolate, invoke_api_callbacks); |
| timer.Stop(); |
| if (FLAG_verbose_gc) { |
| @@ -591,4 +616,24 @@ void Scavenger::WriteProtect(bool read_only) { |
| read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); |
| } |
| + |
| +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
|
| + if (peer == NULL) { |
| + peer_.erase(raw_obj); |
| + } else { |
| + peer_[raw_obj] = peer; |
| + } |
| +} |
| + |
| + |
| +void* Scavenger::GetPeer(RawObject* raw_obj) { |
| + std::map<RawObject*, void*>::iterator it = peer_.find(raw_obj); |
| + return (it == peer_.end()) ? NULL : it->second; |
| +} |
| + |
| + |
| +int64_t Scavenger::PeerCount() const { |
| + return static_cast<int64_t>(peer_.size()); |
| +} |
| + |
| } // namespace dart |