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

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

Issue 242031: Heap profiler: correctly determine equivalence of objects having self-refs. (Closed)
Patch Set: Created 11 years, 2 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
« no previous file with comments | « src/heap-profiler.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 #include "heap-profiler.h" 8 #include "heap-profiler.h"
9 #include "string-stream.h" 9 #include "string-stream.h"
10 #include "cctest.h" 10 #include "cctest.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 while (iterator.has_next()) { 67 while (iterator.has_next()) {
68 i::HeapObject* obj = iterator.next(); 68 i::HeapObject* obj = iterator.next();
69 cons_profile.CollectStats(obj); 69 cons_profile.CollectStats(obj);
70 } 70 }
71 CHECK_EQ(0, cons_profile.f_count()); 71 CHECK_EQ(0, cons_profile.f_count());
72 cons_profile.PrintStats(); 72 cons_profile.PrintStats();
73 CHECK_EQ(2, cons_profile.f_count()); 73 CHECK_EQ(2, cons_profile.f_count());
74 } 74 }
75 75
76 76
77 static JSObjectsCluster AddHeapObjectToTree( 77 static JSObjectsCluster AddHeapObjectToTree(JSObjectsRetainerTree* tree,
78 JSObjectsRetainerTree* tree, 78 i::String* constructor,
79 i::String* constructor, 79 int instance,
80 int instance, 80 JSObjectsCluster* ref1 = NULL,
81 JSObjectsCluster* ref1 = NULL, 81 JSObjectsCluster* ref2 = NULL,
82 JSObjectsCluster* ref2 = NULL, 82 JSObjectsCluster* ref3 = NULL) {
83 JSObjectsCluster* ref3 = NULL) {
84 JSObjectsCluster o(constructor, reinterpret_cast<i::Object*>(instance)); 83 JSObjectsCluster o(constructor, reinterpret_cast<i::Object*>(instance));
85 JSObjectsClusterTree* o_tree = new JSObjectsClusterTree(); 84 JSObjectsClusterTree* o_tree = new JSObjectsClusterTree();
86 JSObjectsClusterTree::Locator o_loc; 85 JSObjectsClusterTree::Locator o_loc;
87 if (ref1 != NULL) o_tree->Insert(*ref1, &o_loc); 86 if (ref1 != NULL) o_tree->Insert(*ref1, &o_loc);
88 if (ref2 != NULL) o_tree->Insert(*ref2, &o_loc); 87 if (ref2 != NULL) o_tree->Insert(*ref2, &o_loc);
89 if (ref3 != NULL) o_tree->Insert(*ref3, &o_loc); 88 if (ref3 != NULL) o_tree->Insert(*ref3, &o_loc);
90 JSObjectsRetainerTree::Locator loc; 89 JSObjectsRetainerTree::Locator loc;
91 tree->Insert(o, &loc); 90 tree->Insert(o, &loc);
92 loc.set_value(o_tree); 91 loc.set_value(o_tree);
93 return o; 92 return o;
94 } 93 }
95 94
96 95
96 static void AddSelfReferenceToTree(JSObjectsRetainerTree* tree,
97 JSObjectsCluster* self_ref) {
98 JSObjectsRetainerTree::Locator loc;
99 CHECK(tree->Find(*self_ref, &loc));
100 JSObjectsClusterTree::Locator o_loc;
101 CHECK_NE(NULL, loc.value());
102 loc.value()->Insert(*self_ref, &o_loc);
103 }
104
105
97 static inline void CheckEqualsHelper(const char* file, int line, 106 static inline void CheckEqualsHelper(const char* file, int line,
98 const char* expected_source, 107 const char* expected_source,
99 const JSObjectsCluster& expected, 108 const JSObjectsCluster& expected,
100 const char* value_source, 109 const char* value_source,
101 const JSObjectsCluster& value) { 110 const JSObjectsCluster& value) {
102 if (JSObjectsCluster::Compare(expected, value) != 0) { 111 if (JSObjectsCluster::Compare(expected, value) != 0) {
103 i::HeapStringAllocator allocator; 112 i::HeapStringAllocator allocator;
104 i::StringStream stream(&allocator); 113 i::StringStream stream(&allocator);
105 stream.Add("# Expected: "); 114 stream.Add("# Expected: ");
106 expected.DebugPrint(&stream); 115 expected.DebugPrint(&stream);
107 stream.Add("\n# Found: "); 116 stream.Add("\n# Found: ");
108 value.DebugPrint(&stream); 117 value.DebugPrint(&stream);
109 V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n%s", 118 V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n%s",
110 expected_source, value_source, 119 expected_source, value_source,
111 *stream.ToCString()); 120 *stream.ToCString());
112 } 121 }
113 } 122 }
114 123
115 124
116 static inline void CheckNonEqualsHelper(const char* file, int line, 125 static inline void CheckNonEqualsHelper(const char* file, int line,
117 const char* expected_source, 126 const char* expected_source,
118 const JSObjectsCluster& expected, 127 const JSObjectsCluster& expected,
119 const char* value_source, 128 const char* value_source,
120 const JSObjectsCluster& value) { 129 const JSObjectsCluster& value) {
121 if (JSObjectsCluster::Compare(expected, value) == 0) { 130 if (JSObjectsCluster::Compare(expected, value) == 0) {
122 i::HeapStringAllocator allocator; 131 i::HeapStringAllocator allocator;
123 i::StringStream stream(&allocator); 132 i::StringStream stream(&allocator);
124 stream.Add("# Expected: "); 133 stream.Add("# !Expected: ");
125 expected.DebugPrint(&stream); 134 expected.DebugPrint(&stream);
126 stream.Add("\n# Found: "); 135 stream.Add("\n# Found: ");
127 value.DebugPrint(&stream); 136 value.DebugPrint(&stream);
128 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n%s", 137 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n%s",
129 expected_source, value_source, 138 expected_source, value_source,
130 *stream.ToCString()); 139 *stream.ToCString());
131 } 140 }
132 } 141 }
133 142
134 143
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x300, &o21); 245 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x300, &o21);
237 JSObjectsCluster q = 246 JSObjectsCluster q =
238 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x310, &o21, &o22); 247 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x310, &o21, &o22);
239 JSObjectsCluster r = 248 JSObjectsCluster r =
240 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x320, &o22); 249 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x320, &o22);
241 250
242 ClustersCoarser coarser; 251 ClustersCoarser coarser;
243 coarser.Process(&tree); 252 coarser.Process(&tree);
244 253
245 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o)); 254 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
255 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o11));
246 CHECK_EQ(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o12)); 256 CHECK_EQ(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o12));
247 CHECK_EQ(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(o22)); 257 CHECK_EQ(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(o22));
248 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o21)); 258 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o21));
259 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
249 CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q)); 260 CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
250 CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r)); 261 CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
251 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(p)); 262 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(p));
252 CHECK_NE(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(p)); 263 CHECK_NE(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(p));
253 } 264 }
254 265
255 266
267 TEST(ClustersCoarserSelf) {
268 v8::HandleScope scope;
269 v8::Handle<v8::Context> env = v8::Context::New();
270 env->Enter();
271
272 i::ZoneScope zn_scope(i::DELETE_ON_EXIT);
273
274 JSObjectsRetainerTree tree;
275
276 // On the following graph:
277 //
278 // p (self-referencing)
279 // <- o1 <-
280 // q (self-referencing) o
281 // <- o2 <-
282 // r (self-referencing)
283 //
284 // we expect that coarser will deduce equivalences: p ~ q ~ r, o1 ~ o2;
285
286 JSObjectsCluster o =
287 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100);
288 JSObjectsCluster o1 =
289 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x110, &o);
290 JSObjectsCluster o2 =
291 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x120, &o);
292 JSObjectsCluster p =
293 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x300, &o1);
294 AddSelfReferenceToTree(&tree, &p);
295 JSObjectsCluster q =
296 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x310, &o1, &o2);
297 AddSelfReferenceToTree(&tree, &q);
298 JSObjectsCluster r =
299 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x320, &o2);
300 AddSelfReferenceToTree(&tree, &r);
301
302 ClustersCoarser coarser;
303 coarser.Process(&tree);
304
305 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
306 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o1));
307 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
308 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
309 CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
310 CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
311 CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(p));
312 }
313
314
256 namespace { 315 namespace {
257 316
258 class RetainerProfilePrinter : public RetainerHeapProfile::Printer { 317 class RetainerProfilePrinter : public RetainerHeapProfile::Printer {
259 public: 318 public:
260 RetainerProfilePrinter() : stream_(&allocator_), lines_(100) {} 319 RetainerProfilePrinter() : stream_(&allocator_), lines_(100) {}
261 320
262 void PrintRetainers(const JSObjectsCluster& cluster, 321 void PrintRetainers(const JSObjectsCluster& cluster,
263 const i::StringStream& retainers) { 322 const i::StringStream& retainers) {
264 cluster.Print(&stream_); 323 cluster.Print(&stream_);
265 stream_.Add("%s", *(retainers.ToCString())); 324 stream_.Add("%s", *(retainers.ToCString()));
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 CHECK_EQ(static_cast<int>(strlen("(global property);1,B;2,C;2")), 387 CHECK_EQ(static_cast<int>(strlen("(global property);1,B;2,C;2")),
329 static_cast<int>(strlen(retainers_of_a))); 388 static_cast<int>(strlen(retainers_of_a)));
330 CHECK(strstr(retainers_of_a, "(global property);1") != NULL); 389 CHECK(strstr(retainers_of_a, "(global property);1") != NULL);
331 CHECK(strstr(retainers_of_a, "B;2") != NULL); 390 CHECK(strstr(retainers_of_a, "B;2") != NULL);
332 CHECK(strstr(retainers_of_a, "C;2") != NULL); 391 CHECK(strstr(retainers_of_a, "C;2") != NULL);
333 CHECK_EQ("(global property);2", printer.GetRetainers("B")); 392 CHECK_EQ("(global property);2", printer.GetRetainers("B"));
334 CHECK_EQ("(global property);1", printer.GetRetainers("C")); 393 CHECK_EQ("(global property);1", printer.GetRetainers("C"));
335 } 394 }
336 395
337 #endif // ENABLE_LOGGING_AND_PROFILING 396 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/heap-profiler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698