1 // Copyright (c) 2005, Google Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 // Unittest for the TCMalloc implementation.
33 // * The test consists of a set of threads.
34 // * Each thread maintains a set of allocated objects, with
35 // a bound on the total amount of data in the set.
36 // * Each allocated object's contents are generated by
37 // hashing the object pointer, and a generation count
38 // in the object. This allows us to easily check for
40 // * At any given step, the thread can do any of the following:
41 // a. Allocate an object
42 // b. Increment an object's generation count and update
44 // c. Pass the object to another thread
46 // Also, at the end of every step, object(s) are freed to maintain
47 // the memory upper-bound.
49 // If this test is compiled with -DDEBUGALLOCATION, then we don't
50 // run some tests that test the inner workings of tcmalloc and
51 // break on debugallocation: that certain allocations are aligned
52 // in a certain way (even though no standard requires it), and that
53 // realloc() tries to minimize copying (which debug allocators don't
56 #include "config_for_unittests.h"
57 // Complicated ordering requirements. tcmalloc.h defines (indirectly)
58 // _POSIX_C_SOURCE, which it needs so stdlib.h defines posix_memalign.
59 // unistd.h, on the other hand, requires _POSIX_C_SOURCE to be unset,
60 // at least on FreeBSD, in order to define sbrk. The solution
61 // is to #include unistd.h first. This is safe because unistd.h
62 // doesn't sub-include stdlib.h, so we'll still get posix_memalign
63 // when we #include stdlib.h. Blah.
65 #include <unistd.h> // for testing sbrk hooks
67 #include "tcmalloc.h" // must come early, to pick up posix_memalign
71 #if defined HAVE_STDINT_H
72 #include <stdint.h> // for intptr_t
74 #include <sys/types.h> // for size_t
76 #include <fcntl.h> // for open; used with mmap-hook test
79 #include <sys/mman.h> // for testing mmap hooks
82 #include <malloc.h> // defines pvalloc/etc on cygwin
89 #include "base/logging.h"
90 #include "base/simple_mutex.h"
91 #include "gperftools/malloc_hook.h"
92 #include "gperftools/malloc_extension.h"
93 #include "gperftools/tcmalloc.h"
94 #include "thread_cache.h"
95 #include "tests/testutil.h"
97 // Windows doesn't define pvalloc and a few other obsolete unix
98 // functions; nor does it define posix_memalign (which is not obsolete).
100 # define cfree free // don't bother to try to test these obsolete fns
101 # define valloc malloc
102 # define pvalloc malloc
103 // I'd like to map posix_memalign to _aligned_malloc, but _aligned_malloc
104 // must be paired with _aligned_free (not normal free), which is too
105 // invasive a change to how we allocate memory here. So just bail
106 static bool kOSSupportsMemalign
= false;
107 static inline void* Memalign(size_t align
, size_t size
) {
108 //LOG(FATAL) << "memalign not supported on windows";
112 static inline int PosixMemalign(void** ptr
, size_t align
, size_t size
) {
113 //LOG(FATAL) << "posix_memalign not supported on windows";
118 // OS X defines posix_memalign in some OS versions but not others;
119 // it's confusing enough to check that it's easiest to just not to test.
120 #elif defined(__APPLE__)
121 static bool kOSSupportsMemalign
= false;
122 static inline void* Memalign(size_t align
, size_t size
) {
123 //LOG(FATAL) << "memalign not supported on OS X";
127 static inline int PosixMemalign(void** ptr
, size_t align
, size_t size
) {
128 //LOG(FATAL) << "posix_memalign not supported on OS X";
134 static bool kOSSupportsMemalign
= true;
135 static inline void* Memalign(size_t align
, size_t size
) {
136 return memalign(align
, size
);
138 static inline int PosixMemalign(void** ptr
, size_t align
, size_t size
) {
139 return posix_memalign(ptr
, align
, size
);
144 // On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
145 // form of the name instead.
146 #ifndef MAP_ANONYMOUS
147 # define MAP_ANONYMOUS MAP_ANON
150 #define LOGSTREAM stdout
155 DECLARE_double(tcmalloc_release_rate
);
156 DECLARE_int32(max_free_queue_size
); // in debugallocation.cc
157 DECLARE_int64(tcmalloc_sample_parameter
);
161 static const int FLAGS_numtests
= 50000;
162 static const int FLAGS_log_every_n_tests
= 50000; // log exactly once
164 // Testing parameters
165 static const int FLAGS_lgmaxsize
= 16; // lg() of the max size object to alloc
166 static const int FLAGS_numthreads
= 10; // Number of threads
167 static const int FLAGS_threadmb
= 4; // Max memory size allocated by thread
168 static const int FLAGS_lg_max_memalign
= 18; // lg of max alignment for memalign
170 static const double FLAGS_memalign_min_fraction
= 0; // min expected%
171 static const double FLAGS_memalign_max_fraction
= 0.4; // max expected%
172 static const double FLAGS_memalign_max_alignment_ratio
= 6; // alignment/size
174 // Weights of different operations
175 static const int FLAGS_allocweight
= 50; // Weight for picking allocation
176 static const int FLAGS_freeweight
= 50; // Weight for picking free
177 static const int FLAGS_updateweight
= 10; // Weight for picking update
178 static const int FLAGS_passweight
= 1; // Weight for passing object
180 static const int kSizeBits
= 8 * sizeof(size_t);
181 static const size_t kMaxSize
= ~static_cast<size_t>(0);
182 static const size_t kMaxSignedSize
= ((size_t(1) << (kSizeBits
-1)) - 1);
184 static const size_t kNotTooBig
= 100000;
185 // We want an allocation that is definitely more than main memory. OS
186 // X has special logic to discard very big allocs before even passing
187 // the request along to the user-defined memory allocator; we're not
188 // interested in testing their logic, so we have to make sure we're
190 static const size_t kTooBig
= kMaxSize
- 100000;
192 static int news_handled
= 0;
194 // Global array of threads
196 static TesterThread
** threads
;
198 // To help with generating random numbers
201 // Information kept per type
209 TestHarness(int seed
)
210 : types_(new vector
<Type
>), total_weight_(0), num_tests_(0) {
217 // Add operation type with specified weight. When starting a new
218 // iteration, an operation type is picked with probability
219 // proportional to its weight.
221 // "type" must be non-negative.
222 // "weight" must be non-negative.
223 void AddType(int type
, int weight
, const char* name
);
225 // Call this to get the type of operation for the next iteration.
226 // It returns a random operation type from the set of registered
227 // operations. Returns -1 if tests should finish.
230 // If n == 0, returns the next pseudo-random number in the range [0 .. 0]
231 // If n != 0, returns the next pseudo-random number in the range [0 .. n)
239 // Pick "base" uniformly from range [0,max_log] and then return
240 // "base" random bits. The effect is to pick a number in the range
241 // [0,2^max_log-1] with bias towards smaller numbers.
242 int Skewed(int max_log
) {
243 const int base
= random() % (max_log
+1);
244 return random() % (1 << base
);
248 vector
<Type
>* types_
; // Registered types
249 int total_weight_
; // Total weight of all types
250 int num_tests_
; // Num tests run so far
253 void TestHarness::AddType(int type
, int weight
, const char* name
) {
258 types_
->push_back(t
);
259 total_weight_
+= weight
;
262 int TestHarness::PickType() {
263 if (num_tests_
>= FLAGS_numtests
) return -1;
266 assert(total_weight_
> 0);
267 // This is a little skewed if total_weight_ doesn't divide 2^31, but it's close
268 int v
= Uniform(total_weight_
);
270 for (i
= 0; i
< types_
->size(); i
++) {
271 v
-= (*types_
)[i
].weight
;
277 assert(i
< types_
->size());
278 if ((num_tests_
% FLAGS_log_every_n_tests
) == 0) {
279 fprintf(LOGSTREAM
, " Test %d out of %d: %s\n",
280 num_tests_
, FLAGS_numtests
, (*types_
)[i
].name
.c_str());
282 return (*types_
)[i
].type
;
285 class AllocatorState
: public TestHarness
{
287 explicit AllocatorState(int seed
) : TestHarness(seed
), memalign_fraction_(0) {
288 if (kOSSupportsMemalign
) {
289 CHECK_GE(FLAGS_memalign_max_fraction
, 0);
290 CHECK_LE(FLAGS_memalign_max_fraction
, 1);
291 CHECK_GE(FLAGS_memalign_min_fraction
, 0);
292 CHECK_LE(FLAGS_memalign_min_fraction
, 1);
293 double delta
= FLAGS_memalign_max_fraction
- FLAGS_memalign_min_fraction
;
295 memalign_fraction_
= (Uniform(10000)/10000.0 * delta
+
296 FLAGS_memalign_min_fraction
);
297 //fprintf(LOGSTREAM, "memalign fraction: %f\n", memalign_fraction_);
300 virtual ~AllocatorState() {}
302 // Allocate memory. Randomly choose between malloc() or posix_memalign().
303 void* alloc(size_t size
) {
304 if (Uniform(100) < memalign_fraction_
* 100) {
305 // Try a few times to find a reasonable alignment, or fall back on malloc.
306 for (int i
= 0; i
< 5; i
++) {
307 size_t alignment
= 1 << Uniform(FLAGS_lg_max_memalign
);
308 if (alignment
>= sizeof(intptr_t) &&
309 (size
< sizeof(intptr_t) ||
310 alignment
< FLAGS_memalign_max_alignment_ratio
* size
)) {
311 void *result
= reinterpret_cast<void*>(static_cast<intptr_t>(0x1234));
312 int err
= PosixMemalign(&result
, alignment
, size
);
314 CHECK_EQ(err
, ENOMEM
);
316 return err
== 0 ? result
: NULL
;
324 double memalign_fraction_
;
328 // Info kept per thread
331 // Info kept per allocated object
333 char* ptr
; // Allocated pointer
334 int size
; // Allocated size
335 int generation
; // Generation counter of object contents
338 Mutex lock_
; // For passing in another thread's obj
339 int id_
; // My thread id
340 AllocatorState rnd_
; // For generating random numbers
341 vector
<Object
> heap_
; // This thread's heap
342 vector
<Object
> passed_
; // Pending objects passed from others
343 size_t heap_size_
; // Current heap size
344 int locks_ok_
; // Number of OK TryLock() ops
345 int locks_failed_
; // Number of failed TryLock() ops
347 // Type of operations
348 enum Type
{ ALLOC
, FREE
, UPDATE
, PASS
};
350 // ACM minimal standard random number generator. (re-entrant.)
354 explicit ACMRandom(int32 seed
) { seed_
= seed
; }
356 const int32 M
= 2147483647L; // 2^31-1
357 const int32 A
= 16807;
358 // In effect, we are computing seed_ = (seed_ * A) % M, where M = 2^31-1
359 uint32 lo
= A
* (int32
)(seed_
& 0xFFFF);
360 uint32 hi
= A
* (int32
)((uint32
)seed_
>> 16);
361 lo
+= (hi
& 0x7FFF) << 16;
371 return (seed_
= (int32
) lo
);
384 virtual ~TesterThread() {
386 fprintf(LOGSTREAM
, "Thread %2d: locks %6d ok; %6d trylocks failed\n",
387 id_
, locks_ok_
, locks_failed_
);
388 if (locks_ok_
+ locks_failed_
>= 1000) {
389 CHECK_LE(locks_failed_
, locks_ok_
/ 2);
394 rnd_
.AddType(ALLOC
, FLAGS_allocweight
, "allocate");
395 rnd_
.AddType(FREE
, FLAGS_freeweight
, "free");
396 rnd_
.AddType(UPDATE
, FLAGS_updateweight
, "update");
397 rnd_
.AddType(PASS
, FLAGS_passweight
, "pass");
400 AcquirePassedObjects();
402 switch (rnd_
.PickType()) {
403 case ALLOC
: AllocateObject(); break;
404 case FREE
: FreeObject(); break;
405 case UPDATE
: UpdateObject(); break;
406 case PASS
: PassObject(); break;
408 default: assert(NULL
== "Unknown type");
418 // Allocate a new object
419 void AllocateObject() {
421 object
.size
= rnd_
.Skewed(FLAGS_lgmaxsize
);
422 object
.ptr
= static_cast<char*>(rnd_
.alloc(object
.size
));
424 object
.generation
= 0;
425 FillContents(&object
);
426 heap_
.push_back(object
);
427 heap_size_
+= object
.size
;
430 // Mutate a random object
431 void UpdateObject() {
432 if (heap_
.empty()) return;
433 const int index
= rnd_
.Uniform(heap_
.size());
434 CheckContents(heap_
[index
]);
435 heap_
[index
].generation
++;
436 FillContents(&heap_
[index
]);
439 // Free a random object
441 if (heap_
.empty()) return;
442 const int index
= rnd_
.Uniform(heap_
.size());
443 Object object
= heap_
[index
];
444 CheckContents(object
);
446 heap_size_
-= object
.size
;
447 heap_
[index
] = heap_
[heap_
.size()-1];
451 // Delete all objects in the heap
453 while (!heap_
.empty()) {
458 // Free objects until our heap is small enough
460 while (heap_size_
> FLAGS_threadmb
<< 20) {
461 assert(!heap_
.empty());
466 // Pass a random object to another thread
468 // Pick object to pass
469 if (heap_
.empty()) return;
470 const int index
= rnd_
.Uniform(heap_
.size());
471 Object object
= heap_
[index
];
472 CheckContents(object
);
474 // Pick thread to pass
475 const int tid
= rnd_
.Uniform(FLAGS_numthreads
);
476 TesterThread
* thread
= threads
[tid
];
478 if (thread
->lock_
.TryLock()) {
481 thread
->passed_
.push_back(object
);
482 thread
->lock_
.Unlock();
483 heap_size_
-= object
.size
;
484 heap_
[index
] = heap_
[heap_
.size()-1];
491 // Grab any objects passed to this thread by another thread
492 void AcquirePassedObjects() {
493 // We do not create unnecessary contention by always using
494 // TryLock(). Plus we unlock immediately after swapping passed
495 // objects into a local vector.
498 if (!lock_
.TryLock()) {
507 for (int i
= 0; i
< copy
.size(); ++i
) {
508 const Object
& object
= copy
[i
];
509 CheckContents(object
);
510 heap_
.push_back(object
);
511 heap_size_
+= object
.size
;
515 // Fill object contents according to ptr/generation
516 void FillContents(Object
* object
) {
517 ACMRandom
r(reinterpret_cast<intptr_t>(object
->ptr
) & 0x7fffffff);
518 for (int i
= 0; i
< object
->generation
; ++i
) {
521 const char c
= static_cast<char>(r
.Next());
522 memset(object
->ptr
, c
, object
->size
);
525 // Check object contents
526 void CheckContents(const Object
& object
) {
527 ACMRandom
r(reinterpret_cast<intptr_t>(object
.ptr
) & 0x7fffffff);
528 for (int i
= 0; i
< object
.generation
; ++i
) {
532 // For large objects, we just check a prefix/suffix
533 const char expected
= static_cast<char>(r
.Next());
534 const int limit1
= object
.size
< 32 ? object
.size
: 32;
535 const int start2
= limit1
> object
.size
- 32 ? limit1
: object
.size
- 32;
536 for (int i
= 0; i
< limit1
; ++i
) {
537 CHECK_EQ(object
.ptr
[i
], expected
);
539 for (int i
= start2
; i
< object
.size
; ++i
) {
540 CHECK_EQ(object
.ptr
[i
], expected
);
545 static void RunThread(int thread_id
) {
546 threads
[thread_id
]->Run();
549 static void TryHugeAllocation(size_t s
, AllocatorState
* rnd
) {
550 void* p
= rnd
->alloc(s
);
551 CHECK(p
== NULL
); // huge allocation s should fail!
554 static void TestHugeAllocations(AllocatorState
* rnd
) {
555 // Check that asking for stuff tiny bit smaller than largest possible
556 // size returns NULL.
557 for (size_t i
= 0; i
< 70000; i
+= rnd
->Uniform(20)) {
558 TryHugeAllocation(kMaxSize
- i
, rnd
);
560 // Asking for memory sizes near signed/unsigned boundary (kMaxSignedSize)
561 // might work or not, depending on the amount of virtual memory.
562 #ifndef DEBUGALLOCATION // debug allocation takes forever for huge allocs
563 for (size_t i
= 0; i
< 100; i
++) {
565 p
= rnd
->alloc(kMaxSignedSize
+ i
);
566 if (p
) free(p
); // if: free(NULL) is not necessarily defined
567 p
= rnd
->alloc(kMaxSignedSize
- i
);
572 // Check that ReleaseFreeMemory has no visible effect (aka, does not
574 MallocExtension
* inst
= MallocExtension::instance();
576 inst
->ReleaseFreeMemory();
579 static void TestCalloc(size_t n
, size_t s
, bool ok
) {
580 char* p
= reinterpret_cast<char*>(calloc(n
, s
));
582 fprintf(LOGSTREAM
, "calloc(%"PRIxS
", %"PRIxS
"): %p\n", n
, s
, p
);
584 CHECK(p
== NULL
); // calloc(n, s) should not succeed
586 CHECK(p
!= NULL
); // calloc(n, s) should succeed
587 for (int i
= 0; i
< n
*s
; i
++) {
594 // This makes sure that reallocing a small number of bytes in either
595 // direction doesn't cause us to allocate new memory.
596 static void TestRealloc() {
597 #ifndef DEBUGALLOCATION // debug alloc doesn't try to minimize reallocs
598 // When sampling, we always allocate in units of page-size, which
599 // makes reallocs of small sizes do extra work (thus, failing these
600 // checks). Since sampling is random, we turn off sampling to make
601 // sure that doesn't happen to us here.
602 const int64 old_sample_parameter
= FLAGS_tcmalloc_sample_parameter
;
603 FLAGS_tcmalloc_sample_parameter
= 0; // turn off sampling
605 int start_sizes
[] = { 100, 1000, 10000, 100000 };
606 int deltas
[] = { 1, -2, 4, -8, 16, -32, 64, -128 };
608 for (int s
= 0; s
< sizeof(start_sizes
)/sizeof(*start_sizes
); ++s
) {
609 void* p
= malloc(start_sizes
[s
]);
611 // The larger the start-size, the larger the non-reallocing delta.
612 for (int d
= 0; d
< (s
+1) * 2; ++d
) {
613 void* new_p
= realloc(p
, start_sizes
[s
] + deltas
[d
]);
614 CHECK(p
== new_p
); // realloc should not allocate new memory
616 // Test again, but this time reallocing smaller first.
617 for (int d
= 0; d
< s
*2; ++d
) {
618 void* new_p
= realloc(p
, start_sizes
[s
] - deltas
[d
]);
619 CHECK(p
== new_p
); // realloc should not allocate new memory
623 FLAGS_tcmalloc_sample_parameter
= old_sample_parameter
;
627 static void TestNewHandler() throw (std::bad_alloc
) {
629 throw std::bad_alloc();
632 static void TestOneNew(void* (*func
)(size_t)) {
635 void* ptr
= (*func
)(kNotTooBig
);
637 fprintf(LOGSTREAM
, "allocation should not have failed.\n");
641 fprintf(LOGSTREAM
, "allocation threw unexpected exception.\n");
646 // we should always receive a bad_alloc exception
649 fprintf(LOGSTREAM
, "allocation should have failed.\n");
651 } catch (const std::bad_alloc
&) {
654 fprintf(LOGSTREAM
, "allocation threw unexpected exception.\n");
659 static void TestNew(void* (*func
)(size_t)) {
662 // test without new_handler:
663 std::new_handler saved_handler
= std::set_new_handler(0);
666 // test with new_handler:
667 std::set_new_handler(TestNewHandler
);
669 if (news_handled
!= 1) {
670 fprintf(LOGSTREAM
, "new_handler was not called.\n");
673 std::set_new_handler(saved_handler
);
676 static void TestOneNothrowNew(void* (*func
)(size_t, const std::nothrow_t
&)) {
679 void* ptr
= (*func
)(kNotTooBig
, std::nothrow
);
681 fprintf(LOGSTREAM
, "allocation should not have failed.\n");
685 fprintf(LOGSTREAM
, "allocation threw unexpected exception.\n");
690 // we should always receive a bad_alloc exception
692 if ((*func
)(kTooBig
, std::nothrow
) != 0) {
693 fprintf(LOGSTREAM
, "allocation should have failed.\n");
697 fprintf(LOGSTREAM
, "nothrow allocation threw unexpected exception.\n");
702 static void TestNothrowNew(void* (*func
)(size_t, const std::nothrow_t
&)) {
705 // test without new_handler:
706 std::new_handler saved_handler
= std::set_new_handler(0);
707 TestOneNothrowNew(func
);
709 // test with new_handler:
710 std::set_new_handler(TestNewHandler
);
711 TestOneNothrowNew(func
);
712 if (news_handled
!= 1) {
713 fprintf(LOGSTREAM
, "nothrow new_handler was not called.\n");
716 std::set_new_handler(saved_handler
);
720 // These are used as callbacks by the sanity-check. Set* and Reset*
721 // register the hook that counts how many times the associated memory
722 // function is called. After each such call, call Verify* to verify
723 // that we used the tcmalloc version of the call, and not the libc.
724 // Note the ... in the hook signature: we don't care what arguments
726 #define MAKE_HOOK_CALLBACK(hook_type) \
727 static int g_##hook_type##_calls = 0; \
728 static void IncrementCallsTo##hook_type(...) { \
729 g_##hook_type##_calls++; \
731 static void Verify##hook_type##WasCalled() { \
732 CHECK_GT(g_##hook_type##_calls, 0); \
733 g_##hook_type##_calls = 0; /* reset for next call */ \
735 static void Set##hook_type() { \
736 CHECK(MallocHook::Add##hook_type( \
737 (MallocHook::hook_type)&IncrementCallsTo##hook_type)); \
739 static void Reset##hook_type() { \
740 CHECK(MallocHook::Remove##hook_type( \
741 (MallocHook::hook_type)&IncrementCallsTo##hook_type)); \
744 // We do one for each hook typedef in malloc_hook.h
745 MAKE_HOOK_CALLBACK(NewHook
);
746 MAKE_HOOK_CALLBACK(DeleteHook
);
747 MAKE_HOOK_CALLBACK(MmapHook
);
748 MAKE_HOOK_CALLBACK(MremapHook
);
749 MAKE_HOOK_CALLBACK(MunmapHook
);
750 MAKE_HOOK_CALLBACK(SbrkHook
);
752 static void TestAlignmentForSize(int size
) {
753 fprintf(LOGSTREAM
, "Testing alignment of malloc(%d)\n", size
);
754 static const int kNum
= 100;
756 for (int i
= 0; i
< kNum
; i
++) {
757 ptrs
[i
] = malloc(size
);
758 uintptr_t p
= reinterpret_cast<uintptr_t>(ptrs
[i
]);
759 CHECK((p
% sizeof(void*)) == 0);
760 CHECK((p
% sizeof(double)) == 0);
762 // Must have 16-byte alignment for large enough objects
764 CHECK((p
% 16) == 0);
767 for (int i
= 0; i
< kNum
; i
++) {
772 static void TestMallocAlignment() {
773 for (int lg
= 0; lg
< 16; lg
++) {
774 TestAlignmentForSize((1<<lg
) - 1);
775 TestAlignmentForSize((1<<lg
) + 0);
776 TestAlignmentForSize((1<<lg
) + 1);
780 static void TestHugeThreadCache() {
781 fprintf(LOGSTREAM
, "==== Testing huge thread cache\n");
782 // More than 2^16 to cause integer overflow of 16 bit counters.
783 static const int kNum
= 70000;
784 char** array
= new char*[kNum
];
785 for (int i
= 0; i
< kNum
; ++i
) {
786 array
[i
] = new char[10];
788 for (int i
= 0; i
< kNum
; ++i
) {
796 struct RangeCallbackState
{
798 base::MallocRange::Type expected_type
;
803 static void RangeCallback(void* arg
, const base::MallocRange
* r
) {
804 RangeCallbackState
* state
= reinterpret_cast<RangeCallbackState
*>(arg
);
805 if (state
->ptr
>= r
->address
&&
806 state
->ptr
< r
->address
+ r
->length
) {
807 if (state
->expected_type
== base::MallocRange::FREE
) {
808 // We are expecting r->type == FREE, but ReleaseMemory
809 // may have already moved us to UNMAPPED state instead (this happens in
810 // approximately 0.1% of executions). Accept either state.
811 CHECK(r
->type
== base::MallocRange::FREE
||
812 r
->type
== base::MallocRange::UNMAPPED
);
814 CHECK_EQ(r
->type
, state
->expected_type
);
816 CHECK_GE(r
->length
, state
->min_size
);
817 state
->matched
= true;
821 // Check that at least one of the callbacks from Ranges() contains
822 // the specified address with the specified type, and has size
824 static void CheckRangeCallback(void* ptr
, base::MallocRange::Type type
,
826 RangeCallbackState state
;
827 state
.ptr
= reinterpret_cast<uintptr_t>(ptr
);
828 state
.expected_type
= type
;
829 state
.min_size
= min_size
;
830 state
.matched
= false;
831 MallocExtension::instance()->Ranges(&state
, RangeCallback
);
832 CHECK(state
.matched
);
837 static void TestRanges() {
838 static const int MB
= 1048576;
839 void* a
= malloc(MB
);
840 void* b
= malloc(MB
);
841 CheckRangeCallback(a
, base::MallocRange::INUSE
, MB
);
842 CheckRangeCallback(b
, base::MallocRange::INUSE
, MB
);
844 CheckRangeCallback(a
, base::MallocRange::FREE
, MB
);
845 CheckRangeCallback(b
, base::MallocRange::INUSE
, MB
);
846 MallocExtension::instance()->ReleaseFreeMemory();
847 CheckRangeCallback(a
, base::MallocRange::UNMAPPED
, MB
);
848 CheckRangeCallback(b
, base::MallocRange::INUSE
, MB
);
850 CheckRangeCallback(a
, base::MallocRange::UNMAPPED
, MB
);
851 CheckRangeCallback(b
, base::MallocRange::FREE
, MB
);
854 #ifndef DEBUGALLOCATION
855 static size_t GetUnmappedBytes() {
857 CHECK(MallocExtension::instance()->GetNumericProperty(
858 "tcmalloc.pageheap_unmapped_bytes", &bytes
));
863 static void TestReleaseToSystem() {
864 // Debug allocation mode adds overhead to each allocation which
865 // messes up all the equality tests here. I just disable the
866 // teset in this mode. TODO(csilvers): get it to work for debugalloc?
867 #ifndef DEBUGALLOCATION
868 const double old_tcmalloc_release_rate
= FLAGS_tcmalloc_release_rate
;
869 FLAGS_tcmalloc_release_rate
= 0;
871 static const int MB
= 1048576;
872 void* a
= malloc(MB
);
873 void* b
= malloc(MB
);
874 MallocExtension::instance()->ReleaseFreeMemory();
875 size_t starting_bytes
= GetUnmappedBytes();
877 // Calling ReleaseFreeMemory() a second time shouldn't do anything.
878 MallocExtension::instance()->ReleaseFreeMemory();
879 EXPECT_EQ(starting_bytes
, GetUnmappedBytes());
881 // ReleaseToSystem shouldn't do anything either.
882 MallocExtension::instance()->ReleaseToSystem(MB
);
883 EXPECT_EQ(starting_bytes
, GetUnmappedBytes());
887 // The span to release should be 1MB.
888 MallocExtension::instance()->ReleaseToSystem(MB
/2);
889 EXPECT_EQ(starting_bytes
+ MB
, GetUnmappedBytes());
891 // Should do nothing since the previous call released too much.
892 MallocExtension::instance()->ReleaseToSystem(MB
/4);
893 EXPECT_EQ(starting_bytes
+ MB
, GetUnmappedBytes());
897 // Use up the extra MB/4 bytes from 'a' and also release 'b'.
898 MallocExtension::instance()->ReleaseToSystem(MB
/2);
899 EXPECT_EQ(starting_bytes
+ 2*MB
, GetUnmappedBytes());
901 // Should do nothing since the previous call released too much.
902 MallocExtension::instance()->ReleaseToSystem(MB
/2);
903 EXPECT_EQ(starting_bytes
+ 2*MB
, GetUnmappedBytes());
905 // Nothing else to release.
906 MallocExtension::instance()->ReleaseFreeMemory();
907 EXPECT_EQ(starting_bytes
+ 2*MB
, GetUnmappedBytes());
911 EXPECT_EQ(starting_bytes
+ MB
, GetUnmappedBytes());
913 // Releasing less than a page should still trigger a release.
914 MallocExtension::instance()->ReleaseToSystem(1);
915 EXPECT_EQ(starting_bytes
+ 2*MB
, GetUnmappedBytes());
917 FLAGS_tcmalloc_release_rate
= old_tcmalloc_release_rate
;
918 #endif // #ifndef DEBUGALLOCATION
921 // On MSVC10, in release mode, the optimizer convinces itself
922 // g_no_memory is never changed (I guess it doesn't realize OnNoMemory
923 // might be called). Work around this by setting the var volatile.
924 volatile bool g_no_memory
= false;
925 std::new_handler g_old_handler
= NULL
;
926 static void OnNoMemory() {
928 std::set_new_handler(g_old_handler
);
931 static void TestSetNewMode() {
932 int old_mode
= tc_set_new_mode(1);
934 g_old_handler
= std::set_new_handler(&OnNoMemory
);
936 void* ret
= malloc(kTooBig
);
937 EXPECT_EQ(NULL
, ret
);
938 EXPECT_TRUE(g_no_memory
);
940 g_old_handler
= std::set_new_handler(&OnNoMemory
);
942 ret
= calloc(1, kTooBig
);
943 EXPECT_EQ(NULL
, ret
);
944 EXPECT_TRUE(g_no_memory
);
946 g_old_handler
= std::set_new_handler(&OnNoMemory
);
948 ret
= realloc(NULL
, kTooBig
);
949 EXPECT_EQ(NULL
, ret
);
950 EXPECT_TRUE(g_no_memory
);
952 if (kOSSupportsMemalign
) {
953 // Not really important, but must be small enough such that
954 // kAlignment + kTooBig does not overflow.
955 const int kAlignment
= 1 << 5;
957 g_old_handler
= std::set_new_handler(&OnNoMemory
);
959 ret
= Memalign(kAlignment
, kTooBig
);
960 EXPECT_EQ(NULL
, ret
);
961 EXPECT_TRUE(g_no_memory
);
963 g_old_handler
= std::set_new_handler(&OnNoMemory
);
966 PosixMemalign(&ret
, kAlignment
, kTooBig
));
967 EXPECT_EQ(NULL
, ret
);
968 EXPECT_TRUE(g_no_memory
);
971 tc_set_new_mode(old_mode
);
974 static int RunAllTests(int argc
, char** argv
) {
975 // Optional argv[1] is the seed
976 AllocatorState
rnd(argc
> 1 ? atoi(argv
[1]) : 100);
978 SetTestResourceLimit();
980 // TODO(odo): This test has been disabled because it is only by luck that it
981 // does not result in fragmentation. When tcmalloc makes an allocation which
982 // spans previously unused leaves of the pagemap it will allocate and fill in
983 // the leaves to cover the new allocation. The leaves happen to be 256MiB in
984 // the 64-bit build, and with the sbrk allocator these allocations just
985 // happen to fit in one leaf by luck. With other allocators (mmap,
986 // memfs_malloc when used with small pages) the allocations generally span
987 // two leaves and this results in a very bad fragmentation pattern with this
988 // code. The same failure can be forced with the sbrk allocator just by
989 // allocating something on the order of 128MiB prior to starting this test so
990 // that the test allocations straddle a 256MiB boundary.
992 // TODO(csilvers): port MemoryUsage() over so the test can use that
994 # include <unistd.h> // for getpid()
995 // Allocate and deallocate blocks of increasing sizes to check if the alloc
996 // metadata fragments the memory. (Do not put other allocations/deallocations
997 // before this test, it may break).
999 size_t memory_usage
= MemoryUsage(getpid());
1000 fprintf(LOGSTREAM
, "Testing fragmentation\n");
1001 for ( int i
= 200; i
< 240; ++i
) {
1003 void *test1
= rnd
.alloc(size
);
1005 for ( int j
= 0; j
< size
; j
+= (1 << 12) ) {
1006 static_cast<char*>(test1
)[j
] = 1;
1010 // There may still be a bit of fragmentation at the beginning, until we
1011 // reach kPageMapBigAllocationThreshold bytes so we check for
1012 // 200 + 240 + margin.
1013 CHECK_LT(MemoryUsage(getpid()), memory_usage
+ (450 << 20) );
1017 // Check that empty allocation works
1018 fprintf(LOGSTREAM
, "Testing empty allocation\n");
1020 void* p1
= rnd
.alloc(0);
1022 void* p2
= rnd
.alloc(0);
1029 // This code stresses some of the memory allocation via STL.
1030 // It may call operator delete(void*, nothrow_t).
1031 fprintf(LOGSTREAM
, "Testing STL use\n");
1038 std::stable_sort(v
.begin(), v
.end());
1041 // Test each of the memory-allocation functions once, just as a sanity-check
1042 fprintf(LOGSTREAM
, "Sanity-testing all the memory allocation functions\n");
1044 // We use new-hook and delete-hook to verify we actually called the
1045 // tcmalloc version of these routines, and not the libc version.
1046 SetNewHook(); // defined as part of MAKE_HOOK_CALLBACK, above
1047 SetDeleteHook(); // ditto
1049 void* p1
= malloc(10);
1050 CHECK(p1
!= NULL
); // force use of this variable
1051 VerifyNewHookWasCalled();
1052 // Also test the non-standard tc_malloc_size
1053 size_t actual_p1_size
= tc_malloc_size(p1
);
1054 CHECK_GE(actual_p1_size
, 10);
1055 CHECK_LT(actual_p1_size
, 100000); // a reasonable upper-bound, I think
1057 VerifyDeleteHookWasCalled();
1062 VerifyNewHookWasCalled();
1063 // We make sure we realloc to a big size, since some systems (OS
1064 // X) will notice if the realloced size continues to fit into the
1065 // malloc-block and make this a noop if so.
1066 p1
= realloc(p1
, 30000);
1068 VerifyNewHookWasCalled();
1069 VerifyDeleteHookWasCalled();
1070 cfree(p1
); // synonym for free
1071 VerifyDeleteHookWasCalled();
1073 if (kOSSupportsMemalign
) {
1074 CHECK_EQ(PosixMemalign(&p1
, sizeof(p1
), 40), 0);
1076 VerifyNewHookWasCalled();
1078 VerifyDeleteHookWasCalled();
1080 p1
= Memalign(sizeof(p1
) * 2, 50);
1082 VerifyNewHookWasCalled();
1084 VerifyDeleteHookWasCalled();
1087 // Windows has _aligned_malloc. Let's test that that's captured too.
1088 #if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(PERFTOOLS_NO_ALIGNED_MALLOC)
1089 p1
= _aligned_malloc(sizeof(p1
) * 2, 64);
1091 VerifyNewHookWasCalled();
1093 VerifyDeleteHookWasCalled();
1098 VerifyNewHookWasCalled();
1100 VerifyDeleteHookWasCalled();
1104 VerifyNewHookWasCalled();
1106 VerifyDeleteHookWasCalled();
1108 char* p2
= new char;
1110 VerifyNewHookWasCalled();
1112 VerifyDeleteHookWasCalled();
1116 VerifyNewHookWasCalled();
1118 VerifyDeleteHookWasCalled();
1120 p2
= new(std::nothrow
) char;
1122 VerifyNewHookWasCalled();
1124 VerifyDeleteHookWasCalled();
1126 p2
= new(std::nothrow
) char[100];
1128 VerifyNewHookWasCalled();
1130 VerifyDeleteHookWasCalled();
1132 // Another way of calling operator new
1133 p2
= static_cast<char*>(::operator new(100));
1135 VerifyNewHookWasCalled();
1136 ::operator delete(p2
);
1137 VerifyDeleteHookWasCalled();
1139 // Try to call nothrow's delete too. Compilers use this.
1140 p2
= static_cast<char*>(::operator new(100, std::nothrow
));
1142 VerifyNewHookWasCalled();
1143 ::operator delete(p2
, std::nothrow
);
1144 VerifyDeleteHookWasCalled();
1146 // Try strdup(), which the system allocates but we must free. If
1147 // all goes well, libc will use our malloc!
1148 p2
= strdup("test");
1150 VerifyNewHookWasCalled();
1152 VerifyDeleteHookWasCalled();
1155 // Test mmap too: both anonymous mmap and mmap of a file
1156 // Note that for right now we only override mmap on linux
1157 // systems, so those are the only ones for which we check.
1161 #if defined(HAVE_MMAP) && defined(__linux) && \
1162 (defined(__i386__) || defined(__x86_64__))
1164 p1
= mmap(NULL
, size
, PROT_WRITE
|PROT_READ
, MAP_ANONYMOUS
|MAP_PRIVATE
,
1167 VerifyMmapHookWasCalled();
1168 p1
= mremap(p1
, size
, size
/2, 0);
1170 VerifyMremapHookWasCalled();
1173 VerifyMunmapHookWasCalled();
1175 int fd
= open("/dev/zero", O_RDONLY
);
1176 CHECK_GE(fd
, 0); // make sure the open succeeded
1177 p1
= mmap(NULL
, 8192, PROT_READ
, MAP_SHARED
, fd
, 0);
1179 VerifyMmapHookWasCalled();
1181 VerifyMunmapHookWasCalled();
1183 #else // this is just to quiet the compiler: make sure all fns are called
1184 IncrementCallsToMmapHook();
1185 IncrementCallsToMunmapHook();
1186 IncrementCallsToMremapHook();
1187 VerifyMmapHookWasCalled();
1188 VerifyMremapHookWasCalled();
1189 VerifyMunmapHookWasCalled();
1194 #if defined(HAVE_SBRK) && defined(__linux) && \
1195 (defined(__i386__) || defined(__x86_64__))
1198 VerifySbrkHookWasCalled();
1201 VerifySbrkHookWasCalled();
1202 // However, sbrk hook should *not* be called with sbrk(0)
1205 CHECK_EQ(g_SbrkHook_calls
, 0);
1206 #else // this is just to quiet the compiler: make sure all fns are called
1207 IncrementCallsToSbrkHook();
1208 VerifySbrkHookWasCalled();
1211 // Reset the hooks to what they used to be. These are all
1212 // defined as part of MAKE_HOOK_CALLBACK, above.
1221 // Check that "lots" of memory can be allocated
1222 fprintf(LOGSTREAM
, "Testing large allocation\n");
1224 const int mb_to_allocate
= 100;
1225 void* p
= rnd
.alloc(mb_to_allocate
<< 20);
1226 CHECK(p
!= NULL
); // could not allocate
1230 TestMallocAlignment();
1232 // Check calloc() with various arguments
1233 fprintf(LOGSTREAM
, "Testing calloc\n");
1234 TestCalloc(0, 0, true);
1235 TestCalloc(0, 1, true);
1236 TestCalloc(1, 1, true);
1237 TestCalloc(1<<10, 0, true);
1238 TestCalloc(1<<20, 0, true);
1239 TestCalloc(0, 1<<10, true);
1240 TestCalloc(0, 1<<20, true);
1241 TestCalloc(1<<20, 2, true);
1242 TestCalloc(2, 1<<20, true);
1243 TestCalloc(1000, 1000, true);
1245 TestCalloc(kMaxSize
, 2, false);
1246 TestCalloc(2, kMaxSize
, false);
1247 TestCalloc(kMaxSize
, kMaxSize
, false);
1249 TestCalloc(kMaxSignedSize
, 3, false);
1250 TestCalloc(3, kMaxSignedSize
, false);
1251 TestCalloc(kMaxSignedSize
, kMaxSignedSize
, false);
1253 // Test that realloc doesn't always reallocate and copy memory.
1254 fprintf(LOGSTREAM
, "Testing realloc\n");
1257 fprintf(LOGSTREAM
, "Testing operator new(nothrow).\n");
1258 TestNothrowNew(&::operator new);
1259 fprintf(LOGSTREAM
, "Testing operator new[](nothrow).\n");
1260 TestNothrowNew(&::operator new[]);
1261 fprintf(LOGSTREAM
, "Testing operator new.\n");
1262 TestNew(&::operator new);
1263 fprintf(LOGSTREAM
, "Testing operator new[].\n");
1264 TestNew(&::operator new[]);
1267 fprintf(LOGSTREAM
, "Testing threaded allocation/deallocation (%d threads)\n",
1269 threads
= new TesterThread
*[FLAGS_numthreads
];
1270 for (int i
= 0; i
< FLAGS_numthreads
; ++i
) {
1271 threads
[i
] = new TesterThread(i
);
1274 // This runs all the tests at the same time, with a 1M stack size each
1275 RunManyThreadsWithId(RunThread
, FLAGS_numthreads
, 1<<20);
1277 for (int i
= 0; i
< FLAGS_numthreads
; ++i
) delete threads
[i
]; // Cleanup
1279 // Do the memory intensive tests after threads are done, since exhausting
1280 // the available address space can make pthread_create to fail.
1282 // Check that huge allocations fail with NULL instead of crashing
1283 fprintf(LOGSTREAM
, "Testing huge allocations\n");
1284 TestHugeAllocations(&rnd
);
1286 // Check that large allocations fail with NULL instead of crashing
1287 #ifndef DEBUGALLOCATION // debug allocation takes forever for huge allocs
1288 fprintf(LOGSTREAM
, "Testing out of memory\n");
1289 for (int s
= 0; ; s
+= (10<<20)) {
1290 void* large_object
= rnd
.alloc(s
);
1291 if (large_object
== NULL
) break;
1296 TestHugeThreadCache();
1298 TestReleaseToSystem();
1306 using testing::RunAllTests
;
1308 int main(int argc
, char** argv
) {
1309 #ifdef DEBUGALLOCATION // debug allocation takes forever for huge allocs
1310 FLAGS_max_free_queue_size
= 0; // return freed blocks to tcmalloc immediately
1313 RunAllTests(argc
, argv
);
1315 // Test tc_version()
1316 fprintf(LOGSTREAM
, "Testing tc_version()\n");
1321 const char* human_version
= tc_version(&major
, &minor
, &patch
);
1322 snprintf(mmp
, sizeof(mmp
), "%d.%d%s", major
, minor
, patch
);
1323 CHECK(!strcmp(PACKAGE_STRING
, human_version
));
1324 CHECK(!strcmp(PACKAGE_VERSION
, mmp
));
1326 fprintf(LOGSTREAM
, "PASS\n");