low_level_alloc.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. // Copyright 2017 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // A low-level allocator that can be used by other low-level
  15. // modules without introducing dependency cycles.
  16. // This allocator is slow and wasteful of memory;
  17. // it should not be used when performance is key.
  18. #include "absl/base/internal/low_level_alloc.h"
  19. #include <type_traits>
  20. #include "absl/base/call_once.h"
  21. #include "absl/base/config.h"
  22. #include "absl/base/internal/direct_mmap.h"
  23. #include "absl/base/internal/scheduling_mode.h"
  24. #include "absl/base/macros.h"
  25. #include "absl/base/thread_annotations.h"
  26. // LowLevelAlloc requires that the platform support low-level
  27. // allocation of virtual memory. Platforms lacking this cannot use
  28. // LowLevelAlloc.
  29. #ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
  30. #ifndef _WIN32
  31. #include <pthread.h>
  32. #include <signal.h>
  33. #include <sys/mman.h>
  34. #include <unistd.h>
  35. #else
  36. #include <windows.h>
  37. #endif
  38. #ifdef __linux__
  39. #include <sys/prctl.h>
  40. #endif
  41. #include <string.h>
  42. #include <algorithm>
  43. #include <atomic>
  44. #include <cerrno>
  45. #include <cstddef>
  46. #include <new> // for placement-new
  47. #include "absl/base/dynamic_annotations.h"
  48. #include "absl/base/internal/raw_logging.h"
  49. #include "absl/base/internal/spinlock.h"
  50. #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
  51. #define MAP_ANONYMOUS MAP_ANON
  52. #endif
  53. namespace absl {
  54. ABSL_NAMESPACE_BEGIN
  55. namespace base_internal {
  56. // A first-fit allocator with amortized logarithmic free() time.
  57. // ---------------------------------------------------------------------------
  58. static const int kMaxLevel = 30;
  59. namespace {
  60. // This struct describes one allocated block, or one free block.
  61. struct AllocList {
  62. struct Header {
  63. // Size of entire region, including this field. Must be
  64. // first. Valid in both allocated and unallocated blocks.
  65. uintptr_t size;
  66. // kMagicAllocated or kMagicUnallocated xor this.
  67. uintptr_t magic;
  68. // Pointer to parent arena.
  69. LowLevelAlloc::Arena *arena;
  70. // Aligns regions to 0 mod 2*sizeof(void*).
  71. void *dummy_for_alignment;
  72. } header;
  73. // Next two fields: in unallocated blocks: freelist skiplist data
  74. // in allocated blocks: overlaps with client data
  75. // Levels in skiplist used.
  76. int levels;
  77. // Actually has levels elements. The AllocList node may not have room
  78. // for all kMaxLevel entries. See max_fit in LLA_SkiplistLevels().
  79. AllocList *next[kMaxLevel];
  80. };
  81. } // namespace
  82. // ---------------------------------------------------------------------------
  83. // A trivial skiplist implementation. This is used to keep the freelist
  84. // in address order while taking only logarithmic time per insert and delete.
  85. // An integer approximation of log2(size/base)
  86. // Requires size >= base.
  87. static int IntLog2(size_t size, size_t base) {
  88. int result = 0;
  89. for (size_t i = size; i > base; i >>= 1) { // i == floor(size/2**result)
  90. result++;
  91. }
  92. // floor(size / 2**result) <= base < floor(size / 2**(result-1))
  93. // => log2(size/(base+1)) <= result < 1+log2(size/base)
  94. // => result ~= log2(size/base)
  95. return result;
  96. }
  97. // Return a random integer n: p(n)=1/(2**n) if 1 <= n; p(n)=0 if n < 1.
  98. static int Random(uint32_t *state) {
  99. uint32_t r = *state;
  100. int result = 1;
  101. while ((((r = r * 1103515245 + 12345) >> 30) & 1) == 0) {
  102. result++;
  103. }
  104. *state = r;
  105. return result;
  106. }
  107. // Return a number of skiplist levels for a node of size bytes, where
  108. // base is the minimum node size. Compute level=log2(size / base)+n
  109. // where n is 1 if random is false and otherwise a random number generated with
  110. // the standard distribution for a skiplist: See Random() above.
  111. // Bigger nodes tend to have more skiplist levels due to the log2(size / base)
  112. // term, so first-fit searches touch fewer nodes. "level" is clipped so
  113. // level<kMaxLevel and next[level-1] will fit in the node.
  114. // 0 < LLA_SkiplistLevels(x,y,false) <= LLA_SkiplistLevels(x,y,true) < kMaxLevel
  115. static int LLA_SkiplistLevels(size_t size, size_t base, uint32_t *random) {
  116. // max_fit is the maximum number of levels that will fit in a node for the
  117. // given size. We can't return more than max_fit, no matter what the
  118. // random number generator says.
  119. size_t max_fit = (size - offsetof(AllocList, next)) / sizeof(AllocList *);
  120. int level = IntLog2(size, base) + (random != nullptr ? Random(random) : 1);
  121. if (static_cast<size_t>(level) > max_fit) level = static_cast<int>(max_fit);
  122. if (level > kMaxLevel - 1) level = kMaxLevel - 1;
  123. ABSL_RAW_CHECK(level >= 1, "block not big enough for even one level");
  124. return level;
  125. }
  126. // Return "atleast", the first element of AllocList *head s.t. *atleast >= *e.
  127. // For 0 <= i < head->levels, set prev[i] to "no_greater", where no_greater
  128. // points to the last element at level i in the AllocList less than *e, or is
  129. // head if no such element exists.
  130. static AllocList *LLA_SkiplistSearch(AllocList *head, AllocList *e,
  131. AllocList **prev) {
  132. AllocList *p = head;
  133. for (int level = head->levels - 1; level >= 0; level--) {
  134. for (AllocList *n; (n = p->next[level]) != nullptr && n < e; p = n) {
  135. }
  136. prev[level] = p;
  137. }
  138. return (head->levels == 0) ? nullptr : prev[0]->next[0];
  139. }
  140. // Insert element *e into AllocList *head. Set prev[] as LLA_SkiplistSearch.
  141. // Requires that e->levels be previously set by the caller (using
  142. // LLA_SkiplistLevels())
  143. static void LLA_SkiplistInsert(AllocList *head, AllocList *e,
  144. AllocList **prev) {
  145. LLA_SkiplistSearch(head, e, prev);
  146. for (; head->levels < e->levels; head->levels++) { // extend prev pointers
  147. prev[head->levels] = head; // to all *e's levels
  148. }
  149. for (int i = 0; i != e->levels; i++) { // add element to list
  150. e->next[i] = prev[i]->next[i];
  151. prev[i]->next[i] = e;
  152. }
  153. }
  154. // Remove element *e from AllocList *head. Set prev[] as LLA_SkiplistSearch().
  155. // Requires that e->levels be previous set by the caller (using
  156. // LLA_SkiplistLevels())
  157. static void LLA_SkiplistDelete(AllocList *head, AllocList *e,
  158. AllocList **prev) {
  159. AllocList *found = LLA_SkiplistSearch(head, e, prev);
  160. ABSL_RAW_CHECK(e == found, "element not in freelist");
  161. for (int i = 0; i != e->levels && prev[i]->next[i] == e; i++) {
  162. prev[i]->next[i] = e->next[i];
  163. }
  164. while (head->levels > 0 && head->next[head->levels - 1] == nullptr) {
  165. head->levels--; // reduce head->levels if level unused
  166. }
  167. }
  168. // ---------------------------------------------------------------------------
  169. // Arena implementation
  170. // Metadata for an LowLevelAlloc arena instance.
  171. struct LowLevelAlloc::Arena {
  172. // Constructs an arena with the given LowLevelAlloc flags.
  173. explicit Arena(uint32_t flags_value);
  174. base_internal::SpinLock mu;
  175. // Head of free list, sorted by address
  176. AllocList freelist ABSL_GUARDED_BY(mu);
  177. // Count of allocated blocks
  178. int32_t allocation_count ABSL_GUARDED_BY(mu);
  179. // flags passed to NewArena
  180. const uint32_t flags;
  181. // Result of sysconf(_SC_PAGESIZE)
  182. const size_t pagesize;
  183. // Lowest power of two >= max(16, sizeof(AllocList))
  184. const size_t round_up;
  185. // Smallest allocation block size
  186. const size_t min_size;
  187. // PRNG state
  188. uint32_t random ABSL_GUARDED_BY(mu);
  189. };
  190. namespace {
  191. // Static storage space for the lazily-constructed, default global arena
  192. // instances. We require this space because the whole point of LowLevelAlloc
  193. // is to avoid relying on malloc/new.
  194. alignas(LowLevelAlloc::Arena) unsigned char default_arena_storage[sizeof(
  195. LowLevelAlloc::Arena)];
  196. alignas(LowLevelAlloc::Arena) unsigned char unhooked_arena_storage[sizeof(
  197. LowLevelAlloc::Arena)];
  198. #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  199. alignas(
  200. LowLevelAlloc::Arena) unsigned char unhooked_async_sig_safe_arena_storage
  201. [sizeof(LowLevelAlloc::Arena)];
  202. #endif
  203. // We must use LowLevelCallOnce here to construct the global arenas, rather than
  204. // using function-level statics, to avoid recursively invoking the scheduler.
  205. absl::once_flag create_globals_once;
  206. void CreateGlobalArenas() {
  207. new (&default_arena_storage)
  208. LowLevelAlloc::Arena(LowLevelAlloc::kCallMallocHook);
  209. new (&unhooked_arena_storage) LowLevelAlloc::Arena(0);
  210. #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  211. new (&unhooked_async_sig_safe_arena_storage)
  212. LowLevelAlloc::Arena(LowLevelAlloc::kAsyncSignalSafe);
  213. #endif
  214. }
  215. // Returns a global arena that does not call into hooks. Used by NewArena()
  216. // when kCallMallocHook is not set.
  217. LowLevelAlloc::Arena *UnhookedArena() {
  218. base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas);
  219. return reinterpret_cast<LowLevelAlloc::Arena *>(&unhooked_arena_storage);
  220. }
  221. #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  222. // Returns a global arena that is async-signal safe. Used by NewArena() when
  223. // kAsyncSignalSafe is set.
  224. LowLevelAlloc::Arena *UnhookedAsyncSigSafeArena() {
  225. base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas);
  226. return reinterpret_cast<LowLevelAlloc::Arena *>(
  227. &unhooked_async_sig_safe_arena_storage);
  228. }
  229. #endif
  230. } // namespace
  231. // Returns the default arena, as used by LowLevelAlloc::Alloc() and friends.
  232. LowLevelAlloc::Arena *LowLevelAlloc::DefaultArena() {
  233. base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas);
  234. return reinterpret_cast<LowLevelAlloc::Arena *>(&default_arena_storage);
  235. }
  236. // magic numbers to identify allocated and unallocated blocks
  237. static const uintptr_t kMagicAllocated = 0x4c833e95U;
  238. static const uintptr_t kMagicUnallocated = ~kMagicAllocated;
  239. namespace {
  240. class ABSL_SCOPED_LOCKABLE ArenaLock {
  241. public:
  242. explicit ArenaLock(LowLevelAlloc::Arena *arena)
  243. ABSL_EXCLUSIVE_LOCK_FUNCTION(arena->mu)
  244. : arena_(arena) {
  245. #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  246. if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
  247. sigset_t all;
  248. sigfillset(&all);
  249. mask_valid_ = pthread_sigmask(SIG_BLOCK, &all, &mask_) == 0;
  250. }
  251. #endif
  252. arena_->mu.Lock();
  253. }
  254. ~ArenaLock() { ABSL_RAW_CHECK(left_, "haven't left Arena region"); }
  255. void Leave() ABSL_UNLOCK_FUNCTION() {
  256. arena_->mu.Unlock();
  257. #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  258. if (mask_valid_) {
  259. const int err = pthread_sigmask(SIG_SETMASK, &mask_, nullptr);
  260. if (err != 0) {
  261. ABSL_RAW_LOG(FATAL, "pthread_sigmask failed: %d", err);
  262. }
  263. }
  264. #endif
  265. left_ = true;
  266. }
  267. private:
  268. bool left_ = false; // whether left region
  269. #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  270. bool mask_valid_ = false;
  271. sigset_t mask_; // old mask of blocked signals
  272. #endif
  273. LowLevelAlloc::Arena *arena_;
  274. ArenaLock(const ArenaLock &) = delete;
  275. ArenaLock &operator=(const ArenaLock &) = delete;
  276. };
  277. } // namespace
  278. // create an appropriate magic number for an object at "ptr"
  279. // "magic" should be kMagicAllocated or kMagicUnallocated
  280. inline static uintptr_t Magic(uintptr_t magic, AllocList::Header *ptr) {
  281. return magic ^ reinterpret_cast<uintptr_t>(ptr);
  282. }
  283. namespace {
  284. size_t GetPageSize() {
  285. #ifdef _WIN32
  286. SYSTEM_INFO system_info;
  287. GetSystemInfo(&system_info);
  288. return std::max(system_info.dwPageSize, system_info.dwAllocationGranularity);
  289. #elif defined(__wasm__) || defined(__asmjs__) || defined(__hexagon__)
  290. return getpagesize();
  291. #else
  292. return static_cast<size_t>(sysconf(_SC_PAGESIZE));
  293. #endif
  294. }
  295. size_t RoundedUpBlockSize() {
  296. // Round up block sizes to a power of two close to the header size.
  297. size_t round_up = 16;
  298. while (round_up < sizeof(AllocList::Header)) {
  299. round_up += round_up;
  300. }
  301. return round_up;
  302. }
  303. } // namespace
  304. LowLevelAlloc::Arena::Arena(uint32_t flags_value)
  305. : mu(base_internal::SCHEDULE_KERNEL_ONLY),
  306. allocation_count(0),
  307. flags(flags_value),
  308. pagesize(GetPageSize()),
  309. round_up(RoundedUpBlockSize()),
  310. min_size(2 * round_up),
  311. random(0) {
  312. freelist.header.size = 0;
  313. freelist.header.magic = Magic(kMagicUnallocated, &freelist.header);
  314. freelist.header.arena = this;
  315. freelist.levels = 0;
  316. memset(freelist.next, 0, sizeof(freelist.next));
  317. }
  318. // L < meta_data_arena->mu
  319. LowLevelAlloc::Arena *LowLevelAlloc::NewArena(uint32_t flags) {
  320. Arena *meta_data_arena = DefaultArena();
  321. #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  322. if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
  323. meta_data_arena = UnhookedAsyncSigSafeArena();
  324. } else // NOLINT(readability/braces)
  325. #endif
  326. if ((flags & LowLevelAlloc::kCallMallocHook) == 0) {
  327. meta_data_arena = UnhookedArena();
  328. }
  329. Arena *result =
  330. new (AllocWithArena(sizeof(*result), meta_data_arena)) Arena(flags);
  331. return result;
  332. }
  333. // L < arena->mu, L < arena->arena->mu
  334. bool LowLevelAlloc::DeleteArena(Arena *arena) {
  335. ABSL_RAW_CHECK(
  336. arena != nullptr && arena != DefaultArena() && arena != UnhookedArena(),
  337. "may not delete default arena");
  338. ArenaLock section(arena);
  339. if (arena->allocation_count != 0) {
  340. section.Leave();
  341. return false;
  342. }
  343. while (arena->freelist.next[0] != nullptr) {
  344. AllocList *region = arena->freelist.next[0];
  345. size_t size = region->header.size;
  346. arena->freelist.next[0] = region->next[0];
  347. ABSL_RAW_CHECK(
  348. region->header.magic == Magic(kMagicUnallocated, &region->header),
  349. "bad magic number in DeleteArena()");
  350. ABSL_RAW_CHECK(region->header.arena == arena,
  351. "bad arena pointer in DeleteArena()");
  352. ABSL_RAW_CHECK(size % arena->pagesize == 0,
  353. "empty arena has non-page-aligned block size");
  354. ABSL_RAW_CHECK(reinterpret_cast<uintptr_t>(region) % arena->pagesize == 0,
  355. "empty arena has non-page-aligned block");
  356. int munmap_result;
  357. #ifdef _WIN32
  358. munmap_result = VirtualFree(region, 0, MEM_RELEASE);
  359. ABSL_RAW_CHECK(munmap_result != 0,
  360. "LowLevelAlloc::DeleteArena: VitualFree failed");
  361. #else
  362. #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  363. if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
  364. munmap_result = munmap(region, size);
  365. } else {
  366. munmap_result = base_internal::DirectMunmap(region, size);
  367. }
  368. #else
  369. munmap_result = munmap(region, size);
  370. #endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  371. if (munmap_result != 0) {
  372. ABSL_RAW_LOG(FATAL, "LowLevelAlloc::DeleteArena: munmap failed: %d",
  373. errno);
  374. }
  375. #endif // _WIN32
  376. }
  377. section.Leave();
  378. arena->~Arena();
  379. Free(arena);
  380. return true;
  381. }
  382. // ---------------------------------------------------------------------------
  383. // Addition, checking for overflow. The intent is to die if an external client
  384. // manages to push through a request that would cause arithmetic to fail.
  385. static inline uintptr_t CheckedAdd(uintptr_t a, uintptr_t b) {
  386. uintptr_t sum = a + b;
  387. ABSL_RAW_CHECK(sum >= a, "LowLevelAlloc arithmetic overflow");
  388. return sum;
  389. }
  390. // Return value rounded up to next multiple of align.
  391. // align must be a power of two.
  392. static inline uintptr_t RoundUp(uintptr_t addr, uintptr_t align) {
  393. return CheckedAdd(addr, align - 1) & ~(align - 1);
  394. }
  395. // Equivalent to "return prev->next[i]" but with sanity checking
  396. // that the freelist is in the correct order, that it
  397. // consists of regions marked "unallocated", and that no two regions
  398. // are adjacent in memory (they should have been coalesced).
  399. // L >= arena->mu
  400. static AllocList *Next(int i, AllocList *prev, LowLevelAlloc::Arena *arena) {
  401. ABSL_RAW_CHECK(i < prev->levels, "too few levels in Next()");
  402. AllocList *next = prev->next[i];
  403. if (next != nullptr) {
  404. ABSL_RAW_CHECK(
  405. next->header.magic == Magic(kMagicUnallocated, &next->header),
  406. "bad magic number in Next()");
  407. ABSL_RAW_CHECK(next->header.arena == arena, "bad arena pointer in Next()");
  408. if (prev != &arena->freelist) {
  409. ABSL_RAW_CHECK(prev < next, "unordered freelist");
  410. ABSL_RAW_CHECK(reinterpret_cast<char *>(prev) + prev->header.size <
  411. reinterpret_cast<char *>(next),
  412. "malformed freelist");
  413. }
  414. }
  415. return next;
  416. }
  417. // Coalesce list item "a" with its successor if they are adjacent.
  418. static void Coalesce(AllocList *a) {
  419. AllocList *n = a->next[0];
  420. if (n != nullptr && reinterpret_cast<char *>(a) + a->header.size ==
  421. reinterpret_cast<char *>(n)) {
  422. LowLevelAlloc::Arena *arena = a->header.arena;
  423. a->header.size += n->header.size;
  424. n->header.magic = 0;
  425. n->header.arena = nullptr;
  426. AllocList *prev[kMaxLevel];
  427. LLA_SkiplistDelete(&arena->freelist, n, prev);
  428. LLA_SkiplistDelete(&arena->freelist, a, prev);
  429. a->levels =
  430. LLA_SkiplistLevels(a->header.size, arena->min_size, &arena->random);
  431. LLA_SkiplistInsert(&arena->freelist, a, prev);
  432. }
  433. }
  434. // Adds block at location "v" to the free list
  435. // L >= arena->mu
  436. static void AddToFreelist(void *v, LowLevelAlloc::Arena *arena) {
  437. AllocList *f = reinterpret_cast<AllocList *>(reinterpret_cast<char *>(v) -
  438. sizeof(f->header));
  439. ABSL_RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
  440. "bad magic number in AddToFreelist()");
  441. ABSL_RAW_CHECK(f->header.arena == arena,
  442. "bad arena pointer in AddToFreelist()");
  443. f->levels =
  444. LLA_SkiplistLevels(f->header.size, arena->min_size, &arena->random);
  445. AllocList *prev[kMaxLevel];
  446. LLA_SkiplistInsert(&arena->freelist, f, prev);
  447. f->header.magic = Magic(kMagicUnallocated, &f->header);
  448. Coalesce(f); // maybe coalesce with successor
  449. Coalesce(prev[0]); // maybe coalesce with predecessor
  450. }
  451. // Frees storage allocated by LowLevelAlloc::Alloc().
  452. // L < arena->mu
  453. void LowLevelAlloc::Free(void *v) {
  454. if (v != nullptr) {
  455. AllocList *f = reinterpret_cast<AllocList *>(reinterpret_cast<char *>(v) -
  456. sizeof(f->header));
  457. LowLevelAlloc::Arena *arena = f->header.arena;
  458. ArenaLock section(arena);
  459. AddToFreelist(v, arena);
  460. ABSL_RAW_CHECK(arena->allocation_count > 0, "nothing in arena to free");
  461. arena->allocation_count--;
  462. section.Leave();
  463. }
  464. }
  465. // allocates and returns a block of size bytes, to be freed with Free()
  466. // L < arena->mu
  467. static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
  468. void *result = nullptr;
  469. if (request != 0) {
  470. AllocList *s; // will point to region that satisfies request
  471. ArenaLock section(arena);
  472. // round up with header
  473. size_t req_rnd =
  474. RoundUp(CheckedAdd(request, sizeof(s->header)), arena->round_up);
  475. for (;;) { // loop until we find a suitable region
  476. // find the minimum levels that a block of this size must have
  477. int i = LLA_SkiplistLevels(req_rnd, arena->min_size, nullptr) - 1;
  478. if (i < arena->freelist.levels) { // potential blocks exist
  479. AllocList *before = &arena->freelist; // predecessor of s
  480. while ((s = Next(i, before, arena)) != nullptr &&
  481. s->header.size < req_rnd) {
  482. before = s;
  483. }
  484. if (s != nullptr) { // we found a region
  485. break;
  486. }
  487. }
  488. // we unlock before mmap() both because mmap() may call a callback hook,
  489. // and because it may be slow.
  490. arena->mu.Unlock();
  491. // mmap generous 64K chunks to decrease
  492. // the chances/impact of fragmentation:
  493. size_t new_pages_size = RoundUp(req_rnd, arena->pagesize * 16);
  494. void *new_pages;
  495. #ifdef _WIN32
  496. new_pages = VirtualAlloc(nullptr, new_pages_size,
  497. MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  498. ABSL_RAW_CHECK(new_pages != nullptr, "VirtualAlloc failed");
  499. #else
  500. #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  501. if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
  502. new_pages = base_internal::DirectMmap(nullptr, new_pages_size,
  503. PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
  504. } else {
  505. new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ,
  506. MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  507. }
  508. #else
  509. new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ,
  510. MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  511. #endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
  512. if (new_pages == MAP_FAILED) {
  513. ABSL_RAW_LOG(FATAL, "mmap error: %d", errno);
  514. }
  515. #ifdef __linux__
  516. #if defined(PR_SET_VMA) && defined(PR_SET_VMA_ANON_NAME)
  517. // Attempt to name the allocated address range in /proc/$PID/smaps on
  518. // Linux.
  519. //
  520. // This invocation of prctl() may fail if the Linux kernel was not
  521. // configured with the CONFIG_ANON_VMA_NAME option. This is OK since
  522. // the naming of arenas is primarily a debugging aid.
  523. prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, new_pages, new_pages_size,
  524. "absl");
  525. #endif
  526. #endif // __linux__
  527. #endif // _WIN32
  528. arena->mu.Lock();
  529. s = reinterpret_cast<AllocList *>(new_pages);
  530. s->header.size = new_pages_size;
  531. // Pretend the block is allocated; call AddToFreelist() to free it.
  532. s->header.magic = Magic(kMagicAllocated, &s->header);
  533. s->header.arena = arena;
  534. AddToFreelist(&s->levels, arena); // insert new region into free list
  535. }
  536. AllocList *prev[kMaxLevel];
  537. LLA_SkiplistDelete(&arena->freelist, s, prev); // remove from free list
  538. // s points to the first free region that's big enough
  539. if (CheckedAdd(req_rnd, arena->min_size) <= s->header.size) {
  540. // big enough to split
  541. AllocList *n =
  542. reinterpret_cast<AllocList *>(req_rnd + reinterpret_cast<char *>(s));
  543. n->header.size = s->header.size - req_rnd;
  544. n->header.magic = Magic(kMagicAllocated, &n->header);
  545. n->header.arena = arena;
  546. s->header.size = req_rnd;
  547. AddToFreelist(&n->levels, arena);
  548. }
  549. s->header.magic = Magic(kMagicAllocated, &s->header);
  550. ABSL_RAW_CHECK(s->header.arena == arena, "");
  551. arena->allocation_count++;
  552. section.Leave();
  553. result = &s->levels;
  554. }
  555. ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(result, request);
  556. return result;
  557. }
  558. void *LowLevelAlloc::Alloc(size_t request) {
  559. void *result = DoAllocWithArena(request, DefaultArena());
  560. return result;
  561. }
  562. void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) {
  563. ABSL_RAW_CHECK(arena != nullptr, "must pass a valid arena");
  564. void *result = DoAllocWithArena(request, arena);
  565. return result;
  566. }
  567. } // namespace base_internal
  568. ABSL_NAMESPACE_END
  569. } // namespace absl
  570. #endif // ABSL_LOW_LEVEL_ALLOC_MISSING