В Вт, 24/05/2022 в 17:39 -0700, Andres Freund пишет: > > A variation on your patch would be to only store the offset to the block > header - that should always fit into 32bit (huge allocations being their own > block, which is why this wouldn't work for storing an offset to the > context). With a bit of care that'd allow aset.c to half it's overhead, by > using 4 bytes of space for all non-huge allocations. Of course, it'd increase > the cost of pfree() of small allocations, because AllocSetFree() currently > doesn't need to access the block for those. But I'd guess that'd be outweighed > by the reduced memory usage.
I'm +1 for this. And with this change every memory context kind can have same header: typedef struct MemoryChunk { #ifdef MEMORY_CONTEXT_CHECKING Size requested_size; #endif uint32 encoded_size; /* encoded allocation size */ uint32 offset_to_block; /* backward offset to block header */ } Allocated size always could be encoded into uint32 since it is rounded for large allocations (I believe, large allocations certainly rounded to at least 4096 bytes): encoded_size = size < (1u<<31) ? size : (1u<<31)|(size>>12); /* and reverse */ size = (encoded_size >> 31) ? ((Size)(encoded_size<<1)<<12) : (Size)encoded_size; There is a glitch with Aset since it currently reuses `aset` pointer for freelist link. With such change this link had to be encoded in chunk-body itself instead of header. I was confused with this, since there are valgrind hooks, and I was not sure how to change it (I'm not good at valgrind hooks). But after thinking more about I believe it is doable. regards ------- Yura Sokolov