Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(899)

Side by Side Diff: base/allocator/allocator_unittest.cc

Issue 1647803004: Move base to DEPS (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/allocator/allocator_shim_win.cc ('k') | base/allocator/debugallocation_shim.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <algorithm> // for min()
8
9 #include "base/macros.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
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);
18
19 namespace {
20
21 using std::min;
22
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);
27 }
28 }
29
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)) {
35 return false;
36 }
37 }
38 return true;
39 }
40
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++) {
44 if (buffer[i] != 0) {
45 return false;
46 }
47 }
48 return true;
49 }
50
51 // Check alignment
52 static void CheckAlignment(void* p, int align) {
53 EXPECT_EQ(0, reinterpret_cast<uintptr_t>(p) & (align-1));
54 }
55
56 // Return the next interesting size/delta to check. Returns -1 if no more.
57 static int NextSize(int size) {
58 if (size < 100)
59 return size+1;
60
61 if (size < 100000) {
62 // Find next power of two
63 int power = 1;
64 while (power < size)
65 power <<= 1;
66
67 // Yield (power-1, power, power+1)
68 if (size < power-1)
69 return power-1;
70
71 if (size == power-1)
72 return power;
73
74 assert(size == power);
75 return power+1;
76 } else {
77 return -1;
78 }
79 }
80
81 static void TestCalloc(size_t n, size_t s, bool ok) {
82 char* p = reinterpret_cast<char*>(calloc(n, s));
83 if (!ok) {
84 EXPECT_EQ(NULL, p) << "calloc(n, s) should not succeed";
85 } else {
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]);
90 }
91 free(p);
92 }
93 }
94
95 } // namespace
96
97 //-----------------------------------------------------------------------------
98
99
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
105 Fill(ptr, size);
106 EXPECT_TRUE(Valid(ptr, size));
107 free(ptr);
108 }
109 }
110
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);
122
123 TestCalloc(kMaxSize, 2, false);
124 TestCalloc(2, kMaxSize, false);
125 TestCalloc(kMaxSize, kMaxSize, false);
126
127 TestCalloc(kMaxSignedSize, 3, false);
128 TestCalloc(3, kMaxSignedSize, false);
129 TestCalloc(kMaxSignedSize, kMaxSignedSize, false);
130 }
131
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 };
137
138 for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) {
139 void* p = malloc(start_sizes[s]);
140 ASSERT_TRUE(p);
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
145 }
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
150 }
151 free(p);
152 }
153 }
154
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));
159 Fill(src, src_size);
160 unsigned char* dst =
161 reinterpret_cast<unsigned char*>(realloc(src, dst_size));
162 EXPECT_TRUE(Valid(dst, min(src_size, dst_size)));
163 Fill(dst, dst_size);
164 EXPECT_TRUE(Valid(dst, dst_size));
165 if (dst != NULL) free(dst);
166 }
167 }
168
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));
174 int sum = 0;
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
179 }
180 for (int i = 0; i < kNumEntries; i++) {
181 p[i] = reinterpret_cast<int*>(realloc(p[i], 9000));
182 }
183 for (int i = 0; i < kNumEntries; i++) {
184 sum += p[i][1000];
185 free(p[i]);
186 }
187 EXPECT_EQ(kNumEntries/2 * (kNumEntries - 1), sum); // assume kNE is even
188 free(p);
189 }
190
191 // Test recalloc
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)) {
195 unsigned char* src =
196 reinterpret_cast<unsigned char*>(_recalloc(NULL, 1, src_size));
197 EXPECT_TRUE(IsZeroed(src, src_size));
198 Fill(src, src_size);
199 unsigned char* dst =
200 reinterpret_cast<unsigned char*>(_recalloc(src, 1, dst_size));
201 EXPECT_TRUE(Valid(dst, min(src_size, dst_size)));
202 Fill(dst, dst_size);
203 EXPECT_TRUE(Valid(dst, dst_size));
204 if (dst != NULL)
205 free(dst);
206 }
207 }
208 }
209
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]);
219 Fill(ptr, size);
220 EXPECT_TRUE(Valid(ptr, size));
221
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]);
231 Fill(ptr2, size);
232 EXPECT_TRUE(Valid(ptr2, size));
233
234 // Should never happen, but sanity check just in case.
235 ASSERT_NE(ptr, ptr2);
236 _aligned_free(ptr);
237 _aligned_free(ptr2);
238 }
239 }
240 }
241
242 int main(int argc, char** argv) {
243 testing::InitGoogleTest(&argc, argv);
244 return RUN_ALL_TESTS();
245 }
OLDNEW
« no previous file with comments | « base/allocator/allocator_shim_win.cc ('k') | base/allocator/debugallocation_shim.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698