48#define Bump_BLOCKHDRSZ MAXALIGN(sizeof(BumpBlock))
51#ifdef MEMORY_CONTEXT_CHECKING
52#define Bump_CHUNKHDRSZ sizeof(MemoryChunk)
54#define Bump_CHUNKHDRSZ 0
57#define Bump_CHUNK_FRACTION 8
60#define KeeperBlock(set) ((BumpBlock *) ((char *) (set) + \
61 MAXALIGN(sizeof(BumpContext))))
62#define IsKeeperBlock(set, blk) (KeeperBlock(set) == (blk))
89#ifdef MEMORY_CONTEXT_CHECKING
100#define BumpIsValid(set) \
101 (PointerIsValid(set) && IsA(set, BumpContext))
108#define ExternalChunkGetBlock(chunk) \
109 (BumpBlock *) ((char *) chunk - Bump_BLOCKHDRSZ)
132 Size initBlockSize,
Size maxBlockSize)
141 "sizeof(MemoryChunk) is not maxaligned");
155 initBlockSize >= 1024);
157 maxBlockSize >= initBlockSize &&
159 Assert(minContextSize == 0 ||
160 (minContextSize ==
MAXALIGN(minContextSize) &&
161 minContextSize >= 1024 &&
162 minContextSize <= maxBlockSize));
168 if (minContextSize != 0)
169 allocSize =
Max(allocSize, minContextSize);
171 allocSize =
Max(allocSize, initBlockSize);
182 (
errcode(ERRCODE_OUT_OF_MEMORY),
184 errdetail(
"Failed while creating memory context \"%s\".",
250#ifdef MEMORY_CONTEXT_CHECKING
297#ifdef MEMORY_CONTEXT_CHECKING
307#ifdef MEMORY_CONTEXT_CHECKING
326#ifdef MEMORY_CONTEXT_CHECKING
328 block->context = set;
335 chunk->requested_size = size;
337 Assert(size < chunk_size);
340#ifdef RANDOMIZE_ALLOCATED_MEMORY
352#ifdef MEMORY_CONTEXT_CHECKING
374#ifdef MEMORY_CONTEXT_CHECKING
384#ifdef MEMORY_CONTEXT_CHECKING
394#ifdef MEMORY_CONTEXT_CHECKING
399 chunk->requested_size = size;
401 Assert(size < chunk_size);
404#ifdef RANDOMIZE_ALLOCATED_MEMORY
450 if (blksize < required_size)
500#ifdef MEMORY_CONTEXT_CHECKING
537#ifdef MEMORY_CONTEXT_CHECKING
538 block->context = context;
541 block->
endptr = ((
char *) block) + blksize;
565#if defined(USE_VALGRIND) || defined(CLOBBER_FREED_MEMORY)
569#ifdef CLOBBER_FREED_MEMORY
570 wipe_mem(datastart, block->
freeptr - datastart);
605#ifdef CLOBBER_FREED_MEMORY
606 wipe_mem(block, ((
char *) block->
endptr - (
char *) block));
619 elog(
ERROR,
"%s is not supported by the bump memory allocator",
"pfree");
629 elog(
ERROR,
"%s is not supported by the bump memory allocator",
"realloc");
640 elog(
ERROR,
"%s is not supported by the bump memory allocator",
"GetMemoryChunkContext");
651 elog(
ERROR,
"%s is not supported by the bump memory allocator",
"GetMemoryChunkSpace");
704 totalspace += (block->
endptr - (
char *) block);
710 char stats_string[200];
712 snprintf(stats_string,
sizeof(stats_string),
713 "%zu total in %zu blocks; %zu free; %zu used",
714 totalspace, nblocks, freespace, totalspace - freespace);
715 printfunc(context, passthru, stats_string, print_to_stderr);
727#ifdef MEMORY_CONTEXT_CHECKING
743 Size total_allocated = 0;
751 bool has_external_chunk =
false;
754 total_allocated += block->
endptr - (
char *) bump;
756 total_allocated += block->
endptr - (
char *) block;
759 if (block->context != bump)
760 elog(
WARNING,
"problem in Bump %s: bogus context link in block %p",
767 while (ptr < block->freeptr)
780 has_external_chunk =
true;
794 if (chunkblock != block)
795 elog(
WARNING,
"problem in Bump %s: bogus block link in block %p, chunk %p",
799 if (has_external_chunk && nchunks > 1)
800 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_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 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