mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Reduce size of common allocation header.
The new slab allocator needs different per-allocation information than
the classical aset.c. The definition in 58b25e981
wasn't sufficiently
careful on 32 platforms with 8 byte alignment, leading to buildfarm
failures. That's not entirely easy to fix by just adjusting the
definition.
As slab.c doesn't actually need the size part(s) of the common header,
all chunks are equally sized after all, it seems better to instead
reduce the header to the part needed by all allocators, namely which
context an allocation belongs to. That has the advantage of reducing
the overhead of slab allocations, and also allows for more flexibility
in future allocators.
To avoid spreading the logic about accessing a chunk's context around,
centralize it in GetMemoryChunkContext(), which allows to delete a
good number of lines.
A followup commit will revise the mmgr/README portion about
StandardChunkHeader, and more.
Author: Andres Freund
Discussion: https://postgr.es/m/20170228074420.aazv4iw6k562mnxg@alap3.anarazel.de
This commit is contained in:
@ -45,27 +45,6 @@
|
||||
|
||||
#define AllocHugeSizeIsValid(size) ((Size) (size) <= MaxAllocHugeSize)
|
||||
|
||||
/*
|
||||
* All chunks allocated by any memory context manager are required to be
|
||||
* preceded by a StandardChunkHeader at a spacing of STANDARDCHUNKHEADERSIZE.
|
||||
* A currently-allocated chunk must contain a backpointer to its owning
|
||||
* context as well as the allocated size of the chunk. The backpointer is
|
||||
* used by pfree() and repalloc() to find the context to call. The allocated
|
||||
* size is not absolutely essential, but it's expected to be needed by any
|
||||
* reasonable implementation.
|
||||
*/
|
||||
typedef struct StandardChunkHeader
|
||||
{
|
||||
MemoryContext context; /* owning context */
|
||||
Size size; /* size of data space allocated in chunk */
|
||||
#ifdef MEMORY_CONTEXT_CHECKING
|
||||
/* when debugging memory usage, also store actual requested size */
|
||||
Size requested_size;
|
||||
#endif
|
||||
} StandardChunkHeader;
|
||||
|
||||
#define STANDARDCHUNKHEADERSIZE MAXALIGN(sizeof(StandardChunkHeader))
|
||||
|
||||
|
||||
/*
|
||||
* Standard top-level memory contexts.
|
||||
@ -100,7 +79,6 @@ extern void MemoryContextDeleteChildren(MemoryContext context);
|
||||
extern void MemoryContextSetParent(MemoryContext context,
|
||||
MemoryContext new_parent);
|
||||
extern Size GetMemoryChunkSpace(void *pointer);
|
||||
extern MemoryContext GetMemoryChunkContext(void *pointer);
|
||||
extern MemoryContext MemoryContextGetParent(MemoryContext context);
|
||||
extern bool MemoryContextIsEmpty(MemoryContext context);
|
||||
extern void MemoryContextStats(MemoryContext context);
|
||||
@ -113,6 +91,42 @@ extern void MemoryContextCheck(MemoryContext context);
|
||||
#endif
|
||||
extern bool MemoryContextContains(MemoryContext context, void *pointer);
|
||||
|
||||
/*
|
||||
* GetMemoryChunkContext
|
||||
* Given a currently-allocated chunk, determine the context
|
||||
* it belongs to.
|
||||
*
|
||||
* All chunks allocated by any memory context manager are required to be
|
||||
* preceded by the corresponding MemoryContext stored, without padding, in the
|
||||
* preceding sizeof(void*) bytes. A currently-allocated chunk must contain a
|
||||
* backpointer to its owning context. The backpointer is used by pfree() and
|
||||
* repalloc() to find the context to call.
|
||||
*/
|
||||
#ifndef FRONTEND
|
||||
static inline MemoryContext
|
||||
GetMemoryChunkContext(void *pointer)
|
||||
{
|
||||
MemoryContext context;
|
||||
|
||||
/*
|
||||
* 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 context.
|
||||
*/
|
||||
context = *(MemoryContext *) (((char *) pointer) - sizeof(void *));
|
||||
|
||||
AssertArg(MemoryContextIsValid(context));
|
||||
|
||||
return context;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This routine handles the context-type-independent part of memory
|
||||
* context creation. It's intended to be called from context-type-
|
||||
|
Reference in New Issue
Block a user