73 #ifdef MEMORY_CONTEXT_CHECKING
114 #define SlabPointerGetChunk(ptr) \
115 ((SlabChunk *)(((char *)(ptr)) - sizeof(SlabChunk)))
116 #define SlabChunkGetPointer(chk) \
117 ((void *)(((char *)(chk)) + sizeof(SlabChunk)))
118 #define SlabBlockGetChunk(slab, block, idx) \
119 ((SlabChunk *) ((char *) (block) + sizeof(SlabBlock) \
120 + (idx * slab->fullChunkSize)))
121 #define SlabBlockStart(block) \
122 ((char *) block + sizeof(SlabBlock))
123 #define SlabChunkIndex(slab, block, chunk) \
124 (((char *) chunk - SlabBlockStart(block)) / slab->fullChunkSize)
139 bool print_to_stderr);
140 #ifdef MEMORY_CONTEXT_CHECKING
156 #ifdef MEMORY_CONTEXT_CHECKING
189 "sizeof(SlabChunk) is not maxaligned");
192 "padding calculation in SlabChunk is wrong");
195 if (chunkSize <
sizeof(
int))
196 chunkSize =
sizeof(int);
202 if (blockSize < fullChunkSize +
sizeof(
SlabBlock))
203 elog(
ERROR,
"block size %zu for slab is too small for %zu chunks",
204 blockSize, chunkSize);
207 chunksPerBlock = (blockSize -
sizeof(
SlabBlock)) / fullChunkSize;
210 freelistSize =
sizeof(
dlist_head) * (chunksPerBlock + 1);
220 #ifdef MEMORY_CONTEXT_CHECKING
227 headerSize += chunksPerBlock *
sizeof(
bool);
235 (
errcode(ERRCODE_OUT_OF_MEMORY),
237 errdetail(
"Failed while creating memory context \"%s\".",
259 #ifdef MEMORY_CONTEXT_CHECKING
290 #ifdef MEMORY_CONTEXT_CHECKING
306 #ifdef CLOBBER_FREED_MEMORY
354 elog(
ERROR,
"unexpected alloc chunk size %zu (expected %zu)",
412 Assert((
idx >= 0) && (idx < slab->chunksPerBlock));
437 (block->
nfree == 0 &&
469 chunk->
block = block;
472 #ifdef MEMORY_CONTEXT_CHECKING
483 #ifdef RANDOMIZE_ALLOCATED_MEMORY
505 #ifdef MEMORY_CONTEXT_CHECKING
508 if (!sentinel_ok(pointer, slab->
chunkSize))
509 elog(
WARNING,
"detected write past chunk end in %s %p",
524 #ifdef CLOBBER_FREED_MEMORY
526 wipe_mem((
char *) pointer +
sizeof(
int32),
596 elog(
ERROR,
"slab allocator does not support realloc()");
642 bool print_to_stderr)
665 freechunks += block->
nfree;
671 char stats_string[200];
673 snprintf(stats_string,
sizeof(stats_string),
674 "%zu total in %zu blocks; %zu free (%zu chunks); %zu used",
675 totalspace, nblocks, freespace, freechunks,
676 totalspace - freespace);
677 printfunc(context, passthru, stats_string, print_to_stderr);
690 #ifdef MEMORY_CONTEXT_CHECKING
728 elog(
WARNING,
"problem in slab %s: number of free chunks %d in block %p does not match freelist %d",
732 memset(slab->freechunks, 0, (slab->
chunksPerBlock *
sizeof(
bool)));
743 while (idx < slab->chunksPerBlock)
749 slab->freechunks[
idx] =
true;
760 if (!slab->freechunks[
j])
765 if (chunk->
block != block)
766 elog(
WARNING,
"problem in slab %s: bogus block link in block %p, chunk %p",
769 if (chunk->
slab != slab)
770 elog(
WARNING,
"problem in slab %s: bogus slab link in block %p, chunk %p",
775 if (!sentinel_ok(chunk, slab->
chunkSize))
776 elog(
WARNING,
"problem in slab %s: detected write past chunk end in block %p, chunk %p",
785 if (nfree != block->
nfree)
786 elog(
WARNING,
"problem in slab %s: number of free chunks %d in block %p does not match bitmap %d",
Datum idx(PG_FUNCTION_ARGS)
#define offsetof(type, field)
#define FLEXIBLE_ARRAY_MEMBER
#define StaticAssertStmt(condition, errmessage)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define dlist_foreach(iter, lhead)
static void dlist_init(dlist_head *head)
#define dlist_head_element(type, membername, lhead)
static bool dlist_is_empty(dlist_head *head)
static void dlist_delete(dlist_node *node)
struct dlist_head dlist_head
static void dlist_push_head(dlist_head *head, dlist_node *node)
#define dlist_foreach_modify(iter, lhead)
#define dlist_container(type, membername, ptr)
Assert(fmt[strlen(fmt) - 1] !='\n')
MemoryContext TopMemoryContext
void MemoryContextStats(MemoryContext context)
void MemoryContextCreate(MemoryContext node, NodeTag tag, const MemoryContextMethods *methods, MemoryContext parent, const char *name)
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
#define VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
void(* MemoryStatsPrintFunc)(MemoryContext context, void *passthru, const char *stats_string, bool print_to_stderr)
#define castNode(_type_, nodeptr)
#define SlabChunkIndex(slab, block, chunk)
#define SlabPointerGetChunk(ptr)
struct SlabBlock SlabBlock
static void SlabReset(MemoryContext context)
static void SlabFree(MemoryContext context, void *pointer)
#define SlabBlockGetChunk(slab, block, idx)
struct SlabContext SlabContext
#define SlabChunkGetPointer(chk)
MemoryContext SlabContextCreate(MemoryContext parent, const char *name, Size blockSize, Size chunkSize)
static void SlabDelete(MemoryContext context)
static const MemoryContextMethods SlabMethods
static void SlabStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
static Size SlabGetChunkSpace(MemoryContext context, void *pointer)
static void * SlabAlloc(MemoryContext context, Size size)
static void * SlabRealloc(MemoryContext context, void *pointer, Size size)
static bool SlabIsEmpty(MemoryContext context)
struct SlabChunk SlabChunk
dlist_head freelist[FLEXIBLE_ARRAY_MEMBER]