Add support for CPU and heap profiles deletion.

R=vitalyr@chromium.org
BUG=none
TEST=none

Review URL: http://codereview.chromium.org/6685084

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7308 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5051d2c6
......@@ -131,6 +131,16 @@ class V8EXPORT CpuProfile {
/** Returns the root node of the top down call tree. */
const CpuProfileNode* GetTopDownRoot() const;
/**
* Deletes the profile and removes it from CpuProfiler's list.
* All pointers to nodes previously returned become invalid.
* Profiles with the same uid but obtained using different
* security token are not deleted, but become inaccessible
* using FindProfile method. It is embedder's responsibility
* to call Delete on these profiles.
*/
void Delete();
};
......@@ -181,6 +191,13 @@ class V8EXPORT CpuProfiler {
static const CpuProfile* StopProfiling(
Handle<String> title,
Handle<Value> security_token = Handle<Value>());
/**
* Deletes all existing profiles, also cancelling all profiling
* activity. All previously returned pointers to profiles and their
* contents become invalid after this call.
*/
static void DeleteAllProfiles();
};
......@@ -367,6 +384,13 @@ class V8EXPORT HeapSnapshot {
*/
const HeapSnapshotsDiff* CompareWith(const HeapSnapshot* snapshot) const;
/**
* Deletes the snapshot and removes it from HeapProfiler's list.
* All pointers to nodes, edges and paths previously returned become
* invalid.
*/
void Delete();
/**
* Prepare a serialized representation of the snapshot. The result
* is written into the stream provided in chunks of specified size.
......@@ -427,6 +451,12 @@ class V8EXPORT HeapProfiler {
HeapSnapshot::Type type = HeapSnapshot::kFull,
ActivityControl* control = NULL);
/**
* Deletes all snapshots taken. All previously returned pointers to
* snapshots and their contents become invalid after this call.
*/
static void DeleteAllSnapshots();
/** Binds a callback to embedder's class ID. */
static void DefineWrapperClass(
uint16_t class_id,
......
......@@ -5078,6 +5078,18 @@ const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
}
void CpuProfile::Delete() {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::CpuProfile::Delete");
i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
if (i::CpuProfiler::GetProfilesCount() == 0 &&
!i::CpuProfiler::HasDetachedProfiles()) {
// If this was the last profile, clean up all accessory data as well.
i::CpuProfiler::DeleteAllProfiles();
}
}
unsigned CpuProfile::GetUid() const {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
......@@ -5157,6 +5169,13 @@ const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
}
void CpuProfiler::DeleteAllProfiles() {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
i::CpuProfiler::DeleteAllProfiles();
}
static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
return const_cast<i::HeapGraphEdge*>(
reinterpret_cast<const i::HeapGraphEdge*>(edge));
......@@ -5363,6 +5382,18 @@ static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
}
void HeapSnapshot::Delete() {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
if (i::HeapProfiler::GetSnapshotsCount() > 1) {
ToInternal(this)->Delete();
} else {
// If this is the last snapshot, clean up all accessory data as well.
i::HeapProfiler::DeleteAllSnapshots();
}
}
HeapSnapshot::Type HeapSnapshot::GetType() const {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
......@@ -5472,6 +5503,13 @@ const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
}
void HeapProfiler::DeleteAllSnapshots() {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
i::HeapProfiler::DeleteAllSnapshots();
}
void HeapProfiler::DefineWrapperClass(uint16_t class_id,
WrapperInfoCallback callback) {
i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
......
......@@ -331,6 +331,27 @@ TickSample* CpuProfiler::TickSampleEvent(Isolate* isolate) {
}
void CpuProfiler::DeleteAllProfiles() {
ASSERT(Isolate::Current()->cpu_profiler() != NULL);
if (is_profiling())
Isolate::Current()->cpu_profiler()->StopProcessor();
Isolate::Current()->cpu_profiler()->ResetProfiles();
}
void CpuProfiler::DeleteProfile(CpuProfile* profile) {
ASSERT(Isolate::Current()->cpu_profiler() != NULL);
Isolate::Current()->cpu_profiler()->profiles_->RemoveProfile(profile);
delete profile;
}
bool CpuProfiler::HasDetachedProfiles() {
ASSERT(Isolate::Current()->cpu_profiler() != NULL);
return Isolate::Current()->cpu_profiler()->profiles_->HasDetachedProfiles();
}
void CpuProfiler::CallbackEvent(String* name, Address entry_point) {
Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
......@@ -452,6 +473,11 @@ CpuProfiler::~CpuProfiler() {
}
void CpuProfiler::ResetProfiles() {
delete profiles_;
profiles_ = new CpuProfilesCollection();
}
void CpuProfiler::StartCollectingProfile(const char* title) {
if (profiles_->StartProfiling(title, next_profile_uid_++)) {
StartProcessorIfNotStarted();
......@@ -521,7 +547,11 @@ CpuProfile* CpuProfiler::StopCollectingProfile(Object* security_token,
void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
if (profiles_->IsLastProfile(title)) {
if (profiles_->IsLastProfile(title)) StopProcessor();
}
void CpuProfiler::StopProcessor() {
Sampler* sampler = reinterpret_cast<Sampler*>(LOGGER->ticker_);
sampler->DecreaseProfilingDepth();
if (need_to_stop_sampler_) {
......@@ -536,7 +566,6 @@ void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
NoBarrier_Store(&is_profiling_, false);
generator_ = NULL;
LOGGER->logging_nesting_ = saved_logging_nesting_;
}
}
} } // namespace v8::internal
......
......@@ -227,6 +227,9 @@ class CpuProfiler {
static int GetProfilesCount();
static CpuProfile* GetProfile(Object* security_token, int index);
static CpuProfile* FindProfile(Object* security_token, unsigned uid);
static void DeleteAllProfiles();
static void DeleteProfile(CpuProfile* profile);
static bool HasDetachedProfiles();
// Invoked from stack sampler (thread or signal handler.)
static TickSample* TickSampleEvent(Isolate* isolate);
......@@ -276,6 +279,8 @@ class CpuProfiler {
CpuProfile* StopCollectingProfile(const char* title);
CpuProfile* StopCollectingProfile(Object* security_token, String* title);
void StopProcessorIfLastProfile(const char* title);
void StopProcessor();
void ResetProfiles();
CpuProfilesCollection* profiles_;
unsigned next_profile_uid_;
......
......@@ -326,6 +326,13 @@ HeapProfiler::~HeapProfiler() {
delete snapshots_;
}
void HeapProfiler::ResetSnapshots() {
delete snapshots_;
snapshots_ = new HeapSnapshotsCollection();
}
#endif // ENABLE_LOGGING_AND_PROFILING
void HeapProfiler::Setup() {
......@@ -450,6 +457,13 @@ HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
}
void HeapProfiler::DeleteAllSnapshots() {
HeapProfiler* profiler = Isolate::Current()->heap_profiler();
ASSERT(profiler != NULL);
profiler->ResetSnapshots();
}
void HeapProfiler::ObjectMoveEvent(Address from, Address to) {
snapshots_->ObjectMoveEvent(from, to);
}
......
......@@ -67,6 +67,7 @@ class HeapProfiler {
static int GetSnapshotsCount();
static HeapSnapshot* GetSnapshot(int index);
static HeapSnapshot* FindSnapshot(unsigned uid);
static void DeleteAllSnapshots();
void ObjectMoveEvent(Address from, Address to);
......@@ -92,6 +93,7 @@ class HeapProfiler {
HeapSnapshot* TakeSnapshotImpl(String* name,
int type,
v8::ActivityControl* control);
void ResetSnapshots();
HeapSnapshotsCollection* snapshots_;
unsigned next_snapshot_uid_;
......
......@@ -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) {
if (*list_ptr != NULL) {
(*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 != NULL;
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) {
......
......@@ -300,6 +300,8 @@ class CpuProfilesCollection {
}
CpuProfile* GetProfile(int security_token_id, unsigned uid);
bool IsLastProfile(const char* title);
void RemoveProfile(CpuProfile* profile);
bool HasDetachedProfiles() { return detached_profiles_.length() > 0; }
CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
String* name, String* resource_name, int line_number);
......@@ -322,6 +324,7 @@ class CpuProfilesCollection {
const char* GetFunctionName(const char* name) {
return function_and_resource_names_.GetFunctionName(name);
}
int GetProfileIndex(unsigned uid);
List<CpuProfile*>* GetProfilesList(int security_token_id);
int TokenToIndex(int security_token_id);
......@@ -335,6 +338,7 @@ class CpuProfilesCollection {
// Mapping from profiles' uids to indexes in the second nested list
// of profiles_by_token_.
HashMap profiles_uids_;
List<CpuProfile*> detached_profiles_;
// Accessed by VM thread and profile generator thread.
List<CpuProfile*> current_profiles_;
......@@ -673,6 +677,7 @@ class HeapSnapshot {
const char* title,
unsigned uid);
~HeapSnapshot();
void Delete();
HeapSnapshotsCollection* collection() { return collection_; }
Type type() { return type_; }
......@@ -840,6 +845,7 @@ class HeapSnapshotsCollection {
void SnapshotGenerationFinished(HeapSnapshot* snapshot);
List<HeapSnapshot*>* snapshots() { return &snapshots_; }
HeapSnapshot* GetSnapshot(unsigned uid);
void RemoveSnapshot(HeapSnapshot* snapshot);
StringsStorage* names() { return &names_; }
TokenEnumerator* token_enumerator() { return token_enumerator_; }
......
......@@ -7,6 +7,7 @@
#include "v8.h"
#include "cpu-profiler-inl.h"
#include "cctest.h"
#include "../include/v8-profiler.h"
namespace i = v8::internal;
......@@ -236,4 +237,138 @@ TEST(CrashIfStoppingLastNonExistentProfile) {
CpuProfiler::TearDown();
}
TEST(DeleteAllCpuProfiles) {
InitializeVM();
TestSetup test_setup;
CpuProfiler::Setup();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CpuProfiler::DeleteAllProfiles();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CpuProfiler::StartProfiling("1");
CpuProfiler::StopProfiling("1");
CHECK_EQ(1, CpuProfiler::GetProfilesCount());
CpuProfiler::DeleteAllProfiles();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CpuProfiler::StartProfiling("1");
CpuProfiler::StartProfiling("2");
CpuProfiler::StopProfiling("2");
CpuProfiler::StopProfiling("1");
CHECK_EQ(2, CpuProfiler::GetProfilesCount());
CpuProfiler::DeleteAllProfiles();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
// Test profiling cancellation by the 'delete' command.
CpuProfiler::StartProfiling("1");
CpuProfiler::StartProfiling("2");
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CpuProfiler::DeleteAllProfiles();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CpuProfiler::TearDown();
}
TEST(DeleteCpuProfile) {
v8::HandleScope scope;
LocalContext env;
CHECK_EQ(0, v8::CpuProfiler::GetProfilesCount());
v8::Local<v8::String> name1 = v8::String::New("1");
v8::CpuProfiler::StartProfiling(name1);
const v8::CpuProfile* p1 = v8::CpuProfiler::StopProfiling(name1);
CHECK_NE(NULL, p1);
CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
unsigned uid1 = p1->GetUid();
CHECK_EQ(p1, v8::CpuProfiler::FindProfile(uid1));
const_cast<v8::CpuProfile*>(p1)->Delete();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
v8::Local<v8::String> name2 = v8::String::New("2");
v8::CpuProfiler::StartProfiling(name2);
const v8::CpuProfile* p2 = v8::CpuProfiler::StopProfiling(name2);
CHECK_NE(NULL, p2);
CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
unsigned uid2 = p2->GetUid();
CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2));
CHECK_EQ(p2, v8::CpuProfiler::FindProfile(uid2));
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
v8::Local<v8::String> name3 = v8::String::New("3");
v8::CpuProfiler::StartProfiling(name3);
const v8::CpuProfile* p3 = v8::CpuProfiler::StopProfiling(name3);
CHECK_NE(NULL, p3);
CHECK_EQ(2, v8::CpuProfiler::GetProfilesCount());
unsigned uid3 = p3->GetUid();
CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3));
CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
const_cast<v8::CpuProfile*>(p2)->Delete();
CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2));
CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
const_cast<v8::CpuProfile*>(p3)->Delete();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid3));
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2));
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
}
TEST(DeleteCpuProfileDifferentTokens) {
v8::HandleScope scope;
LocalContext env;
CHECK_EQ(0, v8::CpuProfiler::GetProfilesCount());
v8::Local<v8::String> name1 = v8::String::New("1");
v8::CpuProfiler::StartProfiling(name1);
const v8::CpuProfile* p1 = v8::CpuProfiler::StopProfiling(name1);
CHECK_NE(NULL, p1);
CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
unsigned uid1 = p1->GetUid();
CHECK_EQ(p1, v8::CpuProfiler::FindProfile(uid1));
v8::Local<v8::String> token1 = v8::String::New("token1");
const v8::CpuProfile* p1_t1 = v8::CpuProfiler::FindProfile(uid1, token1);
CHECK_NE(NULL, p1_t1);
CHECK_NE(p1, p1_t1);
CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
const_cast<v8::CpuProfile*>(p1)->Delete();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1));
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid1, token1));
const_cast<v8::CpuProfile*>(p1_t1)->Delete();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
v8::Local<v8::String> name2 = v8::String::New("2");
v8::CpuProfiler::StartProfiling(name2);
v8::Local<v8::String> token2 = v8::String::New("token2");
const v8::CpuProfile* p2_t2 = v8::CpuProfiler::StopProfiling(name2, token2);
CHECK_NE(NULL, p2_t2);
CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
unsigned uid2 = p2_t2->GetUid();
CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2));
const v8::CpuProfile* p2 = v8::CpuProfiler::FindProfile(uid2);
CHECK_NE(p2_t2, p2);
v8::Local<v8::String> name3 = v8::String::New("3");
v8::CpuProfiler::StartProfiling(name3);
const v8::CpuProfile* p3 = v8::CpuProfiler::StopProfiling(name3);
CHECK_NE(NULL, p3);
CHECK_EQ(2, v8::CpuProfiler::GetProfilesCount());
unsigned uid3 = p3->GetUid();
CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3));
CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
const_cast<v8::CpuProfile*>(p2_t2)->Delete();
CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2));
CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
const_cast<v8::CpuProfile*>(p2)->Delete();
CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount());
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2));
CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3));
const_cast<v8::CpuProfile*>(p3)->Delete();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid3));
}
#endif // ENABLE_LOGGING_AND_PROFILING
......@@ -1395,4 +1395,62 @@ TEST(HeapSnapshotRetainedObjectInfo) {
CHECK_EQ(ccc, GetProperty(n_CCC, v8::HeapGraphEdge::kInternal, "Native"));
}
TEST(DeleteAllHeapSnapshots) {
v8::HandleScope scope;
LocalContext env;
CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
v8::HeapProfiler::DeleteAllSnapshots();
CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8::String::New("1")));
CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount());
v8::HeapProfiler::DeleteAllSnapshots();
CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8::String::New("1")));
CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8::String::New("2")));
CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount());
v8::HeapProfiler::DeleteAllSnapshots();
CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
}
TEST(DeleteHeapSnapshot) {
v8::HandleScope scope;
LocalContext env;
CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
const v8::HeapSnapshot* s1 =
v8::HeapProfiler::TakeSnapshot(v8::String::New("1"));
CHECK_NE(NULL, s1);
CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount());
unsigned uid1 = s1->GetUid();
CHECK_EQ(s1, v8::HeapProfiler::FindSnapshot(uid1));
const_cast<v8::HeapSnapshot*>(s1)->Delete();
CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid1));
const v8::HeapSnapshot* s2 =
v8::HeapProfiler::TakeSnapshot(v8::String::New("2"));
CHECK_NE(NULL, s2);
CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount());
unsigned uid2 = s2->GetUid();
CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2));
CHECK_EQ(s2, v8::HeapProfiler::FindSnapshot(uid2));
const v8::HeapSnapshot* s3 =
v8::HeapProfiler::TakeSnapshot(v8::String::New("3"));
CHECK_NE(NULL, s3);
CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount());
unsigned uid3 = s3->GetUid();
CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3));
CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3));
const_cast<v8::HeapSnapshot*>(s2)->Delete();
CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount());
CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid2));
CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3));
const_cast<v8::HeapSnapshot*>(s3)->Delete();
CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid3));
}
#endif // ENABLE_LOGGING_AND_PROFILING
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment