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
321 context->mem_allocated += blksize;
326 #ifdef MEMORY_CONTEXT_CHECKING
328 block->context = set;
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
404 #ifdef RANDOMIZE_ALLOCATED_MEMORY
450 if (blksize < required_size)
458 context->mem_allocated += blksize;
500 #ifdef MEMORY_CONTEXT_CHECKING
537 #ifdef MEMORY_CONTEXT_CHECKING
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 pg_noinline void * BumpAllocLarge(MemoryContext context, Size size, int flags)
static void BumpBlockMarkEmpty(BumpBlock *block)
static void BumpBlockInit(BumpContext *context, BumpBlock *block, Size blksize)
MemoryContext BumpGetChunkContext(void *pointer)
void * BumpRealloc(void *pointer, Size size, int flags)
#define IsKeeperBlock(set, blk)
struct BumpContext BumpContext
MemoryContext BumpContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
static void * BumpAllocChunkFromBlock(MemoryContext context, BumpBlock *block, Size size, Size chunk_size)
void * BumpAlloc(MemoryContext context, Size size, int flags)
void BumpReset(MemoryContext context)
static pg_noinline void * BumpAllocFromNewBlock(MemoryContext context, Size size, int flags, Size chunk_size)
bool BumpIsEmpty(MemoryContext context)
static Size BumpBlockFreeBytes(BumpBlock *block)
#define ExternalChunkGetBlock(chunk)
#define Assert(condition)
#define StaticAssertDecl(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)
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)
#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)
static dlist_node * dlist_head_node(dlist_head *head)
#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 MemoryChunkSetHdrMaskExternal(MemoryChunk *chunk, MemoryContextMethodID methodid)
static void * MemoryChunkGetBlock(MemoryChunk *chunk)
static void MemoryChunkSetHdrMask(MemoryChunk *chunk, void *block, Size value, MemoryContextMethodID methodid)
struct MemoryContextData * MemoryContext
#define pg_nextpower2_size_t
static pg_noinline void Size size