@@ -172,6 +172,7 @@ Allocator::reallocate(void *inPtr, const size_t inSize) const {
172172 *
173173 * @see See also the notes for PGAllocator::allocate(const size_t) and
174174 * PGAllocator::allocate(const size_t, const std::nothrow_t&)
175+ * CBDB_FIX: see Allocator::makeAligned
175176 */
176177template <dbal::MemoryContext MC>
177178inline
@@ -186,7 +187,8 @@ Allocator::free(void *inPtr) const {
186187 */
187188 HOLD_INTERRUPTS ();
188189 PG_TRY (); {
189- pfree (unaligned (inPtr));
190+ void * ptr = unaligned (inPtr);
191+ ptr ? pfree (ptr) : std::free (inPtr);
190192 } PG_CATCH (); {
191193 FlushErrorState ();
192194 } PG_END_TRY ();
@@ -214,11 +216,11 @@ Allocator::internalPalloc(size_t inSize) const {
214216#if MAXIMUM_ALIGNOF >= 16
215217 return (ZM == dbal::DoZero) ? palloc0 (inSize) : palloc (inSize);
216218#else
217- if (inSize > std::numeric_limits<size_t >::max () - 16 )
219+ if (inSize > std::numeric_limits<size_t >::max () - 32 )
218220 return NULL ;
219221
220222 /* Precondition: inSize <= std::numeric_limits<size_t>::max() - 16 */
221- const size_t size = inSize + 16 ;
223+ const size_t size = inSize + 32 ;
222224 void *raw = (ZM == dbal::DoZero) ? palloc0 (size) : palloc (size);
223225 return makeAligned (raw);
224226#endif
@@ -246,14 +248,18 @@ Allocator::internalRePalloc(void *inPtr, size_t inSize) const {
246248#if MAXIMUM_ALIGNOF >= 16
247249 return repalloc (inPtr, inSize);
248250#else
249- if (inSize > std::numeric_limits<size_t >::max () - 16 ) {
250- pfree (unaligned (inPtr));
251+ void * ptr = unaligned (inPtr);
252+ if (!ptr)
253+ return std::realloc (inPtr, inSize);
254+
255+ if (inSize > std::numeric_limits<size_t >::max () - 32 ) {
256+ pfree (ptr);
251257 return NULL ;
252258 }
253259
254260 /* Precondition: inSize <= std::numeric_limits<size_t>::max() - 16 */
255- const size_t size = inSize + 16 ;
256- void *raw = repalloc (unaligned (inPtr) , size);
261+ const size_t size = inSize + 32 ;
262+ void *raw = repalloc (ptr , size);
257263
258264 if (ZM == dbal::DoZero) {
259265 std::fill (
@@ -269,6 +275,9 @@ Allocator::internalRePalloc(void *inPtr, size_t inSize) const {
269275 * @internal
270276 * @brief Return next 16-byte boundary after inPtr and store inPtr in word
271277 * immediately before that
278+ * CBDB_FIX: A weird bug causes std::malloc to be called for allocation,
279+ * but custom free for destruction. Hacky workacound this by prepending
280+ * each chunk with a magic number 0xCBDBCBDB to indicate custom allocation.
272281 */
273282inline
274283void *
@@ -282,15 +291,17 @@ Allocator::makeAligned(void *inPtr) const {
282291 * to us an can be written to safely.
283292 */
284293 void *aligned = reinterpret_cast <void *>(
285- (reinterpret_cast <uintptr_t >(inPtr) & ~(uintptr_t (15 ))) + 16 );
294+ (reinterpret_cast <uintptr_t >(inPtr) & ~(uintptr_t (15 ))) + 32 );
286295 *(reinterpret_cast <void **>(aligned) - 1 ) = inPtr;
296+ *(reinterpret_cast <size_t *>(aligned) - 2 ) = 0xCBDBCBDB ;
287297 return aligned;
288298}
289299
290300/* *
291301 * @internal
292302 * @brief Return the address of memory block that corresponds to the given
293303 * 16-byte aligned address
304+ * @see CBDB_FIX: see Allocator::makeAligned
294305 *
295306 * Unless <tt>MAXIMUM_ALIGNOF >= 16</tt>, we free the block of memory pointed to
296307 * by the word immediately in front of the memory pointed to by \c inPtr.
@@ -301,6 +312,11 @@ Allocator::unaligned(void *inPtr) const {
301312#if MAXIMUM_ALIGNOF >= 16
302313 return inPtr;
303314#else
315+ size_t magic = *(reinterpret_cast <size_t *>(inPtr) - 2 );
316+ if (magic != 0xCBDBCBDB ) {
317+ elog (WARNING, " non-custom-allocator allocation detected" );
318+ return nullptr ;
319+ }
304320 return (*(reinterpret_cast <void **>(inPtr) - 1 ));
305321#endif
306322}
0 commit comments