Index: src/profile-generator.cc |
diff --git a/src/profile-generator.cc b/src/profile-generator.cc |
index 814ff8d68dd935c43ea8a49725f4caa63bdb82e6..979d64ebb5e82dfb6751c2fd793b6561bc8537c7 100644 |
--- a/src/profile-generator.cc |
+++ b/src/profile-generator.cc |
@@ -1406,6 +1406,84 @@ 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() { |
+ fragment_infos_.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(); |
+ fragment_infos_.Add(FragmentInfo(next_id_)); |
+ int collected_fragment_updates = 0; |
+ int prefered_chunk_size = stream->GetChunkSize(); |
+ List<uint32_t> stats_buffer; |
+ ASSERT(entries_->length()); |
+ EntryInfo* entry_info = &entries_->first(); |
+ EntryInfo* end_entry_info = &entries_->last() + 1; |
+ uint32_t count = 0; |
+ for (int fragment_index = 0; |
+ fragment_index < fragment_infos_.length(); |
+ ++fragment_index) { |
+ FragmentInfo& fragment_info = fragment_infos_[fragment_index]; |
+ SnapshotObjectId fragment_id = fragment_info.id; |
+ while (entry_info < end_entry_info && entry_info->id < fragment_id) { |
alexeif
2012/04/11 14:38:51
it doesn't look very efficient.
May be do the bina
|
+ ++count; |
+ ++entry_info; |
+ } |
+ if (fragment_info.count != count) { |
+ stats_buffer.Add(fragment_index); |
+ stats_buffer.Add(fragment_info.count = count); |
+ ++collected_fragment_updates; |
+ if (stats_buffer.length() >= prefered_chunk_size) { |
+ stream->WriteUint32Chunk(&stats_buffer.first(), |
+ stats_buffer.length()); |
+ stats_buffer.Clear(); |
+ } |
+ } |
+ count = 0; |
+ } |
+ ASSERT(entry_info == end_entry_info); |
+ if (stats_buffer.length()) { |
+ stream->WriteUint32Chunk(&stats_buffer.first(), stats_buffer.length()); |
+ } |
+ stream->EndOfStream(); |
+} |
+ |
+ |
void HeapObjectsMap::RemoveDeadEntries() { |
ASSERT(entries_->length() > 0 && |
entries_->at(0).id == 0 && |