Chromium Code Reviews| 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_heap_dump_writer.h" | 5 #include "base/trace_event/heap_profiler_heap_dump_writer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 const ListValue* json_entries; | 61 const ListValue* json_entries; |
| 62 EXPECT_TRUE(dictionary->GetList("entries", &json_entries)); | 62 EXPECT_TRUE(dictionary->GetList("entries", &json_entries)); |
| 63 | 63 |
| 64 const DictionaryValue* json_entry; | 64 const DictionaryValue* json_entry; |
| 65 EXPECT_TRUE(json_entries->GetDictionary(0, &json_entry)); | 65 EXPECT_TRUE(json_entries->GetDictionary(0, &json_entry)); |
| 66 | 66 |
| 67 return json_entry->CreateDeepCopy(); | 67 return json_entry->CreateDeepCopy(); |
| 68 } | 68 } |
| 69 | 69 |
| 70 // Given a desired stack frame ID and type ID, looks up the entry in the set and | 70 // Given a desired stack frame ID and type ID, looks up the entry in the set and |
| 71 // asserts that it is present and has the expected size. | 71 // asserts that it is present and has the expected size. |
|
Primiano Tucci (use gerrit)
2016/04/14 19:37:21
+ and count :)
ssid
2016/04/14 20:17:10
Done.
| |
| 72 void AssertSizeEq(const std::set<Entry>& entries, | 72 void AssertSizeAndCountEq(const std::set<Entry>& entries, |
| 73 int stack_frame_id, | 73 int stack_frame_id, |
| 74 int type_id, | 74 int type_id, |
| 75 size_t expected_size) { | 75 const AllocationsSizeAndCount& expected) { |
| 76 // The comparison operator for |Entry| does not take size into account, so by | 76 // The comparison operator for |Entry| does not take size into account, so by |
| 77 // setting only stack frame ID and type ID, the real entry can be found. | 77 // setting only stack frame ID and type ID, the real entry can be found. |
| 78 Entry entry; | 78 Entry entry; |
| 79 entry.stack_frame_id = stack_frame_id; | 79 entry.stack_frame_id = stack_frame_id; |
| 80 entry.type_id = type_id; | 80 entry.type_id = type_id; |
| 81 auto it = entries.find(entry); | 81 auto it = entries.find(entry); |
| 82 | 82 |
| 83 ASSERT_NE(entries.end(), it) << "No entry found for sf = " << stack_frame_id | 83 ASSERT_NE(entries.end(), it) << "No entry found for sf = " << stack_frame_id |
| 84 << ", type = " << type_id << "."; | 84 << ", type = " << type_id << "."; |
| 85 ASSERT_EQ(expected_size, it->size) << "Wrong size for sf = " << stack_frame_id | 85 ASSERT_EQ(expected.size, it->size) << "Wrong size for sf = " << stack_frame_id |
| 86 << ", type = " << type_id << "."; | 86 << ", type = " << type_id << "."; |
| 87 ASSERT_EQ(expected.count, it->count) | |
| 88 << "Wrong count for sf = " << stack_frame_id << ", type = " << type_id | |
| 89 << "."; | |
| 87 } | 90 } |
| 88 | 91 |
| 89 // Given a desired stack frame ID and type ID, asserts that no entry was dumped | 92 // Given a desired stack frame ID and type ID, asserts that no entry was dumped |
| 90 // for that that particular combination of stack frame and type. | 93 // for that that particular combination of stack frame and type. |
| 91 void AssertNotDumped(const std::set<Entry>& entries, | 94 void AssertNotDumped(const std::set<Entry>& entries, |
| 92 int stack_frame_id, | 95 int stack_frame_id, |
| 93 int type_id) { | 96 int type_id) { |
| 94 // The comparison operator for |Entry| does not take size into account, so by | 97 // The comparison operator for |Entry| does not take size into account, so by |
| 95 // setting only stack frame ID and type ID, the real entry can be found. | 98 // setting only stack frame ID and type ID, the real entry can be found. |
| 96 Entry entry; | 99 Entry entry; |
| 97 entry.stack_frame_id = stack_frame_id; | 100 entry.stack_frame_id = stack_frame_id; |
| 98 entry.type_id = type_id; | 101 entry.type_id = type_id; |
| 99 auto it = entries.find(entry); | 102 auto it = entries.find(entry); |
| 100 ASSERT_EQ(entries.end(), it) | 103 ASSERT_EQ(entries.end(), it) |
| 101 << "Entry should not be present for sf = " << stack_frame_id | 104 << "Entry should not be present for sf = " << stack_frame_id |
| 102 << ", type = " << type_id << "."; | 105 << ", type = " << type_id << "."; |
| 103 } | 106 } |
| 104 | 107 |
| 105 TEST(HeapDumpWriterTest, BacktraceIndex) { | 108 TEST(HeapDumpWriterTest, BacktraceIndex) { |
| 106 Entry entry; | 109 Entry entry; |
| 107 entry.stack_frame_id = -1; // -1 means empty backtrace. | 110 entry.stack_frame_id = -1; // -1 means empty backtrace. |
| 108 entry.type_id = 0; | 111 entry.type_id = 0; |
| 109 entry.size = 1; | 112 entry.size = 1; |
| 113 entry.count = 1; | |
| 110 | 114 |
| 111 std::unique_ptr<const DictionaryValue> json_entry = | 115 std::unique_ptr<const DictionaryValue> json_entry = |
| 112 WriteAndReadBackEntry(entry); | 116 WriteAndReadBackEntry(entry); |
| 113 | 117 |
| 114 // For an empty backtrace, the "bt" key cannot reference a stack frame. | 118 // For an empty backtrace, the "bt" key cannot reference a stack frame. |
| 115 // Instead it should be set to the empty string. | 119 // Instead it should be set to the empty string. |
| 116 std::string backtrace_index; | 120 std::string backtrace_index; |
| 117 ASSERT_TRUE(json_entry->GetString("bt", &backtrace_index)); | 121 ASSERT_TRUE(json_entry->GetString("bt", &backtrace_index)); |
| 118 ASSERT_EQ("", backtrace_index); | 122 ASSERT_EQ("", backtrace_index); |
| 119 | 123 |
| 120 // Also verify that a non-negative backtrace index is dumped properly. | 124 // Also verify that a non-negative backtrace index is dumped properly. |
| 121 entry.stack_frame_id = 2; | 125 entry.stack_frame_id = 2; |
| 122 json_entry = WriteAndReadBackEntry(entry); | 126 json_entry = WriteAndReadBackEntry(entry); |
| 123 ASSERT_TRUE(json_entry->GetString("bt", &backtrace_index)); | 127 ASSERT_TRUE(json_entry->GetString("bt", &backtrace_index)); |
| 124 ASSERT_EQ("2", backtrace_index); | 128 ASSERT_EQ("2", backtrace_index); |
| 125 } | 129 } |
| 126 | 130 |
| 127 TEST(HeapDumpWriterTest, TypeId) { | 131 TEST(HeapDumpWriterTest, TypeId) { |
| 128 Entry entry; | 132 Entry entry; |
| 129 entry.type_id = -1; // -1 means sum over all types. | 133 entry.type_id = -1; // -1 means sum over all types. |
| 130 entry.stack_frame_id = 0; | 134 entry.stack_frame_id = 0; |
| 131 entry.size = 1; | 135 entry.size = 1; |
| 136 entry.count = 1; | |
| 132 | 137 |
| 133 std::unique_ptr<const DictionaryValue> json_entry = | 138 std::unique_ptr<const DictionaryValue> json_entry = |
| 134 WriteAndReadBackEntry(entry); | 139 WriteAndReadBackEntry(entry); |
| 135 | 140 |
| 136 // Entries for the cumulative size of all types should not have the "type" | 141 // Entries for the cumulative size of all types should not have the "type" |
| 137 // key set. | 142 // key set. |
| 138 ASSERT_FALSE(json_entry->HasKey("type")); | 143 ASSERT_FALSE(json_entry->HasKey("type")); |
| 139 | 144 |
| 140 // Also verify that a non-negative type ID is dumped properly. | 145 // Also verify that a non-negative type ID is dumped properly. |
| 141 entry.type_id = 2; | 146 entry.type_id = 2; |
| 142 json_entry = WriteAndReadBackEntry(entry); | 147 json_entry = WriteAndReadBackEntry(entry); |
| 143 std::string type_id; | 148 std::string type_id; |
| 144 ASSERT_TRUE(json_entry->GetString("type", &type_id)); | 149 ASSERT_TRUE(json_entry->GetString("type", &type_id)); |
| 145 ASSERT_EQ("2", type_id); | 150 ASSERT_EQ("2", type_id); |
| 146 } | 151 } |
| 147 | 152 |
| 148 TEST(HeapDumpWriterTest, SizeIsHexadecimalString) { | 153 TEST(HeapDumpWriterTest, SizeAndCountAreHexadecimal) { |
| 149 // Take a number between 2^63 and 2^64 (or between 2^31 and 2^32 if |size_t| | 154 // Take a number between 2^63 and 2^64 (or between 2^31 and 2^32 if |size_t| |
| 150 // is not 64 bits). | 155 // is not 64 bits). |
| 151 const size_t large_value = | 156 const size_t large_value = |
| 152 sizeof(size_t) == 8 ? 0xffffffffffffffc5 : 0xffffff9d; | 157 sizeof(size_t) == 8 ? 0xffffffffffffffc5 : 0xffffff9d; |
| 153 const char* large_value_str = | 158 const char* large_value_str = |
| 154 sizeof(size_t) == 8 ? "ffffffffffffffc5" : "ffffff9d"; | 159 sizeof(size_t) == 8 ? "ffffffffffffffc5" : "ffffff9d"; |
| 155 Entry entry; | 160 Entry entry; |
| 156 entry.type_id = 0; | 161 entry.type_id = 0; |
| 157 entry.stack_frame_id = 0; | 162 entry.stack_frame_id = 0; |
| 158 entry.size = large_value; | 163 entry.size = large_value; |
| 164 entry.count = large_value; | |
| 159 | 165 |
| 160 std::unique_ptr<const DictionaryValue> json_entry = | 166 std::unique_ptr<const DictionaryValue> json_entry = |
| 161 WriteAndReadBackEntry(entry); | 167 WriteAndReadBackEntry(entry); |
| 162 | 168 |
| 163 std::string size; | 169 std::string size; |
| 164 ASSERT_TRUE(json_entry->GetString("size", &size)); | 170 ASSERT_TRUE(json_entry->GetString("size", &size)); |
| 165 ASSERT_EQ(large_value_str, size); | 171 ASSERT_EQ(large_value_str, size); |
| 172 | |
| 173 std::string count; | |
| 174 ASSERT_TRUE(json_entry->GetString("count", &count)); | |
| 175 ASSERT_EQ(large_value_str, count); | |
| 166 } | 176 } |
| 167 | 177 |
| 168 TEST(HeapDumpWriterTest, BacktraceTypeNameTable) { | 178 TEST(HeapDumpWriterTest, BacktraceTypeNameTable) { |
| 169 hash_map<AllocationContext, size_t> bytes_by_context; | 179 hash_map<AllocationContext, AllocationsSizeAndCount> metrics_by_context; |
| 170 | 180 |
| 171 AllocationContext ctx = AllocationContext::Empty(); | 181 AllocationContext ctx = AllocationContext::Empty(); |
| 172 ctx.backtrace.frames[0] = kBrowserMain; | 182 ctx.backtrace.frames[0] = kBrowserMain; |
| 173 ctx.backtrace.frames[1] = kCreateWidget; | 183 ctx.backtrace.frames[1] = kCreateWidget; |
| 174 ctx.type_name = kInt; | 184 ctx.type_name = kInt; |
| 175 | 185 |
| 176 // 10 bytes with context { type: int, bt: [BrowserMain, CreateWidget] }. | 186 // 10 bytes with context { type: int, bt: [BrowserMain, CreateWidget] }. |
| 177 bytes_by_context[ctx] = 10; | 187 metrics_by_context[ctx] = {10, 5}; |
| 178 | 188 |
| 179 ctx.type_name = kBool; | 189 ctx.type_name = kBool; |
| 180 | 190 |
| 181 // 18 bytes with context { type: bool, bt: [BrowserMain, CreateWidget] }. | 191 // 18 bytes with context { type: bool, bt: [BrowserMain, CreateWidget] }. |
| 182 bytes_by_context[ctx] = 18; | 192 metrics_by_context[ctx] = {18, 18}; |
| 183 | 193 |
| 184 ctx.backtrace.frames[0] = kRendererMain; | 194 ctx.backtrace.frames[0] = kRendererMain; |
| 185 ctx.backtrace.frames[1] = kInitialize; | 195 ctx.backtrace.frames[1] = kInitialize; |
| 186 | 196 |
| 187 // 30 bytes with context { type: bool, bt: [RendererMain, Initialize] }. | 197 // 30 bytes with context { type: bool, bt: [RendererMain, Initialize] }. |
| 188 bytes_by_context[ctx] = 30; | 198 metrics_by_context[ctx] = {30, 30}; |
| 189 | 199 |
| 190 ctx.type_name = kString; | 200 ctx.type_name = kString; |
| 191 | 201 |
| 192 // 19 bytes with context { type: string, bt: [RendererMain, Initialize] }. | 202 // 19 bytes with context { type: string, bt: [RendererMain, Initialize] }. |
| 193 bytes_by_context[ctx] = 19; | 203 metrics_by_context[ctx] = {19, 4}; |
| 194 | 204 |
| 195 // At this point the heap looks like this: | 205 // At this point the heap looks like this: |
| 196 // | 206 // |
| 197 // | | CrWidget <- BrMain | Init <- RenMain | Sum | | 207 // | | CrWidget <- BrMain | Init <- RenMain | Sum | |
| 198 // +--------+--------------------+-----------------+-----+ | 208 // +--------+--------------------+-----------------+-------------+ |
| 199 // | int | 10 | 0 | 10 | | 209 // | | size count | size count | size count | |
|
Primiano Tucci (use gerrit)
2016/04/14 19:37:21
many thanks for updating this :)
ssid
2016/04/14 20:17:10
Acknowledged.
| |
| 200 // | bool | 18 | 30 | 48 | | 210 // | int | 10 5 | 0 0 | 10 5 | |
| 201 // | string | 0 | 19 | 19 | | 211 // | bool | 18 18 | 30 30 | 48 48 | |
| 202 // +--------+--------------------+-----------------+-----+ | 212 // | string | 0 0 | 19 4 | 19 4 | |
| 203 // | Sum | 28 | 49 | 77 | | 213 // +--------+--------------------+-----------------+-------------+ |
| 214 // | Sum | 28 23 | 49 34 | 77 57 | | |
| 204 | 215 |
| 205 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); | 216 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); |
| 206 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); | 217 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); |
| 207 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); | 218 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); |
| 208 const std::set<Entry>& dump = writer.Summarize(bytes_by_context); | 219 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); |
| 209 | 220 |
| 210 // Get the indices of the backtraces and types by adding them again to the | 221 // Get the indices of the backtraces and types by adding them again to the |
| 211 // deduplicator. Because they were added before, the same number is returned. | 222 // deduplicator. Because they were added before, the same number is returned. |
| 212 StackFrame bt0[] = {kRendererMain, kInitialize}; | 223 StackFrame bt0[] = {kRendererMain, kInitialize}; |
| 213 StackFrame bt1[] = {kBrowserMain, kCreateWidget}; | 224 StackFrame bt1[] = {kBrowserMain, kCreateWidget}; |
| 214 int bt_renderer_main = sf_deduplicator->Insert(bt0, bt0 + 1); | 225 int bt_renderer_main = sf_deduplicator->Insert(bt0, bt0 + 1); |
| 215 int bt_browser_main = sf_deduplicator->Insert(bt1, bt1 + 1); | 226 int bt_browser_main = sf_deduplicator->Insert(bt1, bt1 + 1); |
| 216 int bt_renderer_main_initialize = sf_deduplicator->Insert(bt0, bt0 + 2); | 227 int bt_renderer_main_initialize = sf_deduplicator->Insert(bt0, bt0 + 2); |
| 217 int bt_browser_main_create_widget = sf_deduplicator->Insert(bt1, bt1 + 2); | 228 int bt_browser_main_create_widget = sf_deduplicator->Insert(bt1, bt1 + 2); |
| 218 int type_id_int = tn_deduplicator->Insert(kInt); | 229 int type_id_int = tn_deduplicator->Insert(kInt); |
| 219 int type_id_bool = tn_deduplicator->Insert(kBool); | 230 int type_id_bool = tn_deduplicator->Insert(kBool); |
| 220 int type_id_string = tn_deduplicator->Insert(kString); | 231 int type_id_string = tn_deduplicator->Insert(kString); |
| 221 | 232 |
| 222 // Full heap should have size 77. | 233 // Full heap should have size 77. |
| 223 AssertSizeEq(dump, -1, -1, 77); | 234 AssertSizeAndCountEq(dump, -1, -1, {77, 57}); |
| 224 | 235 |
| 225 // 49 bytes were allocated in RendererMain and children. Also check the type | 236 // 49 bytes in 34 chunks were allocated in RendererMain and children. Also |
| 226 // breakdown. | 237 // check the type breakdown. |
| 227 AssertSizeEq(dump, bt_renderer_main, -1, 49); | 238 AssertSizeAndCountEq(dump, bt_renderer_main, -1, {49, 34}); |
| 228 AssertSizeEq(dump, bt_renderer_main, type_id_bool, 30); | 239 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_bool, {30, 30}); |
| 229 AssertSizeEq(dump, bt_renderer_main, type_id_string, 19); | 240 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_string, {19, 4}); |
| 230 | 241 |
| 231 // 28 bytes were allocated in BrowserMain and children. Also check the type | 242 // 28 bytes in 23 chunks were allocated in BrowserMain and children. Also |
| 232 // breakdown. | 243 // check the type breakdown. |
| 233 AssertSizeEq(dump, bt_browser_main, -1, 28); | 244 AssertSizeAndCountEq(dump, bt_browser_main, -1, {28, 23}); |
| 234 AssertSizeEq(dump, bt_browser_main, type_id_int, 10); | 245 AssertSizeAndCountEq(dump, bt_browser_main, type_id_int, {10, 5}); |
| 235 AssertSizeEq(dump, bt_browser_main, type_id_bool, 18); | 246 AssertSizeAndCountEq(dump, bt_browser_main, type_id_bool, {18, 18}); |
| 236 | 247 |
| 237 // In this test all bytes are allocated in leaf nodes, so check again one | 248 // In this test all bytes are allocated in leaf nodes, so check again one |
| 238 // level deeper. | 249 // level deeper. |
| 239 AssertSizeEq(dump, bt_renderer_main_initialize, -1, 49); | 250 AssertSizeAndCountEq(dump, bt_renderer_main_initialize, -1, {49, 34}); |
| 240 AssertSizeEq(dump, bt_renderer_main_initialize, type_id_bool, 30); | 251 AssertSizeAndCountEq(dump, bt_renderer_main_initialize, type_id_bool, |
| 241 AssertSizeEq(dump, bt_renderer_main_initialize, type_id_string, 19); | 252 {30, 30}); |
| 242 AssertSizeEq(dump, bt_browser_main_create_widget, -1, 28); | 253 AssertSizeAndCountEq(dump, bt_renderer_main_initialize, type_id_string, |
| 243 AssertSizeEq(dump, bt_browser_main_create_widget, type_id_int, 10); | 254 {19, 4}); |
| 244 AssertSizeEq(dump, bt_browser_main_create_widget, type_id_bool, 18); | 255 AssertSizeAndCountEq(dump, bt_browser_main_create_widget, -1, {28, 23}); |
| 256 AssertSizeAndCountEq(dump, bt_browser_main_create_widget, type_id_int, | |
| 257 {10, 5}); | |
| 258 AssertSizeAndCountEq(dump, bt_browser_main_create_widget, type_id_bool, | |
| 259 {18, 18}); | |
| 245 | 260 |
| 246 // The type breakdown of the entrie heap should have been dumped as well. | 261 // The type breakdown of the entrie heap should have been dumped as well. |
| 247 AssertSizeEq(dump, -1, type_id_int, 10); | 262 AssertSizeAndCountEq(dump, -1, type_id_int, {10, 5}); |
| 248 AssertSizeEq(dump, -1, type_id_bool, 48); | 263 AssertSizeAndCountEq(dump, -1, type_id_bool, {48, 48}); |
| 249 AssertSizeEq(dump, -1, type_id_string, 19); | 264 AssertSizeAndCountEq(dump, -1, type_id_string, {19, 4}); |
| 250 } | 265 } |
| 251 | 266 |
| 252 TEST(HeapDumpWriterTest, InsignificantValuesNotDumped) { | 267 TEST(HeapDumpWriterTest, InsignificantValuesNotDumped) { |
| 253 hash_map<AllocationContext, size_t> bytes_by_context; | 268 hash_map<AllocationContext, AllocationsSizeAndCount> metrics_by_context; |
| 254 | 269 |
| 255 AllocationContext ctx = AllocationContext::Empty(); | 270 AllocationContext ctx = AllocationContext::Empty(); |
| 256 ctx.backtrace.frames[0] = kBrowserMain; | 271 ctx.backtrace.frames[0] = kBrowserMain; |
| 257 ctx.backtrace.frames[1] = kCreateWidget; | 272 ctx.backtrace.frames[1] = kCreateWidget; |
| 258 | 273 |
| 259 // 0.5a KiB in BrowserMain -> CreateWidget itself. | 274 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget itself. |
| 260 bytes_by_context[ctx] = 512; | 275 metrics_by_context[ctx] = {512, 1}; |
| 261 | 276 |
| 262 // 1 MiB in BrowserMain -> CreateWidget -> GetBitmap. | 277 // 1 MiB and 1 chunk in BrowserMain -> CreateWidget -> GetBitmap. |
| 263 ctx.backtrace.frames[2] = kGetBitmap; | 278 ctx.backtrace.frames[2] = kGetBitmap; |
| 264 bytes_by_context[ctx] = 1024 * 1024; | 279 metrics_by_context[ctx] = {1024 * 1024, 1}; |
| 265 | 280 |
| 266 // 0.5 KiB in BrowserMain -> CreateWidget -> Initialize. | 281 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget -> Initialize. |
| 267 ctx.backtrace.frames[2] = kInitialize; | 282 ctx.backtrace.frames[2] = kInitialize; |
| 268 bytes_by_context[ctx] = 512; | 283 metrics_by_context[ctx] = {512, 1}; |
| 269 | 284 |
| 270 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); | 285 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); |
| 271 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); | 286 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); |
| 272 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); | 287 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); |
| 273 const std::set<Entry>& dump = writer.Summarize(bytes_by_context); | 288 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); |
| 274 | 289 |
| 275 // Get the indices of the backtraces and types by adding them again to the | 290 // Get the indices of the backtraces and types by adding them again to the |
| 276 // deduplicator. Because they were added before, the same number is returned. | 291 // deduplicator. Because they were added before, the same number is returned. |
| 277 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; | 292 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; |
| 278 StackFrame bt1[] = {kBrowserMain, kCreateWidget, kInitialize}; | 293 StackFrame bt1[] = {kBrowserMain, kCreateWidget, kInitialize}; |
| 279 int bt_browser_main = sf_deduplicator->Insert(bt0, bt0 + 1); | 294 int bt_browser_main = sf_deduplicator->Insert(bt0, bt0 + 1); |
| 280 int bt_create_widget = sf_deduplicator->Insert(bt0, bt0 + 2); | 295 int bt_create_widget = sf_deduplicator->Insert(bt0, bt0 + 2); |
| 281 int bt_get_bitmap = sf_deduplicator->Insert(bt0, bt0 + 3); | 296 int bt_get_bitmap = sf_deduplicator->Insert(bt0, bt0 + 3); |
| 282 int bt_initialize = sf_deduplicator->Insert(bt1, bt1 + 3); | 297 int bt_initialize = sf_deduplicator->Insert(bt1, bt1 + 3); |
| 283 | 298 |
| 284 // Full heap should have size of 1 MiB + 1 KiB. | 299 // Full heap should have size of 1 MiB + 1 KiB and 3 chunks. |
| 285 AssertSizeEq(dump, -1, -1 /* No type specified */, 1024 * 1024 + 512 + 512); | 300 AssertSizeAndCountEq(dump, -1, -1 /* No type specified */, |
| 301 {1024 * 1024 + 512 + 512, 3}); | |
| 286 | 302 |
| 287 // |GetBitmap| allocated 1 MiB. | 303 // |GetBitmap| allocated 1 MiB and 1 chunk. |
| 288 AssertSizeEq(dump, bt_get_bitmap, -1, 1024 * 1024); | 304 AssertSizeAndCountEq(dump, bt_get_bitmap, -1, {1024 * 1024, 1}); |
| 289 | 305 |
| 290 // Because |GetBitmap| was dumped, all of its parent nodes should have been | 306 // Because |GetBitmap| was dumped, all of its parent nodes should have been |
| 291 // dumped too. |CreateWidget| has 1 MiB in |GetBitmap|, 512 bytes in | 307 // dumped too. |CreateWidget| has 1 MiB in |GetBitmap|, 512 bytes in |
| 292 // |Initialize|, and 512 bytes of its own. | 308 // |Initialize|, and 512 bytes of its own and each in 1 chunk. |
| 293 AssertSizeEq(dump, bt_create_widget, -1, 1024 * 1024 + 512 + 512); | 309 AssertSizeAndCountEq(dump, bt_create_widget, -1, |
| 294 AssertSizeEq(dump, bt_browser_main, -1, 1024 * 1024 + 512 + 512); | 310 {1024 * 1024 + 512 + 512, 3}); |
| 311 AssertSizeAndCountEq(dump, bt_browser_main, -1, {1024 * 1024 + 512 + 512, 3}); | |
| 295 | 312 |
| 296 // Initialize was not significant, it should not have been dumped. | 313 // Initialize was not significant, it should not have been dumped. |
| 297 AssertNotDumped(dump, bt_initialize, -1); | 314 AssertNotDumped(dump, bt_initialize, -1); |
| 298 } | 315 } |
| 299 | 316 |
| 300 } // namespace internal | 317 } // namespace internal |
| 301 } // namespace trace_event | 318 } // namespace trace_event |
| 302 } // namespace base | 319 } // namespace base |
| OLD | NEW |