1 // Copyright 2009 Google Inc. All Rights Reserved.
2 // Author: fikes@google.com (Andrew Fikes)
4 #include "config_for_unittests.h"
5 #include <stdio.h> // for puts()
6 #include "stack_trace_table.h"
7 #include "base/logging.h"
8 #include "base/spinlock.h"
9 #include "static_vars.h"
11 #undef ARRAYSIZE // may be defined on, eg, windows
12 #define ARRAYSIZE(a) ( sizeof(a) / sizeof(*(a)) )
14 static void CheckTracesAndReset(tcmalloc::StackTraceTable
* table
,
15 const uintptr_t* expected
, int len
) {
16 void** entries
= table
->ReadStackTracesAndClear();
17 for (int i
= 0; i
< len
; ++i
) {
18 CHECK_EQ(reinterpret_cast<uintptr_t>(entries
[i
]), expected
[i
]);
23 static void AddTrace(tcmalloc::StackTraceTable
* table
,
24 const tcmalloc::StackTrace
& t
) {
25 // Normally we'd need this lock, but since the test is single-threaded
26 // we don't. I comment it out on windows because the DLL-decl thing
27 // is really annoying in this case.
29 SpinLockHolder
h(tcmalloc::Static::pageheap_lock());
34 int main(int argc
, char **argv
) {
35 tcmalloc::StackTraceTable table
;
38 CHECK_EQ(table
.depth_total(), 0);
39 CHECK_EQ(table
.bucket_total(), 0);
40 static const uintptr_t k1
[] = {0};
41 CheckTracesAndReset(&table
, k1
, ARRAYSIZE(k1
));
43 tcmalloc::StackTrace t1
;
44 t1
.size
= static_cast<uintptr_t>(1024);
45 t1
.depth
= static_cast<uintptr_t>(2);
46 t1
.stack
[0] = reinterpret_cast<void*>(1);
47 t1
.stack
[1] = reinterpret_cast<void*>(2);
50 tcmalloc::StackTrace t2
;
51 t2
.size
= static_cast<uintptr_t>(512);
52 t2
.depth
= static_cast<uintptr_t>(2);
53 t2
.stack
[0] = reinterpret_cast<void*>(2);
54 t2
.stack
[1] = reinterpret_cast<void*>(1);
58 CHECK_EQ(table
.depth_total(), 2);
59 CHECK_EQ(table
.bucket_total(), 1);
60 static const uintptr_t k2
[] = {1, 1024, 2, 1, 2, 0};
61 CheckTracesAndReset(&table
, k2
, ARRAYSIZE(k2
));
66 CHECK_EQ(table
.depth_total(), 4);
67 CHECK_EQ(table
.bucket_total(), 2);
68 static const uintptr_t k3
[] = {1, 1024, 2, 1, 2, 1, 512, 2, 2, 1, 0};
69 CheckTracesAndReset(&table
, k3
, ARRAYSIZE(k3
));
71 // Table w/ 2 x t1, 1 x t2
75 CHECK_EQ(table
.depth_total(), 4);
76 CHECK_EQ(table
.bucket_total(), 2);
77 static const uintptr_t k4
[] = {2, 2048, 2, 1, 2, 1, 512, 2, 2, 1, 0};
78 CheckTracesAndReset(&table
, k4
, ARRAYSIZE(k4
));
80 // Same stack as t1, but w/ different size
81 tcmalloc::StackTrace t3
;
82 t3
.size
= static_cast<uintptr_t>(2);
83 t3
.depth
= static_cast<uintptr_t>(2);
84 t3
.stack
[0] = reinterpret_cast<void*>(1);
85 t3
.stack
[1] = reinterpret_cast<void*>(2);
90 CHECK_EQ(table
.depth_total(), 2);
91 CHECK_EQ(table
.bucket_total(), 1);
92 static const uintptr_t k5
[] = {2, 1026, 2, 1, 2, 0};
93 CheckTracesAndReset(&table
, k5
, ARRAYSIZE(k5
));