tcmalloc_unittest.cc 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432
  1. // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
  2. // Copyright (c) 2005, Google Inc.
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  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. #include "config_for_unittests.h"
  56. // Complicated ordering requirements. tcmalloc.h defines (indirectly)
  57. // _POSIX_C_SOURCE, which it needs so stdlib.h defines posix_memalign.
  58. // unistd.h, on the other hand, requires _POSIX_C_SOURCE to be unset,
  59. // at least on FreeBSD, in order to define sbrk. The solution
  60. // is to #include unistd.h first. This is safe because unistd.h
  61. // doesn't sub-include stdlib.h, so we'll still get posix_memalign
  62. // when we #include stdlib.h. Blah.
  63. #ifdef HAVE_UNISTD_H
  64. #include <unistd.h> // for testing sbrk hooks
  65. #endif
  66. #include "tcmalloc.h" // must come early, to pick up posix_memalign
  67. #include <stdlib.h>
  68. #include <string.h>
  69. #include <stdio.h>
  70. #if defined HAVE_STDINT_H
  71. #include <stdint.h> // for intptr_t
  72. #endif
  73. #include <sys/types.h> // for size_t
  74. #ifdef HAVE_FCNTL_H
  75. #include <fcntl.h> // for open; used with mmap-hook test
  76. #endif
  77. #ifdef HAVE_MMAP
  78. #include <sys/mman.h> // for testing mmap hooks
  79. #endif
  80. #ifdef HAVE_MALLOC_H
  81. #include <malloc.h> // defines pvalloc/etc on cygwin
  82. #endif
  83. #include <assert.h>
  84. #include <vector>
  85. #include <algorithm>
  86. #include <string>
  87. #include <new>
  88. #include "base/logging.h"
  89. #include "base/simple_mutex.h"
  90. #include "gperftools/malloc_hook.h"
  91. #include "gperftools/malloc_extension.h"
  92. #include "gperftools/tcmalloc.h"
  93. #include "thread_cache.h"
  94. #include "system-alloc.h"
  95. #include "tests/testutil.h"
  96. // Windows doesn't define pvalloc and a few other obsolete unix
  97. // functions; nor does it define posix_memalign (which is not obsolete).
  98. #if defined(_WIN32)
  99. # define cfree free // don't bother to try to test these obsolete fns
  100. # define valloc malloc
  101. # define pvalloc malloc
  102. // I'd like to map posix_memalign to _aligned_malloc, but _aligned_malloc
  103. // must be paired with _aligned_free (not normal free), which is too
  104. // invasive a change to how we allocate memory here. So just bail
  105. static bool kOSSupportsMemalign = false;
  106. static inline void* Memalign(size_t align, size_t size) {
  107. //LOG(FATAL) << "memalign not supported on windows";
  108. exit(1);
  109. return NULL;
  110. }
  111. static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
  112. //LOG(FATAL) << "posix_memalign not supported on windows";
  113. exit(1);
  114. return -1;
  115. }
  116. // OS X defines posix_memalign in some OS versions but not others;
  117. // it's confusing enough to check that it's easiest to just not to test.
  118. #elif defined(__APPLE__)
  119. static bool kOSSupportsMemalign = false;
  120. static inline void* Memalign(size_t align, size_t size) {
  121. //LOG(FATAL) << "memalign not supported on OS X";
  122. exit(1);
  123. return NULL;
  124. }
  125. static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
  126. //LOG(FATAL) << "posix_memalign not supported on OS X";
  127. exit(1);
  128. return -1;
  129. }
  130. #else
  131. static bool kOSSupportsMemalign = true;
  132. static inline void* Memalign(size_t align, size_t size) {
  133. return memalign(align, size);
  134. }
  135. static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
  136. return posix_memalign(ptr, align, size);
  137. }
  138. #endif
  139. // On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
  140. // form of the name instead.
  141. #ifndef MAP_ANONYMOUS
  142. # define MAP_ANONYMOUS MAP_ANON
  143. #endif
  144. #define LOGSTREAM stdout
  145. using std::vector;
  146. using std::string;
  147. DECLARE_double(tcmalloc_release_rate);
  148. DECLARE_int32(max_free_queue_size); // in debugallocation.cc
  149. DECLARE_int64(tcmalloc_sample_parameter);
  150. namespace testing {
  151. static const int FLAGS_numtests = 50000;
  152. static const int FLAGS_log_every_n_tests = 50000; // log exactly once
  153. // Testing parameters
  154. static const int FLAGS_lgmaxsize = 16; // lg() of the max size object to alloc
  155. static const int FLAGS_numthreads = 10; // Number of threads
  156. static const int FLAGS_threadmb = 4; // Max memory size allocated by thread
  157. static const int FLAGS_lg_max_memalign = 18; // lg of max alignment for memalign
  158. static const double FLAGS_memalign_min_fraction = 0; // min expected%
  159. static const double FLAGS_memalign_max_fraction = 0.4; // max expected%
  160. static const double FLAGS_memalign_max_alignment_ratio = 6; // alignment/size
  161. // Weights of different operations
  162. static const int FLAGS_allocweight = 50; // Weight for picking allocation
  163. static const int FLAGS_freeweight = 50; // Weight for picking free
  164. static const int FLAGS_updateweight = 10; // Weight for picking update
  165. static const int FLAGS_passweight = 1; // Weight for passing object
  166. static const int kSizeBits = 8 * sizeof(size_t);
  167. static const size_t kMaxSize = ~static_cast<size_t>(0);
  168. static const size_t kMaxSignedSize = ((size_t(1) << (kSizeBits-1)) - 1);
  169. static const size_t kNotTooBig = 100000;
  170. // We want an allocation that is definitely more than main memory. OS
  171. // X has special logic to discard very big allocs before even passing
  172. // the request along to the user-defined memory allocator; we're not
  173. // interested in testing their logic, so we have to make sure we're
  174. // not *too* big.
  175. static const size_t kTooBig = kMaxSize - 100000;
  176. static int news_handled = 0;
  177. // Global array of threads
  178. class TesterThread;
  179. static TesterThread** threads;
  180. // To help with generating random numbers
  181. class TestHarness {
  182. private:
  183. // Information kept per type
  184. struct Type {
  185. string name;
  186. int type;
  187. int weight;
  188. };
  189. public:
  190. TestHarness(int seed)
  191. : types_(new vector<Type>), total_weight_(0), num_tests_(0) {
  192. srandom(seed);
  193. }
  194. ~TestHarness() {
  195. delete types_;
  196. }
  197. // Add operation type with specified weight. When starting a new
  198. // iteration, an operation type is picked with probability
  199. // proportional to its weight.
  200. //
  201. // "type" must be non-negative.
  202. // "weight" must be non-negative.
  203. void AddType(int type, int weight, const char* name);
  204. // Call this to get the type of operation for the next iteration.
  205. // It returns a random operation type from the set of registered
  206. // operations. Returns -1 if tests should finish.
  207. int PickType();
  208. // If n == 0, returns the next pseudo-random number in the range [0 .. 0]
  209. // If n != 0, returns the next pseudo-random number in the range [0 .. n)
  210. int Uniform(int n) {
  211. if (n == 0) {
  212. return random() * 0;
  213. } else {
  214. return random() % n;
  215. }
  216. }
  217. // Pick "base" uniformly from range [0,max_log] and then return
  218. // "base" random bits. The effect is to pick a number in the range
  219. // [0,2^max_log-1] with bias towards smaller numbers.
  220. int Skewed(int max_log) {
  221. const int base = random() % (max_log+1);
  222. return random() % (1 << base);
  223. }
  224. private:
  225. vector<Type>* types_; // Registered types
  226. int total_weight_; // Total weight of all types
  227. int num_tests_; // Num tests run so far
  228. };
  229. void TestHarness::AddType(int type, int weight, const char* name) {
  230. Type t;
  231. t.name = name;
  232. t.type = type;
  233. t.weight = weight;
  234. types_->push_back(t);
  235. total_weight_ += weight;
  236. }
  237. int TestHarness::PickType() {
  238. if (num_tests_ >= FLAGS_numtests) return -1;
  239. num_tests_++;
  240. assert(total_weight_ > 0);
  241. // This is a little skewed if total_weight_ doesn't divide 2^31, but it's close
  242. int v = Uniform(total_weight_);
  243. int i;
  244. for (i = 0; i < types_->size(); i++) {
  245. v -= (*types_)[i].weight;
  246. if (v < 0) {
  247. break;
  248. }
  249. }
  250. assert(i < types_->size());
  251. if ((num_tests_ % FLAGS_log_every_n_tests) == 0) {
  252. fprintf(LOGSTREAM, " Test %d out of %d: %s\n",
  253. num_tests_, FLAGS_numtests, (*types_)[i].name.c_str());
  254. }
  255. return (*types_)[i].type;
  256. }
  257. class AllocatorState : public TestHarness {
  258. public:
  259. explicit AllocatorState(int seed) : TestHarness(seed), memalign_fraction_(0) {
  260. if (kOSSupportsMemalign) {
  261. CHECK_GE(FLAGS_memalign_max_fraction, 0);
  262. CHECK_LE(FLAGS_memalign_max_fraction, 1);
  263. CHECK_GE(FLAGS_memalign_min_fraction, 0);
  264. CHECK_LE(FLAGS_memalign_min_fraction, 1);
  265. double delta = FLAGS_memalign_max_fraction - FLAGS_memalign_min_fraction;
  266. CHECK_GE(delta, 0);
  267. memalign_fraction_ = (Uniform(10000)/10000.0 * delta +
  268. FLAGS_memalign_min_fraction);
  269. //fprintf(LOGSTREAM, "memalign fraction: %f\n", memalign_fraction_);
  270. }
  271. }
  272. virtual ~AllocatorState() {}
  273. // Allocate memory. Randomly choose between malloc() or posix_memalign().
  274. void* alloc(size_t size) {
  275. if (Uniform(100) < memalign_fraction_ * 100) {
  276. // Try a few times to find a reasonable alignment, or fall back on malloc.
  277. for (int i = 0; i < 5; i++) {
  278. size_t alignment = 1 << Uniform(FLAGS_lg_max_memalign);
  279. if (alignment >= sizeof(intptr_t) &&
  280. (size < sizeof(intptr_t) ||
  281. alignment < FLAGS_memalign_max_alignment_ratio * size)) {
  282. void *result = reinterpret_cast<void*>(static_cast<intptr_t>(0x1234));
  283. int err = PosixMemalign(&result, alignment, size);
  284. if (err != 0) {
  285. CHECK_EQ(err, ENOMEM);
  286. }
  287. return err == 0 ? result : NULL;
  288. }
  289. }
  290. }
  291. return malloc(size);
  292. }
  293. private:
  294. double memalign_fraction_;
  295. };
  296. // Info kept per thread
  297. class TesterThread {
  298. private:
  299. // Info kept per allocated object
  300. struct Object {
  301. char* ptr; // Allocated pointer
  302. int size; // Allocated size
  303. int generation; // Generation counter of object contents
  304. };
  305. Mutex lock_; // For passing in another thread's obj
  306. int id_; // My thread id
  307. AllocatorState rnd_; // For generating random numbers
  308. vector<Object> heap_; // This thread's heap
  309. vector<Object> passed_; // Pending objects passed from others
  310. size_t heap_size_; // Current heap size
  311. int locks_ok_; // Number of OK TryLock() ops
  312. int locks_failed_; // Number of failed TryLock() ops
  313. // Type of operations
  314. enum Type { ALLOC, FREE, UPDATE, PASS };
  315. // ACM minimal standard random number generator. (re-entrant.)
  316. class ACMRandom {
  317. int32 seed_;
  318. public:
  319. explicit ACMRandom(int32 seed) { seed_ = seed; }
  320. int32 Next() {
  321. const int32 M = 2147483647L; // 2^31-1
  322. const int32 A = 16807;
  323. // In effect, we are computing seed_ = (seed_ * A) % M, where M = 2^31-1
  324. uint32 lo = A * (int32)(seed_ & 0xFFFF);
  325. uint32 hi = A * (int32)((uint32)seed_ >> 16);
  326. lo += (hi & 0x7FFF) << 16;
  327. if (lo > M) {
  328. lo &= M;
  329. ++lo;
  330. }
  331. lo += hi >> 15;
  332. if (lo > M) {
  333. lo &= M;
  334. ++lo;
  335. }
  336. return (seed_ = (int32) lo);
  337. }
  338. };
  339. public:
  340. TesterThread(int id)
  341. : id_(id),
  342. rnd_(id+1),
  343. heap_size_(0),
  344. locks_ok_(0),
  345. locks_failed_(0) {
  346. }
  347. virtual ~TesterThread() {
  348. if (FLAGS_verbose)
  349. fprintf(LOGSTREAM, "Thread %2d: locks %6d ok; %6d trylocks failed\n",
  350. id_, locks_ok_, locks_failed_);
  351. if (locks_ok_ + locks_failed_ >= 1000) {
  352. CHECK_LE(locks_failed_, locks_ok_ / 2);
  353. }
  354. }
  355. virtual void Run() {
  356. rnd_.AddType(ALLOC, FLAGS_allocweight, "allocate");
  357. rnd_.AddType(FREE, FLAGS_freeweight, "free");
  358. rnd_.AddType(UPDATE, FLAGS_updateweight, "update");
  359. rnd_.AddType(PASS, FLAGS_passweight, "pass");
  360. while (true) {
  361. AcquirePassedObjects();
  362. switch (rnd_.PickType()) {
  363. case ALLOC: AllocateObject(); break;
  364. case FREE: FreeObject(); break;
  365. case UPDATE: UpdateObject(); break;
  366. case PASS: PassObject(); break;
  367. case -1: goto done;
  368. default: assert(NULL == "Unknown type");
  369. }
  370. ShrinkHeap();
  371. }
  372. done:
  373. DeleteHeap();
  374. }
  375. // Allocate a new object
  376. void AllocateObject() {
  377. Object object;
  378. object.size = rnd_.Skewed(FLAGS_lgmaxsize);
  379. object.ptr = static_cast<char*>(rnd_.alloc(object.size));
  380. CHECK(object.ptr);
  381. object.generation = 0;
  382. FillContents(&object);
  383. heap_.push_back(object);
  384. heap_size_ += object.size;
  385. }
  386. // Mutate a random object
  387. void UpdateObject() {
  388. if (heap_.empty()) return;
  389. const int index = rnd_.Uniform(heap_.size());
  390. CheckContents(heap_[index]);
  391. heap_[index].generation++;
  392. FillContents(&heap_[index]);
  393. }
  394. // Free a random object
  395. void FreeObject() {
  396. if (heap_.empty()) return;
  397. const int index = rnd_.Uniform(heap_.size());
  398. Object object = heap_[index];
  399. CheckContents(object);
  400. free(object.ptr);
  401. heap_size_ -= object.size;
  402. heap_[index] = heap_[heap_.size()-1];
  403. heap_.pop_back();
  404. }
  405. // Delete all objects in the heap
  406. void DeleteHeap() {
  407. while (!heap_.empty()) {
  408. FreeObject();
  409. }
  410. }
  411. // Free objects until our heap is small enough
  412. void ShrinkHeap() {
  413. while (heap_size_ > FLAGS_threadmb << 20) {
  414. assert(!heap_.empty());
  415. FreeObject();
  416. }
  417. }
  418. // Pass a random object to another thread
  419. void PassObject() {
  420. // Pick object to pass
  421. if (heap_.empty()) return;
  422. const int index = rnd_.Uniform(heap_.size());
  423. Object object = heap_[index];
  424. CheckContents(object);
  425. // Pick thread to pass
  426. const int tid = rnd_.Uniform(FLAGS_numthreads);
  427. TesterThread* thread = threads[tid];
  428. if (thread->lock_.TryLock()) {
  429. // Pass the object
  430. locks_ok_++;
  431. thread->passed_.push_back(object);
  432. thread->lock_.Unlock();
  433. heap_size_ -= object.size;
  434. heap_[index] = heap_[heap_.size()-1];
  435. heap_.pop_back();
  436. } else {
  437. locks_failed_++;
  438. }
  439. }
  440. // Grab any objects passed to this thread by another thread
  441. void AcquirePassedObjects() {
  442. // We do not create unnecessary contention by always using
  443. // TryLock(). Plus we unlock immediately after swapping passed
  444. // objects into a local vector.
  445. vector<Object> copy;
  446. { // Locking scope
  447. if (!lock_.TryLock()) {
  448. locks_failed_++;
  449. return;
  450. }
  451. locks_ok_++;
  452. swap(copy, passed_);
  453. lock_.Unlock();
  454. }
  455. for (int i = 0; i < copy.size(); ++i) {
  456. const Object& object = copy[i];
  457. CheckContents(object);
  458. heap_.push_back(object);
  459. heap_size_ += object.size;
  460. }
  461. }
  462. // Fill object contents according to ptr/generation
  463. void FillContents(Object* object) {
  464. ACMRandom r(reinterpret_cast<intptr_t>(object->ptr) & 0x7fffffff);
  465. for (int i = 0; i < object->generation; ++i) {
  466. r.Next();
  467. }
  468. const char c = static_cast<char>(r.Next());
  469. memset(object->ptr, c, object->size);
  470. }
  471. // Check object contents
  472. void CheckContents(const Object& object) {
  473. ACMRandom r(reinterpret_cast<intptr_t>(object.ptr) & 0x7fffffff);
  474. for (int i = 0; i < object.generation; ++i) {
  475. r.Next();
  476. }
  477. // For large objects, we just check a prefix/suffix
  478. const char expected = static_cast<char>(r.Next());
  479. const int limit1 = object.size < 32 ? object.size : 32;
  480. const int start2 = limit1 > object.size - 32 ? limit1 : object.size - 32;
  481. for (int i = 0; i < limit1; ++i) {
  482. CHECK_EQ(object.ptr[i], expected);
  483. }
  484. for (int i = start2; i < object.size; ++i) {
  485. CHECK_EQ(object.ptr[i], expected);
  486. }
  487. }
  488. };
  489. static void RunThread(int thread_id) {
  490. threads[thread_id]->Run();
  491. }
  492. static void TryHugeAllocation(size_t s, AllocatorState* rnd) {
  493. void* p = rnd->alloc(s);
  494. CHECK(p == NULL); // huge allocation s should fail!
  495. }
  496. static void TestHugeAllocations(AllocatorState* rnd) {
  497. // Check that asking for stuff tiny bit smaller than largest possible
  498. // size returns NULL.
  499. for (size_t i = 0; i < 70000; i += rnd->Uniform(20)) {
  500. TryHugeAllocation(kMaxSize - i, rnd);
  501. }
  502. // Asking for memory sizes near signed/unsigned boundary (kMaxSignedSize)
  503. // might work or not, depending on the amount of virtual memory.
  504. #ifndef DEBUGALLOCATION // debug allocation takes forever for huge allocs
  505. for (size_t i = 0; i < 100; i++) {
  506. void* p = NULL;
  507. p = rnd->alloc(kMaxSignedSize + i);
  508. if (p) free(p); // if: free(NULL) is not necessarily defined
  509. p = rnd->alloc(kMaxSignedSize - i);
  510. if (p) free(p);
  511. }
  512. #endif
  513. // Check that ReleaseFreeMemory has no visible effect (aka, does not
  514. // crash the test):
  515. MallocExtension* inst = MallocExtension::instance();
  516. CHECK(inst);
  517. inst->ReleaseFreeMemory();
  518. }
  519. static void TestCalloc(size_t n, size_t s, bool ok) {
  520. char* p = reinterpret_cast<char*>(calloc(n, s));
  521. if (FLAGS_verbose)
  522. fprintf(LOGSTREAM, "calloc(%" PRIxS ", %" PRIxS "): %p\n", n, s, p);
  523. if (!ok) {
  524. CHECK(p == NULL); // calloc(n, s) should not succeed
  525. } else {
  526. CHECK(p != NULL); // calloc(n, s) should succeed
  527. for (int i = 0; i < n*s; i++) {
  528. CHECK(p[i] == '\0');
  529. }
  530. free(p);
  531. }
  532. }
  533. // This makes sure that reallocing a small number of bytes in either
  534. // direction doesn't cause us to allocate new memory.
  535. static void TestRealloc() {
  536. #ifndef DEBUGALLOCATION // debug alloc doesn't try to minimize reallocs
  537. // When sampling, we always allocate in units of page-size, which
  538. // makes reallocs of small sizes do extra work (thus, failing these
  539. // checks). Since sampling is random, we turn off sampling to make
  540. // sure that doesn't happen to us here.
  541. const int64 old_sample_parameter = FLAGS_tcmalloc_sample_parameter;
  542. FLAGS_tcmalloc_sample_parameter = 0; // turn off sampling
  543. int start_sizes[] = { 100, 1000, 10000, 100000 };
  544. int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 };
  545. for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) {
  546. void* p = malloc(start_sizes[s]);
  547. CHECK(p);
  548. // The larger the start-size, the larger the non-reallocing delta.
  549. for (int d = 0; d < (s+1) * 2; ++d) {
  550. void* new_p = realloc(p, start_sizes[s] + deltas[d]);
  551. CHECK(p == new_p); // realloc should not allocate new memory
  552. }
  553. // Test again, but this time reallocing smaller first.
  554. for (int d = 0; d < s*2; ++d) {
  555. void* new_p = realloc(p, start_sizes[s] - deltas[d]);
  556. CHECK(p == new_p); // realloc should not allocate new memory
  557. }
  558. free(p);
  559. }
  560. FLAGS_tcmalloc_sample_parameter = old_sample_parameter;
  561. #endif
  562. }
  563. static void TestNewHandler() throw (std::bad_alloc) {
  564. ++news_handled;
  565. throw std::bad_alloc();
  566. }
  567. static void TestOneNew(void* (*func)(size_t)) {
  568. // success test
  569. try {
  570. void* ptr = (*func)(kNotTooBig);
  571. if (0 == ptr) {
  572. fprintf(LOGSTREAM, "allocation should not have failed.\n");
  573. abort();
  574. }
  575. } catch (...) {
  576. fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
  577. abort();
  578. }
  579. // failure test
  580. // we should always receive a bad_alloc exception
  581. try {
  582. (*func)(kTooBig);
  583. fprintf(LOGSTREAM, "allocation should have failed.\n");
  584. abort();
  585. } catch (const std::bad_alloc&) {
  586. // correct
  587. } catch (...) {
  588. fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
  589. abort();
  590. }
  591. }
  592. static void TestNew(void* (*func)(size_t)) {
  593. news_handled = 0;
  594. // test without new_handler:
  595. std::new_handler saved_handler = std::set_new_handler(0);
  596. TestOneNew(func);
  597. // test with new_handler:
  598. std::set_new_handler(TestNewHandler);
  599. TestOneNew(func);
  600. if (news_handled != 1) {
  601. fprintf(LOGSTREAM, "new_handler was not called.\n");
  602. abort();
  603. }
  604. std::set_new_handler(saved_handler);
  605. }
  606. static void TestOneNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {
  607. // success test
  608. try {
  609. void* ptr = (*func)(kNotTooBig, std::nothrow);
  610. if (0 == ptr) {
  611. fprintf(LOGSTREAM, "allocation should not have failed.\n");
  612. abort();
  613. }
  614. } catch (...) {
  615. fprintf(LOGSTREAM, "allocation threw unexpected exception.\n");
  616. abort();
  617. }
  618. // failure test
  619. // we should always receive a bad_alloc exception
  620. try {
  621. if ((*func)(kTooBig, std::nothrow) != 0) {
  622. fprintf(LOGSTREAM, "allocation should have failed.\n");
  623. abort();
  624. }
  625. } catch (...) {
  626. fprintf(LOGSTREAM, "nothrow allocation threw unexpected exception.\n");
  627. abort();
  628. }
  629. }
  630. static void TestNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {
  631. news_handled = 0;
  632. // test without new_handler:
  633. std::new_handler saved_handler = std::set_new_handler(0);
  634. TestOneNothrowNew(func);
  635. // test with new_handler:
  636. std::set_new_handler(TestNewHandler);
  637. TestOneNothrowNew(func);
  638. if (news_handled != 1) {
  639. fprintf(LOGSTREAM, "nothrow new_handler was not called.\n");
  640. abort();
  641. }
  642. std::set_new_handler(saved_handler);
  643. }
  644. // These are used as callbacks by the sanity-check. Set* and Reset*
  645. // register the hook that counts how many times the associated memory
  646. // function is called. After each such call, call Verify* to verify
  647. // that we used the tcmalloc version of the call, and not the libc.
  648. // Note the ... in the hook signature: we don't care what arguments
  649. // the hook takes.
  650. #define MAKE_HOOK_CALLBACK(hook_type, ...) \
  651. static volatile int g_##hook_type##_calls = 0; \
  652. static void IncrementCallsTo##hook_type(__VA_ARGS__) { \
  653. g_##hook_type##_calls++; \
  654. } \
  655. static void Verify##hook_type##WasCalled() { \
  656. CHECK_GT(g_##hook_type##_calls, 0); \
  657. g_##hook_type##_calls = 0; /* reset for next call */ \
  658. } \
  659. static void Set##hook_type() { \
  660. CHECK(MallocHook::Add##hook_type( \
  661. (MallocHook::hook_type)&IncrementCallsTo##hook_type)); \
  662. } \
  663. static void Reset##hook_type() { \
  664. CHECK(MallocHook::Remove##hook_type( \
  665. (MallocHook::hook_type)&IncrementCallsTo##hook_type)); \
  666. }
  667. // We do one for each hook typedef in malloc_hook.h
  668. MAKE_HOOK_CALLBACK(NewHook, const void*, size_t);
  669. MAKE_HOOK_CALLBACK(DeleteHook, const void*);
  670. MAKE_HOOK_CALLBACK(MmapHook, const void*, const void*, size_t, int, int, int,
  671. off_t);
  672. MAKE_HOOK_CALLBACK(MremapHook, const void*, const void*, size_t, size_t, int,
  673. const void*);
  674. MAKE_HOOK_CALLBACK(MunmapHook, const void *, size_t);
  675. MAKE_HOOK_CALLBACK(SbrkHook, const void *, ptrdiff_t);
  676. static void TestAlignmentForSize(int size) {
  677. fprintf(LOGSTREAM, "Testing alignment of malloc(%d)\n", size);
  678. static const int kNum = 100;
  679. void* ptrs[kNum];
  680. for (int i = 0; i < kNum; i++) {
  681. ptrs[i] = malloc(size);
  682. uintptr_t p = reinterpret_cast<uintptr_t>(ptrs[i]);
  683. CHECK((p % sizeof(void*)) == 0);
  684. CHECK((p % sizeof(double)) == 0);
  685. // Must have 16-byte (or 8-byte in case of -DTCMALLOC_ALIGN_8BYTES)
  686. // alignment for large enough objects
  687. if (size >= kMinAlign) {
  688. CHECK((p % kMinAlign) == 0);
  689. }
  690. }
  691. for (int i = 0; i < kNum; i++) {
  692. free(ptrs[i]);
  693. }
  694. }
  695. static void TestMallocAlignment() {
  696. for (int lg = 0; lg < 16; lg++) {
  697. TestAlignmentForSize((1<<lg) - 1);
  698. TestAlignmentForSize((1<<lg) + 0);
  699. TestAlignmentForSize((1<<lg) + 1);
  700. }
  701. }
  702. static void TestHugeThreadCache() {
  703. fprintf(LOGSTREAM, "==== Testing huge thread cache\n");
  704. // More than 2^16 to cause integer overflow of 16 bit counters.
  705. static const int kNum = 70000;
  706. char** array = new char*[kNum];
  707. for (int i = 0; i < kNum; ++i) {
  708. array[i] = new char[10];
  709. }
  710. for (int i = 0; i < kNum; ++i) {
  711. delete[] array[i];
  712. }
  713. delete[] array;
  714. }
  715. namespace {
  716. struct RangeCallbackState {
  717. uintptr_t ptr;
  718. base::MallocRange::Type expected_type;
  719. size_t min_size;
  720. bool matched;
  721. };
  722. static void RangeCallback(void* arg, const base::MallocRange* r) {
  723. RangeCallbackState* state = reinterpret_cast<RangeCallbackState*>(arg);
  724. if (state->ptr >= r->address &&
  725. state->ptr < r->address + r->length) {
  726. if (state->expected_type == base::MallocRange::FREE) {
  727. // We are expecting r->type == FREE, but ReleaseMemory
  728. // may have already moved us to UNMAPPED state instead (this happens in
  729. // approximately 0.1% of executions). Accept either state.
  730. CHECK(r->type == base::MallocRange::FREE ||
  731. r->type == base::MallocRange::UNMAPPED);
  732. } else {
  733. CHECK_EQ(r->type, state->expected_type);
  734. }
  735. CHECK_GE(r->length, state->min_size);
  736. state->matched = true;
  737. }
  738. }
  739. // Check that at least one of the callbacks from Ranges() contains
  740. // the specified address with the specified type, and has size
  741. // >= min_size.
  742. static void CheckRangeCallback(void* ptr, base::MallocRange::Type type,
  743. size_t min_size) {
  744. RangeCallbackState state;
  745. state.ptr = reinterpret_cast<uintptr_t>(ptr);
  746. state.expected_type = type;
  747. state.min_size = min_size;
  748. state.matched = false;
  749. MallocExtension::instance()->Ranges(&state, RangeCallback);
  750. CHECK(state.matched);
  751. }
  752. }
  753. static bool HaveSystemRelease =
  754. TCMalloc_SystemRelease(TCMalloc_SystemAlloc(kPageSize, NULL, 0), kPageSize);
  755. static void TestRanges() {
  756. static const int MB = 1048576;
  757. void* a = malloc(MB);
  758. void* b = malloc(MB);
  759. base::MallocRange::Type releasedType =
  760. HaveSystemRelease ? base::MallocRange::UNMAPPED : base::MallocRange::FREE;
  761. CheckRangeCallback(a, base::MallocRange::INUSE, MB);
  762. CheckRangeCallback(b, base::MallocRange::INUSE, MB);
  763. free(a);
  764. CheckRangeCallback(a, base::MallocRange::FREE, MB);
  765. CheckRangeCallback(b, base::MallocRange::INUSE, MB);
  766. MallocExtension::instance()->ReleaseFreeMemory();
  767. CheckRangeCallback(a, releasedType, MB);
  768. CheckRangeCallback(b, base::MallocRange::INUSE, MB);
  769. free(b);
  770. CheckRangeCallback(a, releasedType, MB);
  771. CheckRangeCallback(b, base::MallocRange::FREE, MB);
  772. }
  773. #ifndef DEBUGALLOCATION
  774. static size_t GetUnmappedBytes() {
  775. size_t bytes;
  776. CHECK(MallocExtension::instance()->GetNumericProperty(
  777. "tcmalloc.pageheap_unmapped_bytes", &bytes));
  778. return bytes;
  779. }
  780. #endif
  781. class AggressiveDecommitChanger {
  782. size_t old_value_;
  783. public:
  784. AggressiveDecommitChanger(size_t new_value) {
  785. MallocExtension *inst = MallocExtension::instance();
  786. bool rv = inst->GetNumericProperty("tcmalloc.aggressive_memory_decommit", &old_value_);
  787. CHECK_CONDITION(rv);
  788. rv = inst->SetNumericProperty("tcmalloc.aggressive_memory_decommit", new_value);
  789. CHECK_CONDITION(rv);
  790. }
  791. ~AggressiveDecommitChanger() {
  792. MallocExtension *inst = MallocExtension::instance();
  793. bool rv = inst->SetNumericProperty("tcmalloc.aggressive_memory_decommit", old_value_);
  794. CHECK_CONDITION(rv);
  795. }
  796. };
  797. static void TestReleaseToSystem() {
  798. // Debug allocation mode adds overhead to each allocation which
  799. // messes up all the equality tests here. I just disable the
  800. // teset in this mode. TODO(csilvers): get it to work for debugalloc?
  801. #ifndef DEBUGALLOCATION
  802. if(!HaveSystemRelease) return;
  803. const double old_tcmalloc_release_rate = FLAGS_tcmalloc_release_rate;
  804. FLAGS_tcmalloc_release_rate = 0;
  805. AggressiveDecommitChanger disabler(0);
  806. static const int MB = 1048576;
  807. void* a = malloc(MB);
  808. void* b = malloc(MB);
  809. MallocExtension::instance()->ReleaseFreeMemory();
  810. size_t starting_bytes = GetUnmappedBytes();
  811. // Calling ReleaseFreeMemory() a second time shouldn't do anything.
  812. MallocExtension::instance()->ReleaseFreeMemory();
  813. EXPECT_EQ(starting_bytes, GetUnmappedBytes());
  814. // ReleaseToSystem shouldn't do anything either.
  815. MallocExtension::instance()->ReleaseToSystem(MB);
  816. EXPECT_EQ(starting_bytes, GetUnmappedBytes());
  817. free(a);
  818. // The span to release should be 1MB.
  819. MallocExtension::instance()->ReleaseToSystem(MB/2);
  820. EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
  821. // Should do nothing since the previous call released too much.
  822. MallocExtension::instance()->ReleaseToSystem(MB/4);
  823. EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
  824. free(b);
  825. // Use up the extra MB/4 bytes from 'a' and also release 'b'.
  826. MallocExtension::instance()->ReleaseToSystem(MB/2);
  827. EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
  828. // Should do nothing since the previous call released too much.
  829. MallocExtension::instance()->ReleaseToSystem(MB/2);
  830. EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
  831. // Nothing else to release.
  832. MallocExtension::instance()->ReleaseFreeMemory();
  833. EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
  834. a = malloc(MB);
  835. free(a);
  836. EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
  837. // Releasing less than a page should still trigger a release.
  838. MallocExtension::instance()->ReleaseToSystem(1);
  839. EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
  840. FLAGS_tcmalloc_release_rate = old_tcmalloc_release_rate;
  841. #endif // #ifndef DEBUGALLOCATION
  842. }
  843. static void TestAggressiveDecommit() {
  844. // Debug allocation mode adds overhead to each allocation which
  845. // messes up all the equality tests here. I just disable the
  846. // teset in this mode.
  847. #ifndef DEBUGALLOCATION
  848. if(!HaveSystemRelease) return;
  849. fprintf(LOGSTREAM, "Testing aggressive de-commit\n");
  850. AggressiveDecommitChanger enabler(1);
  851. static const int MB = 1048576;
  852. void* a = malloc(MB);
  853. void* b = malloc(MB);
  854. size_t starting_bytes = GetUnmappedBytes();
  855. // ReleaseToSystem shouldn't do anything either.
  856. MallocExtension::instance()->ReleaseToSystem(MB);
  857. EXPECT_EQ(starting_bytes, GetUnmappedBytes());
  858. free(a);
  859. // The span to release should be 1MB.
  860. EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
  861. free(b);
  862. EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
  863. // Nothing else to release.
  864. MallocExtension::instance()->ReleaseFreeMemory();
  865. EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
  866. a = malloc(MB);
  867. free(a);
  868. EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
  869. fprintf(LOGSTREAM, "Done testing aggressive de-commit\n");
  870. #endif // #ifndef DEBUGALLOCATION
  871. }
  872. // On MSVC10, in release mode, the optimizer convinces itself
  873. // g_no_memory is never changed (I guess it doesn't realize OnNoMemory
  874. // might be called). Work around this by setting the var volatile.
  875. volatile bool g_no_memory = false;
  876. std::new_handler g_old_handler = NULL;
  877. static void OnNoMemory() {
  878. g_no_memory = true;
  879. std::set_new_handler(g_old_handler);
  880. }
  881. static void TestSetNewMode() {
  882. int old_mode = tc_set_new_mode(1);
  883. g_old_handler = std::set_new_handler(&OnNoMemory);
  884. g_no_memory = false;
  885. void* ret = malloc(kTooBig);
  886. EXPECT_EQ(NULL, ret);
  887. EXPECT_TRUE(g_no_memory);
  888. g_old_handler = std::set_new_handler(&OnNoMemory);
  889. g_no_memory = false;
  890. ret = calloc(1, kTooBig);
  891. EXPECT_EQ(NULL, ret);
  892. EXPECT_TRUE(g_no_memory);
  893. g_old_handler = std::set_new_handler(&OnNoMemory);
  894. g_no_memory = false;
  895. ret = realloc(NULL, kTooBig);
  896. EXPECT_EQ(NULL, ret);
  897. EXPECT_TRUE(g_no_memory);
  898. if (kOSSupportsMemalign) {
  899. // Not really important, but must be small enough such that
  900. // kAlignment + kTooBig does not overflow.
  901. const int kAlignment = 1 << 5;
  902. g_old_handler = std::set_new_handler(&OnNoMemory);
  903. g_no_memory = false;
  904. ret = Memalign(kAlignment, kTooBig);
  905. EXPECT_EQ(NULL, ret);
  906. EXPECT_TRUE(g_no_memory);
  907. g_old_handler = std::set_new_handler(&OnNoMemory);
  908. g_no_memory = false;
  909. EXPECT_EQ(ENOMEM,
  910. PosixMemalign(&ret, kAlignment, kTooBig));
  911. EXPECT_EQ(NULL, ret);
  912. EXPECT_TRUE(g_no_memory);
  913. }
  914. tc_set_new_mode(old_mode);
  915. }
  916. static void TestErrno(void) {
  917. void* ret;
  918. if (kOSSupportsMemalign) {
  919. errno = 0;
  920. ret = Memalign(128, kTooBig);
  921. EXPECT_EQ(NULL, ret);
  922. EXPECT_EQ(ENOMEM, errno);
  923. }
  924. errno = 0;
  925. ret = malloc(kTooBig);
  926. EXPECT_EQ(NULL, ret);
  927. EXPECT_EQ(ENOMEM, errno);
  928. errno = 0;
  929. ret = tc_malloc_skip_new_handler(kTooBig);
  930. EXPECT_EQ(NULL, ret);
  931. EXPECT_EQ(ENOMEM, errno);
  932. }
  933. static int RunAllTests(int argc, char** argv) {
  934. // Optional argv[1] is the seed
  935. AllocatorState rnd(argc > 1 ? atoi(argv[1]) : 100);
  936. SetTestResourceLimit();
  937. // TODO(odo): This test has been disabled because it is only by luck that it
  938. // does not result in fragmentation. When tcmalloc makes an allocation which
  939. // spans previously unused leaves of the pagemap it will allocate and fill in
  940. // the leaves to cover the new allocation. The leaves happen to be 256MiB in
  941. // the 64-bit build, and with the sbrk allocator these allocations just
  942. // happen to fit in one leaf by luck. With other allocators (mmap,
  943. // memfs_malloc when used with small pages) the allocations generally span
  944. // two leaves and this results in a very bad fragmentation pattern with this
  945. // code. The same failure can be forced with the sbrk allocator just by
  946. // allocating something on the order of 128MiB prior to starting this test so
  947. // that the test allocations straddle a 256MiB boundary.
  948. // TODO(csilvers): port MemoryUsage() over so the test can use that
  949. #if 0
  950. # include <unistd.h> // for getpid()
  951. // Allocate and deallocate blocks of increasing sizes to check if the alloc
  952. // metadata fragments the memory. (Do not put other allocations/deallocations
  953. // before this test, it may break).
  954. {
  955. size_t memory_usage = MemoryUsage(getpid());
  956. fprintf(LOGSTREAM, "Testing fragmentation\n");
  957. for ( int i = 200; i < 240; ++i ) {
  958. int size = i << 20;
  959. void *test1 = rnd.alloc(size);
  960. CHECK(test1);
  961. for ( int j = 0; j < size; j += (1 << 12) ) {
  962. static_cast<char*>(test1)[j] = 1;
  963. }
  964. free(test1);
  965. }
  966. // There may still be a bit of fragmentation at the beginning, until we
  967. // reach kPageMapBigAllocationThreshold bytes so we check for
  968. // 200 + 240 + margin.
  969. CHECK_LT(MemoryUsage(getpid()), memory_usage + (450 << 20) );
  970. }
  971. #endif
  972. // Check that empty allocation works
  973. fprintf(LOGSTREAM, "Testing empty allocation\n");
  974. {
  975. void* p1 = rnd.alloc(0);
  976. CHECK(p1 != NULL);
  977. void* p2 = rnd.alloc(0);
  978. CHECK(p2 != NULL);
  979. CHECK(p1 != p2);
  980. free(p1);
  981. free(p2);
  982. }
  983. // This code stresses some of the memory allocation via STL.
  984. // It may call operator delete(void*, nothrow_t).
  985. fprintf(LOGSTREAM, "Testing STL use\n");
  986. {
  987. std::vector<int> v;
  988. v.push_back(1);
  989. v.push_back(2);
  990. v.push_back(3);
  991. v.push_back(0);
  992. std::stable_sort(v.begin(), v.end());
  993. }
  994. // Test each of the memory-allocation functions once, just as a sanity-check
  995. fprintf(LOGSTREAM, "Sanity-testing all the memory allocation functions\n");
  996. {
  997. // We use new-hook and delete-hook to verify we actually called the
  998. // tcmalloc version of these routines, and not the libc version.
  999. SetNewHook(); // defined as part of MAKE_HOOK_CALLBACK, above
  1000. SetDeleteHook(); // ditto
  1001. void* p1 = malloc(10);
  1002. CHECK(p1 != NULL); // force use of this variable
  1003. VerifyNewHookWasCalled();
  1004. // Also test the non-standard tc_malloc_size
  1005. size_t actual_p1_size = tc_malloc_size(p1);
  1006. CHECK_GE(actual_p1_size, 10);
  1007. CHECK_LT(actual_p1_size, 100000); // a reasonable upper-bound, I think
  1008. free(p1);
  1009. VerifyDeleteHookWasCalled();
  1010. p1 = tc_malloc_skip_new_handler(10);
  1011. CHECK(p1 != NULL);
  1012. VerifyNewHookWasCalled();
  1013. free(p1);
  1014. VerifyDeleteHookWasCalled();
  1015. p1 = calloc(10, 2);
  1016. CHECK(p1 != NULL);
  1017. VerifyNewHookWasCalled();
  1018. // We make sure we realloc to a big size, since some systems (OS
  1019. // X) will notice if the realloced size continues to fit into the
  1020. // malloc-block and make this a noop if so.
  1021. p1 = realloc(p1, 30000);
  1022. CHECK(p1 != NULL);
  1023. VerifyNewHookWasCalled();
  1024. VerifyDeleteHookWasCalled();
  1025. cfree(p1); // synonym for free
  1026. VerifyDeleteHookWasCalled();
  1027. if (kOSSupportsMemalign) {
  1028. CHECK_EQ(PosixMemalign(&p1, sizeof(p1), 40), 0);
  1029. CHECK(p1 != NULL);
  1030. VerifyNewHookWasCalled();
  1031. free(p1);
  1032. VerifyDeleteHookWasCalled();
  1033. p1 = Memalign(sizeof(p1) * 2, 50);
  1034. CHECK(p1 != NULL);
  1035. VerifyNewHookWasCalled();
  1036. free(p1);
  1037. VerifyDeleteHookWasCalled();
  1038. }
  1039. // Windows has _aligned_malloc. Let's test that that's captured too.
  1040. #if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(PERFTOOLS_NO_ALIGNED_MALLOC)
  1041. p1 = _aligned_malloc(sizeof(p1) * 2, 64);
  1042. CHECK(p1 != NULL);
  1043. VerifyNewHookWasCalled();
  1044. _aligned_free(p1);
  1045. VerifyDeleteHookWasCalled();
  1046. #endif
  1047. p1 = valloc(60);
  1048. CHECK(p1 != NULL);
  1049. VerifyNewHookWasCalled();
  1050. free(p1);
  1051. VerifyDeleteHookWasCalled();
  1052. p1 = pvalloc(70);
  1053. CHECK(p1 != NULL);
  1054. VerifyNewHookWasCalled();
  1055. free(p1);
  1056. VerifyDeleteHookWasCalled();
  1057. char* p2 = new char;
  1058. CHECK(p2 != NULL);
  1059. VerifyNewHookWasCalled();
  1060. delete p2;
  1061. VerifyDeleteHookWasCalled();
  1062. p2 = new char[100];
  1063. CHECK(p2 != NULL);
  1064. VerifyNewHookWasCalled();
  1065. delete[] p2;
  1066. VerifyDeleteHookWasCalled();
  1067. p2 = new(std::nothrow) char;
  1068. CHECK(p2 != NULL);
  1069. VerifyNewHookWasCalled();
  1070. delete p2;
  1071. VerifyDeleteHookWasCalled();
  1072. p2 = new(std::nothrow) char[100];
  1073. CHECK(p2 != NULL);
  1074. VerifyNewHookWasCalled();
  1075. delete[] p2;
  1076. VerifyDeleteHookWasCalled();
  1077. // Another way of calling operator new
  1078. p2 = static_cast<char*>(::operator new(100));
  1079. CHECK(p2 != NULL);
  1080. VerifyNewHookWasCalled();
  1081. ::operator delete(p2);
  1082. VerifyDeleteHookWasCalled();
  1083. // Try to call nothrow's delete too. Compilers use this.
  1084. p2 = static_cast<char*>(::operator new(100, std::nothrow));
  1085. CHECK(p2 != NULL);
  1086. VerifyNewHookWasCalled();
  1087. ::operator delete(p2, std::nothrow);
  1088. VerifyDeleteHookWasCalled();
  1089. // Try strdup(), which the system allocates but we must free. If
  1090. // all goes well, libc will use our malloc!
  1091. p2 = strdup("test");
  1092. CHECK(p2 != NULL);
  1093. VerifyNewHookWasCalled();
  1094. free(p2);
  1095. VerifyDeleteHookWasCalled();
  1096. // Test mmap too: both anonymous mmap and mmap of a file
  1097. // Note that for right now we only override mmap on linux
  1098. // systems, so those are the only ones for which we check.
  1099. SetMmapHook();
  1100. SetMremapHook();
  1101. SetMunmapHook();
  1102. #if defined(HAVE_MMAP) && defined(__linux) && \
  1103. (defined(__i386__) || defined(__x86_64__))
  1104. int size = 8192*2;
  1105. p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE,
  1106. -1, 0);
  1107. CHECK(p1 != NULL);
  1108. VerifyMmapHookWasCalled();
  1109. p1 = mremap(p1, size, size/2, 0);
  1110. CHECK(p1 != NULL);
  1111. VerifyMremapHookWasCalled();
  1112. size /= 2;
  1113. munmap(p1, size);
  1114. VerifyMunmapHookWasCalled();
  1115. int fd = open("/dev/zero", O_RDONLY);
  1116. CHECK_GE(fd, 0); // make sure the open succeeded
  1117. p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);
  1118. CHECK(p1 != NULL);
  1119. VerifyMmapHookWasCalled();
  1120. munmap(p1, 8192);
  1121. VerifyMunmapHookWasCalled();
  1122. close(fd);
  1123. #else // this is just to quiet the compiler: make sure all fns are called
  1124. IncrementCallsToMmapHook(NULL, NULL, 0, 0, 0, 0, 0);
  1125. IncrementCallsToMunmapHook(NULL, 0);
  1126. IncrementCallsToMremapHook(NULL, NULL, 0, 0, 0, NULL);
  1127. VerifyMmapHookWasCalled();
  1128. VerifyMremapHookWasCalled();
  1129. VerifyMunmapHookWasCalled();
  1130. #endif
  1131. // Test sbrk
  1132. SetSbrkHook();
  1133. #if defined(HAVE_SBRK) && defined(__linux) && \
  1134. (defined(__i386__) || defined(__x86_64__))
  1135. p1 = sbrk(8192);
  1136. CHECK(p1 != NULL);
  1137. VerifySbrkHookWasCalled();
  1138. p1 = sbrk(-8192);
  1139. CHECK(p1 != NULL);
  1140. VerifySbrkHookWasCalled();
  1141. // However, sbrk hook should *not* be called with sbrk(0)
  1142. p1 = sbrk(0);
  1143. CHECK(p1 != NULL);
  1144. CHECK_EQ(g_SbrkHook_calls, 0);
  1145. #else // this is just to quiet the compiler: make sure all fns are called
  1146. IncrementCallsToSbrkHook(NULL, 0);
  1147. VerifySbrkHookWasCalled();
  1148. #endif
  1149. // Reset the hooks to what they used to be. These are all
  1150. // defined as part of MAKE_HOOK_CALLBACK, above.
  1151. ResetNewHook();
  1152. ResetDeleteHook();
  1153. ResetMmapHook();
  1154. ResetMremapHook();
  1155. ResetMunmapHook();
  1156. ResetSbrkHook();
  1157. }
  1158. // Check that "lots" of memory can be allocated
  1159. fprintf(LOGSTREAM, "Testing large allocation\n");
  1160. {
  1161. const int mb_to_allocate = 100;
  1162. void* p = rnd.alloc(mb_to_allocate << 20);
  1163. CHECK(p != NULL); // could not allocate
  1164. free(p);
  1165. }
  1166. TestMallocAlignment();
  1167. // Check calloc() with various arguments
  1168. fprintf(LOGSTREAM, "Testing calloc\n");
  1169. TestCalloc(0, 0, true);
  1170. TestCalloc(0, 1, true);
  1171. TestCalloc(1, 1, true);
  1172. TestCalloc(1<<10, 0, true);
  1173. TestCalloc(1<<20, 0, true);
  1174. TestCalloc(0, 1<<10, true);
  1175. TestCalloc(0, 1<<20, true);
  1176. TestCalloc(1<<20, 2, true);
  1177. TestCalloc(2, 1<<20, true);
  1178. TestCalloc(1000, 1000, true);
  1179. TestCalloc(kMaxSize, 2, false);
  1180. TestCalloc(2, kMaxSize, false);
  1181. TestCalloc(kMaxSize, kMaxSize, false);
  1182. TestCalloc(kMaxSignedSize, 3, false);
  1183. TestCalloc(3, kMaxSignedSize, false);
  1184. TestCalloc(kMaxSignedSize, kMaxSignedSize, false);
  1185. // Test that realloc doesn't always reallocate and copy memory.
  1186. fprintf(LOGSTREAM, "Testing realloc\n");
  1187. TestRealloc();
  1188. fprintf(LOGSTREAM, "Testing operator new(nothrow).\n");
  1189. TestNothrowNew(&::operator new);
  1190. fprintf(LOGSTREAM, "Testing operator new[](nothrow).\n");
  1191. TestNothrowNew(&::operator new[]);
  1192. fprintf(LOGSTREAM, "Testing operator new.\n");
  1193. TestNew(&::operator new);
  1194. fprintf(LOGSTREAM, "Testing operator new[].\n");
  1195. TestNew(&::operator new[]);
  1196. // Create threads
  1197. fprintf(LOGSTREAM, "Testing threaded allocation/deallocation (%d threads)\n",
  1198. FLAGS_numthreads);
  1199. threads = new TesterThread*[FLAGS_numthreads];
  1200. for (int i = 0; i < FLAGS_numthreads; ++i) {
  1201. threads[i] = new TesterThread(i);
  1202. }
  1203. // This runs all the tests at the same time, with a 1M stack size each
  1204. RunManyThreadsWithId(RunThread, FLAGS_numthreads, 1<<20);
  1205. for (int i = 0; i < FLAGS_numthreads; ++i) delete threads[i]; // Cleanup
  1206. // Do the memory intensive tests after threads are done, since exhausting
  1207. // the available address space can make pthread_create to fail.
  1208. // Check that huge allocations fail with NULL instead of crashing
  1209. fprintf(LOGSTREAM, "Testing huge allocations\n");
  1210. TestHugeAllocations(&rnd);
  1211. // Check that large allocations fail with NULL instead of crashing
  1212. #ifndef DEBUGALLOCATION // debug allocation takes forever for huge allocs
  1213. fprintf(LOGSTREAM, "Testing out of memory\n");
  1214. for (int s = 0; ; s += (10<<20)) {
  1215. void* large_object = rnd.alloc(s);
  1216. if (large_object == NULL) break;
  1217. free(large_object);
  1218. }
  1219. #endif
  1220. TestHugeThreadCache();
  1221. TestRanges();
  1222. TestReleaseToSystem();
  1223. TestAggressiveDecommit();
  1224. TestSetNewMode();
  1225. TestErrno();
  1226. return 0;
  1227. }
  1228. }
  1229. using testing::RunAllTests;
  1230. int main(int argc, char** argv) {
  1231. #ifdef DEBUGALLOCATION // debug allocation takes forever for huge allocs
  1232. FLAGS_max_free_queue_size = 0; // return freed blocks to tcmalloc immediately
  1233. #endif
  1234. RunAllTests(argc, argv);
  1235. // Test tc_version()
  1236. fprintf(LOGSTREAM, "Testing tc_version()\n");
  1237. int major;
  1238. int minor;
  1239. const char* patch;
  1240. char mmp[64];
  1241. const char* human_version = tc_version(&major, &minor, &patch);
  1242. snprintf(mmp, sizeof(mmp), "%d.%d%s", major, minor, patch);
  1243. CHECK(!strcmp(PACKAGE_STRING, human_version));
  1244. CHECK(!strcmp(PACKAGE_VERSION, mmp));
  1245. fprintf(LOGSTREAM, "PASS\n");
  1246. }