diff options
Diffstat (limited to 'src/backend/utils/mmgr')
-rw-r--r-- | src/backend/utils/mmgr/aset.c | 5 | ||||
-rw-r--r-- | src/backend/utils/mmgr/mcxt.c | 74 |
2 files changed, 71 insertions, 8 deletions
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c index ab93620ae2..ff04a38cda 100644 --- a/src/backend/utils/mmgr/aset.c +++ b/src/backend/utils/mmgr/aset.c @@ -458,6 +458,7 @@ AllocSetContextCreate(MemoryContext parent, maxBlockSize = MAXALIGN(maxBlockSize); if (maxBlockSize < initBlockSize) maxBlockSize = initBlockSize; + Assert(AllocHugeSizeIsValid(maxBlockSize)); /* must be safe to double */ context->initBlockSize = initBlockSize; context->maxBlockSize = maxBlockSize; context->nextBlockSize = initBlockSize; @@ -643,6 +644,10 @@ AllocSetDelete(MemoryContext context) * AllocSetAlloc * Returns pointer to allocated memory of given size; memory is added * to the set. + * + * No request may exceed: + * MAXALIGN_DOWN(SIZE_MAX) - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ + * All callers use a much-lower limit. */ static void * AllocSetAlloc(MemoryContext context, Size size) diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index 46961e9ee9..9574fd3c7a 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -455,14 +455,7 @@ MemoryContextContains(MemoryContext context, void *pointer) header = (StandardChunkHeader *) ((char *) pointer - STANDARDCHUNKHEADERSIZE); - /* - * If the context link doesn't match then we certainly have a non-member - * chunk. Also check for a reasonable-looking size as extra guard against - * being fooled by bogus pointers. - */ - if (header->context == context && AllocSizeIsValid(header->size)) - return true; - return false; + return header->context == context; } /*-------------------- @@ -758,6 +751,71 @@ repalloc(void *pointer, Size size) } /* + * MemoryContextAllocHuge + * Allocate (possibly-expansive) space within the specified context. + * + * See considerations in comment at MaxAllocHugeSize. + */ +void * +MemoryContextAllocHuge(MemoryContext context, Size size) +{ + void *ret; + + AssertArg(MemoryContextIsValid(context)); + + if (!AllocHugeSizeIsValid(size)) + elog(ERROR, "invalid memory alloc request size %lu", + (unsigned long) size); + + context->isReset = false; + + ret = (*context->methods->alloc) (context, size); + VALGRIND_MEMPOOL_ALLOC(context, ret, size); + + return ret; +} + +/* + * repalloc_huge + * Adjust the size of a previously allocated chunk, permitting a large + * value. The previous allocation need not have been "huge". + */ +void * +repalloc_huge(void *pointer, Size size) +{ + MemoryContext context; + void *ret; + + if (!AllocHugeSizeIsValid(size)) + elog(ERROR, "invalid memory alloc request size %lu", + (unsigned long) size); + + /* + * Try to detect bogus pointers handed to us, poorly though we can. + * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an + * allocated chunk. + */ + Assert(pointer != NULL); + Assert(pointer == (void *) MAXALIGN(pointer)); + + /* + * OK, it's probably safe to look at the chunk header. + */ + context = ((StandardChunkHeader *) + ((char *) pointer - STANDARDCHUNKHEADERSIZE))->context; + + AssertArg(MemoryContextIsValid(context)); + + /* isReset must be false already */ + Assert(!context->isReset); + + ret = (*context->methods->realloc) (context, pointer, size); + VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size); + + return ret; +} + +/* * MemoryContextStrdup * Like strdup(), but allocate from the specified context */ |