Home | History | Annotate | Download | only in tests
      1 // Copyright (c) 2005, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      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
     13 // distribution.
     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.
     17 //
     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.
     29 
     30 // ---
     31 // Unittest for the TCMalloc implementation.
     32 //
     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
     39 //   data corruption.
     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
     43 //        its contents.
     44 //     c. Pass the object to another thread
     45 //     d. Free an object
     46 //   Also, at the end of every step, object(s) are freed to maintain
     47 //   the memory upper-bound.
     48 //
     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
     54 // care about).
     55 
     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.
     64 #ifdef HAVE_UNISTD_H
     65 #include <unistd.h>        // for testing sbrk hooks
     66 #endif
     67 #include "tcmalloc.h"      // must come early, to pick up posix_memalign
     68 #include <stdlib.h>
     69 #include <string.h>
     70 #include <stdio.h>
     71 #if defined HAVE_STDINT_H
     72 #include <stdint.h>        // for intptr_t
     73 #endif
     74 #include <sys/types.h>     // for size_t
     75 #ifdef HAVE_FCNTL_H
     76 #include <fcntl.h>         // for open; used with mmap-hook test
     77 #endif
     78 #ifdef HAVE_MMAP
     79 #include <sys/mman.h>      // for testing mmap hooks
     80 #endif
     81 #ifdef HAVE_MALLOC_H
     82 #include <malloc.h>        // defines pvalloc/etc on cygwin
     83 #endif
     84 #include <assert.h>
     85 #include <vector>
     86 #include <algorithm>
     87 #include <string>
     88 #include <new>
     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"
     96 
     97 // Windows doesn't define pvalloc and a few other obsolete unix
     98 // functions; nor does it define posix_memalign (which is not obsolete).
     99 #if defined(_WIN32)
    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";
    109   exit(1);
    110   return NULL;
    111 }
    112 static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
    113   //LOG(FATAL) << "posix_memalign not supported on windows";
    114   exit(1);
    115   return -1;
    116 }
    117 
    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";
    124   exit(1);
    125   return NULL;
    126 }
    127 static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
    128   //LOG(FATAL) << "posix_memalign not supported on OS X";
    129   exit(1);
    130   return -1;
    131 }
    132 
    133 #else
    134 static bool kOSSupportsMemalign = true;
    135 static inline void* Memalign(size_t align, size_t size) {
    136   return memalign(align, size);
    137 }
    138 static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
    139   return posix_memalign(ptr, align, size);
    140 }
    141 
    142 #endif
    143 
    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
    148 #endif
    149 
    150 #define LOGSTREAM   stdout
    151 
    152 using std::vector;
    153 using std::string;
    154 
    155 DECLARE_double(tcmalloc_release_rate);
    156 DECLARE_int32(max_free_queue_size);     // in debugallocation.cc
    157 DECLARE_int64(tcmalloc_sample_parameter);
    158 
    159 namespace testing {
    160 
    161 static const int FLAGS_numtests = 50000;
    162 static const int FLAGS_log_every_n_tests = 50000; // log exactly once
    163 
    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
    169 
    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
    173 
    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
    179 
    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);
    183 
    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
    189 // not *too* big.
    190 static const size_t kTooBig = kMaxSize - 100000;
    191 
    192 static int news_handled = 0;
    193 
    194 // Global array of threads
    195 class TesterThread;
    196 static TesterThread** threads;
    197 
    198 // To help with generating random numbers
    199 class TestHarness {
    200  private:
    201   // Information kept per type
    202   struct Type {
    203     string      name;
    204     int         type;
    205     int         weight;
    206   };
    207 
    208  public:
    209   TestHarness(int seed)
    210       : types_(new vector<Type>), total_weight_(0), num_tests_(0) {
    211     srandom(seed);
    212   }
    213   ~TestHarness() {
    214     delete types_;
    215   }
    216 
    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.
    220   //
    221   // "type" must be non-negative.
    222   // "weight" must be non-negative.
    223   void AddType(int type, int weight, const char* name);
    224 
    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.
    228   int PickType();
    229 
    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)
    232   int Uniform(int n) {
    233     if (n == 0) {
    234       return random() * 0;
    235     } else {
    236       return random() % n;
    237     }
    238   }
    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);
    245   }
    246 
    247  private:
    248   vector<Type>*         types_;         // Registered types
    249   int                   total_weight_;  // Total weight of all types
    250   int                   num_tests_;     // Num tests run so far
    251 };
    252 
    253 void TestHarness::AddType(int type, int weight, const char* name) {
    254   Type t;
    255   t.name = name;
    256   t.type = type;
    257   t.weight = weight;
    258   types_->push_back(t);
    259   total_weight_ += weight;
    260 }
    261 
    262 int TestHarness::PickType() {
    263   if (num_tests_ >= FLAGS_numtests) return -1;
    264   num_tests_++;
    265 
    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_);
    269   int i;
    270   for (i = 0; i < types_->size(); i++) {
    271     v -= (*types_)[i].weight;
    272     if (v < 0) {
    273       break;
    274     }
    275   }
    276 
    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());
    281   }
    282   return (*types_)[i].type;
    283 }
    284 
    285 class AllocatorState : public TestHarness {
    286  public:
    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;
    294       CHECK_GE(delta, 0);
    295       memalign_fraction_ = (Uniform(10000)/10000.0 * delta +
    296                             FLAGS_memalign_min_fraction);
    297       //fprintf(LOGSTREAM, "memalign fraction: %f\n", memalign_fraction_);
    298     }
    299   }
    300   virtual ~AllocatorState() {}
    301 
    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);
    313           if (err != 0) {
    314             CHECK_EQ(err, ENOMEM);
    315           }
    316           return err == 0 ? result : NULL;
    317         }
    318       }
    319     }
    320     return malloc(size);
    321   }
    322 
    323  private:
    324   double memalign_fraction_;
    325 };
    326 
    327 
    328 // Info kept per thread
    329 class TesterThread {
    330  private:
    331   // Info kept per allocated object
    332   struct Object {
    333     char*       ptr;                    // Allocated pointer
    334     int         size;                   // Allocated size
    335     int         generation;             // Generation counter of object contents
    336   };
    337 
    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
    346 
    347   // Type of operations
    348   enum Type { ALLOC, FREE, UPDATE, PASS };
    349 
    350   // ACM minimal standard random number generator.  (re-entrant.)
    351   class ACMRandom {
    352     int32 seed_;
    353    public:
    354     explicit ACMRandom(int32 seed) { seed_ = seed; }
    355     int32 Next() {
    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;
    362       if (lo > M) {
    363         lo &= M;
    364         ++lo;
    365       }
    366       lo += hi >> 15;
    367       if (lo > M) {
    368         lo &= M;
    369         ++lo;
    370       }
    371       return (seed_ = (int32) lo);
    372     }
    373   };
    374 
    375  public:
    376   TesterThread(int id)
    377     : id_(id),
    378       rnd_(id+1),
    379       heap_size_(0),
    380       locks_ok_(0),
    381       locks_failed_(0) {
    382   }
    383 
    384   virtual ~TesterThread() {
    385     if (FLAGS_verbose)
    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);
    390     }
    391   }
    392 
    393   virtual void Run() {
    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");
    398 
    399     while (true) {
    400       AcquirePassedObjects();
    401 
    402       switch (rnd_.PickType()) {
    403         case ALLOC:   AllocateObject(); break;
    404         case FREE:    FreeObject();     break;
    405         case UPDATE:  UpdateObject();   break;
    406         case PASS:    PassObject();     break;
    407         case -1:      goto done;
    408         default:      assert(NULL == "Unknown type");
    409       }
    410 
    411       ShrinkHeap();
    412     }
    413 
    414  done:
    415     DeleteHeap();
    416   }
    417 
    418   // Allocate a new object
    419   void AllocateObject() {
    420     Object object;
    421     object.size = rnd_.Skewed(FLAGS_lgmaxsize);
    422     object.ptr = static_cast<char*>(rnd_.alloc(object.size));
    423     CHECK(object.ptr);
    424     object.generation = 0;
    425     FillContents(&object);
    426     heap_.push_back(object);
    427     heap_size_ += object.size;
    428   }
    429 
    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]);
    437   }
    438 
    439   // Free a random object
    440   void FreeObject() {
    441     if (heap_.empty()) return;
    442     const int index = rnd_.Uniform(heap_.size());
    443     Object object = heap_[index];
    444     CheckContents(object);
    445     free(object.ptr);
    446     heap_size_ -= object.size;
    447     heap_[index] = heap_[heap_.size()-1];
    448     heap_.pop_back();
    449   }
    450 
    451   // Delete all objects in the heap
    452   void DeleteHeap() {
    453     while (!heap_.empty()) {
    454       FreeObject();
    455     }
    456   }
    457 
    458   // Free objects until our heap is small enough
    459   void ShrinkHeap() {
    460     while (heap_size_ > FLAGS_threadmb << 20) {
    461       assert(!heap_.empty());
    462       FreeObject();
    463     }
    464   }
    465 
    466   // Pass a random object to another thread
    467   void PassObject() {
    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);
    473 
    474     // Pick thread to pass
    475     const int tid = rnd_.Uniform(FLAGS_numthreads);
    476     TesterThread* thread = threads[tid];
    477 
    478     if (thread->lock_.TryLock()) {
    479       // Pass the object
    480       locks_ok_++;
    481       thread->passed_.push_back(object);
    482       thread->lock_.Unlock();
    483       heap_size_ -= object.size;
    484       heap_[index] = heap_[heap_.size()-1];
    485       heap_.pop_back();
    486     } else {
    487       locks_failed_++;
    488     }
    489   }
    490 
    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.
    496     vector<Object> copy;
    497     { // Locking scope
    498       if (!lock_.TryLock()) {
    499         locks_failed_++;
    500         return;
    501       }
    502       locks_ok_++;
    503       swap(copy, passed_);
    504       lock_.Unlock();
    505     }
    506 
    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;
    512     }
    513   }
    514 
    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) {
    519       r.Next();
    520     }
    521     const char c = static_cast<char>(r.Next());
    522     memset(object->ptr, c, object->size);
    523   }
    524 
    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) {
    529       r.Next();
    530     }
    531 
    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);
    538     }
    539     for (int i = start2; i < object.size; ++i) {
    540       CHECK_EQ(object.ptr[i], expected);
    541     }
    542   }
    543 };
    544 
    545 static void RunThread(int thread_id) {
    546   threads[thread_id]->Run();
    547 }
    548 
    549 static void TryHugeAllocation(size_t s, AllocatorState* rnd) {
    550   void* p = rnd->alloc(s);
    551   CHECK(p == NULL);   // huge allocation s should fail!
    552 }
    553 
    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);
    559   }
    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++) {
    564     void* p = NULL;
    565     p = rnd->alloc(kMaxSignedSize + i);
    566     if (p) free(p);    // if: free(NULL) is not necessarily defined
    567     p = rnd->alloc(kMaxSignedSize - i);
    568     if (p) free(p);
    569   }
    570 #endif
    571 
    572   // Check that ReleaseFreeMemory has no visible effect (aka, does not
    573   // crash the test):
    574   MallocExtension* inst = MallocExtension::instance();
    575   CHECK(inst);
    576   inst->ReleaseFreeMemory();
    577 }
    578 
    579 static void TestCalloc(size_t n, size_t s, bool ok) {
    580   char* p = reinterpret_cast<char*>(calloc(n, s));
    581   if (FLAGS_verbose)
    582     fprintf(LOGSTREAM, "calloc(%"PRIxS", %"PRIxS"): %p\n", n, s, p);
    583   if (!ok) {
    584     CHECK(p == NULL);  // calloc(n, s) should not succeed
    585   } else {
    586     CHECK(p != NULL);  // calloc(n, s) should succeed
    587     for (int i = 0; i < n*s; i++) {
    588       CHECK(p[i] == '\0');
    589     }
    590     free(p);
    591   }
    592 }
    593 
    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
    604 
    605   int start_sizes[] = { 100, 1000, 10000, 100000 };
    606   int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 };
    607 
    608   for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) {
    609     void* p = malloc(start_sizes[s]);
    610     CHECK(p);
    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
    615     }
    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
    620     }
    621     free(p);
    622   }
    623   FLAGS_tcmalloc_sample_parameter = old_sample_parameter;
    624 #endif
    625 }
    626 
    627 static void TestNewHandler() throw (std::bad_alloc) {
    628   ++news_handled;
    629   throw std::bad_alloc();
    630 }
    631 
    632 static void TestOneNew(void* (*func)(size_t)) {
    633   // success test
    634   try {
    635     void* ptr = (*func)(kNotTooBig);
    636     if (0 == ptr) {
    637       fprintf(LOGSTREAM, "allocation should not have failed.\n");
    638       abort();
    639     }
    640   } catch (...) {
    641     fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
    642     abort();
    643   }
    644 
    645   // failure test
    646   // we should always receive a bad_alloc exception
    647   try {
    648     (*func)(kTooBig);
    649     fprintf(LOGSTREAM, "allocation should have failed.\n");
    650     abort();
    651   } catch (const std::bad_alloc&) {
    652     // correct
    653   } catch (...) {
    654     fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
    655     abort();
    656   }
    657 }
    658 
    659 static void TestNew(void* (*func)(size_t)) {
    660   news_handled = 0;
    661 
    662   // test without new_handler:
    663   std::new_handler saved_handler = std::set_new_handler(0);
    664   TestOneNew(func);
    665 
    666   // test with new_handler:
    667   std::set_new_handler(TestNewHandler);
    668   TestOneNew(func);
    669   if (news_handled != 1) {
    670     fprintf(LOGSTREAM, "new_handler was not called.\n");
    671     abort();
    672   }
    673   std::set_new_handler(saved_handler);
    674 }
    675 
    676 static void TestOneNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {
    677   // success test
    678   try {
    679     void* ptr = (*func)(kNotTooBig, std::nothrow);
    680     if (0 == ptr) {
    681       fprintf(LOGSTREAM, "allocation should not have failed.\n");
    682       abort();
    683     }
    684   } catch (...) {
    685     fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
    686     abort();
    687   }
    688 
    689   // failure test
    690   // we should always receive a bad_alloc exception
    691   try {
    692     if ((*func)(kTooBig, std::nothrow) != 0) {
    693       fprintf(LOGSTREAM, "allocation should have failed.\n");
    694       abort();
    695     }
    696   } catch (...) {
    697     fprintf(LOGSTREAM, "nothrow allocation threw unexpected exception.\n");
    698     abort();
    699   }
    700 }
    701 
    702 static void TestNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {
    703   news_handled = 0;
    704 
    705   // test without new_handler:
    706   std::new_handler saved_handler = std::set_new_handler(0);
    707   TestOneNothrowNew(func);
    708 
    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");
    714     abort();
    715   }
    716   std::set_new_handler(saved_handler);
    717 }
    718 
    719 
    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
    725 // the hook takes.
    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++;                                            \
    730   }                                                                     \
    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 */               \
    734   }                                                                     \
    735   static void Set##hook_type() {                                        \
    736     CHECK(MallocHook::Add##hook_type(                                   \
    737         (MallocHook::hook_type)&IncrementCallsTo##hook_type));          \
    738   }                                                                     \
    739   static void Reset##hook_type() {                                      \
    740     CHECK(MallocHook::Remove##hook_type(                                \
    741         (MallocHook::hook_type)&IncrementCallsTo##hook_type));          \
    742   }
    743 
    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);
    751 
    752 static void TestAlignmentForSize(int size) {
    753   fprintf(LOGSTREAM, "Testing alignment of malloc(%d)\n", size);
    754   static const int kNum = 100;
    755   void* ptrs[kNum];
    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);
    761 
    762     // Must have 16-byte alignment for large enough objects
    763     if (size >= 16) {
    764       CHECK((p % 16) == 0);
    765     }
    766   }
    767   for (int i = 0; i < kNum; i++) {
    768     free(ptrs[i]);
    769   }
    770 }
    771 
    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);
    777   }
    778 }
    779 
    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];
    787   }
    788   for (int i = 0; i < kNum; ++i) {
    789     delete[] array[i];
    790   }
    791   delete[] array;
    792 }
    793 
    794 namespace {
    795 
    796 struct RangeCallbackState {
    797   uintptr_t ptr;
    798   base::MallocRange::Type expected_type;
    799   size_t min_size;
    800   bool matched;
    801 };
    802 
    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);
    813     } else {
    814       CHECK_EQ(r->type, state->expected_type);
    815     }
    816     CHECK_GE(r->length, state->min_size);
    817     state->matched = true;
    818   }
    819 }
    820 
    821 // Check that at least one of the callbacks from Ranges() contains
    822 // the specified address with the specified type, and has size
    823 // >= min_size.
    824 static void CheckRangeCallback(void* ptr, base::MallocRange::Type type,
    825                                size_t min_size) {
    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);
    833 }
    834 
    835 }
    836 
    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);
    843   free(a);
    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);
    849   free(b);
    850   CheckRangeCallback(a, base::MallocRange::UNMAPPED, MB);
    851   CheckRangeCallback(b, base::MallocRange::FREE, MB);
    852 }
    853 
    854 #ifndef DEBUGALLOCATION
    855 static size_t GetUnmappedBytes() {
    856   size_t bytes;
    857   CHECK(MallocExtension::instance()->GetNumericProperty(
    858       "tcmalloc.pageheap_unmapped_bytes", &bytes));
    859   return bytes;
    860 }
    861 #endif
    862 
    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;
    870 
    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();
    876 
    877   // Calling ReleaseFreeMemory() a second time shouldn't do anything.
    878   MallocExtension::instance()->ReleaseFreeMemory();
    879   EXPECT_EQ(starting_bytes, GetUnmappedBytes());
    880 
    881   // ReleaseToSystem shouldn't do anything either.
    882   MallocExtension::instance()->ReleaseToSystem(MB);
    883   EXPECT_EQ(starting_bytes, GetUnmappedBytes());
    884 
    885   free(a);
    886 
    887   // The span to release should be 1MB.
    888   MallocExtension::instance()->ReleaseToSystem(MB/2);
    889   EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
    890 
    891   // Should do nothing since the previous call released too much.
    892   MallocExtension::instance()->ReleaseToSystem(MB/4);
    893   EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
    894 
    895   free(b);
    896 
    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());
    900 
    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());
    904 
    905   // Nothing else to release.
    906   MallocExtension::instance()->ReleaseFreeMemory();
    907   EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
    908 
    909   a = malloc(MB);
    910   free(a);
    911   EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
    912 
    913   // Releasing less than a page should still trigger a release.
    914   MallocExtension::instance()->ReleaseToSystem(1);
    915   EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
    916 
    917   FLAGS_tcmalloc_release_rate = old_tcmalloc_release_rate;
    918 #endif   // #ifndef DEBUGALLOCATION
    919 }
    920 
    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() {
    927   g_no_memory = true;
    928   std::set_new_handler(g_old_handler);
    929 }
    930 
    931 static void TestSetNewMode() {
    932   int old_mode = tc_set_new_mode(1);
    933 
    934   g_old_handler = std::set_new_handler(&OnNoMemory);
    935   g_no_memory = false;
    936   void* ret = malloc(kTooBig);
    937   EXPECT_EQ(NULL, ret);
    938   EXPECT_TRUE(g_no_memory);
    939 
    940   g_old_handler = std::set_new_handler(&OnNoMemory);
    941   g_no_memory = false;
    942   ret = calloc(1, kTooBig);
    943   EXPECT_EQ(NULL, ret);
    944   EXPECT_TRUE(g_no_memory);
    945 
    946   g_old_handler = std::set_new_handler(&OnNoMemory);
    947   g_no_memory = false;
    948   ret = realloc(NULL, kTooBig);
    949   EXPECT_EQ(NULL, ret);
    950   EXPECT_TRUE(g_no_memory);
    951 
    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;
    956 
    957     g_old_handler = std::set_new_handler(&OnNoMemory);
    958     g_no_memory = false;
    959     ret = Memalign(kAlignment, kTooBig);
    960     EXPECT_EQ(NULL, ret);
    961     EXPECT_TRUE(g_no_memory);
    962 
    963     g_old_handler = std::set_new_handler(&OnNoMemory);
    964     g_no_memory = false;
    965     EXPECT_EQ(ENOMEM,
    966               PosixMemalign(&ret, kAlignment, kTooBig));
    967     EXPECT_EQ(NULL, ret);
    968     EXPECT_TRUE(g_no_memory);
    969   }
    970 
    971   tc_set_new_mode(old_mode);
    972 }
    973 
    974 static int RunAllTests(int argc, char** argv) {
    975   // Optional argv[1] is the seed
    976   AllocatorState rnd(argc > 1 ? atoi(argv[1]) : 100);
    977 
    978   SetTestResourceLimit();
    979 
    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.
    991 
    992   // TODO(csilvers): port MemoryUsage() over so the test can use that
    993 #if 0
    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).
    998   {
    999     size_t memory_usage = MemoryUsage(getpid());
   1000     fprintf(LOGSTREAM, "Testing fragmentation\n");
   1001     for ( int i = 200; i < 240; ++i ) {
   1002       int size = i << 20;
   1003       void *test1 = rnd.alloc(size);
   1004       CHECK(test1);
   1005       for ( int j = 0; j < size; j += (1 << 12) ) {
   1006         static_cast<char*>(test1)[j] = 1;
   1007       }
   1008       free(test1);
   1009     }
   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) );
   1014   }
   1015 #endif
   1016 
   1017   // Check that empty allocation works
   1018   fprintf(LOGSTREAM, "Testing empty allocation\n");
   1019   {
   1020     void* p1 = rnd.alloc(0);
   1021     CHECK(p1 != NULL);
   1022     void* p2 = rnd.alloc(0);
   1023     CHECK(p2 != NULL);
   1024     CHECK(p1 != p2);
   1025     free(p1);
   1026     free(p2);
   1027   }
   1028 
   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");
   1032   {
   1033     std::vector<int> v;
   1034     v.push_back(1);
   1035     v.push_back(2);
   1036     v.push_back(3);
   1037     v.push_back(0);
   1038     std::stable_sort(v.begin(), v.end());
   1039   }
   1040 
   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");
   1043   {
   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
   1048 
   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
   1056     free(p1);
   1057     VerifyDeleteHookWasCalled();
   1058 
   1059 
   1060     p1 = calloc(10, 2);
   1061     CHECK(p1 != NULL);
   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);
   1067     CHECK(p1 != NULL);
   1068     VerifyNewHookWasCalled();
   1069     VerifyDeleteHookWasCalled();
   1070     cfree(p1);  // synonym for free
   1071     VerifyDeleteHookWasCalled();
   1072 
   1073     if (kOSSupportsMemalign) {
   1074       CHECK_EQ(PosixMemalign(&p1, sizeof(p1), 40), 0);
   1075       CHECK(p1 != NULL);
   1076       VerifyNewHookWasCalled();
   1077       free(p1);
   1078       VerifyDeleteHookWasCalled();
   1079 
   1080       p1 = Memalign(sizeof(p1) * 2, 50);
   1081       CHECK(p1 != NULL);
   1082       VerifyNewHookWasCalled();
   1083       free(p1);
   1084       VerifyDeleteHookWasCalled();
   1085     }
   1086 
   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);
   1090     CHECK(p1 != NULL);
   1091     VerifyNewHookWasCalled();
   1092     _aligned_free(p1);
   1093     VerifyDeleteHookWasCalled();
   1094 #endif
   1095 
   1096     p1 = valloc(60);
   1097     CHECK(p1 != NULL);
   1098     VerifyNewHookWasCalled();
   1099     free(p1);
   1100     VerifyDeleteHookWasCalled();
   1101 
   1102     p1 = pvalloc(70);
   1103     CHECK(p1 != NULL);
   1104     VerifyNewHookWasCalled();
   1105     free(p1);
   1106     VerifyDeleteHookWasCalled();
   1107 
   1108     char* p2 = new char;
   1109     CHECK(p2 != NULL);
   1110     VerifyNewHookWasCalled();
   1111     delete p2;
   1112     VerifyDeleteHookWasCalled();
   1113 
   1114     p2 = new char[100];
   1115     CHECK(p2 != NULL);
   1116     VerifyNewHookWasCalled();
   1117     delete[] p2;
   1118     VerifyDeleteHookWasCalled();
   1119 
   1120     p2 = new(std::nothrow) char;
   1121     CHECK(p2 != NULL);
   1122     VerifyNewHookWasCalled();
   1123     delete p2;
   1124     VerifyDeleteHookWasCalled();
   1125 
   1126     p2 = new(std::nothrow) char[100];
   1127     CHECK(p2 != NULL);
   1128     VerifyNewHookWasCalled();
   1129     delete[] p2;
   1130     VerifyDeleteHookWasCalled();
   1131 
   1132     // Another way of calling operator new
   1133     p2 = static_cast<char*>(::operator new(100));
   1134     CHECK(p2 != NULL);
   1135     VerifyNewHookWasCalled();
   1136     ::operator delete(p2);
   1137     VerifyDeleteHookWasCalled();
   1138 
   1139     // Try to call nothrow's delete too.  Compilers use this.
   1140     p2 = static_cast<char*>(::operator new(100, std::nothrow));
   1141     CHECK(p2 != NULL);
   1142     VerifyNewHookWasCalled();
   1143     ::operator delete(p2, std::nothrow);
   1144     VerifyDeleteHookWasCalled();
   1145 
   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");
   1149     CHECK(p2 != NULL);
   1150     VerifyNewHookWasCalled();
   1151     free(p2);
   1152     VerifyDeleteHookWasCalled();
   1153 
   1154 
   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.
   1158     SetMmapHook();
   1159     SetMremapHook();
   1160     SetMunmapHook();
   1161 #if defined(HAVE_MMAP) && defined(__linux) && \
   1162        (defined(__i386__) || defined(__x86_64__))
   1163     int size = 8192*2;
   1164     p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE,
   1165               -1, 0);
   1166     CHECK(p1 != NULL);
   1167     VerifyMmapHookWasCalled();
   1168     p1 = mremap(p1, size, size/2, 0);
   1169     CHECK(p1 != NULL);
   1170     VerifyMremapHookWasCalled();
   1171     size /= 2;
   1172     munmap(p1, size);
   1173     VerifyMunmapHookWasCalled();
   1174 
   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);
   1178     CHECK(p1 != NULL);
   1179     VerifyMmapHookWasCalled();
   1180     munmap(p1, 8192);
   1181     VerifyMunmapHookWasCalled();
   1182     close(fd);
   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();
   1190 #endif
   1191 
   1192     // Test sbrk
   1193     SetSbrkHook();
   1194 #if defined(HAVE_SBRK) && defined(__linux) && \
   1195        (defined(__i386__) || defined(__x86_64__))
   1196     p1 = sbrk(8192);
   1197     CHECK(p1 != NULL);
   1198     VerifySbrkHookWasCalled();
   1199     p1 = sbrk(-8192);
   1200     CHECK(p1 != NULL);
   1201     VerifySbrkHookWasCalled();
   1202     // However, sbrk hook should *not* be called with sbrk(0)
   1203     p1 = sbrk(0);
   1204     CHECK(p1 != NULL);
   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();
   1209 #endif
   1210 
   1211     // Reset the hooks to what they used to be.  These are all
   1212     // defined as part of MAKE_HOOK_CALLBACK, above.
   1213     ResetNewHook();
   1214     ResetDeleteHook();
   1215     ResetMmapHook();
   1216     ResetMremapHook();
   1217     ResetMunmapHook();
   1218     ResetSbrkHook();
   1219   }
   1220 
   1221   // Check that "lots" of memory can be allocated
   1222   fprintf(LOGSTREAM, "Testing large allocation\n");
   1223   {
   1224     const int mb_to_allocate = 100;
   1225     void* p = rnd.alloc(mb_to_allocate << 20);
   1226     CHECK(p != NULL);  // could not allocate
   1227     free(p);
   1228   }
   1229 
   1230   TestMallocAlignment();
   1231 
   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);
   1244 
   1245   TestCalloc(kMaxSize, 2, false);
   1246   TestCalloc(2, kMaxSize, false);
   1247   TestCalloc(kMaxSize, kMaxSize, false);
   1248 
   1249   TestCalloc(kMaxSignedSize, 3, false);
   1250   TestCalloc(3, kMaxSignedSize, false);
   1251   TestCalloc(kMaxSignedSize, kMaxSignedSize, false);
   1252 
   1253   // Test that realloc doesn't always reallocate and copy memory.
   1254   fprintf(LOGSTREAM, "Testing realloc\n");
   1255   TestRealloc();
   1256 
   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[]);
   1265 
   1266   // Create threads
   1267   fprintf(LOGSTREAM, "Testing threaded allocation/deallocation (%d threads)\n",
   1268           FLAGS_numthreads);
   1269   threads = new TesterThread*[FLAGS_numthreads];
   1270   for (int i = 0; i < FLAGS_numthreads; ++i) {
   1271     threads[i] = new TesterThread(i);
   1272   }
   1273 
   1274   // This runs all the tests at the same time, with a 1M stack size each
   1275   RunManyThreadsWithId(RunThread, FLAGS_numthreads, 1<<20);
   1276 
   1277   for (int i = 0; i < FLAGS_numthreads; ++i) delete threads[i];    // Cleanup
   1278 
   1279   // Do the memory intensive tests after threads are done, since exhausting
   1280   // the available address space can make pthread_create to fail.
   1281 
   1282   // Check that huge allocations fail with NULL instead of crashing
   1283   fprintf(LOGSTREAM, "Testing huge allocations\n");
   1284   TestHugeAllocations(&rnd);
   1285 
   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;
   1292     free(large_object);
   1293   }
   1294 #endif
   1295 
   1296   TestHugeThreadCache();
   1297   TestRanges();
   1298   TestReleaseToSystem();
   1299   TestSetNewMode();
   1300 
   1301   return 0;
   1302 }
   1303 
   1304 }
   1305 
   1306 using testing::RunAllTests;
   1307 
   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
   1311 #endif
   1312 
   1313   RunAllTests(argc, argv);
   1314 
   1315   // Test tc_version()
   1316   fprintf(LOGSTREAM, "Testing tc_version()\n");
   1317   int major;
   1318   int minor;
   1319   const char* patch;
   1320   char mmp[64];
   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));
   1325 
   1326   fprintf(LOGSTREAM, "PASS\n");
   1327 }
   1328