de-dup THREAD_LOCAL macros
[hiphop-php.git] / hphp / runtime / base / memory-manager.h
blob7b11c2330bc5bbb762ab431a4b329ef0e3689817
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_MEMORY_MANAGER_H_
18 #define incl_HPHP_MEMORY_MANAGER_H_
20 #include <array>
21 #include <vector>
22 #include <utility>
23 #include <set>
24 #include <unordered_map>
25 #include <bitset>
27 #include <folly/Memory.h>
29 #include "hphp/util/alloc.h" // must be included before USE_JEMALLOC is used
30 #include "hphp/util/compilation-flags.h"
31 #include "hphp/util/thread-local.h"
32 #include "hphp/util/trace.h"
33 #include "hphp/util/type-scan.h"
35 #include "hphp/runtime/base/memory-usage-stats.h"
36 #include "hphp/runtime/base/request-event-handler.h"
37 #include "hphp/runtime/base/runtime-option.h"
38 #include "hphp/runtime/base/sweepable.h"
39 #include "hphp/runtime/base/header-kind.h"
40 #include "hphp/runtime/base/req-containers.h"
41 #include "hphp/runtime/base/req-malloc.h"
42 #include "hphp/runtime/base/req-ptr.h"
44 namespace HPHP {
46 struct APCLocalArray;
47 struct MemoryManager;
48 struct ObjectData;
49 struct ResourceData;
51 namespace req {
52 struct root_handle;
53 void* malloc_big(size_t, type_scan::Index);
54 void* calloc_big(size_t, type_scan::Index);
55 void* realloc_big(void*, size_t);
56 void free_big(void*);
59 //////////////////////////////////////////////////////////////////////
62 * Request local memory in HHVM is managed by a thread local object
63 * called MemoryManager.
65 * The object may be accessed with tl_heap, but higher-level apis are
66 * also provided.
68 * The MemoryManager serves the following functions in hhvm:
70 * - Managing request-local memory.
72 * - Tracking "sweepable" objects--i.e. objects that must run custom
73 * cleanup code if they are still live at the end of the request.
75 * - Accounting for usage of memory "by this request", whether it
76 * goes through the request-local allocator, or the underlying
77 * malloc implementation. (This feature is gated on being
78 * compiled with jemalloc.)
81 //////////////////////////////////////////////////////////////////////
84 * Slabs are consumed via bump allocation. The individual allocations are
85 * quantized into a fixed set of size classes, the sizes of which are an
86 * implementation detail documented here to shed light on the algorithms that
87 * compute size classes. Request sizes are rounded up to the nearest size in
88 * the relevant SIZE_CLASSES table; e.g. 17 is rounded up to 32. There are
89 * 4 size classes for each doubling of size
90 * (ignoring the alignment-constrained smallest size classes), which limits
91 * internal fragmentation to 20%.
93 * SIZE_CLASSES: Complete table of SIZE_CLASS(index, lg_grp, lg_delta, ndelta,
94 * lg_delta_lookup, ncontig) tuples.
95 * index: Size class index.
96 * lg_grp: Lg group base size (no deltas added).
97 * lg_delta: Lg delta to previous size class.
98 * ndelta: Delta multiplier. size == 1<<lg_grp + ndelta<<lg_delta
99 * lg_delta_lookup: Same as lg_delta if a lookup table size class, 'no'
100 * otherwise.
101 * ncontig: Number of contiguous regions to batch allocate in the slow path
102 * due to the corresponding free list being empty. Must be greater
103 * than zero, and small enough that the contiguous regions fit within
104 * one slab.
106 #define SIZE_CLASSES \
107 /* index, lg_grp, lg_delta, ndelta, lg_delta_lookup, ncontig */ \
108 SIZE_CLASS( 0, 4, 4, 0, 4, 128) \
109 SIZE_CLASS( 1, 4, 4, 1, 4, 128) \
110 SIZE_CLASS( 2, 4, 4, 2, 4, 128) \
111 SIZE_CLASS( 3, 4, 4, 3, 4, 96) /* 64 */\
113 SIZE_CLASS( 4, 6, 4, 1, 4, 96) \
114 SIZE_CLASS( 5, 6, 4, 2, 4, 96) \
115 SIZE_CLASS( 6, 6, 4, 3, 4, 96) \
116 SIZE_CLASS( 7, 6, 4, 4, 4, 64) /* 128 */\
118 SIZE_CLASS( 8, 7, 5, 1, 5, 64) \
119 SIZE_CLASS( 9, 7, 5, 2, 5, 64) \
120 SIZE_CLASS( 10, 7, 5, 3, 5, 64) \
121 SIZE_CLASS( 11, 7, 5, 4, 5, 32) /* 256 */\
123 SIZE_CLASS( 12, 8, 6, 1, 6, 32) \
124 SIZE_CLASS( 13, 8, 6, 2, 6, 32) \
125 SIZE_CLASS( 14, 8, 6, 3, 6, 32) \
126 SIZE_CLASS( 15, 8, 6, 4, 6, 16) /* 512 */\
128 SIZE_CLASS( 16, 9, 7, 1, 7, 16) \
129 SIZE_CLASS( 17, 9, 7, 2, 7, 16) \
130 SIZE_CLASS( 18, 9, 7, 3, 7, 16) \
131 SIZE_CLASS( 19, 9, 7, 4, 7, 8) /* 1K */\
133 SIZE_CLASS( 20, 10, 8, 1, 8, 8) \
134 SIZE_CLASS( 21, 10, 8, 2, 8, 8) \
135 SIZE_CLASS( 22, 10, 8, 3, 8, 8) \
136 SIZE_CLASS( 23, 10, 8, 4, 8, 4) /* 2K */\
138 SIZE_CLASS( 24, 11, 9, 1, 9, 4) \
139 SIZE_CLASS( 25, 11, 9, 2, 9, 4) \
140 SIZE_CLASS( 26, 11, 9, 3, 9, 4) \
141 SIZE_CLASS( 27, 11, 9, 4, 9, 2) /* 4K */\
143 SIZE_CLASS( 28, 12, 10, 1, no, 2) \
144 SIZE_CLASS( 29, 12, 10, 2, no, 2) \
145 SIZE_CLASS( 30, 12, 10, 3, no, 2) \
146 SIZE_CLASS( 31, 12, 10, 4, no, 1) /* 8K */\
148 SIZE_CLASS( 32, 13, 11, 1, no, 1) \
149 SIZE_CLASS( 33, 13, 11, 2, no, 1) \
150 SIZE_CLASS( 34, 13, 11, 3, no, 1) \
151 SIZE_CLASS( 35, 13, 11, 4, no, 1) /* 16K */\
153 SIZE_CLASS( 36, 14, 12, 1, no, 1) \
154 SIZE_CLASS( 37, 14, 12, 2, no, 1) \
155 SIZE_CLASS( 38, 14, 12, 3, no, 1) \
156 SIZE_CLASS( 39, 14, 12, 4, no, 1) /* 32K */\
158 SIZE_CLASS( 40, 15, 13, 1, no, 1) \
159 SIZE_CLASS( 41, 15, 13, 2, no, 1) \
160 SIZE_CLASS( 42, 15, 13, 3, no, 1) \
161 SIZE_CLASS( 43, 15, 13, 4, no, 1) /* 64K */\
163 SIZE_CLASS( 44, 16, 14, 1, no, 1) \
164 SIZE_CLASS( 45, 16, 14, 2, no, 1) \
165 SIZE_CLASS( 46, 16, 14, 3, no, 1) \
166 SIZE_CLASS( 47, 16, 14, 4, no, 1) /* 128K */\
168 SIZE_CLASS( 48, 17, 15, 1, no, 1) \
169 SIZE_CLASS( 49, 17, 15, 2, no, 1) \
170 SIZE_CLASS( 50, 17, 15, 3, no, 1) \
171 SIZE_CLASS( 51, 17, 15, 4, no, 1) /* 256K */\
173 SIZE_CLASS( 52, 18, 16, 1, no, 1) \
174 SIZE_CLASS( 53, 18, 16, 2, no, 1) \
175 SIZE_CLASS( 54, 18, 16, 3, no, 1) \
176 SIZE_CLASS( 55, 18, 16, 4, no, 1) /* 512K */\
178 SIZE_CLASS( 56, 19, 17, 1, no, 1) \
179 SIZE_CLASS( 57, 19, 17, 2, no, 1) \
180 SIZE_CLASS( 58, 19, 17, 3, no, 1) \
181 SIZE_CLASS( 59, 19, 17, 4, no, 1) /* 1M */\
183 SIZE_CLASS( 60, 20, 18, 1, no, 1) \
184 SIZE_CLASS( 61, 20, 18, 2, no, 1) \
185 SIZE_CLASS( 62, 20, 18, 3, no, 1) \
186 SIZE_CLASS( 63, 20, 18, 4, no, 1) /* 2M */\
188 SIZE_CLASS( 64, 21, 19, 1, no, 1) \
189 SIZE_CLASS( 65, 21, 19, 2, no, 1) \
190 SIZE_CLASS( 66, 21, 19, 3, no, 1) \
191 SIZE_CLASS( 67, 21, 19, 4, no, 1) /* 4M */\
193 SIZE_CLASS( 68, 22, 20, 1, no, 1) \
194 SIZE_CLASS( 69, 22, 20, 2, no, 1) \
195 SIZE_CLASS( 70, 22, 20, 3, no, 1) \
196 SIZE_CLASS( 71, 22, 20, 4, no, 1) /* 8M */\
198 SIZE_CLASS( 72, 23, 21, 1, no, 1) \
199 SIZE_CLASS( 73, 23, 21, 2, no, 1) \
200 SIZE_CLASS( 74, 23, 21, 3, no, 1) \
201 SIZE_CLASS( 75, 23, 21, 4, no, 1) /* 16M */\
203 SIZE_CLASS( 76, 24, 22, 1, no, 1) \
204 SIZE_CLASS( 77, 24, 22, 2, no, 1) \
205 SIZE_CLASS( 78, 24, 22, 3, no, 1) \
206 SIZE_CLASS( 79, 24, 22, 4, no, 1) /* 32M */\
208 SIZE_CLASS( 80, 25, 23, 1, no, 1) \
209 SIZE_CLASS( 81, 25, 23, 2, no, 1) \
210 SIZE_CLASS( 82, 25, 23, 3, no, 1) \
211 SIZE_CLASS( 83, 25, 23, 4, no, 1) /* 64M */\
213 SIZE_CLASS( 84, 26, 24, 1, no, 1) \
214 SIZE_CLASS( 85, 26, 24, 2, no, 1) \
215 SIZE_CLASS( 86, 26, 24, 3, no, 1) \
216 SIZE_CLASS( 87, 26, 24, 4, no, 1) /* 128M */\
218 SIZE_CLASS( 88, 27, 25, 1, no, 1) \
219 SIZE_CLASS( 89, 27, 25, 2, no, 1) \
220 SIZE_CLASS( 90, 27, 25, 3, no, 1) \
221 SIZE_CLASS( 91, 27, 25, 4, no, 1) /* 256M */\
223 SIZE_CLASS( 92, 28, 26, 1, no, 1) \
224 SIZE_CLASS( 93, 28, 26, 2, no, 1) \
225 SIZE_CLASS( 94, 28, 26, 3, no, 1) \
226 SIZE_CLASS( 95, 28, 26, 4, no, 1) /* 512M */\
228 SIZE_CLASS( 96, 29, 27, 1, no, 1) \
229 SIZE_CLASS( 97, 29, 27, 2, no, 1) \
230 SIZE_CLASS( 98, 29, 27, 3, no, 1) \
231 SIZE_CLASS( 99, 29, 27, 4, no, 1) /* 1G */\
233 SIZE_CLASS(100, 30, 28, 1, no, 1) \
234 SIZE_CLASS(101, 30, 28, 2, no, 1) \
235 SIZE_CLASS(102, 30, 28, 3, no, 1) \
236 SIZE_CLASS(103, 30, 28, 4, no, 1) /* 2G */\
238 SIZE_CLASS(104, 31, 29, 1, no, 1) \
239 SIZE_CLASS(105, 31, 29, 2, no, 1) \
240 SIZE_CLASS(106, 31, 29, 3, no, 1) \
241 SIZE_CLASS(107, 31, 29, 4, no, 1) /* 4G */\
243 SIZE_CLASS(108, 32, 30, 1, no, 1) \
244 SIZE_CLASS(109, 32, 30, 2, no, 1) \
245 SIZE_CLASS(110, 32, 30, 3, no, 1) \
246 SIZE_CLASS(111, 32, 30, 4, no, 1) /* 8G */\
248 SIZE_CLASS(112, 33, 31, 1, no, 1) \
249 SIZE_CLASS(113, 33, 31, 2, no, 1) \
250 SIZE_CLASS(114, 33, 31, 3, no, 1) \
251 SIZE_CLASS(115, 33, 31, 4, no, 1) /* 16G */\
253 SIZE_CLASS(116, 34, 32, 1, no, 1) \
254 SIZE_CLASS(117, 34, 32, 2, no, 1) \
255 SIZE_CLASS(118, 34, 32, 3, no, 1) \
256 SIZE_CLASS(119, 34, 32, 4, no, 1) /* 32G */\
258 SIZE_CLASS(120, 35, 33, 1, no, 1) \
259 SIZE_CLASS(121, 35, 33, 2, no, 1) \
260 SIZE_CLASS(122, 35, 33, 3, no, 1) \
261 SIZE_CLASS(123, 35, 33, 4, no, 1) /* 64G */\
263 SIZE_CLASS(124, 36, 34, 1, no, 1) \
264 SIZE_CLASS(125, 36, 34, 2, no, 1) \
265 SIZE_CLASS(126, 36, 34, 3, no, 1) \
266 SIZE_CLASS(127, 36, 34, 4, no, 1) /* 128G */\
268 SIZE_CLASS(128, 37, 35, 1, no, 1) \
269 SIZE_CLASS(129, 37, 35, 2, no, 1) \
270 SIZE_CLASS(130, 37, 35, 3, no, 1) \
271 SIZE_CLASS(131, 37, 35, 4, no, 1) /* 256G */\
273 SIZE_CLASS(132, 38, 36, 1, no, 1) \
274 SIZE_CLASS(133, 38, 36, 2, no, 1) \
275 SIZE_CLASS(134, 38, 36, 3, no, 1) \
276 SIZE_CLASS(135, 38, 36, 4, no, 1) /* 512G */\
278 SIZE_CLASS(136, 39, 37, 1, no, 1) \
279 SIZE_CLASS(137, 39, 37, 2, no, 1) \
280 SIZE_CLASS(138, 39, 37, 3, no, 1) \
281 SIZE_CLASS(139, 39, 37, 4, no, 1) /* 1T */\
283 SIZE_CLASS(140, 40, 38, 1, no, 1) \
284 SIZE_CLASS(141, 40, 38, 2, no, 1) \
285 SIZE_CLASS(142, 40, 38, 3, no, 1) \
286 SIZE_CLASS(143, 40, 38, 4, no, 1) /* 2T */\
288 SIZE_CLASS(144, 41, 39, 1, no, 1) \
289 SIZE_CLASS(145, 41, 39, 2, no, 1) \
290 SIZE_CLASS(146, 41, 39, 3, no, 1) \
291 SIZE_CLASS(147, 41, 39, 4, no, 1) /* 4T */\
293 SIZE_CLASS(148, 42, 40, 1, no, 1) \
294 SIZE_CLASS(149, 42, 40, 2, no, 1) \
295 SIZE_CLASS(150, 42, 40, 3, no, 1) \
296 SIZE_CLASS(151, 42, 40, 4, no, 1) /* 8T */\
298 SIZE_CLASS(152, 43, 41, 1, no, 1) \
299 SIZE_CLASS(153, 43, 41, 2, no, 1) \
300 SIZE_CLASS(154, 43, 41, 3, no, 1) \
301 SIZE_CLASS(155, 43, 41, 4, no, 1) /* 16T */\
303 SIZE_CLASS(156, 44, 42, 1, no, 1) \
304 SIZE_CLASS(157, 44, 42, 2, no, 1) \
305 SIZE_CLASS(158, 44, 42, 3, no, 1) \
306 SIZE_CLASS(159, 44, 42, 4, no, 1) /* 32T */\
308 SIZE_CLASS(160, 45, 43, 1, no, 1) \
309 SIZE_CLASS(161, 45, 43, 2, no, 1) \
310 SIZE_CLASS(162, 45, 43, 3, no, 1) \
311 SIZE_CLASS(163, 45, 43, 4, no, 1) /* 64T */\
313 SIZE_CLASS(164, 46, 44, 1, no, 1) \
314 SIZE_CLASS(165, 46, 44, 2, no, 1) \
315 SIZE_CLASS(166, 46, 44, 3, no, 1) \
316 SIZE_CLASS(167, 46, 44, 4, no, 1) /* 128T */\
318 SIZE_CLASS(168, 47, 45, 1, no, 1) \
319 SIZE_CLASS(169, 47, 45, 2, no, 1) \
320 SIZE_CLASS(170, 47, 45, 3, no, 1) \
321 SIZE_CLASS(171, 47, 45, 4, no, 1) /* 256T */\
323 constexpr size_t kNumSizeClasses = 172;
325 alignas(64) constexpr uint8_t kSmallSize2Index[] = {
326 #define S2I_4(i) i,
327 #define S2I_5(i) S2I_4(i) S2I_4(i)
328 #define S2I_6(i) S2I_5(i) S2I_5(i)
329 #define S2I_7(i) S2I_6(i) S2I_6(i)
330 #define S2I_8(i) S2I_7(i) S2I_7(i)
331 #define S2I_9(i) S2I_8(i) S2I_8(i)
332 #define S2I_no(i)
333 #define SIZE_CLASS(index, lg_grp, lg_delta, ndelta, lg_delta_lookup, ncontig) \
334 S2I_##lg_delta_lookup(index)
335 SIZE_CLASSES
336 #undef S2I_4
337 #undef S2I_5
338 #undef S2I_6
339 #undef S2I_7
340 #undef S2I_8
341 #undef S2I_9
342 #undef S2I_no
343 #undef SIZE_CLASS
346 constexpr size_t kSizeIndex2Size[] = {
347 #define SIZE_CLASS(index, lg_grp, lg_delta, ndelta, lg_delta_lookup, ncontig) \
348 ((size_t{1}<<lg_grp) + (size_t{ndelta}<<lg_delta)),
349 SIZE_CLASSES
350 #undef SIZE_CLASS
353 alignas(64) constexpr unsigned kNContigTab[] = {
354 #define SIZE_CLASS(index, lg_grp, lg_delta, ndelta, lg_delta_lookup, ncontig) \
355 ncontig,
356 SIZE_CLASSES
357 #undef SIZE_CLASS
360 constexpr size_t kMaxSmallSizeLookup = 4096;
362 constexpr unsigned kLgSlabSize = 21;
363 constexpr uint32_t kSlabSize = uint32_t{1} << kLgSlabSize;
364 constexpr unsigned kLgSmallSizeQuantum = 4;
365 constexpr size_t kSmallSizeAlign = 1u << kLgSmallSizeQuantum;
366 constexpr size_t kSmallSizeAlignMask = kSmallSizeAlign - 1;
368 constexpr unsigned kLgSizeClassesPerDoubling = 2;
369 constexpr size_t kSizeClassesPerDoubling = (1u << kLgSizeClassesPerDoubling);
372 * The maximum size where we use our custom allocator for request-local memory.
374 * Allocations larger than this size go to the underlying malloc implementation,
375 * and certain specialized allocator functions have preconditions about the
376 * requested size being above or below this number to avoid checking at runtime.
378 * We want kMaxSmallSize to be the largest size-class less than kSlabSize.
380 constexpr size_t kNumSmallSizes = 63;
381 static_assert(kNumSmallSizes <= (1 << 6),
382 "only 6 bits available in HeapObject");
383 static_assert(kNumSmallSizes < kNumSizeClasses,
384 "small sizes should be a proper subset of all sizes");
385 static_assert(kNumSizeClasses <= (sizeof(kSizeIndex2Size) / sizeof(size_t)),
386 "Extend SIZE_CLASSES macro");
388 constexpr size_t kMaxSmallSize = kSizeIndex2Size[kNumSmallSizes-1];
389 static_assert(kMaxSmallSize > kSmallSizeAlign * 2,
390 "Too few size classes");
391 static_assert(kMaxSmallSize < kSlabSize, "fix kNumSmallSizes or kLgSlabSize");
393 constexpr size_t kMaxSizeClass = kSizeIndex2Size[kNumSizeClasses-1];
394 static_assert(kMaxSmallSize < kMaxSizeClass,
395 "largest small size should be smaller than largest overall size");
398 * Constants for the various debug junk-filling of different types of
399 * memory in hhvm.
401 * jemalloc uses 0x5a to fill freed memory, so we use 0x6a for the
402 * request-local allocator so it is easy to tell the difference when
403 * debugging. There's also 0x7a for junk-filling some cases of
404 * ex-TypedValue memory (evaluation stack).
406 constexpr char kSmallFreeFill = 0x6a;
407 constexpr char kRDSTrashFill = 0x6b; // used by RDS for "normal" section
408 constexpr char kTrashClsRef = 0x6c; // used for class-ref slots
409 constexpr char kTrashCufIter = 0x6d; // used for cuf-iters
410 constexpr char kTVTrashFill = 0x7a; // used by interpreter
411 constexpr char kTVTrashFill2 = 0x7b; // used by req::ptr dtors
412 constexpr char kTVTrashJITStk = 0x7c; // used by the JIT for stack slots
413 constexpr char kTVTrashJITFrame = 0x7d; // used by the JIT for stack frames
414 constexpr char kTVTrashJITHeap = 0x7e; // used by the JIT for heap
415 constexpr char kTVTrashJITRetVal = 0x7f; // used by the JIT for ActRec::m_r
416 constexpr uintptr_t kSmallFreeWord = 0x6a6a6a6a6a6a6a6aLL;
417 constexpr uintptr_t kMallocFreeWord = 0x5a5a5a5a5a5a5a5aLL;
419 //////////////////////////////////////////////////////////////////////
421 // Header MemoryManager uses for StringDatas that wrap APCHandle
422 struct StringDataNode {
423 StringDataNode* next;
424 StringDataNode* prev;
427 static_assert(std::numeric_limits<type_scan::Index>::max() <=
428 std::numeric_limits<uint16_t>::max(),
429 "type_scan::Index must be no greater than 16-bits "
430 "to fit into HeapObject");
432 // This is the header MemoryManager uses to remember large allocations
433 // so they can be auto-freed in MemoryManager::reset(), as well as large/small
434 // req::malloc()'d blocks, which must track their size internally.
435 struct MallocNode : HeapObject {
436 size_t nbytes;
437 uint32_t& index() { return m_aux32; }
438 uint16_t& typeIndex() { return m_aux16; }
439 uint16_t typeIndex() const { return m_aux16; }
442 // all FreeList entries are parsed by inspecting this header.
443 struct FreeNode : HeapObject {
444 FreeNode* next;
445 uint32_t& size() { return m_aux32; }
446 uint32_t size() const { return m_aux32; }
447 static FreeNode* InitFrom(void* addr, uint32_t size, HeaderKind);
448 static FreeNode* UninitFrom(void* addr, FreeNode* next);
451 static_assert(sizeof(FreeNode) <= kSmallSizeAlign,
452 "FreeNode must fit into the smallest size class");
454 // header for HNI objects with NativeData payloads. see native-data.h
455 // for details about memory layout.
456 struct NativeNode : HeapObject,
457 type_scan::MarkCollectable<NativeNode> {
458 NativeNode(HeaderKind k, uint32_t off) : obj_offset(off) {
459 initHeader_32(k, 0);
461 uint32_t sweep_index; // index in MemoryManager::m_natives
462 uint32_t obj_offset; // byte offset from this to ObjectData*
463 uint16_t& typeIndex() { return m_aux16; }
464 uint16_t typeIndex() const { return m_aux16; }
465 uint32_t arOff() const { return m_count; } // from this to ActRec, or 0
468 // POD type for tracking arbitrary memory ranges
469 template<class T> struct MemRange {
470 T ptr;
471 size_t size; // bytes
474 using MemBlock = MemRange<void*>;
475 using HdrBlock = MemRange<HeapObject*>;
477 ///////////////////////////////////////////////////////////////////////////////
480 * Allocator for slabs and big blocks.
482 struct SparseHeap {
483 SparseHeap() {}
484 ~SparseHeap();
487 * Is the heap empty?
489 bool empty() const;
492 * Whether `ptr' refers to slab-allocated memory.
494 * Note that memory in big blocks is explicitly excluded.
496 bool contains(void* ptr) const;
499 * Allocate a MemBlock of at least size bytes, track in m_slabs.
501 MemBlock allocSlab(size_t size, MemoryUsageStats& stats);
504 * Allocation API for big blocks.
506 MemBlock allocBig(size_t size, HeaderKind kind,
507 type_scan::Index tyindex, MemoryUsageStats& stats);
508 MemBlock callocBig(size_t size, HeaderKind kind,
509 type_scan::Index tyindex, MemoryUsageStats& stats);
510 MemBlock resizeBig(void* p, size_t size, MemoryUsageStats& stats);
511 void freeBig(void*);
514 * Free all slabs and big blocks.
516 void reset();
519 * Release auxiliary structures to prepare to be idle for a while.
521 * @requires: empty()
523 void flush();
526 * Iterate over all the slabs and big blocks, calling Fn on each block,
527 * including all of the blocks in each slab.
529 template<class Fn> void iterate(Fn);
532 * call OnBig() on each BigObj & BigMalloc header, and OnSlab() on
533 * each slab, without iterating the blocks within each slab.
535 template<class OnBig, class OnSlab> void iterate(OnBig, OnSlab);
538 * Find the HeapObject* which contains `p', else nullptr if `p' is
539 * not contained in any heap allocation.
541 HeapObject* find(const void* p);
544 * Sorts both slabs and big blocks.
546 void sort();
548 protected:
549 void enlist(MallocNode*, HeaderKind kind, size_t size, type_scan::Index);
551 protected:
552 std::vector<MemBlock> m_slabs;
553 std::vector<MallocNode*> m_bigs;
557 * Contiguous heap allocator for chunks
559 struct ContiguousHeap {
560 static constexpr size_t ChunkSize = kSlabSize; // 2MB
561 static constexpr size_t HeapCap = 8 * 1024*1024*1024UL; // 8G
562 static constexpr size_t FreebitsSize = HeapCap / ChunkSize; // 4096
563 ContiguousHeap();
565 ~ContiguousHeap();
568 * Is the heap empty?
570 bool empty() const;
573 * Whether `ptr' refers to slab-allocated memory.
575 bool contains(void* ptr) const;
578 * Allocate a MemBlock of at least size bytes.
580 MemBlock allocSlab(size_t size, MemoryUsageStats& stats);
583 * Allocation API for big blocks.
585 MemBlock allocBig(size_t size, HeaderKind kind,
586 type_scan::Index tyindex, MemoryUsageStats& stats);
587 MemBlock callocBig(size_t size, HeaderKind kind,
588 type_scan::Index tyindex, MemoryUsageStats& stats);
589 MemBlock resizeBig(void* p, size_t size, MemoryUsageStats& stats);
590 void freeBig(void*);
593 * Free all chunks.
595 void reset();
598 * Release auxiliary structures to prepare to be idle for a while.
600 * @requires: empty()
602 void flush();
605 * Iterate over all the chunks.
607 template<class OnBig, class OnSlab> void iterate(OnBig, OnSlab);
608 template<class Fn> void iterate(Fn);
609 template<class Fn> HeapObject* find_if(bool, Fn);
612 * Find the HeapObject* which contains `p'. If `p' is
613 * not contained in any heap allocation, it returns nullptr.
615 HeapObject* find(const void* p);
618 * Sorts both slabs and big blocks.
620 void sort() {}
622 private:
623 char* raw_alloc(size_t size);
624 void raw_free(char* p, size_t size);
625 bool check_invariants() const;
626 char* grow(size_t size);
627 size_t chunk_index(char* p) const;
629 private:
630 char* const m_base; // lowest address in heap
631 char* const m_limit; // limit of heap size
632 char* m_front; // end of the allocated part of the heap
633 std::bitset<FreebitsSize> m_freebits; // 1 for free, 0 for allocated
636 #ifdef USE_CONTIGUOUS_HEAP
637 using HeapImpl = ContiguousHeap;
638 #else
639 using HeapImpl = SparseHeap;
640 #endif
641 ///////////////////////////////////////////////////////////////////////////////
643 struct MemoryManager {
646 * This is an RAII wrapper to temporarily mask counting allocations from
647 * stats tracking in a scoped region.
649 * Usage:
650 * MemoryManager::MaskAlloc masker(tl_heap);
652 struct MaskAlloc;
655 * An RAII wrapper to suppress OOM checking in a region.
657 struct SuppressOOM;
659 MemoryManager();
660 MemoryManager(const MemoryManager&) = delete;
661 MemoryManager& operator=(const MemoryManager&) = delete;
662 ~MemoryManager();
664 /////////////////////////////////////////////////////////////////////////////
665 // Allocation.
668 * Return the size class for a given requested small-allocation size.
670 * The return value is greater than or equal to the parameter, and
671 * less than or equal to kMaxSmallSize.
673 * Pre: requested <= kMaxSmallSize
675 static size_t smallSizeClass(size_t requested);
678 * Return a lower bound estimate of the capacity that will be returned for
679 * the requested size.
681 static size_t estimateCap(size_t requested);
684 * Allocate/deallocate a small memory block in a given small size class.
685 * You must be able to tell the deallocation function how big the
686 * allocation was.
688 * The size passed to mallocSmallSize does not need to be an exact
689 * size class (although stats accounting may undercount in this
690 * case). The size passed to freeSmallSize must be the exact size
691 * that was passed to mallocSmallSize for that allocation.
693 * The returned pointer is guaranteed to be 16-byte aligned.
695 * Pre: size > 0 && size <= kMaxSmallSize
697 void* mallocSmallSize(size_t size);
698 void freeSmallSize(void* p, size_t size);
701 * Allocate/deallocate memory that is too big for the small size classes.
703 * Returns a pointer and the actual size of the allocation, which
704 * may be larger than the requested size. The returned pointer is
705 * guaranteed to be 16-byte aligned.
707 * Pre: size > kMaxSmallSize
709 enum MBS { Unzeroed, Zeroed };
710 template<MBS Mode>
711 void* mallocBigSize(size_t size, HeaderKind kind = HeaderKind::BigObj,
712 type_scan::Index tyindex = 0);
713 void freeBigSize(void* vp);
714 void* resizeBig(MallocNode* n, size_t nbytes);
717 * Allocate/deallocate objects when the size is not known to be
718 * above or below kMaxSmallSize without a runtime check.
720 * These functions use the same underlying allocator as
721 * malloc{Small,Big}Size, and it is safe to return allocations using
722 * one of those apis as long as the appropriate preconditions on the
723 * size are met.
725 * The size passed to objFree must be the size passed in to
726 * objMalloc.
728 * Pre: size > 0
730 void* objMalloc(size_t size);
731 void objFree(void* vp, size_t size);
734 * Allocate/deallocate by size class index. This is useful when size
735 * class is already calculated at the call site.
737 void* mallocSmallIndex(size_t index);
738 void freeSmallIndex(void* ptr, size_t index);
741 * Allocate/deallocate by size class index, when the index is not known to
742 * be < kNumSmallSizes This is useful when size class is already calculated
743 * at the call site, but might not be a small size class.
745 * The index passed to objFreeIndex must be the same one passed to
746 * objMallocIndex.
748 void* objMallocIndex(size_t index);
749 void objFreeIndex(void* ptr, size_t index);
752 * These functions are useful when working directly with size classes outside
753 * this class.
755 * Note that we intentionally use size_t for size class index here, so that
756 * gcc would not generate inefficient code.
758 static size_t computeSize2Index(size_t size);
759 static size_t lookupSmallSize2Index(size_t size);
760 static size_t smallSize2Index(size_t size);
761 static size_t size2Index(size_t size);
762 static size_t sizeIndex2Size(size_t index);
764 /////////////////////////////////////////////////////////////////////////////
765 // Cleanup.
768 * Prepare for being idle for a while by releasing or madvising as much as
769 * possible.
771 void flush();
774 * Release all the request-local allocations.
776 * Zeros all the free lists and may return some underlying storage to the
777 * system allocator. This also resets all internally-stored memory usage
778 * stats.
780 * This is called after sweep in the end-of-request path.
782 void resetAllocator();
785 * Reset all runtime options for MemoryManager.
787 void resetRuntimeOptions();
789 /////////////////////////////////////////////////////////////////////////////
790 // Heap introspection.
793 * Return true if there are no allocated slabs.
795 bool empty() const;
798 * Whether `p' points into memory owned by `m_heap'. checkContains() will
799 * assert that it does.
801 * Note that this explicitly excludes allocations that are made through the
802 * big alloc API.
804 bool contains(void* p) const;
805 bool checkContains(void* p) const;
808 * Heap iterator methods. `fn' takes a HeapObject* argument.
810 * initFree(): prepare to iterate by initializing free block headers,
811 * initializing dead space past m_front, and sorting slabs.
812 * reinitFree(): like initFree() but only update the freelists.
813 * iterate(): Raw iterator loop over every HeapObject in the heap.
814 * Skips BigObj because it's just a detail of which sub-heap we
815 * used to allocate something based on its size, and it can prefix
816 * almost any other header kind, and also skips Hole. Clients can
817 * call this directly to avoid unnecessary initFree()s.
818 * forEachHeapObject(): Like iterate(), but with an eager initFree().
819 * forEachObject(): Iterate just the ObjectDatas, including the kinds with
820 * prefixes (NativeData, AsyncFuncFrame, and ClosureHdr).
822 void initFree();
823 void reinitFree();
824 template<class Fn> void iterate(Fn fn);
825 template<class Fn> void forEachHeapObject(Fn fn);
826 template<class Fn> void forEachObject(Fn fn);
829 * Iterate over the roots owned by MemoryManager.
830 * call fn(ptr, size, type_scan::Index) for each root
832 template<class Fn> void iterateRoots(Fn) const;
835 * Find the HeapObject* which contains `p', else nullptr if `p' is
836 * not contained in any heap allocation.
838 HeapObject* find(const void* p);
840 /////////////////////////////////////////////////////////////////////////////
841 // Stats.
844 * Update the request-memory limit.
846 void setMemoryLimit(size_t limit);
847 int64_t getMemoryLimit() const;
850 * Update the tracked stats in the MemoryManager object, then return
851 * a copy of the stats.
853 MemoryUsageStats getStats();
856 * Get most recent stats data, as one would with getStats(), but without
857 * altering the underlying data stored in the MemoryManager, triggering
858 * OOM, or triggering the memory threshold callback. Used for obtaining
859 * allocation counters passively.
861 MemoryUsageStats getStatsCopy();
864 * Open and close respectively a stats-tracking interval.
866 * Return whether or not the tracking state was changed as a result of the
867 * call.
869 bool startStatsInterval();
870 bool stopStatsInterval();
873 * How much memory this thread has allocated or deallocated.
875 int64_t getAllocated() const;
876 int64_t getDeallocated() const;
877 int64_t currentUsage() const;
880 * Reset all stats that are synchronzied externally from the memory manager.
882 * Used between sessions and to signal that external sync is now safe to
883 * begin (after shared structure initialization that should not be counted is
884 * complete.)
886 void resetExternalStats();
888 /////////////////////////////////////////////////////////////////////////////
889 // OOMs.
892 * Whether an allocation of `size' would run the request out of memory.
894 * This behaves just like the OOM check in refreshStatsImpl(). If the
895 * m_couldOOM flag is already unset, we return false, but if otherwise we
896 * would exceed the limit, we unset the flag and register an OOM fatal
897 * (though we do not modify the MemoryManager's stats).
899 bool preAllocOOM(int64_t size);
902 * Unconditionally register an OOM fatal. Still respects the m_couldOOM flag.
904 void forceOOM();
907 * Reset whether or not we should raise an OOM fatal if we exceed the memory
908 * limit for the request.
910 * After an OOM fatal, the memory manager refuses to raise another OOM error
911 * until this flag has been reset, to try to avoid getting OOMs during the
912 * initial OOM processing.
914 void resetCouldOOM(bool state = true);
916 /////////////////////////////////////////////////////////////////////////////
917 // Sweeping.
920 * Returns true iff a sweep is in progress---i.e., is the current thread
921 * running inside a call to MemoryManager::sweep()?
923 * It is legal to call this function even when the current thread's
924 * MemoryManager may not be set up (i.e. between requests).
926 static bool sweeping();
927 static bool exiting();
928 static void setExiting();
931 * During session shutdown, before resetAllocator(), this phase runs through
932 * the sweep lists, running cleanup for anything that needs to run custom
933 * tear down logic before we throw away the request-local memory.
935 void sweep();
938 * Methods for maintaining dedicated sweep lists of sweepable NativeData
939 * objects, APCLocalArray instances, and Sweepables.
941 void addNativeObject(NativeNode*);
942 void removeNativeObject(NativeNode*);
943 void addApcArray(APCLocalArray*);
944 void removeApcArray(APCLocalArray*);
945 void addSweepable(Sweepable*);
946 template<class Fn> void sweepApcArrays(Fn fn);
947 template<class Fn> void sweepApcStrings(Fn fn);
949 /////////////////////////////////////////////////////////////////////////////
950 // Request profiling.
953 * Trigger heap profiling in the next request.
955 * Allocate the s_trigger atomic so that the next request can consume it. If
956 * an unconsumed trigger exists, do nothing and return false; else return
957 * true.
959 static bool triggerProfiling(const std::string& filename);
962 * Installs a PHP callback for the specified peak memory watermarks
963 * Each request may have 1 memory callback for 1 specific threshold
964 * at a given time
966 void setMemThresholdCallback(size_t threshold);
969 * Do per-request initialization.
971 * Attempt to consume the profiling trigger, and copy it to m_profctx if we
972 * are successful. Also enable jemalloc heap profiling.
974 static void requestInit();
977 * Do per-request shutdown.
979 * Dump a jemalloc heap profiling, then reset the profiler.
981 static void requestShutdown();
984 * Setup/teardown profiling for current request. This causes all allocation
985 * requests to be passed through to the underlying memory allocator so that
986 * heap profiling can capture backtraces for individual allocations rather
987 * than slab allocations.
989 static void setupProfiling();
990 static void teardownProfiling();
992 /////////////////////////////////////////////////////////////////////////////
993 // Garbage collection.
996 * Returns ptr to head node of m_strings linked list. This used by
997 * StringData during a reset, enlist, and delist
999 StringDataNode& getStringList();
1002 * Run the experimental collector.
1004 void collect(const char* phase);
1005 void resetGC();
1006 void updateNextGc();
1008 bool isGCEnabled();
1009 void setGCEnabled(bool isGCEnabled);
1011 struct FreeList {
1012 void* maybePop();
1013 void push(void*);
1014 FreeNode* head{nullptr};
1016 using FreelistArray = std::array<FreeList,kNumSmallSizes>;
1019 * beginQuarantine() swaps out the normal freelists. endQuarantine()
1020 * fills everything freed with holes, then restores the original freelists.
1022 FreelistArray beginQuarantine();
1023 void endQuarantine(FreelistArray&&);
1026 * Run an integrity check on the heap
1028 void checkHeap(const char* phase);
1030 /////////////////////////////////////////////////////////////////////////////
1032 private:
1033 friend struct req::root_handle; // access m_root_handles
1035 // head node of the doubly-linked list of Sweepables
1036 struct SweepableList : Sweepable {
1037 SweepableList() : Sweepable(Init{}) {}
1038 void sweep() override {}
1039 void* owner() override { return nullptr; }
1043 * Request-local heap profiling context.
1045 struct ReqProfContext {
1046 bool flag{false};
1047 bool prof_active{false};
1048 bool thread_prof_active{false};
1049 std::string filename{};
1052 /////////////////////////////////////////////////////////////////////////////
1054 private:
1055 void storeTail(void* tail, uint32_t tailBytes);
1056 void splitTail(void* tail, uint32_t tailBytes, unsigned nSplit,
1057 uint32_t splitUsable, unsigned splitInd);
1058 void* slabAlloc(uint32_t bytes, size_t index);
1059 void* newSlab(uint32_t nbytes);
1060 void* mallocSmallSizeSlow(size_t bytes, size_t index);
1061 void updateBigStats();
1063 static size_t bsrq(size_t x);
1065 static void threadStatsInit();
1066 static void threadStats(uint64_t*&, uint64_t*&);
1067 void refreshStats();
1068 void refreshStatsImpl(MemoryUsageStats& stats);
1069 void refreshStatsHelperExceeded();
1070 void resetAllStats();
1071 void traceStats(const char* when);
1073 static void initHole(void* ptr, uint32_t size);
1075 void requestEagerGC();
1076 void resetEagerGC();
1077 void requestGC();
1079 /////////////////////////////////////////////////////////////////////////////
1081 private:
1082 TRACE_SET_MOD(mm);
1084 void* m_front{nullptr};
1085 void* m_limit{nullptr};
1086 FreelistArray m_freelists;
1087 StringDataNode m_strings; // in-place node is head of circular list
1088 std::vector<APCLocalArray*> m_apc_arrays;
1089 int64_t m_nextGc; // request gc when heap usage reaches this size
1090 int64_t m_usageLimit; // OOM when m_stats.usage() > m_usageLimit
1091 MemoryUsageStats m_stats;
1092 HeapImpl m_heap;
1093 std::vector<NativeNode*> m_natives;
1094 SweepableList m_sweepables;
1096 mutable std::vector<req::root_handle*> m_root_handles;
1098 bool m_exiting{false};
1099 bool m_statsIntervalActive;
1100 bool m_couldOOM{true};
1101 bool m_bypassSlabAlloc;
1102 bool m_gc_enabled{RuntimeOption::EvalEnableGC};
1103 bool m_enableStatsSync{false};
1104 GCBits m_mark_version{GCBits(0)};
1106 ReqProfContext m_profctx;
1107 static std::atomic<ReqProfContext*> s_trigger;
1109 // Peak memory threshold callback (installed via setMemThresholdCallback)
1110 size_t m_memThresholdCallbackPeakUsage{SIZE_MAX};
1112 // pointers to jemalloc-maintained allocation counters
1113 uint64_t* m_allocated;
1114 uint64_t* m_deallocated;
1116 // previous values of *m_[de]allocated from last resetStats()
1117 uint64_t m_resetAllocated;
1118 uint64_t m_resetDeallocated;
1120 // true if mallctlnametomib() setup succeeded, which requires jemalloc
1121 static bool s_statsEnabled;
1123 int64_t m_req_start_micros;
1125 TYPE_SCAN_IGNORE_ALL; // heap-scan handles MemoryManager fields itself.
1128 extern THREAD_LOCAL_FLAT(MemoryManager, tl_heap);
1130 //////////////////////////////////////////////////////////////////////
1134 #include "hphp/runtime/base/memory-manager-inl.h"
1136 #endif