OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" | 5 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" |
6 | 6 |
7 #include <iterator> | 7 #include <iterator> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
11 #include "base/trace_event/heap_profiler_allocation_context.h" | 11 #include "base/trace_event/heap_profiler_allocation_context.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 | 13 |
14 namespace base { | 14 namespace base { |
15 namespace trace_event { | 15 namespace trace_event { |
16 | 16 |
17 // Define all strings once, because the deduplicator requires pointer equality, | 17 // Define all strings once, because the deduplicator requires pointer equality, |
18 // and string interning is unreliable. | 18 // and string interning is unreliable. |
19 const char kBrowserMain[] = "BrowserMain"; | 19 StackFrame kBrowserMain = StackFrame::FromTraceEventName("BrowserMain"); |
20 const char kRendererMain[] = "RendererMain"; | 20 StackFrame kRendererMain = StackFrame::FromTraceEventName("RendererMain"); |
21 const char kCreateWidget[] = "CreateWidget"; | 21 StackFrame kCreateWidget = StackFrame::FromTraceEventName("CreateWidget"); |
22 const char kInitialize[] = "Initialize"; | 22 StackFrame kInitialize = StackFrame::FromTraceEventName("Initialize"); |
23 const char kMalloc[] = "malloc"; | 23 StackFrame kMalloc = StackFrame::FromTraceEventName("malloc"); |
24 | 24 |
25 TEST(StackFrameDeduplicatorTest, SingleBacktrace) { | 25 TEST(StackFrameDeduplicatorTest, SingleBacktrace) { |
26 StackFrame bt[] = {kBrowserMain, kCreateWidget, kMalloc}; | 26 StackFrame bt[] = {kBrowserMain, kCreateWidget, kMalloc}; |
27 | 27 |
28 // The call tree should look like this (index in brackets). | 28 // The call tree should look like this (index in brackets). |
29 // | 29 // |
30 // BrowserMain [0] | 30 // BrowserMain [0] |
31 // CreateWidget [1] | 31 // CreateWidget [1] |
32 // malloc [2] | 32 // malloc [2] |
33 | 33 |
34 std::unique_ptr<StackFrameDeduplicator> dedup(new StackFrameDeduplicator); | 34 std::unique_ptr<StackFrameDeduplicator> dedup(new StackFrameDeduplicator); |
35 ASSERT_EQ(2, dedup->Insert(std::begin(bt), std::end(bt))); | 35 ASSERT_EQ(2, dedup->Insert(std::begin(bt), std::end(bt))); |
36 | 36 |
37 auto iter = dedup->begin(); | 37 auto iter = dedup->begin(); |
38 ASSERT_EQ(kBrowserMain, (iter + 0)->frame); | 38 ASSERT_EQ(kBrowserMain, (iter + 0)->frame); |
39 ASSERT_EQ(-1, (iter + 0)->parent_frame_index); | 39 ASSERT_EQ(-1, (iter + 0)->parent_frame_index); |
40 | 40 |
41 ASSERT_EQ(kCreateWidget, (iter + 1)->frame); | 41 ASSERT_EQ(kCreateWidget, (iter + 1)->frame); |
42 ASSERT_EQ(0, (iter + 1)->parent_frame_index); | 42 ASSERT_EQ(0, (iter + 1)->parent_frame_index); |
43 | 43 |
44 ASSERT_EQ(kMalloc, (iter + 2)->frame); | 44 ASSERT_EQ(kMalloc, (iter + 2)->frame); |
45 ASSERT_EQ(1, (iter + 2)->parent_frame_index); | 45 ASSERT_EQ(1, (iter + 2)->parent_frame_index); |
46 | 46 |
47 ASSERT_EQ(iter + 3, dedup->end()); | 47 ASSERT_EQ(iter + 3, dedup->end()); |
48 } | 48 } |
49 | 49 |
50 TEST(StackFrameDeduplicatorTest, SingleBacktraceWithNull) { | |
Primiano Tucci (use gerrit)
2016/04/19 19:45:06
thanks, really appreciate this :)
Dmitry Skiba
2016/04/19 22:14:14
Acknowledged :)
| |
51 StackFrame null_frame = StackFrame::FromTraceEventName(nullptr); | |
52 StackFrame bt[] = {kBrowserMain, null_frame, kMalloc}; | |
53 | |
54 // Deduplicator doesn't care about what's inside StackFrames, | |
55 // and handles nullptr StackFrame values as any other. | |
56 // | |
57 // So the call tree should look like this (index in brackets). | |
58 // | |
59 // BrowserMain [0] | |
60 // (null) [1] | |
61 // malloc [2] | |
62 | |
63 std::unique_ptr<StackFrameDeduplicator> dedup(new StackFrameDeduplicator); | |
64 ASSERT_EQ(2, dedup->Insert(std::begin(bt), std::end(bt))); | |
65 | |
66 auto iter = dedup->begin(); | |
67 ASSERT_EQ(kBrowserMain, (iter + 0)->frame); | |
68 ASSERT_EQ(-1, (iter + 0)->parent_frame_index); | |
69 | |
70 ASSERT_EQ(null_frame, (iter + 1)->frame); | |
71 ASSERT_EQ(0, (iter + 1)->parent_frame_index); | |
72 | |
73 ASSERT_EQ(kMalloc, (iter + 2)->frame); | |
74 ASSERT_EQ(1, (iter + 2)->parent_frame_index); | |
75 | |
76 ASSERT_EQ(iter + 3, dedup->end()); | |
77 } | |
78 | |
50 // Test that there can be different call trees (there can be multiple bottom | 79 // Test that there can be different call trees (there can be multiple bottom |
51 // frames). Also verify that frames with the same name but a different caller | 80 // frames). Also verify that frames with the same name but a different caller |
52 // are represented as distinct nodes. | 81 // are represented as distinct nodes. |
53 TEST(StackFrameDeduplicatorTest, MultipleRoots) { | 82 TEST(StackFrameDeduplicatorTest, MultipleRoots) { |
54 StackFrame bt0[] = {kBrowserMain, kCreateWidget}; | 83 StackFrame bt0[] = {kBrowserMain, kCreateWidget}; |
55 StackFrame bt1[] = {kRendererMain, kCreateWidget}; | 84 StackFrame bt1[] = {kRendererMain, kCreateWidget}; |
56 | 85 |
57 // The call tree should look like this (index in brackets). | 86 // The call tree should look like this (index in brackets). |
58 // | 87 // |
59 // BrowserMain [0] | 88 // BrowserMain [0] |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 | 141 |
113 ASSERT_EQ(iter + 3, dedup->end()); | 142 ASSERT_EQ(iter + 3, dedup->end()); |
114 | 143 |
115 // Inserting the same backtrace again should return the index of the existing | 144 // Inserting the same backtrace again should return the index of the existing |
116 // node. | 145 // node. |
117 ASSERT_EQ(1, dedup->Insert(std::begin(bt0), std::end(bt0))); | 146 ASSERT_EQ(1, dedup->Insert(std::begin(bt0), std::end(bt0))); |
118 ASSERT_EQ(2, dedup->Insert(std::begin(bt1), std::end(bt1))); | 147 ASSERT_EQ(2, dedup->Insert(std::begin(bt1), std::end(bt1))); |
119 ASSERT_EQ(dedup->begin() + 3, dedup->end()); | 148 ASSERT_EQ(dedup->begin() + 3, dedup->end()); |
120 } | 149 } |
121 | 150 |
122 TEST(StackFrameDeduplicatorTest, NullPaddingIsRemoved) { | |
123 StackFrame bt0[] = {kBrowserMain, nullptr, nullptr, nullptr}; | |
124 | |
125 std::unique_ptr<StackFrameDeduplicator> dedup(new StackFrameDeduplicator); | |
126 | |
127 // There are four frames in the backtrace, but the null pointers should be | |
128 // skipped, so only one frame is inserted, which will have index 0. | |
129 ASSERT_EQ(4u, arraysize(bt0)); | |
130 ASSERT_EQ(0, dedup->Insert(std::begin(bt0), std::end(bt0))); | |
131 ASSERT_EQ(dedup->begin() + 1, dedup->end()); | |
132 } | |
133 | |
134 } // namespace trace_event | 151 } // namespace trace_event |
135 } // namespace base | 152 } // namespace base |
OLD | NEW |