29 #include "utils/fmgrprotos.h"
56 #ifdef MEMORY_CONTEXT_CHECKING
70 #ifdef MEMORY_CONTEXT_CHECKING
84 #ifdef MEMORY_CONTEXT_CHECKING
98 #ifdef MEMORY_CONTEXT_CHECKING
154 bool print,
int max_children,
156 bool print_to_stderr);
158 const char *stats_string,
159 bool print_to_stderr);
166 #define AssertNotInCriticalSection(context) \
167 Assert(CritSectionCount == 0 || (context)->allowInCritSection)
173 #define MCXT_METHOD(pointer, method) \
174 mcxt_methods[GetMemoryChunkMethodID(pointer)].method
193 header = *((
const uint64 *) ((
const char *) pointer -
sizeof(uint64)));
207 return *((
const uint64 *) ((
const char *) pointer -
sizeof(uint64)));
219 elog(
ERROR,
"pfree called with invalid pointer %p (header 0x%016llx)",
226 elog(
ERROR,
"repalloc called with invalid pointer %p (header 0x%016llx)",
234 elog(
ERROR,
"GetMemoryChunkContext called with invalid pointer %p (header 0x%016llx)",
242 elog(
ERROR,
"GetMemoryChunkSpace called with invalid pointer %p (header 0x%016llx)",
419 context->
ident = NULL;
487 while ((cb = context->
reset_cbs) != NULL)
533 Assert(context != new_parent);
536 if (new_parent == context->
parent)
560 context->
parent = new_parent;
602 return MCXT_METHOD(pointer, get_chunk_context) (pointer);
616 return MCXT_METHOD(pointer, get_chunk_space) (pointer);
699 bool print_to_stderr)
703 memset(&grand_totals, 0,
sizeof(grand_totals));
709 "Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used\n",
728 errmsg_internal(
"Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used",
743 bool print,
int max_children,
745 bool print_to_stderr)
757 totals, print_to_stderr);
763 memset(&local_totals, 0,
sizeof(local_totals));
769 if (ichild < max_children)
782 if (ichild > max_children)
790 for (
i = 0;
i <= level;
i++)
793 "%d more child contexts containing %zu total in %zu blocks; %zu free (%zu chunks); %zu used\n",
794 ichild - max_children,
805 errmsg_internal(
"level: %d; %d more child contexts containing %zu total in %zu blocks; %zu free (%zu chunks); %zu used",
807 ichild - max_children,
834 const char *stats_string,
835 bool print_to_stderr)
837 int level = *(
int *) passthru;
839 const char *ident = context->
ident;
840 char truncated_ident[110];
848 if (ident && strcmp(
name,
"dynahash") == 0)
854 truncated_ident[0] =
'\0';
864 int idlen = strlen(ident);
865 bool truncated =
false;
867 strcpy(truncated_ident,
": ");
868 i = strlen(truncated_ident);
878 unsigned char c = *ident++;
882 truncated_ident[
i++] =
c;
884 truncated_ident[
i] =
'\0';
887 strcat(truncated_ident,
"...");
892 for (
i = 0;
i < level;
i++)
894 fprintf(stderr,
"%s: %s%s\n",
name, stats_string, truncated_ident);
901 level,
name, stats_string, truncated_ident)));
910 #ifdef MEMORY_CONTEXT_CHECKING
918 context->
methods->check(context);
920 MemoryContextCheck(child);
1013 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1029 (
errcode(ERRCODE_OUT_OF_MEMORY),
1031 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1032 size, context->
name)));
1056 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1065 (
errcode(ERRCODE_OUT_OF_MEMORY),
1067 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1068 size, context->
name)));
1094 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1103 (
errcode(ERRCODE_OUT_OF_MEMORY),
1105 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1106 size, context->
name)));
1130 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1141 (
errcode(ERRCODE_OUT_OF_MEMORY),
1143 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1144 size, context->
name)));
1220 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1229 (
errcode(ERRCODE_OUT_OF_MEMORY),
1231 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1232 size, context->
name)));
1251 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1260 (
errcode(ERRCODE_OUT_OF_MEMORY),
1262 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1263 size, context->
name)));
1285 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1296 (
errcode(ERRCODE_OUT_OF_MEMORY),
1298 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1299 size, context->
name)));
1329 Size size,
Size alignto,
int flags)
1337 Assert(alignto < (128 * 1024 * 1024));
1340 Assert((alignto & (alignto - 1)) == 0);
1346 if (
unlikely(alignto <= MAXIMUM_ALIGNOF))
1368 #ifdef MEMORY_CONTEXT_CHECKING
1377 aligned = (
void *)
TYPEALIGN(alignto, (
char *) unaligned +
1398 #ifdef MEMORY_CONTEXT_CHECKING
1399 alignedchunk->requested_size = size;
1401 set_sentinel(aligned, size);
1406 (
char *) alignedchunk - (
char *) unaligned);
1461 #if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
1467 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1481 (
errcode(ERRCODE_OUT_OF_MEMORY),
1483 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1503 #if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
1510 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1526 (
errcode(ERRCODE_OUT_OF_MEMORY),
1528 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1551 elog(
ERROR,
"invalid repalloc0 call: oldsize %zu, new size %zu",
1555 memset((
char *) ret + oldsize, 0, (size - oldsize));
1574 elog(
ERROR,
"invalid memory alloc request size %zu", size);
1583 (
errcode(ERRCODE_OUT_OF_MEMORY),
1585 errdetail(
"Failed on request of size %zu in memory context \"%s\".",
1586 size, context->
name)));
1614 Size len = strlen(
string) + 1;
1618 memcpy(nstr,
string,
len);
1642 memcpy(out, in,
len);
1657 while (n > 0 && in[n - 1] ==
'\n')
MemoryContext AlignedAllocGetChunkContext(void *pointer)
void * AlignedAllocRealloc(void *pointer, Size size)
Size AlignedAllocGetChunkSpace(void *pointer)
void AlignedAllocFree(void *pointer)
void AllocSetReset(MemoryContext context)
Size AllocSetGetChunkSpace(void *pointer)
MemoryContext AllocSetGetChunkContext(void *pointer)
void AllocSetStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
bool AllocSetIsEmpty(MemoryContext context)
void * AllocSetRealloc(void *pointer, Size size)
void AllocSetFree(void *pointer)
void AllocSetDelete(MemoryContext context)
void * AllocSetAlloc(MemoryContext context, Size size)
void print(const void *obj)
#define TYPEALIGN(ALIGNVAL, LEN)
#define MemSetAligned(start, val, len)
#define MemSetLoop(start, val, len)
elog(ERROR, "%s: %s", p2, msg)
int errmsg_internal(const char *fmt,...)
int errhidestmt(bool hide_stmt)
int errdetail(const char *fmt,...)
int errhidecontext(bool hide_ctx)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define MCXT_ALLOC_NO_OOM
void GenerationReset(MemoryContext context)
void GenerationFree(void *pointer)
MemoryContext GenerationGetChunkContext(void *pointer)
Size GenerationGetChunkSpace(void *pointer)
void * GenerationAlloc(MemoryContext context, Size size)
bool GenerationIsEmpty(MemoryContext context)
void GenerationStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
void * GenerationRealloc(void *pointer, Size size)
void GenerationDelete(MemoryContext context)
volatile sig_atomic_t LogMemoryContextPending
volatile sig_atomic_t InterruptPending
volatile uint32 CritSectionCount
Assert(fmt[strlen(fmt) - 1] !='\n')
int pg_mbcliplen(const char *mbstr, int len, int limit)
char * pnstrdup(const char *in, Size len)
static void MemoryContextCallResetCallbacks(MemoryContext context)
MemoryContext MessageContext
void * MemoryContextAllocAligned(MemoryContext context, Size size, Size alignto, int flags)
bool MemoryContextIsEmpty(MemoryContext context)
void MemoryContextReset(MemoryContext context)
void MemoryContextCreate(MemoryContext node, NodeTag tag, MemoryContextMethodID method_id, MemoryContext parent, const char *name)
MemoryContext TopTransactionContext
char * pchomp(const char *in)
void HandleLogMemoryContextInterrupt(void)
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
static MemoryContextMethodID GetMemoryChunkMethodID(const void *pointer)
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
void MemoryContextStatsDetail(MemoryContext context, int max_children, bool print_to_stderr)
char * pstrdup(const char *in)
void pfree(void *pointer)
Size GetMemoryChunkSpace(void *pointer)
void * repalloc0(void *pointer, Size oldsize, Size size)
static Size BogusGetChunkSpace(void *pointer)
void MemoryContextDeleteChildren(MemoryContext context)
MemoryContext TopMemoryContext
#define AssertNotInCriticalSection(context)
void * palloc0(Size size)
void * MemoryContextAllocZero(MemoryContext context, Size size)
MemoryContext CurTransactionContext
void * MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
MemoryContext CurrentMemoryContext
void * repalloc(void *pointer, Size size)
void * palloc_extended(Size size, int flags)
MemoryContext GetMemoryChunkContext(void *pointer)
void * MemoryContextAlloc(MemoryContext context, Size size)
void * MemoryContextAllocZeroAligned(MemoryContext context, Size size)
Size MemoryContextMemAllocated(MemoryContext context, bool recurse)
void MemoryContextStats(MemoryContext context)
void MemoryContextInit(void)
static void BogusFree(void *pointer)
MemoryContext PostmasterContext
void * palloc_aligned(Size size, Size alignto, int flags)
char * MemoryContextStrdup(MemoryContext context, const char *string)
static const MemoryContextMethods mcxt_methods[]
static void MemoryContextStatsInternal(MemoryContext context, int level, bool print, int max_children, MemoryContextCounters *totals, bool print_to_stderr)
MemoryContext MemoryContextGetParent(MemoryContext context)
static void * BogusRealloc(void *pointer, Size size)
void ProcessLogMemoryContextInterrupt(void)
MemoryContext ErrorContext
static MemoryContext BogusGetChunkContext(void *pointer)
MemoryContext CacheMemoryContext
void * MemoryContextAllocHuge(MemoryContext context, Size size)
void MemoryContextDelete(MemoryContext context)
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
void MemoryContextResetChildren(MemoryContext context)
static void MemoryContextStatsPrint(MemoryContext context, void *passthru, const char *stats_string, bool print_to_stderr)
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
void MemoryContextResetOnly(MemoryContext context)
static uint64 GetMemoryChunkHeader(const void *pointer)
MemoryContext PortalContext
void * repalloc_huge(void *pointer, Size size)
void * repalloc_extended(void *pointer, Size size, int flags)
#define MCXT_METHOD(pointer, method)
#define VALGRIND_DESTROY_MEMPOOL(context)
#define VALGRIND_MEMPOOL_CHANGE(context, optr, nptr, size)
#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)
#define VALGRIND_MEMPOOL_ALLOC(context, addr, size)
#define VALGRIND_MEMPOOL_FREE(context, addr)
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
#define MemoryContextIsValid(context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define AllocHugeSizeIsValid(size)
#define AllocSizeIsValid(size)
#define MEMORY_CONTEXT_METHODID_MASK
#define PallocAlignedExtraBytes(alignto)
@ MCTX_ALIGNED_REDIRECT_ID
struct MemoryChunk MemoryChunk
#define PointerGetMemoryChunk(p)
static void MemoryChunkSetHdrMask(MemoryChunk *chunk, void *block, Size value, MemoryContextMethodID methodid)
static void header(const char *fmt,...) pg_attribute_printf(1
size_t strnlen(const char *str, size_t maxlen)
void * SlabAlloc(MemoryContext context, Size size)
void SlabFree(void *pointer)
void SlabReset(MemoryContext context)
Size SlabGetChunkSpace(void *pointer)
bool SlabIsEmpty(MemoryContext context)
MemoryContext SlabGetChunkContext(void *pointer)
void SlabStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
void * SlabRealloc(void *pointer, Size size)
void SlabDelete(MemoryContext context)
struct MemoryContextCallback * next
MemoryContextCallbackFunction func
MemoryContextCallback * reset_cbs
const MemoryContextMethods * methods
void(* delete_context)(MemoryContext context)
void(* stats)(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
bool(* is_empty)(MemoryContext context)
void(* reset)(MemoryContext context)
void *(* alloc)(MemoryContext context, Size size)