low_level_alloc.cc 22 KB

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