|
|
|
|
@ -24,6 +24,7 @@ |
|
|
|
|
|
|
|
|
|
#include "postgres.h" |
|
|
|
|
|
|
|
|
|
#include "miscadmin.h" |
|
|
|
|
#include "utils/memdebug.h" |
|
|
|
|
#include "utils/memutils.h" |
|
|
|
|
|
|
|
|
|
@ -55,6 +56,19 @@ MemoryContext PortalContext = NULL; |
|
|
|
|
|
|
|
|
|
static void MemoryContextStatsInternal(MemoryContext context, int level); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* You should not do memory allocations within a critical section, because |
|
|
|
|
* an out-of-memory error will be escalated to a PANIC. To enforce that |
|
|
|
|
* rule, the allocation functions Assert that. |
|
|
|
|
* |
|
|
|
|
* There are a two exceptions: 1) error recovery uses ErrorContext, which |
|
|
|
|
* has some memory set aside so that you don't run out. And 2) checkpointer |
|
|
|
|
* currently just hopes for the best, which is wrong and ought to be fixed, |
|
|
|
|
* but it's a known issue so let's not complain about in the meanwhile. |
|
|
|
|
*/ |
|
|
|
|
#define AssertNotInCriticalSection(context) \ |
|
|
|
|
Assert(CritSectionCount == 0 || (context) == ErrorContext || \
|
|
|
|
|
AmCheckpointerProcess()) |
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* EXPORTED ROUTINES * |
|
|
|
|
@ -519,6 +533,8 @@ MemoryContextCreate(NodeTag tag, Size size, |
|
|
|
|
MemoryContext node; |
|
|
|
|
Size needed = size + strlen(name) + 1; |
|
|
|
|
|
|
|
|
|
Assert(CritSectionCount == 0); |
|
|
|
|
|
|
|
|
|
/* Get space for node and name */ |
|
|
|
|
if (TopMemoryContext != NULL) |
|
|
|
|
{ |
|
|
|
|
@ -575,6 +591,7 @@ MemoryContextAlloc(MemoryContext context, Size size) |
|
|
|
|
void *ret; |
|
|
|
|
|
|
|
|
|
AssertArg(MemoryContextIsValid(context)); |
|
|
|
|
AssertNotInCriticalSection(context); |
|
|
|
|
|
|
|
|
|
if (!AllocSizeIsValid(size)) |
|
|
|
|
elog(ERROR, "invalid memory alloc request size %zu", size); |
|
|
|
|
@ -600,6 +617,7 @@ MemoryContextAllocZero(MemoryContext context, Size size) |
|
|
|
|
void *ret; |
|
|
|
|
|
|
|
|
|
AssertArg(MemoryContextIsValid(context)); |
|
|
|
|
AssertNotInCriticalSection(context); |
|
|
|
|
|
|
|
|
|
if (!AllocSizeIsValid(size)) |
|
|
|
|
elog(ERROR, "invalid memory alloc request size %zu", size); |
|
|
|
|
@ -627,6 +645,7 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size) |
|
|
|
|
void *ret; |
|
|
|
|
|
|
|
|
|
AssertArg(MemoryContextIsValid(context)); |
|
|
|
|
AssertNotInCriticalSection(context); |
|
|
|
|
|
|
|
|
|
if (!AllocSizeIsValid(size)) |
|
|
|
|
elog(ERROR, "invalid memory alloc request size %zu", size); |
|
|
|
|
@ -648,6 +667,7 @@ palloc(Size size) |
|
|
|
|
void *ret; |
|
|
|
|
|
|
|
|
|
AssertArg(MemoryContextIsValid(CurrentMemoryContext)); |
|
|
|
|
AssertNotInCriticalSection(CurrentMemoryContext); |
|
|
|
|
|
|
|
|
|
if (!AllocSizeIsValid(size)) |
|
|
|
|
elog(ERROR, "invalid memory alloc request size %zu", size); |
|
|
|
|
@ -667,6 +687,7 @@ palloc0(Size size) |
|
|
|
|
void *ret; |
|
|
|
|
|
|
|
|
|
AssertArg(MemoryContextIsValid(CurrentMemoryContext)); |
|
|
|
|
AssertNotInCriticalSection(CurrentMemoryContext); |
|
|
|
|
|
|
|
|
|
if (!AllocSizeIsValid(size)) |
|
|
|
|
elog(ERROR, "invalid memory alloc request size %zu", size); |
|
|
|
|
@ -738,6 +759,7 @@ repalloc(void *pointer, Size size) |
|
|
|
|
((char *) pointer - STANDARDCHUNKHEADERSIZE))->context; |
|
|
|
|
|
|
|
|
|
AssertArg(MemoryContextIsValid(context)); |
|
|
|
|
AssertNotInCriticalSection(context); |
|
|
|
|
|
|
|
|
|
/* isReset must be false already */ |
|
|
|
|
Assert(!context->isReset); |
|
|
|
|
@ -760,6 +782,7 @@ MemoryContextAllocHuge(MemoryContext context, Size size) |
|
|
|
|
void *ret; |
|
|
|
|
|
|
|
|
|
AssertArg(MemoryContextIsValid(context)); |
|
|
|
|
AssertNotInCriticalSection(context); |
|
|
|
|
|
|
|
|
|
if (!AllocHugeSizeIsValid(size)) |
|
|
|
|
elog(ERROR, "invalid memory alloc request size %zu", size); |
|
|
|
|
@ -801,6 +824,7 @@ repalloc_huge(void *pointer, Size size) |
|
|
|
|
((char *) pointer - STANDARDCHUNKHEADERSIZE))->context; |
|
|
|
|
|
|
|
|
|
AssertArg(MemoryContextIsValid(context)); |
|
|
|
|
AssertNotInCriticalSection(context); |
|
|
|
|
|
|
|
|
|
/* isReset must be false already */ |
|
|
|
|
Assert(!context->isReset); |
|
|
|
|
|