Chromium Code Reviews| Index: test/cctest/test-heap-profiler.cc |
| diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc |
| index ad242fe79c1bb0a8d9ebd1d0d35dd42ae84a0833..f14b7d8f4f752651de3799314cfc198da414b8e7 100644 |
| --- a/test/cctest/test-heap-profiler.cc |
| +++ b/test/cctest/test-heap-profiler.cc |
| @@ -1258,4 +1258,140 @@ TEST(TakeHeapSnapshotAborting) { |
| CHECK_GT(control.total(), 0); |
| } |
| + |
| +namespace { |
| + |
| +class TestRetainedObjectInfo : public v8::RetainedObjectInfo { |
| + public: |
| + TestRetainedObjectInfo(int hash, |
| + const char* label, |
| + intptr_t element_count = -1, |
| + intptr_t size = -1) |
| + : disposed_(false), |
| + hash_(hash), |
| + label_(label), |
| + element_count_(element_count), |
| + size_(size) { |
| + instances.Add(this); |
| + } |
| + virtual ~TestRetainedObjectInfo() {} |
| + virtual void Dispose() { |
| + CHECK(!disposed_); |
| + disposed_ = true; |
| + } |
| + virtual bool IsEquivalent(RetainedObjectInfo* other) { |
| + return GetHash() == other->GetHash(); |
| + } |
| + virtual intptr_t GetHash() { return hash_; } |
| + virtual const char* GetLabel() { return label_; } |
| + virtual intptr_t GetElementCount() { return element_count_; } |
| + virtual intptr_t GetSizeInBytes() { return size_; } |
| + bool disposed() { return disposed_; } |
| + |
| + static v8::RetainedObjectInfo* WrapperInfoCallback( |
| + uint16_t class_id, v8::Handle<v8::Value> wrapper) { |
| + if (class_id == 1) { |
| + if (wrapper->IsString()) { |
| + v8::String::AsciiValue ascii(wrapper); |
| + if (strcmp(*ascii, "AAA") == 0) |
| + return new TestRetainedObjectInfo(1, "aaa", 100); |
| + else if (strcmp(*ascii, "BBB") == 0) |
| + return new TestRetainedObjectInfo(1, "aaa", 100); |
|
Vitaly Repeshko
2011/03/09 14:15:49
"bbb"?
mnaganov (inactive)
2011/03/09 15:26:32
No. I'm intentionally returning an equivalent obje
|
| + } |
| + } else if (class_id == 2) { |
| + if (wrapper->IsString()) { |
| + v8::String::AsciiValue ascii(wrapper); |
| + if (strcmp(*ascii, "CCC") == 0) |
| + return new TestRetainedObjectInfo(2, "ccc"); |
| + } |
| + } |
| + CHECK(false); |
| + return NULL; |
| + } |
| + |
| + static i::List<TestRetainedObjectInfo*> instances; |
| + |
| + private: |
| + bool disposed_; |
| + int category_; |
| + int hash_; |
| + const char* label_; |
| + intptr_t element_count_; |
| + intptr_t size_; |
| +}; |
| + |
|
Søren Thygesen Gjesse
2011/03/09 11:38:47
Missing empty line.
mnaganov (inactive)
2011/03/09 15:26:32
Done.
|
| +i::List<TestRetainedObjectInfo*> TestRetainedObjectInfo::instances; |
| +} |
| + |
| + |
| +static const v8::HeapGraphNode* GetNode(const v8::HeapGraphNode* parent, |
| + v8::HeapGraphNode::Type type, |
| + const char* name) { |
| + for (int i = 0, count = parent->GetChildrenCount(); i < count; ++i) { |
| + const v8::HeapGraphNode* node = parent->GetChild(i)->GetToNode(); |
| + if (node->GetType() == type && strcmp(name, |
| + const_cast<i::HeapEntry*>( |
| + reinterpret_cast<const i::HeapEntry*>(node))->name()) == 0) { |
| + return node; |
| + } |
| + } |
| + return NULL; |
| +} |
| + |
| + |
| +TEST(HeapSnapshotRetainedObjectInfo) { |
| + v8::HandleScope scope; |
| + LocalContext env; |
| + |
| + v8::HeapProfiler::DefineWrapperClass( |
| + 1, TestRetainedObjectInfo::WrapperInfoCallback); |
| + v8::HeapProfiler::DefineWrapperClass( |
| + 2, TestRetainedObjectInfo::WrapperInfoCallback); |
| + v8::Persistent<v8::String> p_AAA = |
| + v8::Persistent<v8::String>::New(v8_str("AAA")); |
| + p_AAA.SetWrapperClassId(1); |
| + v8::Persistent<v8::String> p_BBB = |
| + v8::Persistent<v8::String>::New(v8_str("BBB")); |
| + p_BBB.SetWrapperClassId(1); |
| + v8::Persistent<v8::String> p_CCC = |
| + v8::Persistent<v8::String>::New(v8_str("CCC")); |
| + p_CCC.SetWrapperClassId(2); |
| + CHECK_EQ(0, TestRetainedObjectInfo::instances.length()); |
| + const v8::HeapSnapshot* snapshot = |
| + v8::HeapProfiler::TakeSnapshot(v8::String::New("retained")); |
| + |
| + CHECK_EQ(3, TestRetainedObjectInfo::instances.length()); |
| + for (int i = 0; i < TestRetainedObjectInfo::instances.length(); ++i) { |
| + CHECK(TestRetainedObjectInfo::instances[i]->disposed()); |
| + delete TestRetainedObjectInfo::instances[i]; |
| + } |
| + |
| + const v8::HeapGraphNode* natives = GetNode( |
| + snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(Native objects)"); |
| + CHECK_NE(NULL, natives); |
| + CHECK_EQ(2, natives->GetChildrenCount()); |
| + const v8::HeapGraphNode* aaa = GetNode( |
| + natives, v8::HeapGraphNode::kNative, "aaa / 100 entries"); |
| + CHECK_NE(NULL, aaa); |
| + const v8::HeapGraphNode* ccc = GetNode( |
| + natives, v8::HeapGraphNode::kNative, "ccc"); |
| + CHECK_NE(NULL, ccc); |
| + |
| + CHECK_EQ(2, aaa->GetChildrenCount()); |
| + const v8::HeapGraphNode* n_AAA = GetNode( |
| + aaa, v8::HeapGraphNode::kString, "AAA"); |
| + CHECK_NE(NULL, n_AAA); |
| + const v8::HeapGraphNode* n_BBB = GetNode( |
| + aaa, v8::HeapGraphNode::kString, "BBB"); |
| + CHECK_NE(NULL, n_BBB); |
| + CHECK_EQ(1, ccc->GetChildrenCount()); |
| + const v8::HeapGraphNode* n_CCC = GetNode( |
| + ccc, v8::HeapGraphNode::kString, "CCC"); |
| + CHECK_NE(NULL, n_CCC); |
| + |
| + CHECK_EQ(aaa, GetProperty(n_AAA, v8::HeapGraphEdge::kInternal, "Native")); |
| + CHECK_EQ(aaa, GetProperty(n_BBB, v8::HeapGraphEdge::kInternal, "Native")); |
| + CHECK_EQ(ccc, GetProperty(n_CCC, v8::HeapGraphEdge::kInternal, "Native")); |
| +} |
| + |
| #endif // ENABLE_LOGGING_AND_PROFILING |