| Index: src/heap-snapshot-generator.cc
|
| diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
|
| index 6cbdcd67077b2a22001199e3552712304cc4d61c..a18fb63018500bfd8027d15885c73c6778fdb640 100644
|
| --- a/src/heap-snapshot-generator.cc
|
| +++ b/src/heap-snapshot-generator.cc
|
| @@ -404,21 +404,33 @@ void HeapObjectsMap::MoveObject(Address from, Address to) {
|
| ASSERT(from != NULL);
|
| if (from == to) return;
|
| void* from_value = entries_map_.Remove(from, AddressHash(from));
|
| - if (from_value == NULL) return;
|
| - int from_entry_info_index =
|
| - static_cast<int>(reinterpret_cast<intptr_t>(from_value));
|
| - entries_.at(from_entry_info_index).addr = to;
|
| - HashMap::Entry* to_entry = entries_map_.Lookup(to, AddressHash(to), true);
|
| - if (to_entry->value != NULL) {
|
| - int to_entry_info_index =
|
| - static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value));
|
| - // Without this operation we will have two EntryInfo's with the same
|
| - // value in addr field. It is bad because later at RemoveDeadEntries
|
| - // one of this entry will be removed with the corresponding entries_map_
|
| - // entry.
|
| - entries_.at(to_entry_info_index).addr = NULL;
|
| - }
|
| - to_entry->value = reinterpret_cast<void*>(from_entry_info_index);
|
| + if (from_value == NULL) {
|
| + // It may occur that some untracked object moves to an address X and there
|
| + // is a tracked object at that address. In this case we should remove the
|
| + // entry as we know that the object has died.
|
| + void* to_value = entries_map_.Remove(to, AddressHash(to));
|
| + if (to_value != NULL) {
|
| + int to_entry_info_index =
|
| + static_cast<int>(reinterpret_cast<intptr_t>(to_value));
|
| + entries_.at(to_entry_info_index).addr = NULL;
|
| + }
|
| + } else {
|
| + HashMap::Entry* to_entry = entries_map_.Lookup(to, AddressHash(to), true);
|
| + if (to_entry->value != NULL) {
|
| + // We found the existing entry with to address for an old object.
|
| + // Without this operation we will have two EntryInfo's with the same
|
| + // value in addr field. It is bad because later at RemoveDeadEntries
|
| + // one of this entry will be removed with the corresponding entries_map_
|
| + // entry.
|
| + int to_entry_info_index =
|
| + static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value));
|
| + entries_.at(to_entry_info_index).addr = NULL;
|
| + }
|
| + int from_entry_info_index =
|
| + static_cast<int>(reinterpret_cast<intptr_t>(from_value));
|
| + entries_.at(from_entry_info_index).addr = to;
|
| + to_entry->value = from_value;
|
| + }
|
| }
|
|
|
|
|
|
|