Chromium Code Reviews| Index: src/heap-snapshot-generator.cc |
| diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc |
| index 1c8a7b3dc4d7a3bb93cee7dce1d5ab68eae4c248..832aafe76a02016cf1d1edbd5c611da62d9300e0 100644 |
| --- a/src/heap-snapshot-generator.cc |
| +++ b/src/heap-snapshot-generator.cc |
| @@ -395,7 +395,7 @@ void HeapObjectsMap::SnapshotGenerationFinished() { |
| } |
| -void HeapObjectsMap::MoveObject(Address from, Address to) { |
| +void HeapObjectsMap::MoveObject(Address from, Address to, int object_size) { |
| ASSERT(to != NULL); |
| ASSERT(from != NULL); |
| if (from == to) return; |
| @@ -426,11 +426,21 @@ void HeapObjectsMap::MoveObject(Address from, Address to) { |
| int from_entry_info_index = |
| static_cast<int>(reinterpret_cast<intptr_t>(from_value)); |
| entries_.at(from_entry_info_index).addr = to; |
| + // Size of an object can change during its life, so to keep information |
| + // about the object in entries_ consistent, we have to adjust size when the |
| + // object is migrated. |
| + entries_.at(from_entry_info_index).size = object_size; |
| to_entry->value = from_value; |
| } |
| } |
| +void HeapObjectsMap::NewObject(Address addr, int size) { |
| + ASSERT(addr != NULL); |
| + FindOrAddEntry(addr, size, false); |
| +} |
| + |
| + |
| SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { |
| HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), |
| false); |
| @@ -443,7 +453,8 @@ SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { |
| SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, |
| - unsigned int size) { |
| + unsigned int size, |
| + bool accessed) { |
| ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
| HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), |
| true); |
| @@ -451,14 +462,14 @@ SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, |
| int entry_index = |
| static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| EntryInfo& entry_info = entries_.at(entry_index); |
| - entry_info.accessed = true; |
| + entry_info.accessed = accessed; |
| entry_info.size = size; |
| return entry_info.id; |
| } |
| entry->value = reinterpret_cast<void*>(entries_.length()); |
| SnapshotObjectId id = next_id_; |
| next_id_ += kObjectIdStep; |
| - entries_.Add(EntryInfo(id, addr, size)); |
| + entries_.Add(EntryInfo(id, addr, size, accessed)); |
| ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
| return id; |
| } |
| @@ -482,6 +493,27 @@ void HeapObjectsMap::UpdateHeapObjectsMap() { |
| } |
| +int HeapObjectsMap::FindUntrackedObjects() { |
| + HeapIterator iterator(heap_); |
| + int untracked = 0; |
| + for (HeapObject* obj = iterator.next(); |
| + obj != NULL; |
| + obj = iterator.next()) { |
| + HashMap::Entry* entry = entries_map_.Lookup( |
| + obj->address(), ComputePointerHash(obj->address()), false); |
| + if (entry == NULL) { |
| + untracked++; |
| + } else { |
| + int entry_index = static_cast<int>( |
| + reinterpret_cast<intptr_t>(entry->value)); |
| + EntryInfo& entry_info = entries_.at(entry_index); |
| + ASSERT_EQ(obj->Size(), static_cast<int>(entry_info.size)); |
| + } |
| + } |
| + return untracked; |
| +} |
| + |
| + |
| SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { |
| UpdateHeapObjectsMap(); |
| time_intervals_.Add(TimeInterval(next_id_)); |
| @@ -600,6 +632,7 @@ HeapSnapshotsCollection::~HeapSnapshotsCollection() { |
| HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(const char* name, |
| unsigned uid) { |
| is_tracking_objects_ = true; // Start watching for heap objects moves. |
| + heap()->isolate()->heap_profiler()->StartHeapObjectsTracking(); |
|
yurys
2013/08/26 06:32:25
Heap objects tracking should be switched separatel
Alexandra Mikhaylova
2013/08/26 15:48:40
Done.
|
| return new HeapSnapshot(this, name, uid); |
| } |