Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 | 6 |
| 7 #if defined(DART_USE_TCMALLOC) && !defined(PRODUCT) | 7 #if defined(DART_USE_TCMALLOC) && !defined(PRODUCT) |
| 8 | 8 |
| 9 #include <execinfo.h> | |
|
Cutch
2017/02/08 00:28:54
This is a cross platform test file. backtrace/exec
bkonyi
2017/02/08 01:37:05
This was more here for me to check that my impleme
zra
2017/02/08 17:42:55
Not sure how portable this is. Should this be gate
bkonyi
2017/02/09 21:22:46
Yes, it probably should. However, DART_USE_TCMALLO
| |
| 10 | |
| 9 #include "platform/assert.h" | 11 #include "platform/assert.h" |
| 10 #include "vm/class_finalizer.h" | 12 #include "vm/class_finalizer.h" |
| 11 #include "vm/globals.h" | 13 #include "vm/globals.h" |
| 12 #include "vm/malloc_hooks.h" | 14 #include "vm/malloc_hooks.h" |
| 15 #include "vm/native_symbol.h" | |
| 16 #include "vm/profiler.h" | |
| 13 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
| 14 #include "vm/unit_test.h" | 18 #include "vm/unit_test.h" |
| 15 | 19 |
| 16 namespace dart { | 20 namespace dart { |
| 17 | 21 |
| 18 static void MallocHookTestBufferInitializer(volatile char* buffer, | 22 static void MallocHookTestBufferInitializer(volatile char* buffer, |
| 19 uintptr_t size) { | 23 uintptr_t size) { |
| 20 // Run through the buffer and do something. If we don't do this and the memory | 24 // Run through the buffer and do something. If we don't do this and the memory |
| 21 // in buffer isn't touched, the tcmalloc hooks won't be called. | 25 // in buffer isn't touched, the tcmalloc hooks won't be called. |
| 22 for (uintptr_t i = 0; i < size; ++i) { | 26 for (uintptr_t i = 0; i < size; ++i) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size), | 72 EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size), |
| 69 MallocHooks::heap_allocated_memory_in_bytes()); | 73 MallocHooks::heap_allocated_memory_in_bytes()); |
| 70 | 74 |
| 71 | 75 |
| 72 delete[] buffer; | 76 delete[] buffer; |
| 73 EXPECT_EQ(0L, MallocHooks::allocation_count()); | 77 EXPECT_EQ(0L, MallocHooks::allocation_count()); |
| 74 EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes()); | 78 EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes()); |
| 75 MallocHooks::TearDown(); | 79 MallocHooks::TearDown(); |
| 76 } | 80 } |
| 77 | 81 |
| 82 // Helper used to add another frame to the stack before allocating. | |
| 83 char* AllocationHelper(void* stack_trace[32]) { | |
| 84 backtrace(stack_trace, 32); | |
| 85 return static_cast<char*>(malloc(16 * sizeof(char))); | |
| 86 } | |
| 87 | |
| 88 VM_UNIT_TEST_CASE(StackTraceMallocHookTest) { | |
| 89 MallocHooks::ResetStats(); | |
| 90 ASSERT(OSThread::DoesCurrentThreadExist()); | |
| 91 | |
| 92 const intptr_t first_frame_count = 6; | |
| 93 void* stack_trace[32]; | |
| 94 | |
| 95 // Perform the memory allocation and grab the stack trace created by | |
| 96 // backtrace() for comparison purposes. | |
| 97 char* var = AllocationHelper(stack_trace); | |
| 98 | |
| 99 // Update top pc of the stack trace to match the location that malloc was | |
| 100 // called in AllocationHelper. The rest of the pcs should match without any | |
| 101 // changes. | |
| 102 stack_trace[0] = | |
| 103 reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(stack_trace[0]) + 15); | |
| 104 | |
| 105 Sample* sample = MallocHooks::GetSample(var); | |
| 106 ASSERT(sample != NULL); | |
| 107 | |
| 108 intptr_t frame_count = 0; | |
| 109 while (sample != NULL) { | |
|
Cutch
2017/02/08 00:28:53
This test might not be necessary. We have tests wh
bkonyi
2017/02/08 01:37:05
Makes sense. I'll remove it before actually landin
| |
| 110 for (uintptr_t i = 0; i < 8; ++i) { | |
| 111 // Cease comparisons after we pass the frame for main. | |
| 112 if (sample->At(i) == 0) { | |
| 113 break; | |
| 114 } | |
| 115 | |
| 116 // The first 6 frames in the stack trace we generate are all from the | |
| 117 // memory allocation. The frame for AllocationHelper is the 7th element, | |
| 118 // so we skip checking all the frames before that. | |
| 119 if (frame_count >= first_frame_count) { | |
| 120 EXPECT_EQ(reinterpret_cast<uword>( | |
| 121 stack_trace[frame_count - first_frame_count]), | |
| 122 sample->At(i)); | |
| 123 } | |
| 124 ++frame_count; | |
| 125 } | |
| 126 | |
| 127 if (!sample->is_continuation_sample()) { | |
| 128 break; | |
| 129 } | |
| 130 sample = Profiler::sample_buffer()->At(sample->continuation_index()); | |
| 131 } | |
| 132 } | |
| 133 | |
| 78 }; // namespace dart | 134 }; // namespace dart |
| 79 | 135 |
| 80 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) | 136 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) |
| OLD | NEW |