summaryrefslogtreecommitdiff
path: root/src/backend/utils/mmgr
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/mmgr')
-rw-r--r--src/backend/utils/mmgr/aset.c5
-rw-r--r--src/backend/utils/mmgr/mcxt.c74
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
*/