Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * memutils_internal.h
4 : * This file contains declarations for memory allocation utility
5 : * functions for internal use.
6 : *
7 : *
8 : * Portions Copyright (c) 2022-2024, PostgreSQL Global Development Group
9 : * Portions Copyright (c) 1994, Regents of the University of California
10 : *
11 : * src/include/utils/memutils_internal.h
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 :
16 : #ifndef MEMUTILS_INTERNAL_H
17 : #define MEMUTILS_INTERNAL_H
18 :
19 : #include "utils/memutils.h"
20 :
21 : /* These functions implement the MemoryContext API for AllocSet context. */
22 : extern void *AllocSetAlloc(MemoryContext context, Size size, int flags);
23 : extern void AllocSetFree(void *pointer);
24 : extern void *AllocSetRealloc(void *pointer, Size size, int flags);
25 : extern void AllocSetReset(MemoryContext context);
26 : extern void AllocSetDelete(MemoryContext context);
27 : extern MemoryContext AllocSetGetChunkContext(void *pointer);
28 : extern Size AllocSetGetChunkSpace(void *pointer);
29 : extern bool AllocSetIsEmpty(MemoryContext context);
30 : extern void AllocSetStats(MemoryContext context,
31 : MemoryStatsPrintFunc printfunc, void *passthru,
32 : MemoryContextCounters *totals,
33 : bool print_to_stderr);
34 : #ifdef MEMORY_CONTEXT_CHECKING
35 : extern void AllocSetCheck(MemoryContext context);
36 : #endif
37 :
38 : /* These functions implement the MemoryContext API for Generation context. */
39 : extern void *GenerationAlloc(MemoryContext context, Size size, int flags);
40 : extern void GenerationFree(void *pointer);
41 : extern void *GenerationRealloc(void *pointer, Size size, int flags);
42 : extern void GenerationReset(MemoryContext context);
43 : extern void GenerationDelete(MemoryContext context);
44 : extern MemoryContext GenerationGetChunkContext(void *pointer);
45 : extern Size GenerationGetChunkSpace(void *pointer);
46 : extern bool GenerationIsEmpty(MemoryContext context);
47 : extern void GenerationStats(MemoryContext context,
48 : MemoryStatsPrintFunc printfunc, void *passthru,
49 : MemoryContextCounters *totals,
50 : bool print_to_stderr);
51 : #ifdef MEMORY_CONTEXT_CHECKING
52 : extern void GenerationCheck(MemoryContext context);
53 : #endif
54 :
55 :
56 : /* These functions implement the MemoryContext API for Slab context. */
57 : extern void *SlabAlloc(MemoryContext context, Size size, int flags);
58 : extern void SlabFree(void *pointer);
59 : extern void *SlabRealloc(void *pointer, Size size, int flags);
60 : extern void SlabReset(MemoryContext context);
61 : extern void SlabDelete(MemoryContext context);
62 : extern MemoryContext SlabGetChunkContext(void *pointer);
63 : extern Size SlabGetChunkSpace(void *pointer);
64 : extern bool SlabIsEmpty(MemoryContext context);
65 : extern void SlabStats(MemoryContext context,
66 : MemoryStatsPrintFunc printfunc, void *passthru,
67 : MemoryContextCounters *totals,
68 : bool print_to_stderr);
69 : #ifdef MEMORY_CONTEXT_CHECKING
70 : extern void SlabCheck(MemoryContext context);
71 : #endif
72 :
73 : /*
74 : * These functions support the implementation of palloc_aligned() and are not
75 : * part of a fully-fledged MemoryContext type.
76 : */
77 : extern void AlignedAllocFree(void *pointer);
78 : extern void *AlignedAllocRealloc(void *pointer, Size size, int flags);
79 : extern MemoryContext AlignedAllocGetChunkContext(void *pointer);
80 : extern Size AlignedAllocGetChunkSpace(void *pointer);
81 :
82 : /* These functions implement the MemoryContext API for the Bump context. */
83 : extern void *BumpAlloc(MemoryContext context, Size size, int flags);
84 : extern void BumpFree(void *pointer);
85 : extern void *BumpRealloc(void *pointer, Size size, int flags);
86 : extern void BumpReset(MemoryContext context);
87 : extern void BumpDelete(MemoryContext context);
88 : extern MemoryContext BumpGetChunkContext(void *pointer);
89 : extern Size BumpGetChunkSpace(void *pointer);
90 : extern bool BumpIsEmpty(MemoryContext context);
91 : extern void BumpStats(MemoryContext context, MemoryStatsPrintFunc printfunc,
92 : void *passthru, MemoryContextCounters *totals,
93 : bool print_to_stderr);
94 : #ifdef MEMORY_CONTEXT_CHECKING
95 : extern void BumpCheck(MemoryContext context);
96 : #endif
97 :
98 : /*
99 : * How many extra bytes do we need to request in order to ensure that we can
100 : * align a pointer to 'alignto'. Since palloc'd pointers are already aligned
101 : * to MAXIMUM_ALIGNOF we can subtract that amount. We also need to make sure
102 : * there is enough space for the redirection MemoryChunk.
103 : */
104 : #define PallocAlignedExtraBytes(alignto) \
105 : ((alignto) + (sizeof(MemoryChunk) - MAXIMUM_ALIGNOF))
106 :
107 : /*
108 : * MemoryContextMethodID
109 : * A unique identifier for each MemoryContext implementation which
110 : * indicates the index into the mcxt_methods[] array. See mcxt.c.
111 : *
112 : * For robust error detection, ensure that MemoryContextMethodID has a value
113 : * for each possible bit-pattern of MEMORY_CONTEXT_METHODID_MASK, and make
114 : * dummy entries for unused IDs in the mcxt_methods[] array. We also try
115 : * to avoid using bit-patterns as valid IDs if they are likely to occur in
116 : * garbage data, or if they could falsely match on chunks that are really from
117 : * malloc not palloc. (We can't tell that for most malloc implementations,
118 : * but it happens that glibc stores flag bits in the same place where we put
119 : * the MemoryContextMethodID, so the possible values are predictable for it.)
120 : */
121 : typedef enum MemoryContextMethodID
122 : {
123 : MCTX_0_RESERVED_UNUSEDMEM_ID, /* 0000 occurs in never-used memory */
124 : MCTX_1_RESERVED_GLIBC_ID, /* glibc malloc'd chunks usually match 0001 */
125 : MCTX_2_RESERVED_GLIBC_ID, /* glibc malloc'd chunks > 128kB match 0010 */
126 : MCTX_ASET_ID,
127 : MCTX_GENERATION_ID,
128 : MCTX_SLAB_ID,
129 : MCTX_ALIGNED_REDIRECT_ID,
130 : MCTX_BUMP_ID,
131 : MCTX_8_UNUSED_ID,
132 : MCTX_9_UNUSED_ID,
133 : MCTX_10_UNUSED_ID,
134 : MCTX_11_UNUSED_ID,
135 : MCTX_12_UNUSED_ID,
136 : MCTX_13_UNUSED_ID,
137 : MCTX_14_UNUSED_ID,
138 : MCTX_15_RESERVED_WIPEDMEM_ID /* 1111 occurs in wipe_mem'd memory */
139 : } MemoryContextMethodID;
140 :
141 : /*
142 : * The number of bits that 8-byte memory chunk headers can use to encode the
143 : * MemoryContextMethodID.
144 : */
145 : #define MEMORY_CONTEXT_METHODID_BITS 4
146 : #define MEMORY_CONTEXT_METHODID_MASK \
147 : ((((uint64) 1) << MEMORY_CONTEXT_METHODID_BITS) - 1)
148 :
149 : /*
150 : * This routine handles the context-type-independent part of memory
151 : * context creation. It's intended to be called from context-type-
152 : * specific creation routines, and noplace else.
153 : */
154 : extern void MemoryContextCreate(MemoryContext node,
155 : NodeTag tag,
156 : MemoryContextMethodID method_id,
157 : MemoryContext parent,
158 : const char *name);
159 :
160 : extern void *MemoryContextAllocationFailure(MemoryContext context, Size size,
161 : int flags);
162 :
163 : extern void MemoryContextSizeFailure(MemoryContext context, Size size,
164 : int flags) pg_attribute_noreturn();
165 :
166 : static inline void
167 16043724 : MemoryContextCheckSize(MemoryContext context, Size size, int flags)
168 : {
169 16043724 : if (unlikely(!AllocSizeIsValid(size)))
170 : {
171 0 : if (!(flags & MCXT_ALLOC_HUGE) || !AllocHugeSizeIsValid(size))
172 0 : MemoryContextSizeFailure(context, size, flags);
173 : }
174 16043724 : }
175 :
176 : #endif /* MEMUTILS_INTERNAL_H */
|