tcmalloc.cc 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843
  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. // Author: Sanjay Ghemawat <opensource@google.com>
  32. //
  33. // A malloc that uses a per-thread cache to satisfy small malloc requests.
  34. // (The time for malloc/free of a small object drops from 300 ns to 50 ns.)
  35. //
  36. // See doc/tcmalloc.html for a high-level
  37. // description of how this malloc works.
  38. //
  39. // SYNCHRONIZATION
  40. // 1. The thread-specific lists are accessed without acquiring any locks.
  41. // This is safe because each such list is only accessed by one thread.
  42. // 2. We have a lock per central free-list, and hold it while manipulating
  43. // the central free list for a particular size.
  44. // 3. The central page allocator is protected by "pageheap_lock".
  45. // 4. The pagemap (which maps from page-number to descriptor),
  46. // can be read without holding any locks, and written while holding
  47. // the "pageheap_lock".
  48. // 5. To improve performance, a subset of the information one can get
  49. // from the pagemap is cached in a data structure, pagemap_cache_,
  50. // that atomically reads and writes its entries. This cache can be
  51. // read and written without locking.
  52. //
  53. // This multi-threaded access to the pagemap is safe for fairly
  54. // subtle reasons. We basically assume that when an object X is
  55. // allocated by thread A and deallocated by thread B, there must
  56. // have been appropriate synchronization in the handoff of object
  57. // X from thread A to thread B. The same logic applies to pagemap_cache_.
  58. //
  59. // THE PAGEID-TO-SIZECLASS CACHE
  60. // Hot PageID-to-sizeclass mappings are held by pagemap_cache_. If this cache
  61. // returns 0 for a particular PageID then that means "no information," not that
  62. // the sizeclass is 0. The cache may have stale information for pages that do
  63. // not hold the beginning of any free()'able object. Staleness is eliminated
  64. // in Populate() for pages with sizeclass > 0 objects, and in do_malloc() and
  65. // do_memalign() for all other relevant pages.
  66. //
  67. // PAGEMAP
  68. // -------
  69. // Page map contains a mapping from page id to Span.
  70. //
  71. // If Span s occupies pages [p..q],
  72. // pagemap[p] == s
  73. // pagemap[q] == s
  74. // pagemap[p+1..q-1] are undefined
  75. // pagemap[p-1] and pagemap[q+1] are defined:
  76. // NULL if the corresponding page is not yet in the address space.
  77. // Otherwise it points to a Span. This span may be free
  78. // or allocated. If free, it is in one of pageheap's freelist.
  79. //
  80. // TODO: Bias reclamation to larger addresses
  81. // TODO: implement mallinfo/mallopt
  82. // TODO: Better testing
  83. //
  84. // 9/28/2003 (new page-level allocator replaces ptmalloc2):
  85. // * malloc/free of small objects goes from ~300 ns to ~50 ns.
  86. // * allocation of a reasonably complicated struct
  87. // goes from about 1100 ns to about 300 ns.
  88. #include "config.h"
  89. #include <gperftools/tcmalloc.h>
  90. #include <errno.h> // for ENOMEM, EINVAL, errno
  91. #if defined HAVE_STDINT_H
  92. #include <stdint.h>
  93. #elif defined HAVE_INTTYPES_H
  94. #include <inttypes.h>
  95. #else
  96. #include <sys/types.h>
  97. #endif
  98. #include <stddef.h> // for size_t, NULL
  99. #include <stdlib.h> // for getenv
  100. #include <string.h> // for strcmp, memset, strlen, etc
  101. #ifdef HAVE_UNISTD_H
  102. #include <unistd.h> // for getpagesize, write, etc
  103. #endif
  104. #include <algorithm> // for max, min
  105. #include <limits> // for numeric_limits
  106. #include <new> // for nothrow_t (ptr only), etc
  107. #include <vector> // for vector
  108. #include <gperftools/malloc_extension.h>
  109. #include <gperftools/malloc_hook.h> // for MallocHook
  110. #include "base/basictypes.h" // for int64
  111. #include "base/commandlineflags.h" // for RegisterFlagValidator, etc
  112. #include "base/dynamic_annotations.h" // for RunningOnValgrind
  113. #include "base/spinlock.h" // for SpinLockHolder
  114. #include "central_freelist.h" // for CentralFreeListPadded
  115. #include "common.h" // for StackTrace, kPageShift, etc
  116. #include "internal_logging.h" // for ASSERT, TCMalloc_Printer, etc
  117. #include "linked_list.h" // for SLL_SetNext
  118. #include "malloc_hook-inl.h" // for MallocHook::InvokeNewHook, etc
  119. #include "page_heap.h" // for PageHeap, PageHeap::Stats
  120. #include "page_heap_allocator.h" // for PageHeapAllocator
  121. #include "span.h" // for Span, DLL_Prepend, etc
  122. #include "stack_trace_table.h" // for StackTraceTable
  123. #include "static_vars.h" // for Static
  124. #include "system-alloc.h" // for DumpSystemAllocatorStats, etc
  125. #include "tcmalloc_guard.h" // for TCMallocGuard
  126. #include "thread_cache.h" // for ThreadCache
  127. #ifdef __clang__
  128. // clang's apparent focus on code size somehow causes it to ignore
  129. // normal inline directives even for few functions which inlining is
  130. // key for performance. In order to get performance of clang's
  131. // generated code closer to normal, we're forcing inlining via
  132. // attribute.
  133. #define ALWAYS_INLINE inline __attribute__((always_inline))
  134. #else
  135. #define ALWAYS_INLINE inline
  136. #endif
  137. #include "maybe_emergency_malloc.h"
  138. #if (defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)) && !defined(WIN32_OVERRIDE_ALLOCATORS)
  139. # define WIN32_DO_PATCHING 1
  140. #endif
  141. // Some windows file somewhere (at least on cygwin) #define's small (!)
  142. #undef small
  143. using STL_NAMESPACE::max;
  144. using STL_NAMESPACE::numeric_limits;
  145. using STL_NAMESPACE::vector;
  146. #include "libc_override.h"
  147. using tcmalloc::AlignmentForSize;
  148. using tcmalloc::kLog;
  149. using tcmalloc::kCrash;
  150. using tcmalloc::kCrashWithStats;
  151. using tcmalloc::Log;
  152. using tcmalloc::PageHeap;
  153. using tcmalloc::PageHeapAllocator;
  154. using tcmalloc::SizeMap;
  155. using tcmalloc::Span;
  156. using tcmalloc::StackTrace;
  157. using tcmalloc::Static;
  158. using tcmalloc::ThreadCache;
  159. DECLARE_double(tcmalloc_release_rate);
  160. // For windows, the printf we use to report large allocs is
  161. // potentially dangerous: it could cause a malloc that would cause an
  162. // infinite loop. So by default we set the threshold to a huge number
  163. // on windows, so this bad situation will never trigger. You can
  164. // always set TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD manually if you
  165. // want this functionality.
  166. #ifdef _WIN32
  167. const int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 62;
  168. #else
  169. const int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 30;
  170. #endif
  171. DEFINE_int64(tcmalloc_large_alloc_report_threshold,
  172. EnvToInt64("TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD",
  173. kDefaultLargeAllocReportThreshold),
  174. "Allocations larger than this value cause a stack "
  175. "trace to be dumped to stderr. The threshold for "
  176. "dumping stack traces is increased by a factor of 1.125 "
  177. "every time we print a message so that the threshold "
  178. "automatically goes up by a factor of ~1000 every 60 "
  179. "messages. This bounds the amount of extra logging "
  180. "generated by this flag. Default value of this flag "
  181. "is very large and therefore you should see no extra "
  182. "logging unless the flag is overridden. Set to 0 to "
  183. "disable reporting entirely.");
  184. // We already declared these functions in tcmalloc.h, but we have to
  185. // declare them again to give them an ATTRIBUTE_SECTION: we want to
  186. // put all callers of MallocHook::Invoke* in this module into
  187. // ATTRIBUTE_SECTION(google_malloc) section, so that
  188. // MallocHook::GetCallerStackTrace can function accurately.
  189. #ifndef _WIN32 // windows doesn't have attribute_section, so don't bother
  190. extern "C" {
  191. void* tc_malloc(size_t size) PERFTOOLS_THROW
  192. ATTRIBUTE_SECTION(google_malloc);
  193. void tc_free(void* ptr) PERFTOOLS_THROW
  194. ATTRIBUTE_SECTION(google_malloc);
  195. void* tc_realloc(void* ptr, size_t size) PERFTOOLS_THROW
  196. ATTRIBUTE_SECTION(google_malloc);
  197. void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_THROW
  198. ATTRIBUTE_SECTION(google_malloc);
  199. void tc_cfree(void* ptr) PERFTOOLS_THROW
  200. ATTRIBUTE_SECTION(google_malloc);
  201. void* tc_memalign(size_t __alignment, size_t __size) PERFTOOLS_THROW
  202. ATTRIBUTE_SECTION(google_malloc);
  203. int tc_posix_memalign(void** ptr, size_t align, size_t size) PERFTOOLS_THROW
  204. ATTRIBUTE_SECTION(google_malloc);
  205. void* tc_valloc(size_t __size) PERFTOOLS_THROW
  206. ATTRIBUTE_SECTION(google_malloc);
  207. void* tc_pvalloc(size_t __size) PERFTOOLS_THROW
  208. ATTRIBUTE_SECTION(google_malloc);
  209. void tc_malloc_stats(void) PERFTOOLS_THROW
  210. ATTRIBUTE_SECTION(google_malloc);
  211. int tc_mallopt(int cmd, int value) PERFTOOLS_THROW
  212. ATTRIBUTE_SECTION(google_malloc);
  213. #ifdef HAVE_STRUCT_MALLINFO
  214. struct mallinfo tc_mallinfo(void) PERFTOOLS_THROW
  215. ATTRIBUTE_SECTION(google_malloc);
  216. #endif
  217. void* tc_new(size_t size)
  218. ATTRIBUTE_SECTION(google_malloc);
  219. void tc_delete(void* p) PERFTOOLS_THROW
  220. ATTRIBUTE_SECTION(google_malloc);
  221. void* tc_newarray(size_t size)
  222. ATTRIBUTE_SECTION(google_malloc);
  223. void tc_deletearray(void* p) PERFTOOLS_THROW
  224. ATTRIBUTE_SECTION(google_malloc);
  225. // And the nothrow variants of these:
  226. void* tc_new_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_THROW
  227. ATTRIBUTE_SECTION(google_malloc);
  228. void* tc_newarray_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_THROW
  229. ATTRIBUTE_SECTION(google_malloc);
  230. // Surprisingly, standard C++ library implementations use a
  231. // nothrow-delete internally. See, eg:
  232. // http://www.dinkumware.com/manuals/?manual=compleat&page=new.html
  233. void tc_delete_nothrow(void* ptr, const std::nothrow_t&) PERFTOOLS_THROW
  234. ATTRIBUTE_SECTION(google_malloc);
  235. void tc_deletearray_nothrow(void* ptr, const std::nothrow_t&) PERFTOOLS_THROW
  236. ATTRIBUTE_SECTION(google_malloc);
  237. // Some non-standard extensions that we support.
  238. // This is equivalent to
  239. // OS X: malloc_size()
  240. // glibc: malloc_usable_size()
  241. // Windows: _msize()
  242. size_t tc_malloc_size(void* p) PERFTOOLS_THROW
  243. ATTRIBUTE_SECTION(google_malloc);
  244. } // extern "C"
  245. #endif // #ifndef _WIN32
  246. // ----------------------- IMPLEMENTATION -------------------------------
  247. static int tc_new_mode = 0; // See tc_set_new_mode().
  248. // Routines such as free() and realloc() catch some erroneous pointers
  249. // passed to them, and invoke the below when they do. (An erroneous pointer
  250. // won't be caught if it's within a valid span or a stale span for which
  251. // the pagemap cache has a non-zero sizeclass.) This is a cheap (source-editing
  252. // required) kind of exception handling for these routines.
  253. namespace {
  254. void InvalidFree(void* ptr) {
  255. if (tcmalloc::IsEmergencyPtr(ptr)) {
  256. tcmalloc::EmergencyFree(ptr);
  257. return;
  258. }
  259. Log(kCrash, __FILE__, __LINE__, "Attempt to free invalid pointer", ptr);
  260. }
  261. size_t InvalidGetSizeForRealloc(const void* old_ptr) {
  262. Log(kCrash, __FILE__, __LINE__,
  263. "Attempt to realloc invalid pointer", old_ptr);
  264. return 0;
  265. }
  266. size_t InvalidGetAllocatedSize(const void* ptr) {
  267. Log(kCrash, __FILE__, __LINE__,
  268. "Attempt to get the size of an invalid pointer", ptr);
  269. return 0;
  270. }
  271. } // unnamed namespace
  272. // Extract interesting stats
  273. struct TCMallocStats {
  274. uint64_t thread_bytes; // Bytes in thread caches
  275. uint64_t central_bytes; // Bytes in central cache
  276. uint64_t transfer_bytes; // Bytes in central transfer cache
  277. uint64_t metadata_bytes; // Bytes alloced for metadata
  278. PageHeap::Stats pageheap; // Stats from page heap
  279. };
  280. // Get stats into "r". Also, if class_count != NULL, class_count[k]
  281. // will be set to the total number of objects of size class k in the
  282. // central cache, transfer cache, and per-thread caches. If small_spans
  283. // is non-NULL, it is filled. Same for large_spans.
  284. static void ExtractStats(TCMallocStats* r, uint64_t* class_count,
  285. PageHeap::SmallSpanStats* small_spans,
  286. PageHeap::LargeSpanStats* large_spans) {
  287. r->central_bytes = 0;
  288. r->transfer_bytes = 0;
  289. for (int cl = 0; cl < kNumClasses; ++cl) {
  290. const int length = Static::central_cache()[cl].length();
  291. const int tc_length = Static::central_cache()[cl].tc_length();
  292. const size_t cache_overhead = Static::central_cache()[cl].OverheadBytes();
  293. const size_t size = static_cast<uint64_t>(
  294. Static::sizemap()->ByteSizeForClass(cl));
  295. r->central_bytes += (size * length) + cache_overhead;
  296. r->transfer_bytes += (size * tc_length);
  297. if (class_count) {
  298. // Sum the lengths of all per-class freelists, except the per-thread
  299. // freelists, which get counted when we call GetThreadStats(), below.
  300. class_count[cl] = length + tc_length;
  301. }
  302. }
  303. // Add stats from per-thread heaps
  304. r->thread_bytes = 0;
  305. { // scope
  306. SpinLockHolder h(Static::pageheap_lock());
  307. ThreadCache::GetThreadStats(&r->thread_bytes, class_count);
  308. r->metadata_bytes = tcmalloc::metadata_system_bytes();
  309. r->pageheap = Static::pageheap()->stats();
  310. if (small_spans != NULL) {
  311. Static::pageheap()->GetSmallSpanStats(small_spans);
  312. }
  313. if (large_spans != NULL) {
  314. Static::pageheap()->GetLargeSpanStats(large_spans);
  315. }
  316. }
  317. }
  318. #ifndef TCMALLOC_SGX
  319. static double PagesToMiB(uint64_t pages) {
  320. return (pages << kPageShift) / 1048576.0;
  321. }
  322. #endif
  323. // WRITE stats to "out"
  324. static void DumpStats(TCMalloc_Printer* out, int level) {
  325. #ifndef TCMALLOC_SGX /*currently this function is disabled in SGX*/
  326. TCMallocStats stats;
  327. uint64_t class_count[kNumClasses];
  328. PageHeap::SmallSpanStats small;
  329. PageHeap::LargeSpanStats large;
  330. if (level >= 2) {
  331. ExtractStats(&stats, class_count, &small, &large);
  332. } else {
  333. ExtractStats(&stats, NULL, NULL, NULL);
  334. }
  335. static const double MiB = 1048576.0;
  336. const uint64_t virtual_memory_used = (stats.pageheap.system_bytes
  337. + stats.metadata_bytes);
  338. const uint64_t physical_memory_used = (virtual_memory_used
  339. - stats.pageheap.unmapped_bytes);
  340. const uint64_t bytes_in_use_by_app = (physical_memory_used
  341. - stats.metadata_bytes
  342. - stats.pageheap.free_bytes
  343. - stats.central_bytes
  344. - stats.transfer_bytes
  345. - stats.thread_bytes);
  346. #ifdef TCMALLOC_SMALL_BUT_SLOW
  347. out->printf(
  348. "NOTE: SMALL MEMORY MODEL IS IN USE, PERFORMANCE MAY SUFFER.\n");
  349. #endif
  350. out->printf(
  351. "------------------------------------------------\n"
  352. "MALLOC: %12" PRIu64 " (%7.1f MiB) Bytes in use by application\n"
  353. "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in page heap freelist\n"
  354. "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in central cache freelist\n"
  355. "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in transfer cache freelist\n"
  356. "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in thread cache freelists\n"
  357. "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in malloc metadata\n"
  358. "MALLOC: ------------\n"
  359. "MALLOC: = %12" PRIu64 " (%7.1f MiB) Actual memory used (physical + swap)\n"
  360. "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes released to OS (aka unmapped)\n"
  361. "MALLOC: ------------\n"
  362. "MALLOC: = %12" PRIu64 " (%7.1f MiB) Virtual address space used\n"
  363. "MALLOC:\n"
  364. "MALLOC: %12" PRIu64 " Spans in use\n"
  365. "MALLOC: %12" PRIu64 " Thread heaps in use\n"
  366. "MALLOC: %12" PRIu64 " Tcmalloc page size\n"
  367. "------------------------------------------------\n"
  368. "Call ReleaseFreeMemory() to release freelist memory to the OS"
  369. " (via madvise()).\n"
  370. "Bytes released to the OS take up virtual address space"
  371. " but no physical memory.\n",
  372. bytes_in_use_by_app, bytes_in_use_by_app / MiB,
  373. stats.pageheap.free_bytes, stats.pageheap.free_bytes / MiB,
  374. stats.central_bytes, stats.central_bytes / MiB,
  375. stats.transfer_bytes, stats.transfer_bytes / MiB,
  376. stats.thread_bytes, stats.thread_bytes / MiB,
  377. stats.metadata_bytes, stats.metadata_bytes / MiB,
  378. physical_memory_used, physical_memory_used / MiB,
  379. stats.pageheap.unmapped_bytes, stats.pageheap.unmapped_bytes / MiB,
  380. virtual_memory_used, virtual_memory_used / MiB,
  381. uint64_t(Static::span_allocator()->inuse()),
  382. uint64_t(ThreadCache::HeapsInUse()),
  383. uint64_t(kPageSize));
  384. if (level >= 2) {
  385. out->printf("------------------------------------------------\n");
  386. out->printf("Total size of freelists for per-thread caches,\n");
  387. out->printf("transfer cache, and central cache, by size class\n");
  388. out->printf("------------------------------------------------\n");
  389. uint64_t cumulative = 0;
  390. for (int cl = 0; cl < kNumClasses; ++cl) {
  391. if (class_count[cl] > 0) {
  392. uint64_t class_bytes =
  393. class_count[cl] * Static::sizemap()->ByteSizeForClass(cl);
  394. cumulative += class_bytes;
  395. out->printf("class %3d [ %8" PRIuS " bytes ] : "
  396. "%8" PRIu64 " objs; %5.1f MiB; %5.1f cum MiB\n",
  397. cl, Static::sizemap()->ByteSizeForClass(cl),
  398. class_count[cl],
  399. class_bytes / MiB,
  400. cumulative / MiB);
  401. }
  402. }
  403. // append page heap info
  404. int nonempty_sizes = 0;
  405. for (int s = 0; s < kMaxPages; s++) {
  406. if (small.normal_length[s] + small.returned_length[s] > 0) {
  407. nonempty_sizes++;
  408. }
  409. }
  410. out->printf("------------------------------------------------\n");
  411. out->printf("PageHeap: %d sizes; %6.1f MiB free; %6.1f MiB unmapped\n",
  412. nonempty_sizes, stats.pageheap.free_bytes / MiB,
  413. stats.pageheap.unmapped_bytes / MiB);
  414. out->printf("------------------------------------------------\n");
  415. uint64_t total_normal = 0;
  416. uint64_t total_returned = 0;
  417. for (int s = 0; s < kMaxPages; s++) {
  418. const int n_length = small.normal_length[s];
  419. const int r_length = small.returned_length[s];
  420. if (n_length + r_length > 0) {
  421. uint64_t n_pages = s * n_length;
  422. uint64_t r_pages = s * r_length;
  423. total_normal += n_pages;
  424. total_returned += r_pages;
  425. out->printf("%6u pages * %6u spans ~ %6.1f MiB; %6.1f MiB cum"
  426. "; unmapped: %6.1f MiB; %6.1f MiB cum\n",
  427. s,
  428. (n_length + r_length),
  429. PagesToMiB(n_pages + r_pages),
  430. PagesToMiB(total_normal + total_returned),
  431. PagesToMiB(r_pages),
  432. PagesToMiB(total_returned));
  433. }
  434. }
  435. total_normal += large.normal_pages;
  436. total_returned += large.returned_pages;
  437. out->printf(">255 large * %6u spans ~ %6.1f MiB; %6.1f MiB cum"
  438. "; unmapped: %6.1f MiB; %6.1f MiB cum\n",
  439. static_cast<unsigned int>(large.spans),
  440. PagesToMiB(large.normal_pages + large.returned_pages),
  441. PagesToMiB(total_normal + total_returned),
  442. PagesToMiB(large.returned_pages),
  443. PagesToMiB(total_returned));
  444. }
  445. #endif
  446. }
  447. static void PrintStats(int level) {
  448. const int kBufferSize = 16 << 10;
  449. char* buffer = new char[kBufferSize];
  450. TCMalloc_Printer printer(buffer, kBufferSize);
  451. DumpStats(&printer, level);
  452. write(STDERR_FILENO, buffer, strlen(buffer));
  453. delete[] buffer;
  454. }
  455. static void** DumpHeapGrowthStackTraces() {
  456. // Count how much space we need
  457. int needed_slots = 0;
  458. {
  459. SpinLockHolder h(Static::pageheap_lock());
  460. for (StackTrace* t = Static::growth_stacks();
  461. t != NULL;
  462. t = reinterpret_cast<StackTrace*>(
  463. t->stack[tcmalloc::kMaxStackDepth-1])) {
  464. needed_slots += 3 + t->depth;
  465. }
  466. needed_slots += 100; // Slop in case list grows
  467. needed_slots += needed_slots/8; // An extra 12.5% slop
  468. }
  469. void** result = new void*[needed_slots];
  470. if (result == NULL) {
  471. Log(kLog, __FILE__, __LINE__,
  472. "tcmalloc: allocation failed for stack trace slots",
  473. needed_slots * sizeof(*result));
  474. return NULL;
  475. }
  476. SpinLockHolder h(Static::pageheap_lock());
  477. int used_slots = 0;
  478. for (StackTrace* t = Static::growth_stacks();
  479. t != NULL;
  480. t = reinterpret_cast<StackTrace*>(
  481. t->stack[tcmalloc::kMaxStackDepth-1])) {
  482. ASSERT(used_slots < needed_slots); // Need to leave room for terminator
  483. if (used_slots + 3 + t->depth >= needed_slots) {
  484. // No more room
  485. break;
  486. }
  487. result[used_slots+0] = reinterpret_cast<void*>(static_cast<uintptr_t>(1));
  488. result[used_slots+1] = reinterpret_cast<void*>(t->size);
  489. result[used_slots+2] = reinterpret_cast<void*>(t->depth);
  490. for (int d = 0; d < t->depth; d++) {
  491. result[used_slots+3+d] = t->stack[d];
  492. }
  493. used_slots += 3 + t->depth;
  494. }
  495. result[used_slots] = reinterpret_cast<void*>(static_cast<uintptr_t>(0));
  496. return result;
  497. }
  498. static void IterateOverRanges(void* arg, MallocExtension::RangeFunction func) {
  499. PageID page = 1; // Some code may assume that page==0 is never used
  500. bool done = false;
  501. while (!done) {
  502. // Accumulate a small number of ranges in a local buffer
  503. static const int kNumRanges = 16;
  504. static base::MallocRange ranges[kNumRanges];
  505. int n = 0;
  506. {
  507. SpinLockHolder h(Static::pageheap_lock());
  508. while (n < kNumRanges) {
  509. if (!Static::pageheap()->GetNextRange(page, &ranges[n])) {
  510. done = true;
  511. break;
  512. } else {
  513. uintptr_t limit = ranges[n].address + ranges[n].length;
  514. page = (limit + kPageSize - 1) >> kPageShift;
  515. n++;
  516. }
  517. }
  518. }
  519. for (int i = 0; i < n; i++) {
  520. (*func)(arg, &ranges[i]);
  521. }
  522. }
  523. }
  524. // TCMalloc's support for extra malloc interfaces
  525. class TCMallocImplementation : public MallocExtension {
  526. private:
  527. // ReleaseToSystem() might release more than the requested bytes because
  528. // the page heap releases at the span granularity, and spans are of wildly
  529. // different sizes. This member keeps track of the extra bytes bytes
  530. // released so that the app can periodically call ReleaseToSystem() to
  531. // release memory at a constant rate.
  532. // NOTE: Protected by Static::pageheap_lock().
  533. size_t extra_bytes_released_;
  534. public:
  535. TCMallocImplementation()
  536. : extra_bytes_released_(0) {
  537. }
  538. virtual void GetStats(char* buffer, int buffer_length) {
  539. ASSERT(buffer_length > 0);
  540. TCMalloc_Printer printer(buffer, buffer_length);
  541. // Print level one stats unless lots of space is available
  542. if (buffer_length < 10000) {
  543. DumpStats(&printer, 1);
  544. } else {
  545. DumpStats(&printer, 2);
  546. }
  547. }
  548. // We may print an extra, tcmalloc-specific warning message here.
  549. virtual void GetHeapSample(MallocExtensionWriter* writer) {
  550. if (FLAGS_tcmalloc_sample_parameter == 0) {
  551. const char* const kWarningMsg =
  552. "%warn\n"
  553. "%warn This heap profile does not have any data in it, because\n"
  554. "%warn the application was run with heap sampling turned off.\n"
  555. "%warn To get useful data from GetHeapSample(), you must\n"
  556. "%warn set the environment variable TCMALLOC_SAMPLE_PARAMETER to\n"
  557. "%warn a positive sampling period, such as 524288.\n"
  558. "%warn\n";
  559. writer->append(kWarningMsg, strlen(kWarningMsg));
  560. }
  561. MallocExtension::GetHeapSample(writer);
  562. }
  563. virtual void** ReadStackTraces(int* sample_period) {
  564. tcmalloc::StackTraceTable table;
  565. {
  566. SpinLockHolder h(Static::pageheap_lock());
  567. Span* sampled = Static::sampled_objects();
  568. for (Span* s = sampled->next; s != sampled; s = s->next) {
  569. table.AddTrace(*reinterpret_cast<StackTrace*>(s->objects));
  570. }
  571. }
  572. *sample_period = ThreadCache::GetCache()->GetSamplePeriod();
  573. return table.ReadStackTracesAndClear(); // grabs and releases pageheap_lock
  574. }
  575. virtual void** ReadHeapGrowthStackTraces() {
  576. return DumpHeapGrowthStackTraces();
  577. }
  578. virtual size_t GetThreadCacheSize() {
  579. ThreadCache* tc = ThreadCache::GetCacheIfPresent();
  580. if (!tc)
  581. return 0;
  582. return tc->Size();
  583. }
  584. virtual void MarkThreadTemporarilyIdle() {
  585. ThreadCache::BecomeTemporarilyIdle();
  586. }
  587. virtual void Ranges(void* arg, RangeFunction func) {
  588. IterateOverRanges(arg, func);
  589. }
  590. virtual bool GetNumericProperty(const char* name, size_t* value) {
  591. ASSERT(name != NULL);
  592. if (strcmp(name, "generic.current_allocated_bytes") == 0) {
  593. TCMallocStats stats;
  594. ExtractStats(&stats, NULL, NULL, NULL);
  595. *value = stats.pageheap.system_bytes
  596. - stats.thread_bytes
  597. - stats.central_bytes
  598. - stats.transfer_bytes
  599. - stats.pageheap.free_bytes
  600. - stats.pageheap.unmapped_bytes;
  601. return true;
  602. }
  603. if (strcmp(name, "generic.heap_size") == 0) {
  604. TCMallocStats stats;
  605. ExtractStats(&stats, NULL, NULL, NULL);
  606. *value = stats.pageheap.system_bytes;
  607. return true;
  608. }
  609. if (strcmp(name, "tcmalloc.slack_bytes") == 0) {
  610. // Kept for backwards compatibility. Now defined externally as:
  611. // pageheap_free_bytes + pageheap_unmapped_bytes.
  612. SpinLockHolder l(Static::pageheap_lock());
  613. PageHeap::Stats stats = Static::pageheap()->stats();
  614. *value = stats.free_bytes + stats.unmapped_bytes;
  615. return true;
  616. }
  617. if (strcmp(name, "tcmalloc.central_cache_free_bytes") == 0) {
  618. TCMallocStats stats;
  619. ExtractStats(&stats, NULL, NULL, NULL);
  620. *value = stats.central_bytes;
  621. return true;
  622. }
  623. if (strcmp(name, "tcmalloc.transfer_cache_free_bytes") == 0) {
  624. TCMallocStats stats;
  625. ExtractStats(&stats, NULL, NULL, NULL);
  626. *value = stats.transfer_bytes;
  627. return true;
  628. }
  629. if (strcmp(name, "tcmalloc.thread_cache_free_bytes") == 0) {
  630. TCMallocStats stats;
  631. ExtractStats(&stats, NULL, NULL, NULL);
  632. *value = stats.thread_bytes;
  633. return true;
  634. }
  635. if (strcmp(name, "tcmalloc.pageheap_free_bytes") == 0) {
  636. SpinLockHolder l(Static::pageheap_lock());
  637. *value = Static::pageheap()->stats().free_bytes;
  638. return true;
  639. }
  640. if (strcmp(name, "tcmalloc.pageheap_unmapped_bytes") == 0) {
  641. SpinLockHolder l(Static::pageheap_lock());
  642. *value = Static::pageheap()->stats().unmapped_bytes;
  643. return true;
  644. }
  645. if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) {
  646. SpinLockHolder l(Static::pageheap_lock());
  647. *value = ThreadCache::overall_thread_cache_size();
  648. return true;
  649. }
  650. if (strcmp(name, "tcmalloc.current_total_thread_cache_bytes") == 0) {
  651. TCMallocStats stats;
  652. ExtractStats(&stats, NULL, NULL, NULL);
  653. *value = stats.thread_bytes;
  654. return true;
  655. }
  656. if (strcmp(name, "tcmalloc.aggressive_memory_decommit") == 0) {
  657. *value = size_t(Static::pageheap()->GetAggressiveDecommit());
  658. return true;
  659. }
  660. return false;
  661. }
  662. virtual bool SetNumericProperty(const char* name, size_t value) {
  663. ASSERT(name != NULL);
  664. if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) {
  665. SpinLockHolder l(Static::pageheap_lock());
  666. ThreadCache::set_overall_thread_cache_size(value);
  667. return true;
  668. }
  669. if (strcmp(name, "tcmalloc.aggressive_memory_decommit") == 0) {
  670. Static::pageheap()->SetAggressiveDecommit(value != 0);
  671. return true;
  672. }
  673. return false;
  674. }
  675. virtual void MarkThreadIdle() {
  676. ThreadCache::BecomeIdle();
  677. }
  678. virtual void MarkThreadBusy(); // Implemented below
  679. virtual SysAllocator* GetSystemAllocator() {
  680. SpinLockHolder h(Static::pageheap_lock());
  681. return sys_alloc;
  682. }
  683. virtual void SetSystemAllocator(SysAllocator* alloc) {
  684. SpinLockHolder h(Static::pageheap_lock());
  685. sys_alloc = alloc;
  686. }
  687. virtual void ReleaseToSystem(size_t num_bytes) {
  688. SpinLockHolder h(Static::pageheap_lock());
  689. if (num_bytes <= extra_bytes_released_) {
  690. // We released too much on a prior call, so don't release any
  691. // more this time.
  692. extra_bytes_released_ = extra_bytes_released_ - num_bytes;
  693. return;
  694. }
  695. num_bytes = num_bytes - extra_bytes_released_;
  696. // num_bytes might be less than one page. If we pass zero to
  697. // ReleaseAtLeastNPages, it won't do anything, so we release a whole
  698. // page now and let extra_bytes_released_ smooth it out over time.
  699. Length num_pages = max<Length>(num_bytes >> kPageShift, 1);
  700. size_t bytes_released = Static::pageheap()->ReleaseAtLeastNPages(
  701. num_pages) << kPageShift;
  702. if (bytes_released > num_bytes) {
  703. extra_bytes_released_ = bytes_released - num_bytes;
  704. } else {
  705. // The PageHeap wasn't able to release num_bytes. Don't try to
  706. // compensate with a big release next time. Specifically,
  707. // ReleaseFreeMemory() calls ReleaseToSystem(LONG_MAX).
  708. extra_bytes_released_ = 0;
  709. }
  710. }
  711. virtual void SetMemoryReleaseRate(double rate) {
  712. FLAGS_tcmalloc_release_rate = rate;
  713. }
  714. virtual double GetMemoryReleaseRate() {
  715. return FLAGS_tcmalloc_release_rate;
  716. }
  717. virtual size_t GetEstimatedAllocatedSize(size_t size) {
  718. if (size <= kMaxSize) {
  719. const size_t cl = Static::sizemap()->SizeClass(size);
  720. const size_t alloc_size = Static::sizemap()->ByteSizeForClass(cl);
  721. return alloc_size;
  722. } else {
  723. return tcmalloc::pages(size) << kPageShift;
  724. }
  725. }
  726. // This just calls GetSizeWithCallback, but because that's in an
  727. // unnamed namespace, we need to move the definition below it in the
  728. // file.
  729. virtual size_t GetAllocatedSize(const void* ptr);
  730. // This duplicates some of the logic in GetSizeWithCallback, but is
  731. // faster. This is important on OS X, where this function is called
  732. // on every allocation operation.
  733. virtual Ownership GetOwnership(const void* ptr) {
  734. const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
  735. // The rest of tcmalloc assumes that all allocated pointers use at
  736. // most kAddressBits bits. If ptr doesn't, then it definitely
  737. // wasn't alloacted by tcmalloc.
  738. if ((p >> (kAddressBits - kPageShift)) > 0) {
  739. return kNotOwned;
  740. }
  741. size_t cl = Static::pageheap()->GetSizeClassIfCached(p);
  742. if (cl != 0) {
  743. return kOwned;
  744. }
  745. const Span *span = Static::pageheap()->GetDescriptor(p);
  746. return span ? kOwned : kNotOwned;
  747. }
  748. virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {
  749. static const char* kCentralCacheType = "tcmalloc.central";
  750. static const char* kTransferCacheType = "tcmalloc.transfer";
  751. static const char* kThreadCacheType = "tcmalloc.thread";
  752. static const char* kPageHeapType = "tcmalloc.page";
  753. static const char* kPageHeapUnmappedType = "tcmalloc.page_unmapped";
  754. static const char* kLargeSpanType = "tcmalloc.large";
  755. static const char* kLargeUnmappedSpanType = "tcmalloc.large_unmapped";
  756. v->clear();
  757. // central class information
  758. int64 prev_class_size = 0;
  759. for (int cl = 1; cl < kNumClasses; ++cl) {
  760. size_t class_size = Static::sizemap()->ByteSizeForClass(cl);
  761. MallocExtension::FreeListInfo i;
  762. i.min_object_size = prev_class_size + 1;
  763. i.max_object_size = class_size;
  764. i.total_bytes_free =
  765. Static::central_cache()[cl].length() * class_size;
  766. i.type = kCentralCacheType;
  767. v->push_back(i);
  768. // transfer cache
  769. i.total_bytes_free =
  770. Static::central_cache()[cl].tc_length() * class_size;
  771. i.type = kTransferCacheType;
  772. v->push_back(i);
  773. prev_class_size = Static::sizemap()->ByteSizeForClass(cl);
  774. }
  775. // Add stats from per-thread heaps
  776. uint64_t class_count[kNumClasses];
  777. memset(class_count, 0, sizeof(class_count));
  778. {
  779. SpinLockHolder h(Static::pageheap_lock());
  780. uint64_t thread_bytes = 0;
  781. ThreadCache::GetThreadStats(&thread_bytes, class_count);
  782. }
  783. prev_class_size = 0;
  784. for (int cl = 1; cl < kNumClasses; ++cl) {
  785. MallocExtension::FreeListInfo i;
  786. i.min_object_size = prev_class_size + 1;
  787. i.max_object_size = Static::sizemap()->ByteSizeForClass(cl);
  788. i.total_bytes_free =
  789. class_count[cl] * Static::sizemap()->ByteSizeForClass(cl);
  790. i.type = kThreadCacheType;
  791. v->push_back(i);
  792. }
  793. // append page heap info
  794. PageHeap::SmallSpanStats small;
  795. PageHeap::LargeSpanStats large;
  796. {
  797. SpinLockHolder h(Static::pageheap_lock());
  798. Static::pageheap()->GetSmallSpanStats(&small);
  799. Static::pageheap()->GetLargeSpanStats(&large);
  800. }
  801. // large spans: mapped
  802. MallocExtension::FreeListInfo span_info;
  803. span_info.type = kLargeSpanType;
  804. span_info.max_object_size = (numeric_limits<size_t>::max)();
  805. span_info.min_object_size = kMaxPages << kPageShift;
  806. span_info.total_bytes_free = large.normal_pages << kPageShift;
  807. v->push_back(span_info);
  808. // large spans: unmapped
  809. span_info.type = kLargeUnmappedSpanType;
  810. span_info.total_bytes_free = large.returned_pages << kPageShift;
  811. v->push_back(span_info);
  812. // small spans
  813. for (int s = 1; s < kMaxPages; s++) {
  814. MallocExtension::FreeListInfo i;
  815. i.max_object_size = (s << kPageShift);
  816. i.min_object_size = ((s - 1) << kPageShift);
  817. i.type = kPageHeapType;
  818. i.total_bytes_free = (s << kPageShift) * small.normal_length[s];
  819. v->push_back(i);
  820. i.type = kPageHeapUnmappedType;
  821. i.total_bytes_free = (s << kPageShift) * small.returned_length[s];
  822. v->push_back(i);
  823. }
  824. }
  825. };
  826. // The constructor allocates an object to ensure that initialization
  827. // runs before main(), and therefore we do not have a chance to become
  828. // multi-threaded before initialization. We also create the TSD key
  829. // here. Presumably by the time this constructor runs, glibc is in
  830. // good enough shape to handle pthread_key_create().
  831. //
  832. // The constructor also takes the opportunity to tell STL to use
  833. // tcmalloc. We want to do this early, before construct time, so
  834. // all user STL allocations go through tcmalloc (which works really
  835. // well for STL).
  836. //
  837. // The destructor prints stats when the program exits.
  838. static int tcmallocguard_refcount = 0; // no lock needed: runs before main()
  839. TCMallocGuard::TCMallocGuard() {
  840. if (tcmallocguard_refcount++ == 0) {
  841. ReplaceSystemAlloc(); // defined in libc_override_*.h
  842. tc_free(tc_malloc(1));
  843. ThreadCache::InitTSD();
  844. tc_free(tc_malloc(1));
  845. // Either we, or debugallocation.cc, or valgrind will control memory
  846. // management. We register our extension if we're the winner.
  847. #ifdef TCMALLOC_USING_DEBUGALLOCATION
  848. // Let debugallocation register its extension.
  849. #else
  850. if (RunningOnValgrind()) {
  851. // Let Valgrind uses its own malloc (so don't register our extension).
  852. } else {
  853. MallocExtension::Register(new TCMallocImplementation);
  854. }
  855. #endif
  856. }
  857. }
  858. TCMallocGuard::~TCMallocGuard() {
  859. if (--tcmallocguard_refcount == 0) {
  860. const char* env = NULL;
  861. if (!RunningOnValgrind()) {
  862. // Valgrind uses it's own malloc so we cannot do MALLOCSTATS
  863. env = getenv("MALLOCSTATS");
  864. }
  865. if (env != NULL) {
  866. int level = atoi(env);
  867. if (level < 1) level = 1;
  868. PrintStats(level);
  869. }
  870. }
  871. }
  872. #ifndef WIN32_OVERRIDE_ALLOCATORS
  873. static TCMallocGuard module_enter_exit_hook;
  874. #endif
  875. //-------------------------------------------------------------------
  876. // Helpers for the exported routines below
  877. //-------------------------------------------------------------------
  878. static inline bool CheckCachedSizeClass(void *ptr) {
  879. PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
  880. size_t cached_value = Static::pageheap()->GetSizeClassIfCached(p);
  881. return cached_value == 0 ||
  882. cached_value == Static::pageheap()->GetDescriptor(p)->sizeclass;
  883. }
  884. static inline void* CheckedMallocResult(void *result) {
  885. ASSERT(result == NULL || CheckCachedSizeClass(result));
  886. return result;
  887. }
  888. static inline void* SpanToMallocResult(Span *span) {
  889. Static::pageheap()->CacheSizeClass(span->start, 0);
  890. return
  891. CheckedMallocResult(reinterpret_cast<void*>(span->start << kPageShift));
  892. }
  893. static void* DoSampledAllocation(size_t size) {
  894. #ifndef NO_TCMALLOC_SAMPLES
  895. // Grab the stack trace outside the heap lock
  896. StackTrace tmp;
  897. tmp.depth = GetStackTrace(tmp.stack, tcmalloc::kMaxStackDepth, 1);
  898. tmp.size = size;
  899. SpinLockHolder h(Static::pageheap_lock());
  900. // Allocate span
  901. Span *span = Static::pageheap()->New(tcmalloc::pages(size == 0 ? 1 : size));
  902. if (UNLIKELY(span == NULL)) {
  903. return NULL;
  904. }
  905. // Allocate stack trace
  906. StackTrace *stack = Static::stacktrace_allocator()->New();
  907. if (UNLIKELY(stack == NULL)) {
  908. // Sampling failed because of lack of memory
  909. return span;
  910. }
  911. *stack = tmp;
  912. span->sample = 1;
  913. span->objects = stack;
  914. tcmalloc::DLL_Prepend(Static::sampled_objects(), span);
  915. return SpanToMallocResult(span);
  916. #else
  917. abort();
  918. #endif
  919. }
  920. namespace {
  921. typedef void* (*malloc_fn)(void *arg);
  922. SpinLock set_new_handler_lock(SpinLock::LINKER_INITIALIZED);
  923. void* handle_oom(malloc_fn retry_fn,
  924. void* retry_arg,
  925. bool from_operator,
  926. bool nothrow) {
  927. if (!from_operator && !tc_new_mode) {
  928. // we're out of memory in C library function (malloc etc) and no
  929. // "new mode" forced on us. Just return NULL
  930. return NULL;
  931. }
  932. // we're OOM in operator new or "new mode" is set. We might have to
  933. // call new_handle and maybe retry allocation.
  934. for (;;) {
  935. // Get the current new handler. NB: this function is not
  936. // thread-safe. We make a feeble stab at making it so here, but
  937. // this lock only protects against tcmalloc interfering with
  938. // itself, not with other libraries calling set_new_handler.
  939. std::new_handler nh;
  940. {
  941. SpinLockHolder h(&set_new_handler_lock);
  942. nh = std::set_new_handler(0);
  943. (void) std::set_new_handler(nh);
  944. }
  945. #if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
  946. if (!nh) {
  947. return NULL;
  948. }
  949. // Since exceptions are disabled, we don't really know if new_handler
  950. // failed. Assume it will abort if it fails.
  951. (*nh)();
  952. #else
  953. // If no new_handler is established, the allocation failed.
  954. if (!nh) {
  955. if (nothrow) {
  956. return NULL;
  957. }
  958. throw std::bad_alloc();
  959. }
  960. // Otherwise, try the new_handler. If it returns, retry the
  961. // allocation. If it throws std::bad_alloc, fail the allocation.
  962. // if it throws something else, don't interfere.
  963. try {
  964. (*nh)();
  965. } catch (const std::bad_alloc&) {
  966. if (!nothrow) throw;
  967. return NULL;
  968. }
  969. #endif // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
  970. // we get here if new_handler returns successfully. So we retry
  971. // allocation.
  972. void* rv = retry_fn(retry_arg);
  973. if (rv != NULL) {
  974. return rv;
  975. }
  976. // if allocation failed again we go to next loop iteration
  977. }
  978. }
  979. // Copy of FLAGS_tcmalloc_large_alloc_report_threshold with
  980. // automatic increases factored in.
  981. static int64_t large_alloc_threshold =
  982. (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold
  983. ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold);
  984. static void ReportLargeAlloc(Length num_pages, void* result) {
  985. #ifndef TCMALLOC_SGX /*Currently message output functions are all implemented empty, So set this function empty directly*/
  986. StackTrace stack;
  987. stack.depth = GetStackTrace(stack.stack, tcmalloc::kMaxStackDepth, 1);
  988. static const int N = 1000;
  989. char buffer[N];
  990. TCMalloc_Printer printer(buffer, N);
  991. printer.printf("tcmalloc: large alloc %" PRIu64 " bytes == %p @ ",
  992. static_cast<uint64>(num_pages) << kPageShift,
  993. result);
  994. for (int i = 0; i < stack.depth; i++) {
  995. printer.printf(" %p", stack.stack[i]);
  996. }
  997. printer.printf("\n");
  998. write(STDERR_FILENO, buffer, strlen(buffer));
  999. #endif
  1000. }
  1001. void* do_memalign(size_t align, size_t size);
  1002. struct retry_memaligh_data {
  1003. size_t align;
  1004. size_t size;
  1005. };
  1006. static void *retry_do_memalign(void *arg) {
  1007. retry_memaligh_data *data = static_cast<retry_memaligh_data *>(arg);
  1008. return do_memalign(data->align, data->size);
  1009. }
  1010. static void *maybe_do_cpp_memalign_slow(size_t align, size_t size) {
  1011. retry_memaligh_data data;
  1012. data.align = align;
  1013. data.size = size;
  1014. return handle_oom(retry_do_memalign, &data,
  1015. false, true);
  1016. }
  1017. inline void* do_memalign_or_cpp_memalign(size_t align, size_t size) {
  1018. void *rv = do_memalign(align, size);
  1019. if (LIKELY(rv != NULL)) {
  1020. return rv;
  1021. }
  1022. return maybe_do_cpp_memalign_slow(align, size);
  1023. }
  1024. // Must be called with the page lock held.
  1025. inline bool should_report_large(Length num_pages) {
  1026. const int64 threshold = large_alloc_threshold;
  1027. if (threshold > 0 && num_pages >= (threshold >> kPageShift)) {
  1028. // Increase the threshold by 1/8 every time we generate a report.
  1029. // We cap the threshold at 8GiB to avoid overflow problems.
  1030. large_alloc_threshold = (threshold + threshold/8 < 8ll<<30
  1031. ? threshold + threshold/8 : 8ll<<30);
  1032. return true;
  1033. }
  1034. return false;
  1035. }
  1036. // Helper for do_malloc().
  1037. inline void* do_malloc_pages(ThreadCache* heap, size_t size) {
  1038. void* result;
  1039. bool report_large;
  1040. Length num_pages = tcmalloc::pages(size);
  1041. // NOTE: we're passing original size here as opposed to rounded-up
  1042. // size as we do in do_malloc_small. The difference is small here
  1043. // (at most 4k out of at least 256k). And not rounding up saves us
  1044. // from possibility of overflow, which rounding up could produce.
  1045. //
  1046. // See https://github.com/gperftools/gperftools/issues/723
  1047. if (heap->SampleAllocation(size)) {
  1048. result = DoSampledAllocation(size);
  1049. SpinLockHolder h(Static::pageheap_lock());
  1050. report_large = should_report_large(num_pages);
  1051. } else {
  1052. SpinLockHolder h(Static::pageheap_lock());
  1053. Span* span = Static::pageheap()->New(num_pages);
  1054. result = (UNLIKELY(span == NULL) ? NULL : SpanToMallocResult(span));
  1055. report_large = should_report_large(num_pages);
  1056. }
  1057. if (report_large) {
  1058. ReportLargeAlloc(num_pages, result);
  1059. }
  1060. return result;
  1061. }
  1062. ALWAYS_INLINE void* do_malloc_small(ThreadCache* heap, size_t size) {
  1063. ASSERT(Static::IsInited());
  1064. ASSERT(heap != NULL);
  1065. size_t cl = Static::sizemap()->SizeClass(size);
  1066. size = Static::sizemap()->class_to_size(cl);
  1067. if (UNLIKELY(heap->SampleAllocation(size))) {
  1068. return DoSampledAllocation(size);
  1069. } else {
  1070. // The common case, and also the simplest. This just pops the
  1071. // size-appropriate freelist, after replenishing it if it's empty.
  1072. return CheckedMallocResult(heap->Allocate(size, cl));
  1073. }
  1074. }
  1075. ALWAYS_INLINE void* do_malloc(size_t size) {
  1076. if (ThreadCache::have_tls) {
  1077. if (LIKELY(size < ThreadCache::MinSizeForSlowPath())) {
  1078. return do_malloc_small(ThreadCache::GetCacheWhichMustBePresent(), size);
  1079. }
  1080. if (UNLIKELY(ThreadCache::IsUseEmergencyMalloc())) {
  1081. return tcmalloc::EmergencyMalloc(size);
  1082. }
  1083. }
  1084. if (size <= kMaxSize) {
  1085. return do_malloc_small(ThreadCache::GetCache(), size);
  1086. } else {
  1087. return do_malloc_pages(ThreadCache::GetCache(), size);
  1088. }
  1089. }
  1090. static void *retry_malloc(void* size) {
  1091. return do_malloc(reinterpret_cast<size_t>(size));
  1092. }
  1093. ALWAYS_INLINE void* do_malloc_or_cpp_alloc(size_t size) {
  1094. void *rv = do_malloc(size);
  1095. if (LIKELY(rv != NULL)) {
  1096. return rv;
  1097. }
  1098. return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
  1099. false, true);
  1100. }
  1101. ALWAYS_INLINE void* do_calloc(size_t n, size_t elem_size) {
  1102. // Overflow check
  1103. const size_t size = n * elem_size;
  1104. if (elem_size != 0 && size / elem_size != n) return NULL;
  1105. void* result = do_malloc_or_cpp_alloc(size);
  1106. if (result != NULL) {
  1107. memset(result, 0, size);
  1108. }
  1109. return result;
  1110. }
  1111. // If ptr is NULL, do nothing. Otherwise invoke the given function.
  1112. inline void free_null_or_invalid(void* ptr, void (*invalid_free_fn)(void*)) {
  1113. if (ptr != NULL) {
  1114. (*invalid_free_fn)(ptr);
  1115. }
  1116. }
  1117. // Helper for do_free_with_callback(), below. Inputs:
  1118. // ptr is object to be freed
  1119. // invalid_free_fn is a function that gets invoked on certain "bad frees"
  1120. // heap is the ThreadCache for this thread, or NULL if it isn't known
  1121. // heap_must_be_valid is whether heap is known to be non-NULL
  1122. //
  1123. // This function may only be used after Static::IsInited() is true.
  1124. //
  1125. // We can usually detect the case where ptr is not pointing to a page that
  1126. // tcmalloc is using, and in those cases we invoke invalid_free_fn.
  1127. //
  1128. // To maximize speed in the common case, we usually get here with
  1129. // heap_must_be_valid being a manifest constant equal to true.
  1130. ALWAYS_INLINE void do_free_helper(void* ptr,
  1131. void (*invalid_free_fn)(void*),
  1132. ThreadCache* heap,
  1133. bool heap_must_be_valid,
  1134. bool use_hint,
  1135. size_t size_hint) {
  1136. ASSERT((Static::IsInited() && heap != NULL) || !heap_must_be_valid);
  1137. if (!heap_must_be_valid && !Static::IsInited()) {
  1138. // We called free() before malloc(). This can occur if the
  1139. // (system) malloc() is called before tcmalloc is loaded, and then
  1140. // free() is called after tcmalloc is loaded (and tc_free has
  1141. // replaced free), but before the global constructor has run that
  1142. // sets up the tcmalloc data structures.
  1143. free_null_or_invalid(ptr, invalid_free_fn);
  1144. return;
  1145. }
  1146. Span* span = NULL;
  1147. const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
  1148. size_t cl;
  1149. if (use_hint && Static::sizemap()->MaybeSizeClass(size_hint, &cl)) {
  1150. goto non_zero;
  1151. }
  1152. cl = Static::pageheap()->GetSizeClassIfCached(p);
  1153. if (UNLIKELY(cl == 0)) {
  1154. span = Static::pageheap()->GetDescriptor(p);
  1155. if (UNLIKELY(!span)) {
  1156. // span can be NULL because the pointer passed in is NULL or invalid
  1157. // (not something returned by malloc or friends), or because the
  1158. // pointer was allocated with some other allocator besides
  1159. // tcmalloc. The latter can happen if tcmalloc is linked in via
  1160. // a dynamic library, but is not listed last on the link line.
  1161. // In that case, libraries after it on the link line will
  1162. // allocate with libc malloc, but free with tcmalloc's free.
  1163. free_null_or_invalid(ptr, invalid_free_fn);
  1164. return;
  1165. }
  1166. cl = span->sizeclass;
  1167. Static::pageheap()->CacheSizeClass(p, cl);
  1168. }
  1169. ASSERT(ptr != NULL);
  1170. if (LIKELY(cl != 0)) {
  1171. non_zero:
  1172. ASSERT(!Static::pageheap()->GetDescriptor(p)->sample);
  1173. if (heap_must_be_valid || heap != NULL) {
  1174. heap->Deallocate(ptr, cl);
  1175. } else {
  1176. // Delete directly into central cache
  1177. tcmalloc::SLL_SetNext(ptr, NULL);
  1178. Static::central_cache()[cl].InsertRange(ptr, ptr, 1);
  1179. }
  1180. } else {
  1181. SpinLockHolder h(Static::pageheap_lock());
  1182. ASSERT(reinterpret_cast<uintptr_t>(ptr) % kPageSize == 0);
  1183. ASSERT(span != NULL && span->start == p);
  1184. if (span->sample) {
  1185. StackTrace* st = reinterpret_cast<StackTrace*>(span->objects);
  1186. tcmalloc::DLL_Remove(span);
  1187. Static::stacktrace_allocator()->Delete(st);
  1188. span->objects = NULL;
  1189. }
  1190. Static::pageheap()->Delete(span);
  1191. }
  1192. }
  1193. // Helper for the object deletion (free, delete, etc.). Inputs:
  1194. // ptr is object to be freed
  1195. // invalid_free_fn is a function that gets invoked on certain "bad frees"
  1196. //
  1197. // We can usually detect the case where ptr is not pointing to a page that
  1198. // tcmalloc is using, and in those cases we invoke invalid_free_fn.
  1199. ALWAYS_INLINE void do_free_with_callback(void* ptr,
  1200. void (*invalid_free_fn)(void*),
  1201. bool use_hint, size_t size_hint) {
  1202. ThreadCache* heap = NULL;
  1203. heap = ThreadCache::GetCacheIfPresent();
  1204. if (LIKELY(heap)) {
  1205. do_free_helper(ptr, invalid_free_fn, heap, true, use_hint, size_hint);
  1206. } else {
  1207. do_free_helper(ptr, invalid_free_fn, heap, false, use_hint, size_hint);
  1208. }
  1209. }
  1210. // The default "do_free" that uses the default callback.
  1211. ALWAYS_INLINE void do_free(void* ptr) {
  1212. return do_free_with_callback(ptr, &InvalidFree, false, 0);
  1213. }
  1214. // NOTE: some logic here is duplicated in GetOwnership (above), for
  1215. // speed. If you change this function, look at that one too.
  1216. inline size_t GetSizeWithCallback(const void* ptr,
  1217. size_t (*invalid_getsize_fn)(const void*)) {
  1218. if (ptr == NULL)
  1219. return 0;
  1220. const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
  1221. size_t cl = Static::pageheap()->GetSizeClassIfCached(p);
  1222. if (cl != 0) {
  1223. return Static::sizemap()->ByteSizeForClass(cl);
  1224. } else {
  1225. const Span *span = Static::pageheap()->GetDescriptor(p);
  1226. if (UNLIKELY(span == NULL)) { // means we do not own this memory
  1227. return (*invalid_getsize_fn)(ptr);
  1228. } else if (span->sizeclass != 0) {
  1229. Static::pageheap()->CacheSizeClass(p, span->sizeclass);
  1230. return Static::sizemap()->ByteSizeForClass(span->sizeclass);
  1231. } else {
  1232. return span->length << kPageShift;
  1233. }
  1234. }
  1235. }
  1236. // This lets you call back to a given function pointer if ptr is invalid.
  1237. // It is used primarily by windows code which wants a specialized callback.
  1238. ALWAYS_INLINE void* do_realloc_with_callback(
  1239. void* old_ptr, size_t new_size,
  1240. void (*invalid_free_fn)(void*),
  1241. size_t (*invalid_get_size_fn)(const void*)) {
  1242. // Get the size of the old entry
  1243. const size_t old_size = GetSizeWithCallback(old_ptr, invalid_get_size_fn);
  1244. // Reallocate if the new size is larger than the old size,
  1245. // or if the new size is significantly smaller than the old size.
  1246. // We do hysteresis to avoid resizing ping-pongs:
  1247. // . If we need to grow, grow to max(new_size, old_size * 1.X)
  1248. // . Don't shrink unless new_size < old_size * 0.Y
  1249. // X and Y trade-off time for wasted space. For now we do 1.25 and 0.5.
  1250. const size_t lower_bound_to_grow = old_size + old_size / 4ul;
  1251. const size_t upper_bound_to_shrink = old_size / 2ul;
  1252. if ((new_size > old_size) || (new_size < upper_bound_to_shrink)) {
  1253. // Need to reallocate.
  1254. void* new_ptr = NULL;
  1255. if (new_size > old_size && new_size < lower_bound_to_grow) {
  1256. new_ptr = do_malloc_or_cpp_alloc(lower_bound_to_grow);
  1257. }
  1258. if (new_ptr == NULL) {
  1259. // Either new_size is not a tiny increment, or last do_malloc failed.
  1260. new_ptr = do_malloc_or_cpp_alloc(new_size);
  1261. }
  1262. if (UNLIKELY(new_ptr == NULL)) {
  1263. return NULL;
  1264. }
  1265. MallocHook::InvokeNewHook(new_ptr, new_size);
  1266. memcpy(new_ptr, old_ptr, ((old_size < new_size) ? old_size : new_size));
  1267. MallocHook::InvokeDeleteHook(old_ptr);
  1268. // We could use a variant of do_free() that leverages the fact
  1269. // that we already know the sizeclass of old_ptr. The benefit
  1270. // would be small, so don't bother.
  1271. do_free_with_callback(old_ptr, invalid_free_fn, false, 0);
  1272. return new_ptr;
  1273. } else {
  1274. // We still need to call hooks to report the updated size:
  1275. MallocHook::InvokeDeleteHook(old_ptr);
  1276. MallocHook::InvokeNewHook(old_ptr, new_size);
  1277. return old_ptr;
  1278. }
  1279. }
  1280. ALWAYS_INLINE void* do_realloc(void* old_ptr, size_t new_size) {
  1281. return do_realloc_with_callback(old_ptr, new_size,
  1282. &InvalidFree, &InvalidGetSizeForRealloc);
  1283. }
  1284. // For use by exported routines below that want specific alignments
  1285. //
  1286. // Note: this code can be slow for alignments > 16, and can
  1287. // significantly fragment memory. The expectation is that
  1288. // memalign/posix_memalign/valloc/pvalloc will not be invoked very
  1289. // often. This requirement simplifies our implementation and allows
  1290. // us to tune for expected allocation patterns.
  1291. void* do_memalign(size_t align, size_t size) {
  1292. ASSERT((align & (align - 1)) == 0);
  1293. ASSERT(align > 0);
  1294. if (size + align < size) return NULL; // Overflow
  1295. // Fall back to malloc if we would already align this memory access properly.
  1296. if (align <= AlignmentForSize(size)) {
  1297. void* p = do_malloc(size);
  1298. ASSERT((reinterpret_cast<uintptr_t>(p) % align) == 0);
  1299. return p;
  1300. }
  1301. if (UNLIKELY(Static::pageheap() == NULL)) ThreadCache::InitModule();
  1302. // Allocate at least one byte to avoid boundary conditions below
  1303. if (size == 0) size = 1;
  1304. if (size <= kMaxSize && align < kPageSize) {
  1305. // Search through acceptable size classes looking for one with
  1306. // enough alignment. This depends on the fact that
  1307. // InitSizeClasses() currently produces several size classes that
  1308. // are aligned at powers of two. We will waste time and space if
  1309. // we miss in the size class array, but that is deemed acceptable
  1310. // since memalign() should be used rarely.
  1311. int cl = Static::sizemap()->SizeClass(size);
  1312. while (cl < kNumClasses &&
  1313. ((Static::sizemap()->class_to_size(cl) & (align - 1)) != 0)) {
  1314. cl++;
  1315. }
  1316. if (cl < kNumClasses) {
  1317. ThreadCache* heap = ThreadCache::GetCache();
  1318. size = Static::sizemap()->class_to_size(cl);
  1319. return CheckedMallocResult(heap->Allocate(size, cl));
  1320. }
  1321. }
  1322. // We will allocate directly from the page heap
  1323. SpinLockHolder h(Static::pageheap_lock());
  1324. if (align <= kPageSize) {
  1325. // Any page-level allocation will be fine
  1326. // TODO: We could put the rest of this page in the appropriate
  1327. // TODO: cache but it does not seem worth it.
  1328. Span* span = Static::pageheap()->New(tcmalloc::pages(size));
  1329. return UNLIKELY(span == NULL) ? NULL : SpanToMallocResult(span);
  1330. }
  1331. // Allocate extra pages and carve off an aligned portion
  1332. const Length alloc = tcmalloc::pages(size + align);
  1333. Span* span = Static::pageheap()->New(alloc);
  1334. if (UNLIKELY(span == NULL)) return NULL;
  1335. // Skip starting portion so that we end up aligned
  1336. Length skip = 0;
  1337. while ((((span->start+skip) << kPageShift) & (align - 1)) != 0) {
  1338. skip++;
  1339. }
  1340. ASSERT(skip < alloc);
  1341. if (skip > 0) {
  1342. Span* rest = Static::pageheap()->Split(span, skip);
  1343. Static::pageheap()->Delete(span);
  1344. span = rest;
  1345. }
  1346. // Skip trailing portion that we do not need to return
  1347. const Length needed = tcmalloc::pages(size);
  1348. ASSERT(span->length >= needed);
  1349. if (span->length > needed) {
  1350. Span* trailer = Static::pageheap()->Split(span, needed);
  1351. Static::pageheap()->Delete(trailer);
  1352. }
  1353. return SpanToMallocResult(span);
  1354. }
  1355. // Helpers for use by exported routines below:
  1356. inline void do_malloc_stats() {
  1357. PrintStats(1);
  1358. }
  1359. inline int do_mallopt(int cmd, int value) {
  1360. return 1; // Indicates error
  1361. }
  1362. #ifdef HAVE_STRUCT_MALLINFO
  1363. inline struct mallinfo do_mallinfo() {
  1364. TCMallocStats stats;
  1365. ExtractStats(&stats, NULL, NULL, NULL);
  1366. // Just some of the fields are filled in.
  1367. struct mallinfo info;
  1368. memset(&info, 0, sizeof(info));
  1369. // Unfortunately, the struct contains "int" field, so some of the
  1370. // size values will be truncated.
  1371. info.arena = static_cast<int>(stats.pageheap.system_bytes);
  1372. info.fsmblks = static_cast<int>(stats.thread_bytes
  1373. + stats.central_bytes
  1374. + stats.transfer_bytes);
  1375. info.fordblks = static_cast<int>(stats.pageheap.free_bytes +
  1376. stats.pageheap.unmapped_bytes);
  1377. info.uordblks = static_cast<int>(stats.pageheap.system_bytes
  1378. - stats.thread_bytes
  1379. - stats.central_bytes
  1380. - stats.transfer_bytes
  1381. - stats.pageheap.free_bytes
  1382. - stats.pageheap.unmapped_bytes);
  1383. return info;
  1384. }
  1385. #endif // HAVE_STRUCT_MALLINFO
  1386. inline void* cpp_alloc(size_t size, bool nothrow) {
  1387. void* p = do_malloc(size);
  1388. if (LIKELY(p)) {
  1389. return p;
  1390. }
  1391. return handle_oom(retry_malloc, reinterpret_cast<void *>(size),
  1392. true, nothrow);
  1393. }
  1394. } // end unnamed namespace
  1395. // As promised, the definition of this function, declared above.
  1396. size_t TCMallocImplementation::GetAllocatedSize(const void* ptr) {
  1397. if (ptr == NULL)
  1398. return 0;
  1399. ASSERT(TCMallocImplementation::GetOwnership(ptr)
  1400. != TCMallocImplementation::kNotOwned);
  1401. return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize);
  1402. }
  1403. void TCMallocImplementation::MarkThreadBusy() {
  1404. // Allocate to force the creation of a thread cache, but avoid
  1405. // invoking any hooks.
  1406. do_free(do_malloc(0));
  1407. }
  1408. //-------------------------------------------------------------------
  1409. // Exported routines
  1410. //-------------------------------------------------------------------
  1411. extern "C" PERFTOOLS_DLL_DECL const char* tc_version(
  1412. int* major, int* minor, const char** patch) PERFTOOLS_THROW {
  1413. if (major) *major = TC_VERSION_MAJOR;
  1414. if (minor) *minor = TC_VERSION_MINOR;
  1415. if (patch) *patch = TC_VERSION_PATCH;
  1416. return TC_VERSION_STRING;
  1417. }
  1418. // This function behaves similarly to MSVC's _set_new_mode.
  1419. // If flag is 0 (default), calls to malloc will behave normally.
  1420. // If flag is 1, calls to malloc will behave like calls to new,
  1421. // and the std_new_handler will be invoked on failure.
  1422. // Returns the previous mode.
  1423. extern "C" PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_THROW {
  1424. int old_mode = tc_new_mode;
  1425. tc_new_mode = flag;
  1426. return old_mode;
  1427. }
  1428. #ifndef TCMALLOC_USING_DEBUGALLOCATION // debugallocation.cc defines its own
  1429. #if defined(__GNUC__) && defined(__ELF__) && !defined(TCMALLOC_NO_ALIASES)
  1430. #define TC_ALIAS(name) __attribute__((alias(#name)))
  1431. #endif
  1432. // CAVEAT: The code structure below ensures that MallocHook methods are always
  1433. // called from the stack frame of the invoked allocation function.
  1434. // heap-checker.cc depends on this to start a stack trace from
  1435. // the call to the (de)allocation function.
  1436. extern "C" PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_THROW {
  1437. void* result = do_malloc_or_cpp_alloc(size);
  1438. MallocHook::InvokeNewHook(result, size);
  1439. return result;
  1440. }
  1441. extern "C" PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_THROW {
  1442. MallocHook::InvokeDeleteHook(ptr);
  1443. do_free(ptr);
  1444. }
  1445. extern "C" PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_THROW {
  1446. if ((reinterpret_cast<uintptr_t>(ptr) & (kPageSize-1)) == 0) {
  1447. tc_free(ptr);
  1448. return;
  1449. }
  1450. MallocHook::InvokeDeleteHook(ptr);
  1451. do_free_with_callback(ptr, &InvalidFree, true, size);
  1452. }
  1453. #ifdef TC_ALIAS
  1454. extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void *p, size_t size) throw()
  1455. TC_ALIAS(tc_free_sized);
  1456. extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void *p, size_t size) throw()
  1457. TC_ALIAS(tc_free_sized);
  1458. #else
  1459. extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void *p, size_t size) throw() {
  1460. tc_free_sized(p, size);
  1461. }
  1462. extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void *p, size_t size) throw() {
  1463. tc_free_sized(p, size);
  1464. }
  1465. #endif
  1466. extern "C" PERFTOOLS_DLL_DECL void* tc_calloc(size_t n,
  1467. size_t elem_size) PERFTOOLS_THROW {
  1468. if (ThreadCache::IsUseEmergencyMalloc()) {
  1469. return tcmalloc::EmergencyCalloc(n, elem_size);
  1470. }
  1471. void* result = do_calloc(n, elem_size);
  1472. MallocHook::InvokeNewHook(result, n * elem_size);
  1473. return result;
  1474. }
  1475. extern "C" PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_THROW
  1476. #ifdef TC_ALIAS
  1477. TC_ALIAS(tc_free);
  1478. #else
  1479. {
  1480. MallocHook::InvokeDeleteHook(ptr);
  1481. do_free(ptr);
  1482. }
  1483. #endif
  1484. extern "C" PERFTOOLS_DLL_DECL void* tc_realloc(void* old_ptr,
  1485. size_t new_size) PERFTOOLS_THROW {
  1486. if (old_ptr == NULL) {
  1487. void* result = do_malloc_or_cpp_alloc(new_size);
  1488. MallocHook::InvokeNewHook(result, new_size);
  1489. return result;
  1490. }
  1491. if (new_size == 0) {
  1492. MallocHook::InvokeDeleteHook(old_ptr);
  1493. do_free(old_ptr);
  1494. return NULL;
  1495. }
  1496. if (UNLIKELY(tcmalloc::IsEmergencyPtr(old_ptr))) {
  1497. return tcmalloc::EmergencyRealloc(old_ptr, new_size);
  1498. }
  1499. return do_realloc(old_ptr, new_size);
  1500. }
  1501. extern "C" PERFTOOLS_DLL_DECL void* tc_new(size_t size) {
  1502. void* p = cpp_alloc(size, false);
  1503. // We keep this next instruction out of cpp_alloc for a reason: when
  1504. // it's in, and new just calls cpp_alloc, the optimizer may fold the
  1505. // new call into cpp_alloc, which messes up our whole section-based
  1506. // stacktracing (see ATTRIBUTE_SECTION, above). This ensures cpp_alloc
  1507. // isn't the last thing this fn calls, and prevents the folding.
  1508. MallocHook::InvokeNewHook(p, size);
  1509. return p;
  1510. }
  1511. extern "C" PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size, const std::nothrow_t&) PERFTOOLS_THROW {
  1512. void* p = cpp_alloc(size, true);
  1513. MallocHook::InvokeNewHook(p, size);
  1514. return p;
  1515. }
  1516. extern "C" PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_THROW
  1517. #ifdef TC_ALIAS
  1518. TC_ALIAS(tc_free);
  1519. #else
  1520. {
  1521. MallocHook::InvokeDeleteHook(p);
  1522. do_free(p);
  1523. }
  1524. #endif
  1525. // Standard C++ library implementations define and use this
  1526. // (via ::operator delete(ptr, nothrow)).
  1527. // But it's really the same as normal delete, so we just do the same thing.
  1528. extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_THROW
  1529. #ifdef TC_ALIAS
  1530. TC_ALIAS(tc_free);
  1531. #else
  1532. {
  1533. MallocHook::InvokeDeleteHook(p);
  1534. do_free(p);
  1535. }
  1536. #endif
  1537. extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size)
  1538. #ifdef TC_ALIAS
  1539. TC_ALIAS(tc_new);
  1540. #else
  1541. {
  1542. void* p = cpp_alloc(size, false);
  1543. // We keep this next instruction out of cpp_alloc for a reason: when
  1544. // it's in, and new just calls cpp_alloc, the optimizer may fold the
  1545. // new call into cpp_alloc, which messes up our whole section-based
  1546. // stacktracing (see ATTRIBUTE_SECTION, above). This ensures cpp_alloc
  1547. // isn't the last thing this fn calls, and prevents the folding.
  1548. MallocHook::InvokeNewHook(p, size);
  1549. return p;
  1550. }
  1551. #endif
  1552. extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::nothrow_t&)
  1553. PERFTOOLS_THROW
  1554. #ifdef TC_ALIAS
  1555. TC_ALIAS(tc_new_nothrow);
  1556. #else
  1557. {
  1558. void* p = cpp_alloc(size, true);
  1559. MallocHook::InvokeNewHook(p, size);
  1560. return p;
  1561. }
  1562. #endif
  1563. extern "C" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_THROW
  1564. #ifdef TC_ALIAS
  1565. TC_ALIAS(tc_free);
  1566. #else
  1567. {
  1568. MallocHook::InvokeDeleteHook(p);
  1569. do_free(p);
  1570. }
  1571. #endif
  1572. extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_THROW
  1573. #ifdef TC_ALIAS
  1574. TC_ALIAS(tc_free);
  1575. #else
  1576. {
  1577. MallocHook::InvokeDeleteHook(p);
  1578. do_free(p);
  1579. }
  1580. #endif
  1581. extern "C" PERFTOOLS_DLL_DECL void* tc_memalign(size_t align,
  1582. size_t size) PERFTOOLS_THROW {
  1583. void* result = do_memalign_or_cpp_memalign(align, size);
  1584. MallocHook::InvokeNewHook(result, size);
  1585. return result;
  1586. }
  1587. extern "C" PERFTOOLS_DLL_DECL int tc_posix_memalign(
  1588. void** result_ptr, size_t align, size_t size) PERFTOOLS_THROW {
  1589. if (((align % sizeof(void*)) != 0) ||
  1590. ((align & (align - 1)) != 0) ||
  1591. (align == 0)) {
  1592. return EINVAL;
  1593. }
  1594. void* result = do_memalign_or_cpp_memalign(align, size);
  1595. MallocHook::InvokeNewHook(result, size);
  1596. if (UNLIKELY(result == NULL)) {
  1597. return ENOMEM;
  1598. } else {
  1599. *result_ptr = result;
  1600. return 0;
  1601. }
  1602. }
  1603. static size_t pagesize = 0;
  1604. extern "C" PERFTOOLS_DLL_DECL void* tc_valloc(size_t size) PERFTOOLS_THROW {
  1605. // Allocate page-aligned object of length >= size bytes
  1606. if (pagesize == 0) pagesize = getpagesize();
  1607. void* result = do_memalign_or_cpp_memalign(pagesize, size);
  1608. MallocHook::InvokeNewHook(result, size);
  1609. return result;
  1610. }
  1611. extern "C" PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t size) PERFTOOLS_THROW {
  1612. // Round up size to a multiple of pagesize
  1613. if (pagesize == 0) pagesize = getpagesize();
  1614. if (size == 0) { // pvalloc(0) should allocate one page, according to
  1615. size = pagesize; // http://man.free4web.biz/man3/libmpatrol.3.html
  1616. }
  1617. size = (size + pagesize - 1) & ~(pagesize - 1);
  1618. void* result = do_memalign_or_cpp_memalign(pagesize, size);
  1619. MallocHook::InvokeNewHook(result, size);
  1620. return result;
  1621. }
  1622. extern "C" PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_THROW {
  1623. do_malloc_stats();
  1624. }
  1625. extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_THROW {
  1626. return do_mallopt(cmd, value);
  1627. }
  1628. #ifdef HAVE_STRUCT_MALLINFO
  1629. extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_THROW {
  1630. return do_mallinfo();
  1631. }
  1632. #endif
  1633. extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_THROW {
  1634. return MallocExtension::instance()->GetAllocatedSize(ptr);
  1635. }
  1636. extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_THROW {
  1637. void* result = do_malloc(size);
  1638. MallocHook::InvokeNewHook(result, size);
  1639. return result;
  1640. }
  1641. #endif // TCMALLOC_USING_DEBUGALLOCATION