48#define Bump_BLOCKHDRSZ MAXALIGN(sizeof(BumpBlock))
49#define FIRST_BLOCKHDRSZ (MAXALIGN(sizeof(BumpContext)) + \
53#ifdef MEMORY_CONTEXT_CHECKING
54#define Bump_CHUNKHDRSZ sizeof(MemoryChunk)
56#define Bump_CHUNKHDRSZ 0
59#define Bump_CHUNK_FRACTION 8
62#define KeeperBlock(set) ((BumpBlock *) ((char *) (set) + \
63 MAXALIGN(sizeof(BumpContext))))
64#define IsKeeperBlock(set, blk) (KeeperBlock(set) == (blk))
91#ifdef MEMORY_CONTEXT_CHECKING
102#define BumpIsValid(set) \
103 ((set) && IsA(set, BumpContext))
110#define ExternalChunkGetBlock(chunk) \
111 (BumpBlock *) ((char *) chunk - Bump_BLOCKHDRSZ)
134 Size initBlockSize,
Size maxBlockSize)
143 "sizeof(MemoryChunk) is not maxaligned");
157 initBlockSize >= 1024);
159 maxBlockSize >= initBlockSize &&
161 Assert(minContextSize == 0 ||
162 (minContextSize ==
MAXALIGN(minContextSize) &&
163 minContextSize >= 1024 &&
164 minContextSize <= maxBlockSize));
170 if (minContextSize != 0)
171 allocSize =
Max(allocSize, minContextSize);
173 allocSize =
Max(allocSize, initBlockSize);
184 (
errcode(ERRCODE_OUT_OF_MEMORY),
186 errdetail(
"Failed while creating memory context \"%s\".",
258#ifdef MEMORY_CONTEXT_CHECKING
317#ifdef MEMORY_CONTEXT_CHECKING
327#ifdef MEMORY_CONTEXT_CHECKING
349#ifdef MEMORY_CONTEXT_CHECKING
351 block->context = set;
358 chunk->requested_size = size;
360 Assert(size < chunk_size);
363#ifdef RANDOMIZE_ALLOCATED_MEMORY
375#ifdef MEMORY_CONTEXT_CHECKING
397#ifdef MEMORY_CONTEXT_CHECKING
407#ifdef MEMORY_CONTEXT_CHECKING
417#ifdef MEMORY_CONTEXT_CHECKING
422 chunk->requested_size = size;
424 Assert(size < chunk_size);
427#ifdef RANDOMIZE_ALLOCATED_MEMORY
473 if (blksize < required_size)
526#ifdef MEMORY_CONTEXT_CHECKING
563#ifdef MEMORY_CONTEXT_CHECKING
564 block->context = context;
567 block->
endptr = ((
char *) block) + blksize;
591#if defined(USE_VALGRIND) || defined(CLOBBER_FREED_MEMORY)
595#ifdef CLOBBER_FREED_MEMORY
596 wipe_mem(datastart, block->
freeptr - datastart);
631#ifdef CLOBBER_FREED_MEMORY
632 wipe_mem(block, ((
char *) block->
endptr - (
char *) block));
648 elog(
ERROR,
"%s is not supported by the bump memory allocator",
"pfree");
658 elog(
ERROR,
"%s is not supported by the bump memory allocator",
"realloc");
669 elog(
ERROR,
"%s is not supported by the bump memory allocator",
"GetMemoryChunkContext");
680 elog(
ERROR,
"%s is not supported by the bump memory allocator",
"GetMemoryChunkSpace");
733 totalspace += (block->
endptr - (
char *) block);
739 char stats_string[200];
741 snprintf(stats_string,
sizeof(stats_string),
742 "%zu total in %zu blocks; %zu free; %zu used",
743 totalspace, nblocks, freespace, totalspace - freespace);
744 printfunc(context, passthru, stats_string, print_to_stderr);
756#ifdef MEMORY_CONTEXT_CHECKING
772 Size total_allocated = 0;
780 bool has_external_chunk =
false;
783 total_allocated += block->
endptr - (
char *) bump;
785 total_allocated += block->
endptr - (
char *) block;
788 if (block->context != bump)
789 elog(
WARNING,
"problem in Bump %s: bogus context link in block %p",
796 while (ptr < block->freeptr)
809 has_external_chunk =
true;
823 if (chunkblock != block)
824 elog(
WARNING,
"problem in Bump %s: bogus block link in block %p, chunk %p",
828 if (has_external_chunk && nchunks > 1)
829 elog(
WARNING,
"problem in Bump %s: external chunk on non-dedicated block %p",
static bool BumpBlockIsEmpty(BumpBlock *block)
#define Bump_CHUNK_FRACTION
void BumpFree(void *pointer)
void BumpDelete(MemoryContext context)
Size BumpGetChunkSpace(void *pointer)
void BumpStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
static void BumpBlockFree(BumpContext *set, BumpBlock *block)
static void BumpBlockMarkEmpty(BumpBlock *block)
static pg_noinline void * BumpAllocLarge(MemoryContext context, Size size, int flags)
static void BumpBlockInit(BumpContext *context, BumpBlock *block, Size blksize)
MemoryContext BumpGetChunkContext(void *pointer)
#define IsKeeperBlock(set, blk)
struct BumpContext BumpContext
MemoryContext BumpContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
void BumpReset(MemoryContext context)
static pg_noinline void * BumpAllocFromNewBlock(MemoryContext context, Size size, int flags, Size chunk_size)
bool BumpIsEmpty(MemoryContext context)
void * BumpRealloc(void *pointer, Size size, int flags)
static void * BumpAllocChunkFromBlock(MemoryContext context, BumpBlock *block, Size size, Size chunk_size)
static Size BumpBlockFreeBytes(BumpBlock *block)
#define ExternalChunkGetBlock(chunk)
void * BumpAlloc(MemoryContext context, Size size, int flags)
#define StaticAssertDecl(condition, errmessage)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
#define dlist_foreach(iter, lhead)
static void dlist_init(dlist_head *head)
static bool dlist_has_next(const dlist_head *head, const dlist_node *node)
static void dlist_delete(dlist_node *node)
static void dlist_push_head(dlist_head *head, dlist_node *node)
static dlist_node * dlist_head_node(dlist_head *head)
#define dlist_foreach_modify(iter, lhead)
static bool dlist_is_empty(const dlist_head *head)
static void dlist_push_tail(dlist_head *head, dlist_node *node)
#define dlist_container(type, membername, ptr)
void MemoryContextCreate(MemoryContext node, NodeTag tag, MemoryContextMethodID method_id, MemoryContext parent, const char *name)
MemoryContext TopMemoryContext
void MemoryContextStats(MemoryContext context)
void * MemoryContextAllocationFailure(MemoryContext context, Size size, int flags)
#define VALGRIND_DESTROY_MEMPOOL(context)
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)
#define VALGRIND_MEMPOOL_ALLOC(context, addr, size)
#define VALGRIND_MEMPOOL_TRIM(context, addr, size)
#define VALGRIND_MEMPOOL_FREE(context, addr)
#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 AllocHugeSizeIsValid(size)
static void MemoryContextCheckSize(MemoryContext context, Size size, int flags)
#define MEMORYCHUNK_MAX_BLOCKOFFSET
#define MEMORYCHUNK_MAX_VALUE
static Size MemoryChunkGetValue(MemoryChunk *chunk)
#define MemoryChunkGetPointer(c)
static bool MemoryChunkIsExternal(MemoryChunk *chunk)
static void * MemoryChunkGetBlock(MemoryChunk *chunk)
static void MemoryChunkSetHdrMaskExternal(MemoryChunk *chunk, MemoryContextMethodID methodid)
static void MemoryChunkSetHdrMask(MemoryChunk *chunk, void *block, Size value, MemoryContextMethodID methodid)
struct MemoryContextData * MemoryContext
#define pg_nextpower2_size_t