Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: test/cctest/test-heap-profiler.cc

Issue 7247018: Remove obsolete aggregating and non-working producers heap profilers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // 2 //
3 // Tests for heap profiler 3 // Tests for heap profiler
4 4
5 #ifdef ENABLE_LOGGING_AND_PROFILING 5 #ifdef ENABLE_LOGGING_AND_PROFILING
6 6
7 #include "v8.h" 7 #include "v8.h"
8 8
9 #include "cctest.h" 9 #include "cctest.h"
10 #include "heap-profiler.h" 10 #include "heap-profiler.h"
11 #include "snapshot.h" 11 #include "snapshot.h"
12 #include "string-stream.h"
13 #include "utils-inl.h" 12 #include "utils-inl.h"
14 #include "zone-inl.h"
15 #include "../include/v8-profiler.h" 13 #include "../include/v8-profiler.h"
16 14
17 namespace i = v8::internal; 15 namespace i = v8::internal;
18 using i::ClustersCoarser;
19 using i::JSObjectsCluster;
20 using i::JSObjectsRetainerTree;
21 using i::JSObjectsClusterTree;
22 using i::RetainerHeapProfile;
23
24 16
25 namespace { 17 namespace {
26 18
27 class ConstructorHeapProfileTestHelper : public i::ConstructorHeapProfile {
28 public:
29 ConstructorHeapProfileTestHelper()
30 : i::ConstructorHeapProfile(),
31 f_name_(FACTORY->NewStringFromAscii(i::CStrVector("F"))),
32 f_count_(0) {
33 }
34
35 void Call(const JSObjectsCluster& cluster,
36 const i::NumberAndSizeInfo& number_and_size) {
37 if (f_name_->Equals(cluster.constructor())) {
38 CHECK_EQ(f_count_, 0);
39 f_count_ = number_and_size.number();
40 CHECK_GT(f_count_, 0);
41 }
42 }
43
44 int f_count() { return f_count_; }
45
46 private:
47 i::Handle<i::String> f_name_;
48 int f_count_;
49 };
50
51 } // namespace
52
53
54 TEST(ConstructorProfile) {
55 v8::HandleScope scope;
56 LocalContext env;
57
58 CompileRun(
59 "function F() {} // A constructor\n"
60 "var f1 = new F();\n"
61 "var f2 = new F();\n");
62
63 ConstructorHeapProfileTestHelper cons_profile;
64 i::AssertNoAllocation no_alloc;
65 i::HeapIterator iterator;
66 for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
67 cons_profile.CollectStats(obj);
68 CHECK_EQ(0, cons_profile.f_count());
69 cons_profile.PrintStats();
70 CHECK_EQ(2, cons_profile.f_count());
71 }
72
73
74 static JSObjectsCluster AddHeapObjectToTree(JSObjectsRetainerTree* tree,
75 i::String* constructor,
76 int instance,
77 JSObjectsCluster* ref1 = NULL,
78 JSObjectsCluster* ref2 = NULL,
79 JSObjectsCluster* ref3 = NULL) {
80 JSObjectsCluster o(constructor, reinterpret_cast<i::Object*>(instance));
81 JSObjectsClusterTree* o_tree = new JSObjectsClusterTree();
82 JSObjectsClusterTree::Locator o_loc;
83 if (ref1 != NULL) o_tree->Insert(*ref1, &o_loc);
84 if (ref2 != NULL) o_tree->Insert(*ref2, &o_loc);
85 if (ref3 != NULL) o_tree->Insert(*ref3, &o_loc);
86 JSObjectsRetainerTree::Locator loc;
87 tree->Insert(o, &loc);
88 loc.set_value(o_tree);
89 return o;
90 }
91
92
93 static void AddSelfReferenceToTree(JSObjectsRetainerTree* tree,
94 JSObjectsCluster* self_ref) {
95 JSObjectsRetainerTree::Locator loc;
96 CHECK(tree->Find(*self_ref, &loc));
97 JSObjectsClusterTree::Locator o_loc;
98 CHECK_NE(NULL, loc.value());
99 loc.value()->Insert(*self_ref, &o_loc);
100 }
101
102
103 static inline void CheckEqualsHelper(const char* file, int line,
104 const char* expected_source,
105 const JSObjectsCluster& expected,
106 const char* value_source,
107 const JSObjectsCluster& value) {
108 if (JSObjectsCluster::Compare(expected, value) != 0) {
109 i::HeapStringAllocator allocator;
110 i::StringStream stream(&allocator);
111 stream.Add("# Expected: ");
112 expected.DebugPrint(&stream);
113 stream.Add("\n# Found: ");
114 value.DebugPrint(&stream);
115 V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n%s",
116 expected_source, value_source,
117 *stream.ToCString());
118 }
119 }
120
121
122 static inline void CheckNonEqualsHelper(const char* file, int line,
123 const char* expected_source,
124 const JSObjectsCluster& expected,
125 const char* value_source,
126 const JSObjectsCluster& value) {
127 if (JSObjectsCluster::Compare(expected, value) == 0) {
128 i::HeapStringAllocator allocator;
129 i::StringStream stream(&allocator);
130 stream.Add("# !Expected: ");
131 expected.DebugPrint(&stream);
132 stream.Add("\n# Found: ");
133 value.DebugPrint(&stream);
134 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n%s",
135 expected_source, value_source,
136 *stream.ToCString());
137 }
138 }
139
140
141 TEST(ClustersCoarserSimple) {
142 v8::HandleScope scope;
143 LocalContext env;
144
145 i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
146
147 JSObjectsRetainerTree tree;
148 JSObjectsCluster function(HEAP->function_class_symbol());
149 JSObjectsCluster a(*FACTORY->NewStringFromAscii(i::CStrVector("A")));
150 JSObjectsCluster b(*FACTORY->NewStringFromAscii(i::CStrVector("B")));
151
152 // o1 <- Function
153 JSObjectsCluster o1 =
154 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100, &function);
155 // o2 <- Function
156 JSObjectsCluster o2 =
157 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x200, &function);
158 // o3 <- A, B
159 JSObjectsCluster o3 =
160 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &a, &b);
161 // o4 <- B, A
162 JSObjectsCluster o4 =
163 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x400, &b, &a);
164 // o5 <- A, B, Function
165 JSObjectsCluster o5 =
166 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x500,
167 &a, &b, &function);
168
169 ClustersCoarser coarser;
170 coarser.Process(&tree);
171
172 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
173 CHECK_EQ(coarser.GetCoarseEquivalent(o3), coarser.GetCoarseEquivalent(o4));
174 CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o3));
175 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o5));
176 }
177
178
179 TEST(ClustersCoarserMultipleConstructors) {
180 v8::HandleScope scope;
181 LocalContext env;
182
183 i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
184
185 JSObjectsRetainerTree tree;
186 JSObjectsCluster function(HEAP->function_class_symbol());
187
188 // o1 <- Function
189 JSObjectsCluster o1 =
190 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100, &function);
191 // a1 <- Function
192 JSObjectsCluster a1 =
193 AddHeapObjectToTree(&tree, HEAP->Array_symbol(), 0x1000, &function);
194 // o2 <- Function
195 JSObjectsCluster o2 =
196 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x200, &function);
197 // a2 <- Function
198 JSObjectsCluster a2 =
199 AddHeapObjectToTree(&tree, HEAP->Array_symbol(), 0x2000, &function);
200
201 ClustersCoarser coarser;
202 coarser.Process(&tree);
203
204 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
205 CHECK_EQ(coarser.GetCoarseEquivalent(a1), coarser.GetCoarseEquivalent(a2));
206 }
207
208
209 TEST(ClustersCoarserPathsTraversal) {
210 v8::HandleScope scope;
211 LocalContext env;
212
213 i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
214
215 JSObjectsRetainerTree tree;
216
217 // On the following graph:
218 //
219 // p
220 // <- o21 <- o11 <-
221 // q o
222 // <- o22 <- o12 <-
223 // r
224 //
225 // we expect that coarser will deduce equivalences: p ~ q ~ r,
226 // o21 ~ o22, and o11 ~ o12.
227
228 JSObjectsCluster o =
229 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100);
230 JSObjectsCluster o11 =
231 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x110, &o);
232 JSObjectsCluster o12 =
233 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x120, &o);
234 JSObjectsCluster o21 =
235 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x210, &o11);
236 JSObjectsCluster o22 =
237 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x220, &o12);
238 JSObjectsCluster p =
239 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &o21);
240 JSObjectsCluster q =
241 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x310, &o21, &o22);
242 JSObjectsCluster r =
243 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x320, &o22);
244
245 ClustersCoarser coarser;
246 coarser.Process(&tree);
247
248 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
249 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o11));
250 CHECK_EQ(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o12));
251 CHECK_EQ(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(o22));
252 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o21));
253 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
254 CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
255 CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
256 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(p));
257 CHECK_NE(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(p));
258 }
259
260
261 TEST(ClustersCoarserSelf) {
262 v8::HandleScope scope;
263 LocalContext env;
264
265 i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
266
267 JSObjectsRetainerTree tree;
268
269 // On the following graph:
270 //
271 // p (self-referencing)
272 // <- o1 <-
273 // q (self-referencing) o
274 // <- o2 <-
275 // r (self-referencing)
276 //
277 // we expect that coarser will deduce equivalences: p ~ q ~ r, o1 ~ o2;
278
279 JSObjectsCluster o =
280 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100);
281 JSObjectsCluster o1 =
282 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x110, &o);
283 JSObjectsCluster o2 =
284 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x120, &o);
285 JSObjectsCluster p =
286 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &o1);
287 AddSelfReferenceToTree(&tree, &p);
288 JSObjectsCluster q =
289 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x310, &o1, &o2);
290 AddSelfReferenceToTree(&tree, &q);
291 JSObjectsCluster r =
292 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x320, &o2);
293 AddSelfReferenceToTree(&tree, &r);
294
295 ClustersCoarser coarser;
296 coarser.Process(&tree);
297
298 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
299 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o1));
300 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
301 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
302 CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
303 CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
304 CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(p));
305 }
306
307
308 namespace {
309
310 class RetainerProfilePrinter : public RetainerHeapProfile::Printer {
311 public:
312 RetainerProfilePrinter() : stream_(&allocator_), lines_(100) {}
313
314 void PrintRetainers(const JSObjectsCluster& cluster,
315 const i::StringStream& retainers) {
316 cluster.Print(&stream_);
317 stream_.Add("%s", *(retainers.ToCString()));
318 stream_.Put('\0');
319 }
320
321 const char* GetRetainers(const char* constructor) {
322 FillLines();
323 const size_t cons_len = strlen(constructor);
324 for (int i = 0; i < lines_.length(); ++i) {
325 if (strncmp(constructor, lines_[i], cons_len) == 0 &&
326 lines_[i][cons_len] == ',') {
327 return lines_[i] + cons_len + 1;
328 }
329 }
330 return NULL;
331 }
332
333 private:
334 void FillLines() {
335 if (lines_.length() > 0) return;
336 stream_.Put('\0');
337 stream_str_ = stream_.ToCString();
338 const char* pos = *stream_str_;
339 while (pos != NULL && *pos != '\0') {
340 lines_.Add(pos);
341 pos = strchr(pos, '\0');
342 if (pos != NULL) ++pos;
343 }
344 }
345
346 i::HeapStringAllocator allocator_;
347 i::StringStream stream_;
348 i::SmartPointer<const char> stream_str_;
349 i::List<const char*> lines_;
350 };
351
352 } // namespace
353
354
355 TEST(RetainerProfile) {
356 v8::HandleScope scope;
357 LocalContext env;
358
359 CompileRun(
360 "function A() {}\n"
361 "function B(x) { this.x = x; }\n"
362 "function C(x) { this.x1 = x; this.x2 = x; }\n"
363 "var a = new A();\n"
364 "var b1 = new B(a), b2 = new B(a);\n"
365 "var c = new C(a);");
366
367 RetainerHeapProfile ret_profile;
368 i::AssertNoAllocation no_alloc;
369 i::HeapIterator iterator;
370 for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
371 ret_profile.CollectStats(obj);
372 ret_profile.CoarseAndAggregate();
373 RetainerProfilePrinter printer;
374 ret_profile.DebugPrintStats(&printer);
375 const char* retainers_of_a = printer.GetRetainers("A");
376 // The order of retainers is unspecified, so we check string length, and
377 // verify each retainer separately.
378 CHECK_EQ(i::StrLength("(global property);1,B;2,C;2"),
379 i::StrLength(retainers_of_a));
380 CHECK(strstr(retainers_of_a, "(global property);1") != NULL);
381 CHECK(strstr(retainers_of_a, "B;2") != NULL);
382 CHECK(strstr(retainers_of_a, "C;2") != NULL);
383 CHECK_EQ("(global property);2", printer.GetRetainers("B"));
384 CHECK_EQ("(global property);1", printer.GetRetainers("C"));
385 }
386
387
388 namespace {
389
390 class NamedEntriesDetector { 19 class NamedEntriesDetector {
391 public: 20 public:
392 NamedEntriesDetector() 21 NamedEntriesDetector()
393 : has_A2(false), has_B2(false), has_C2(false) { 22 : has_A2(false), has_B2(false), has_C2(false) {
394 } 23 }
395 24
396 void Apply(i::HeapEntry** entry_ptr) { 25 void Apply(i::HeapEntry** entry_ptr) {
397 if (IsReachableNodeWithName(*entry_ptr, "A2")) has_A2 = true; 26 if (IsReachableNodeWithName(*entry_ptr, "A2")) has_A2 = true;
398 if (IsReachableNodeWithName(*entry_ptr, "B2")) has_B2 = true; 27 if (IsReachableNodeWithName(*entry_ptr, "B2")) has_B2 = true;
399 if (IsReachableNodeWithName(*entry_ptr, "C2")) has_C2 = true; 28 if (IsReachableNodeWithName(*entry_ptr, "C2")) has_C2 = true;
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 const v8::HeapSnapshot* snapshot = 348 const v8::HeapSnapshot* snapshot =
720 v8::HeapProfiler::TakeSnapshot(v8::String::New("s")); 349 v8::HeapProfiler::TakeSnapshot(v8::String::New("s"));
721 const v8::HeapGraphNode* root1 = snapshot->GetRoot(); 350 const v8::HeapGraphNode* root1 = snapshot->GetRoot();
722 const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>( 351 const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>(
723 snapshot))->GetSortedEntriesList(); 352 snapshot))->GetSortedEntriesList();
724 const v8::HeapGraphNode* root2 = snapshot->GetRoot(); 353 const v8::HeapGraphNode* root2 = snapshot->GetRoot();
725 CHECK_EQ(root1, root2); 354 CHECK_EQ(root1, root2);
726 } 355 }
727 356
728 357
729 static const v8::HeapGraphNode* GetChild(
730 const v8::HeapGraphNode* node,
731 v8::HeapGraphNode::Type type,
732 const char* name,
733 const v8::HeapGraphNode* after = NULL) {
734 bool ignore_child = after == NULL ? false : true;
735 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
736 const v8::HeapGraphEdge* prop = node->GetChild(i);
737 const v8::HeapGraphNode* child = prop->GetToNode();
738 v8::String::AsciiValue child_name(child->GetName());
739 if (!ignore_child
740 && child->GetType() == type
741 && strcmp(name, *child_name) == 0)
742 return child;
743 if (after != NULL && child == after) ignore_child = false;
744 }
745 return NULL;
746 }
747
748 static bool IsNodeRetainedAs(const v8::HeapGraphNode* node,
749 int element) {
750 for (int i = 0, count = node->GetRetainersCount(); i < count; ++i) {
751 const v8::HeapGraphEdge* prop = node->GetRetainer(i);
752 if (prop->GetType() == v8::HeapGraphEdge::kElement
753 && element == prop->GetName()->Int32Value())
754 return true;
755 }
756 return false;
757 }
758
759 TEST(AggregatedHeapSnapshot) {
760 v8::HandleScope scope;
761 LocalContext env;
762
763 CompileRun(
764 "function A() {}\n"
765 "function B(x) { this.x = x; }\n"
766 "var a = new A();\n"
767 "var b = new B(a);");
768 const v8::HeapSnapshot* snapshot =
769 v8::HeapProfiler::TakeSnapshot(
770 v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
771 const v8::HeapGraphNode* strings = GetChild(snapshot->GetRoot(),
772 v8::HeapGraphNode::kHidden,
773 "STRING_TYPE");
774 CHECK_NE(NULL, strings);
775 CHECK_NE(0, strings->GetSelfSize());
776 CHECK_NE(0, strings->GetInstancesCount());
777 const v8::HeapGraphNode* maps = GetChild(snapshot->GetRoot(),
778 v8::HeapGraphNode::kHidden,
779 "MAP_TYPE");
780 CHECK_NE(NULL, maps);
781 CHECK_NE(0, maps->GetSelfSize());
782 CHECK_NE(0, maps->GetInstancesCount());
783
784 const v8::HeapGraphNode* a = GetChild(snapshot->GetRoot(),
785 v8::HeapGraphNode::kObject,
786 "A");
787 CHECK_NE(NULL, a);
788 CHECK_NE(0, a->GetSelfSize());
789 CHECK_EQ(1, a->GetInstancesCount());
790
791 const v8::HeapGraphNode* b = GetChild(snapshot->GetRoot(),
792 v8::HeapGraphNode::kObject,
793 "B");
794 CHECK_NE(NULL, b);
795 CHECK_NE(0, b->GetSelfSize());
796 CHECK_EQ(1, b->GetInstancesCount());
797
798 const v8::HeapGraphNode* glob_prop = GetChild(snapshot->GetRoot(),
799 v8::HeapGraphNode::kObject,
800 "(global property)",
801 b);
802 CHECK_NE(NULL, glob_prop);
803 CHECK_EQ(0, glob_prop->GetSelfSize());
804 CHECK_EQ(0, glob_prop->GetInstancesCount());
805 CHECK_NE(0, glob_prop->GetChildrenCount());
806
807 const v8::HeapGraphNode* a_from_glob_prop = GetChild(
808 glob_prop,
809 v8::HeapGraphNode::kObject,
810 "A");
811 CHECK_NE(NULL, a_from_glob_prop);
812 CHECK_EQ(0, a_from_glob_prop->GetSelfSize());
813 CHECK_EQ(0, a_from_glob_prop->GetInstancesCount());
814 CHECK_EQ(0, a_from_glob_prop->GetChildrenCount()); // Retains nothing.
815 CHECK(IsNodeRetainedAs(a_from_glob_prop, 1)); // (global propery) has 1 ref.
816
817 const v8::HeapGraphNode* b_with_children = GetChild(
818 snapshot->GetRoot(),
819 v8::HeapGraphNode::kObject,
820 "B",
821 b);
822 CHECK_NE(NULL, b_with_children);
823 CHECK_EQ(0, b_with_children->GetSelfSize());
824 CHECK_EQ(0, b_with_children->GetInstancesCount());
825 CHECK_NE(0, b_with_children->GetChildrenCount());
826
827 const v8::HeapGraphNode* a_from_b = GetChild(
828 b_with_children,
829 v8::HeapGraphNode::kObject,
830 "A");
831 CHECK_NE(NULL, a_from_b);
832 CHECK_EQ(0, a_from_b->GetSelfSize());
833 CHECK_EQ(0, a_from_b->GetInstancesCount());
834 CHECK_EQ(0, a_from_b->GetChildrenCount()); // Retains nothing.
835 CHECK(IsNodeRetainedAs(a_from_b, 1)); // B has 1 ref to A.
836 }
837
838
839 TEST(HeapEntryDominator) { 358 TEST(HeapEntryDominator) {
840 // The graph looks like this: 359 // The graph looks like this:
841 // 360 //
842 // -> node1 361 // -> node1
843 // a |^ 362 // a |^
844 // -> node5 ba 363 // -> node5 ba
845 // a v| 364 // a v|
846 // node6 -> node2 365 // node6 -> node2
847 // b a |^ 366 // b a |^
848 // -> node4 ba 367 // -> node4 ba
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 LocalContext env; 560 LocalContext env;
1042 const v8::HeapSnapshot* snapshot = 561 const v8::HeapSnapshot* snapshot =
1043 v8::HeapProfiler::TakeSnapshot(v8::String::New("abort")); 562 v8::HeapProfiler::TakeSnapshot(v8::String::New("abort"));
1044 TestJSONStream stream(5); 563 TestJSONStream stream(5);
1045 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); 564 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON);
1046 CHECK_GT(stream.size(), 0); 565 CHECK_GT(stream.size(), 0);
1047 CHECK_EQ(0, stream.eos_signaled()); 566 CHECK_EQ(0, stream.eos_signaled());
1048 } 567 }
1049 568
1050 569
1051 // Must not crash in debug mode.
1052 TEST(AggregatedHeapSnapshotJSONSerialization) {
1053 v8::HandleScope scope;
1054 LocalContext env;
1055
1056 const v8::HeapSnapshot* snapshot =
1057 v8::HeapProfiler::TakeSnapshot(
1058 v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
1059 TestJSONStream stream;
1060 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON);
1061 CHECK_GT(stream.size(), 0);
1062 CHECK_EQ(1, stream.eos_signaled());
1063 }
1064
1065
1066 TEST(HeapSnapshotGetNodeById) { 570 TEST(HeapSnapshotGetNodeById) {
1067 v8::HandleScope scope; 571 v8::HandleScope scope;
1068 LocalContext env; 572 LocalContext env;
1069 573
1070 const v8::HeapSnapshot* snapshot = 574 const v8::HeapSnapshot* snapshot =
1071 v8::HeapProfiler::TakeSnapshot(v8::String::New("id")); 575 v8::HeapProfiler::TakeSnapshot(v8::String::New("id"));
1072 const v8::HeapGraphNode* root = snapshot->GetRoot(); 576 const v8::HeapGraphNode* root = snapshot->GetRoot();
1073 CHECK_EQ(root, snapshot->GetNodeById(root->GetId())); 577 CHECK_EQ(root, snapshot->GetNodeById(root->GetId()));
1074 for (int i = 0, count = root->GetChildrenCount(); i < count; ++i) { 578 for (int i = 0, count = root->GetChildrenCount(); i < count; ++i) {
1075 const v8::HeapGraphEdge* prop = root->GetChild(i); 579 const v8::HeapGraphEdge* prop = root->GetChild(i);
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 const int nodes_count = snapshot->GetNodesCount(); 888 const int nodes_count = snapshot->GetNodesCount();
1385 int count = 0; 889 int count = 0;
1386 for (int i = 0; i < nodes_count; ++i) { 890 for (int i = 0; i < nodes_count; ++i) {
1387 if (snapshot->GetNode(i) == global) 891 if (snapshot->GetNode(i) == global)
1388 ++count; 892 ++count;
1389 } 893 }
1390 CHECK_EQ(1, count); 894 CHECK_EQ(1, count);
1391 } 895 }
1392 896
1393 #endif // ENABLE_LOGGING_AND_PROFILING 897 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« src/api.cc ('K') | « src/profile-generator.h ('k') | test/cctest/test-log.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698