Index: src/profile-generator.cc |
diff --git a/src/profile-generator.cc b/src/profile-generator.cc |
index 814ff8d68dd935c43ea8a49725f4caa63bdb82e6..97bc2b2d7732aacd731b3fca319d7a59454898d9 100644 |
--- a/src/profile-generator.cc |
+++ b/src/profile-generator.cc |
@@ -1406,6 +1406,82 @@ SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { |
} |
+SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr) { |
+ ASSERT(static_cast<uint32_t>(entries_->length()) > entries_map_.occupancy()); |
+ HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), true); |
+ if (entry->value != NULL) { |
+ int entry_index = |
+ static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
+ EntryInfo& entry_info = entries_->at(entry_index); |
+ entry_info.accessed = true; |
+ return entry_info.id; |
+ } |
+ entry->value = reinterpret_cast<void*>(entries_->length()); |
+ SnapshotObjectId id = next_id_; |
+ next_id_ += kObjectIdStep; |
+ entries_->Add(EntryInfo(id, addr)); |
+ ASSERT(static_cast<uint32_t>(entries_->length()) > entries_map_.occupancy()); |
+ return id; |
+} |
+ |
+ |
+void HeapObjectsMap::StopHeapObjectsTracking() { |
+ time_intervals_.Clear(); |
+} |
+ |
+void HeapObjectsMap::UpdateHeapObjectsMap() { |
+ HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
+ "HeapSnapshotsCollection::UpdateHeapObjectsMap"); |
+ int entries = 0; |
+ HeapIterator iterator(HeapIterator::kFilterUnreachable); |
+ for (HeapObject* obj = iterator.next(); |
+ obj != NULL; |
+ obj = iterator.next()) { |
+ FindOrAddEntry(obj->address()); |
+ ++entries; |
+ } |
+ initial_fill_mode_ = false; |
+ RemoveDeadEntries(); |
+} |
+ |
+ |
+void HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { |
+ UpdateHeapObjectsMap(); |
+ time_intervals_.Add(TimeInterval(next_id_)); |
+ int prefered_chunk_size = stream->GetChunkSize(); |
+ List<uint32_t> stats_buffer; |
+ ASSERT(entries_->length()); |
mnaganov (inactive)
2012/04/12 13:32:26
entries_->length() != 0 or, alternatively !entries
|
+ EntryInfo* entry_info = &entries_->first(); |
+ EntryInfo* end_entry_info = &entries_->last() + 1; |
+ uint32_t count = 0; |
mnaganov (inactive)
2012/04/12 13:32:26
count -> entries_count ?
|
+ for (int time_interval_index = 0; |
+ time_interval_index < time_intervals_.length(); |
+ ++time_interval_index) { |
+ TimeInterval& time_interval = time_intervals_[time_interval_index]; |
+ SnapshotObjectId time_interval_id = time_interval.id; |
+ while (entry_info < end_entry_info && entry_info->id < time_interval_id) { |
+ ++count; |
+ ++entry_info; |
+ } |
+ if (time_interval.count != count) { |
+ stats_buffer.Add(time_interval_index); |
+ stats_buffer.Add(time_interval.count = count); |
+ if (stats_buffer.length() >= prefered_chunk_size) { |
+ stream->WriteUint32Chunk(&stats_buffer.first(), |
mnaganov (inactive)
2012/04/12 13:32:26
Have you considered checking the result and aborti
|
+ stats_buffer.length()); |
+ stats_buffer.Clear(); |
+ } |
+ } |
+ count = 0; |
+ } |
+ ASSERT(entry_info == end_entry_info); |
+ if (stats_buffer.length()) { |
mnaganov (inactive)
2012/04/12 13:32:26
stats_buffer.length() > 0 or, alternatively !stats
|
+ stream->WriteUint32Chunk(&stats_buffer.first(), stats_buffer.length()); |
+ } |
+ stream->EndOfStream(); |
+} |
+ |
+ |
void HeapObjectsMap::RemoveDeadEntries() { |
ASSERT(entries_->length() > 0 && |
entries_->at(0).id == 0 && |