diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c index 85b3c9acd1..0759e39ecb 100644 --- a/src/backend/utils/mmgr/aset.c +++ b/src/backend/utils/mmgr/aset.c @@ -642,8 +642,8 @@ AllocSetDelete(MemoryContext context) /* * AllocSetAlloc - * Returns pointer to allocated memory of given size; memory is added - * to the set. + * Returns pointer to allocated memory of given size or NULL if + * request could not be completed; memory is added to the set. * * No request may exceed: * MAXALIGN_DOWN(SIZE_MAX) - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ @@ -671,13 +671,7 @@ AllocSetAlloc(MemoryContext context, Size size) blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ; block = (AllocBlock) malloc(blksize); if (block == NULL) - { - MemoryContextStats(TopMemoryContext); - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"), - errdetail("Failed on request of size %zu.", size))); - } + return NULL; block->aset = set; block->freeptr = block->endptr = ((char *) block) + blksize; @@ -865,13 +859,7 @@ AllocSetAlloc(MemoryContext context, Size size) } if (block == NULL) - { - MemoryContextStats(TopMemoryContext); - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"), - errdetail("Failed on request of size %zu.", size))); - } + return NULL; block->aset = set; block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ; @@ -1002,9 +990,10 @@ AllocSetFree(MemoryContext context, void *pointer) /* * AllocSetRealloc - * Returns new pointer to allocated memory of given size; this memory - * is added to the set. Memory associated with given pointer is copied - * into the new memory, and the old memory is freed. + * Returns new pointer to allocated memory of given size or NULL if + * request could not be completed; this memory is added to the set. + * Memory associated with given pointer is copied into the new memory, + * and the old memory is freed. * * Without MEMORY_CONTEXT_CHECKING, we don't know the old request size. This * makes our Valgrind client requests less-precise, hazarding false negatives. @@ -1107,13 +1096,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ; block = (AllocBlock) realloc(block, blksize); if (block == NULL) - { - MemoryContextStats(TopMemoryContext); - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"), - errdetail("Failed on request of size %zu.", size))); - } + return NULL; block->freeptr = block->endptr = ((char *) block) + blksize; /* Update pointers since block has likely been moved */ @@ -1179,6 +1162,10 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) /* allocate new chunk */ newPointer = AllocSetAlloc((MemoryContext) set, size); + /* leave immediately if request was not completed */ + if (newPointer == NULL) + return NULL; + /* * AllocSetAlloc() just made the region NOACCESS. Change it to * UNDEFINED for the moment; memcpy() will then transfer definedness diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index aa0d458d25..c62922a187 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -623,6 +623,15 @@ MemoryContextAlloc(MemoryContext context, Size size) context->isReset = false; ret = (*context->methods->alloc) (context, size); + if (ret == NULL) + { + MemoryContextStats(TopMemoryContext); + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on request of size %zu.", size))); + } + VALGRIND_MEMPOOL_ALLOC(context, ret, size); return ret; @@ -649,6 +658,15 @@ MemoryContextAllocZero(MemoryContext context, Size size) context->isReset = false; ret = (*context->methods->alloc) (context, size); + if (ret == NULL) + { + MemoryContextStats(TopMemoryContext); + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on request of size %zu.", size))); + } + VALGRIND_MEMPOOL_ALLOC(context, ret, size); MemSetAligned(ret, 0, size); @@ -677,6 +695,15 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size) context->isReset = false; ret = (*context->methods->alloc) (context, size); + if (ret == NULL) + { + MemoryContextStats(TopMemoryContext); + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on request of size %zu.", size))); + } + VALGRIND_MEMPOOL_ALLOC(context, ret, size); MemSetLoop(ret, 0, size); @@ -699,6 +726,15 @@ palloc(Size size) CurrentMemoryContext->isReset = false; ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size); + if (ret == NULL) + { + MemoryContextStats(TopMemoryContext); + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on request of size %zu.", size))); + } + VALGRIND_MEMPOOL_ALLOC(CurrentMemoryContext, ret, size); return ret; @@ -719,6 +755,15 @@ palloc0(Size size) CurrentMemoryContext->isReset = false; ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size); + if (ret == NULL) + { + MemoryContextStats(TopMemoryContext); + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on request of size %zu.", size))); + } + VALGRIND_MEMPOOL_ALLOC(CurrentMemoryContext, ret, size); MemSetAligned(ret, 0, size); @@ -789,6 +834,12 @@ repalloc(void *pointer, Size size) Assert(!context->isReset); ret = (*context->methods->realloc) (context, pointer, size); + if (ret == NULL) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on request of size %zu.", size))); + VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size); return ret; @@ -814,6 +865,15 @@ MemoryContextAllocHuge(MemoryContext context, Size size) context->isReset = false; ret = (*context->methods->alloc) (context, size); + if (ret == NULL) + { + MemoryContextStats(TopMemoryContext); + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on request of size %zu.", size))); + } + VALGRIND_MEMPOOL_ALLOC(context, ret, size); return ret; @@ -854,6 +914,12 @@ repalloc_huge(void *pointer, Size size) Assert(!context->isReset); ret = (*context->methods->realloc) (context, pointer, size); + if (ret == NULL) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on request of size %zu.", size))); + VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size); return ret;