Index: src/profile-generator.cc |
diff --git a/src/profile-generator.cc b/src/profile-generator.cc |
index f836583d9ba9b3daf2a084b17fd65b5ca0bfa22a..032b19a1d95cd47749e9439a6f046cbcf77dd6ab 100644 |
--- a/src/profile-generator.cc |
+++ b/src/profile-generator.cc |
@@ -320,7 +320,7 @@ struct NodesPair { |
class FilteredCloneCallback { |
public: |
- explicit FilteredCloneCallback(ProfileNode* dst_root, int security_token_id) |
+ FilteredCloneCallback(ProfileNode* dst_root, int security_token_id) |
: stack_(10), |
security_token_id_(security_token_id) { |
stack_.Add(NodesPair(NULL, dst_root)); |
@@ -550,13 +550,16 @@ static void DeleteCpuProfile(CpuProfile** profile_ptr) { |
} |
static void DeleteProfilesList(List<CpuProfile*>** list_ptr) { |
- (*list_ptr)->Iterate(DeleteCpuProfile); |
- delete *list_ptr; |
+ if (*list_ptr) { |
Vitaly Repeshko
2011/03/22 14:30:36
nit: Use explicit != NULL comparison.
mnaganov (inactive)
2011/03/22 16:03:09
Done.
|
+ (*list_ptr)->Iterate(DeleteCpuProfile); |
+ delete *list_ptr; |
+ } |
} |
CpuProfilesCollection::~CpuProfilesCollection() { |
delete current_profiles_semaphore_; |
current_profiles_.Iterate(DeleteCpuProfile); |
+ detached_profiles_.Iterate(DeleteCpuProfile); |
profiles_by_token_.Iterate(DeleteProfilesList); |
code_entries_.Iterate(DeleteCodeEntry); |
} |
@@ -621,15 +624,8 @@ CpuProfile* CpuProfilesCollection::StopProfiling(int security_token_id, |
CpuProfile* CpuProfilesCollection::GetProfile(int security_token_id, |
unsigned uid) { |
- HashMap::Entry* entry = profiles_uids_.Lookup(reinterpret_cast<void*>(uid), |
- static_cast<uint32_t>(uid), |
- false); |
- int index; |
- if (entry != NULL) { |
- index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
- } else { |
- return NULL; |
- } |
+ int index = GetProfileIndex(uid); |
+ if (index < 0) return NULL; |
List<CpuProfile*>* unabridged_list = |
profiles_by_token_[TokenToIndex(TokenEnumerator::kNoSecurityToken)]; |
if (security_token_id == TokenEnumerator::kNoSecurityToken) { |
@@ -644,6 +640,15 @@ CpuProfile* CpuProfilesCollection::GetProfile(int security_token_id, |
} |
+int CpuProfilesCollection::GetProfileIndex(unsigned uid) { |
+ HashMap::Entry* entry = profiles_uids_.Lookup(reinterpret_cast<void*>(uid), |
+ static_cast<uint32_t>(uid), |
+ false); |
+ return entry != NULL ? |
+ static_cast<int>(reinterpret_cast<intptr_t>(entry->value)) : -1; |
+} |
+ |
+ |
bool CpuProfilesCollection::IsLastProfile(const char* title) { |
// Called from VM thread, and only it can mutate the list, |
// so no locking is needed here. |
@@ -653,6 +658,39 @@ bool CpuProfilesCollection::IsLastProfile(const char* title) { |
} |
+void CpuProfilesCollection::RemoveProfile(CpuProfile* profile) { |
+ // Called from VM thread for a completed profile. |
+ unsigned uid = profile->uid(); |
+ int index = GetProfileIndex(uid); |
+ if (index < 0) { |
+ detached_profiles_.RemoveElement(profile); |
+ return; |
+ } |
+ profiles_uids_.Remove(reinterpret_cast<void*>(uid), |
+ static_cast<uint32_t>(uid)); |
+ // Decrement all indexes above the deleted one. |
+ for (HashMap::Entry* p = profiles_uids_.Start(); |
+ p; |
Vitaly Repeshko
2011/03/22 14:30:36
!= NULL
mnaganov (inactive)
2011/03/22 16:03:09
Done.
|
+ p = profiles_uids_.Next(p)) { |
+ intptr_t p_index = reinterpret_cast<intptr_t>(p->value); |
+ if (p_index > index) { |
+ p->value = reinterpret_cast<void*>(p_index - 1); |
+ } |
+ } |
+ for (int i = 0; i < profiles_by_token_.length(); ++i) { |
+ List<CpuProfile*>* list = profiles_by_token_[i]; |
+ if (list != NULL && index < list->length()) { |
+ // Move all filtered clones into detached_profiles_, |
+ // so we can know that they are still in use. |
+ CpuProfile* cloned_profile = list->Remove(index); |
+ if (cloned_profile != NULL && cloned_profile != profile) { |
+ detached_profiles_.Add(cloned_profile); |
+ } |
+ } |
+ } |
+} |
+ |
+ |
int CpuProfilesCollection::TokenToIndex(int security_token_id) { |
ASSERT(TokenEnumerator::kNoSecurityToken == -1); |
return security_token_id + 1; // kNoSecurityToken -> 0, 0 -> 1, ... |
@@ -1268,6 +1306,12 @@ HeapSnapshot::~HeapSnapshot() { |
} |
+void HeapSnapshot::Delete() { |
+ collection_->RemoveSnapshot(this); |
+ delete this; |
+} |
+ |
+ |
void HeapSnapshot::AllocateEntries(int entries_count, |
int children_count, |
int retainers_count) { |
@@ -1579,6 +1623,14 @@ HeapSnapshot* HeapSnapshotsCollection::GetSnapshot(unsigned uid) { |
} |
+void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) { |
+ snapshots_.RemoveElement(snapshot); |
+ unsigned uid = snapshot->uid(); |
+ snapshots_uids_.Remove(reinterpret_cast<void*>(uid), |
+ static_cast<uint32_t>(uid)); |
+} |
+ |
+ |
HeapSnapshotsDiff* HeapSnapshotsCollection::CompareSnapshots( |
HeapSnapshot* snapshot1, |
HeapSnapshot* snapshot2) { |