1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include <algorithm> // for min()
9 #include "base/macros.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 // Number of bits in a size_t.
13 static const int kSizeBits
= 8 * sizeof(size_t);
14 // The maximum size of a size_t.
15 static const size_t kMaxSize
= ~static_cast<size_t>(0);
16 // Maximum positive size of a size_t if it were signed.
17 static const size_t kMaxSignedSize
= ((size_t(1) << (kSizeBits
-1)) - 1);
23 // Fill a buffer of the specified size with a predetermined pattern
24 static void Fill(unsigned char* buffer
, int n
) {
25 for (int i
= 0; i
< n
; i
++) {
26 buffer
[i
] = (i
& 0xff);
30 // Check that the specified buffer has the predetermined pattern
31 // generated by Fill()
32 static bool Valid(unsigned char* buffer
, int n
) {
33 for (int i
= 0; i
< n
; i
++) {
34 if (buffer
[i
] != (i
& 0xff)) {
41 // Check that a buffer is completely zeroed.
42 static bool IsZeroed(unsigned char* buffer
, int n
) {
43 for (int i
= 0; i
< n
; i
++) {
52 static void CheckAlignment(void* p
, int align
) {
53 EXPECT_EQ(0, reinterpret_cast<uintptr_t>(p
) & (align
-1));
56 // Return the next interesting size/delta to check. Returns -1 if no more.
57 static int NextSize(int size
) {
62 // Find next power of two
67 // Yield (power-1, power, power+1)
74 assert(size
== power
);
81 static void TestCalloc(size_t n
, size_t s
, bool ok
) {
82 char* p
= reinterpret_cast<char*>(calloc(n
, s
));
84 EXPECT_EQ(NULL
, p
) << "calloc(n, s) should not succeed";
86 EXPECT_NE(reinterpret_cast<void*>(NULL
), p
) <<
87 "calloc(n, s) should succeed";
88 for (size_t i
= 0; i
< n
*s
; i
++) {
89 EXPECT_EQ('\0', p
[i
]);
97 //-----------------------------------------------------------------------------
100 TEST(Allocators
, Malloc
) {
101 // Try allocating data with a bunch of alignments and sizes
102 for (int size
= 1; size
< 1048576; size
*= 2) {
103 unsigned char* ptr
= reinterpret_cast<unsigned char*>(malloc(size
));
104 CheckAlignment(ptr
, 2); // Should be 2 byte aligned
106 EXPECT_TRUE(Valid(ptr
, size
));
111 TEST(Allocators
, Calloc
) {
112 TestCalloc(0, 0, true);
113 TestCalloc(0, 1, true);
114 TestCalloc(1, 1, true);
115 TestCalloc(1<<10, 0, true);
116 TestCalloc(1<<20, 0, true);
117 TestCalloc(0, 1<<10, true);
118 TestCalloc(0, 1<<20, true);
119 TestCalloc(1<<20, 2, true);
120 TestCalloc(2, 1<<20, true);
121 TestCalloc(1000, 1000, true);
123 TestCalloc(kMaxSize
, 2, false);
124 TestCalloc(2, kMaxSize
, false);
125 TestCalloc(kMaxSize
, kMaxSize
, false);
127 TestCalloc(kMaxSignedSize
, 3, false);
128 TestCalloc(3, kMaxSignedSize
, false);
129 TestCalloc(kMaxSignedSize
, kMaxSignedSize
, false);
132 // This makes sure that reallocing a small number of bytes in either
133 // direction doesn't cause us to allocate new memory.
134 TEST(Allocators
, Realloc1
) {
135 int start_sizes
[] = { 100, 1000, 10000, 100000 };
136 int deltas
[] = { 1, -2, 4, -8, 16, -32, 64, -128 };
138 for (int s
= 0; s
< sizeof(start_sizes
)/sizeof(*start_sizes
); ++s
) {
139 void* p
= malloc(start_sizes
[s
]);
141 // The larger the start-size, the larger the non-reallocing delta.
142 for (int d
= 0; d
< s
*2; ++d
) {
143 void* new_p
= realloc(p
, start_sizes
[s
] + deltas
[d
]);
144 ASSERT_EQ(p
, new_p
); // realloc should not allocate new memory
146 // Test again, but this time reallocing smaller first.
147 for (int d
= 0; d
< s
*2; ++d
) {
148 void* new_p
= realloc(p
, start_sizes
[s
] - deltas
[d
]);
149 ASSERT_EQ(p
, new_p
); // realloc should not allocate new memory
155 TEST(Allocators
, Realloc2
) {
156 for (int src_size
= 0; src_size
>= 0; src_size
= NextSize(src_size
)) {
157 for (int dst_size
= 0; dst_size
>= 0; dst_size
= NextSize(dst_size
)) {
158 unsigned char* src
= reinterpret_cast<unsigned char*>(malloc(src_size
));
161 reinterpret_cast<unsigned char*>(realloc(src
, dst_size
));
162 EXPECT_TRUE(Valid(dst
, min(src_size
, dst_size
)));
164 EXPECT_TRUE(Valid(dst
, dst_size
));
165 if (dst
!= NULL
) free(dst
);
169 // Now make sure realloc works correctly even when we overflow the
170 // packed cache, so some entries are evicted from the cache.
171 // The cache has 2^12 entries, keyed by page number.
172 const int kNumEntries
= 1 << 14;
173 int** p
= reinterpret_cast<int**>(malloc(sizeof(*p
) * kNumEntries
));
175 for (int i
= 0; i
< kNumEntries
; i
++) {
176 // no page size is likely to be bigger than 8192?
177 p
[i
] = reinterpret_cast<int*>(malloc(8192));
178 p
[i
][1000] = i
; // use memory deep in the heart of p
180 for (int i
= 0; i
< kNumEntries
; i
++) {
181 p
[i
] = reinterpret_cast<int*>(realloc(p
[i
], 9000));
183 for (int i
= 0; i
< kNumEntries
; i
++) {
187 EXPECT_EQ(kNumEntries
/2 * (kNumEntries
- 1), sum
); // assume kNE is even
192 TEST(Allocators
, Recalloc
) {
193 for (int src_size
= 0; src_size
>= 0; src_size
= NextSize(src_size
)) {
194 for (int dst_size
= 0; dst_size
>= 0; dst_size
= NextSize(dst_size
)) {
196 reinterpret_cast<unsigned char*>(_recalloc(NULL
, 1, src_size
));
197 EXPECT_TRUE(IsZeroed(src
, src_size
));
200 reinterpret_cast<unsigned char*>(_recalloc(src
, 1, dst_size
));
201 EXPECT_TRUE(Valid(dst
, min(src_size
, dst_size
)));
203 EXPECT_TRUE(Valid(dst
, dst_size
));
210 // Test windows specific _aligned_malloc() and _aligned_free() methods.
211 TEST(Allocators
, AlignedMalloc
) {
212 // Try allocating data with a bunch of alignments and sizes
213 static const int kTestAlignments
[] = {8, 16, 256, 4096, 8192, 16384};
214 for (int size
= 1; size
> 0; size
= NextSize(size
)) {
215 for (int i
= 0; i
< arraysize(kTestAlignments
); ++i
) {
216 unsigned char* ptr
= static_cast<unsigned char*>(
217 _aligned_malloc(size
, kTestAlignments
[i
]));
218 CheckAlignment(ptr
, kTestAlignments
[i
]);
220 EXPECT_TRUE(Valid(ptr
, size
));
222 // Make a second allocation of the same size and alignment to prevent
223 // allocators from passing this test by accident. Per jar, tcmalloc
224 // provides allocations for new (never before seen) sizes out of a thread
225 // local heap of a given "size class." Each time the test requests a new
226 // size, it will usually get the first element of a span, which is a
227 // 4K aligned allocation.
228 unsigned char* ptr2
= static_cast<unsigned char*>(
229 _aligned_malloc(size
, kTestAlignments
[i
]));
230 CheckAlignment(ptr2
, kTestAlignments
[i
]);
232 EXPECT_TRUE(Valid(ptr2
, size
));
234 // Should never happen, but sanity check just in case.
235 ASSERT_NE(ptr
, ptr2
);
242 int main(int argc
, char** argv
) {
243 testing::InitGoogleTest(&argc
, argv
);
244 return RUN_ALL_TESTS();