VirtualBox

Changeset 25059 in vbox


Ignore:
Timestamp:
Nov 27, 2009 6:17:44 PM (15 years ago)
Author:
vboxsync
Message:

RTHeapOffset: Initial conversion of RTHeapSimple.

Location:
trunk
Files:
5 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/heap.h

    r25055 r25059  
    261261 * Reallocates / Allocates / Frees a heap block.
    262262 *
    263  * @param   hHeap       The heap, mandatory.
     263 * @param   hHeap       The heap handle. This is optional and will only be used
     264 *                      for strict assertions.
    264265 * @param   pv          The heap block returned by RTHeapOffset. If NULL it
    265266 *                      behaves like RTHeapOffsetAlloc().
     
    275276 * Reallocates / Allocates / Frees a heap block, zeroing any new bits.
    276277 *
    277  * @param   hHeap       The heap, mandatory.
     278 * @param   hHeap       The heap handle. This is optional and will only be used
     279 *                      for strict assertions.
    278280 * @param   pv          The heap block returned by RTHeapOffset. If NULL it
    279281 *                      behaves like RTHeapOffsetAllocZ().
     
    289291 * Frees memory allocated from a simple heap.
    290292 *
    291  * @param   hHeap       The heap handle, mandatory.
     293 * @param   hHeap       The heap handle. This is optional and will only be used
     294 *                      for strict assertions.
    292295 * @param   pv          The heap block returned by RTHeapOffset
    293296 */
     
    301304 *          invalid \a pv can also cause traps or trigger assertions.
    302305 *
    303  * @param   hHeap       The heap handle, mandatory.
     306 * @param   hHeap       The heap handle. This is optional and will only be used
     307 *                      for strict assertions.
    304308 * @param   pv          The heap block returned by RTHeapOffset
    305309 */
  • trunk/src/VBox/Runtime/Makefile.kmk

    r24825 r25059  
    205205        common/alloc/alloc.cpp \
    206206        common/alloc/heapsimple.cpp \
     207        common/alloc/heapoffset.cpp \
    207208        common/checksum/adler32.cpp \
    208209        common/checksum/crc32-zlib.cpp \
     
    11441145        common/alloc/alloc.cpp \
    11451146        common/alloc/heapsimple.cpp \
     1147        common/alloc/heapoffset.cpp \
    11461148        common/misc/RTAssertMsg2.cpp \
    11471149        common/checksum/crc32.cpp \
  • trunk/src/VBox/Runtime/common/alloc/heapoffset.cpp

    r25055 r25059  
    11/* $Id$ */
    22/** @file
    3  * IPRT - A Simple Heap.
     3 * IPRT - An Offset Based Heap.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5151*******************************************************************************/
    5252/** Pointer to the heap anchor block. */
    53 typedef struct RTHEAPSIMPLEINTERNAL *PRTHEAPSIMPLEINTERNAL;
     53typedef struct RTHEAPOFFSETINTERNAL *PRTHEAPOFFSETINTERNAL;
    5454/** Pointer to a heap block. */
    55 typedef struct RTHEAPSIMPLEBLOCK *PRTHEAPSIMPLEBLOCK;
     55typedef struct RTHEAPOFFSETBLOCK *PRTHEAPOFFSETBLOCK;
    5656/** Pointer to a free heap block. */
    57 typedef struct RTHEAPSIMPLEFREE *PRTHEAPSIMPLEFREE;
    58 
    59 /**
    60  * Structure describing a simple heap block.
     57typedef struct RTHEAPOFFSETFREE *PRTHEAPOFFSETFREE;
     58
     59/**
     60 * Structure describing a block in an offset based heap.
     61 *
    6162 * If this block is allocated, it is followed by the user data.
    62  * If this block is free, see RTHEAPSIMPLEFREE.
    63  */
    64 typedef struct RTHEAPSIMPLEBLOCK
     63 * If this block is free, see RTHEAPOFFSETFREE.
     64 */
     65typedef struct RTHEAPOFFSETBLOCK
    6566{
    6667    /** The next block in the global block list. */
    67     PRTHEAPSIMPLEBLOCK      pNext;
     68    uint32_t /*PRTHEAPOFFSETBLOCK*/     offNext;
    6869    /** The previous block in the global block list. */
    69     PRTHEAPSIMPLEBLOCK      pPrev;
    70     /** Pointer to the heap anchor block. */
    71     PRTHEAPSIMPLEINTERNAL   pHeap;
     70    uint32_t /*PRTHEAPOFFSETBLOCK*/     offPrev;
     71    /** Offset into the heap of this block. Used to locate the anchor block. */
     72    uint32_t /*PRTHEAPOFFSETINTERNAL*/  offSelf;
    7273    /** Flags + magic. */
    73     uintptr_t               fFlags;
    74 } RTHEAPSIMPLEBLOCK;
    75 AssertCompileSizeAlignment(RTHEAPSIMPLEBLOCK, 16);
     74    uint32_t                            fFlags;
     75} RTHEAPOFFSETBLOCK;
     76AssertCompileSizeAlignment(RTHEAPOFFSETBLOCK, 16);
    7677
    7778/** The block is free if this flag is set. When cleared it's allocated. */
    78 #define RTHEAPSIMPLEBLOCK_FLAGS_FREE        ((uintptr_t)RT_BIT(0))
     79#define RTHEAPOFFSETBLOCK_FLAGS_FREE        (RT_BIT_32(0))
    7980/** The magic value. */
    80 #define RTHEAPSIMPLEBLOCK_FLAGS_MAGIC       ((uintptr_t)0xabcdef00)
    81 /** The mask that needs to be applied to RTHEAPSIMPLEBLOCK::fFlags to obtain the magic value. */
    82 #define RTHEAPSIMPLEBLOCK_FLAGS_MAGIC_MASK  (~(uintptr_t)RT_BIT(0))
     81#define RTHEAPOFFSETBLOCK_FLAGS_MAGIC       (UINT32_C(0xabcdef00))
     82/** The mask that needs to be applied to RTHEAPOFFSETBLOCK::fFlags to obtain the magic value. */
     83#define RTHEAPOFFSETBLOCK_FLAGS_MAGIC_MASK  (~RT_BIT_32(0))
    8384
    8485/**
    8586 * Checks if the specified block is valid or not.
    8687 * @returns boolean answer.
    87  * @param   pBlock      Pointer to a RTHEAPSIMPLEBLOCK structure.
    88  */
    89 #define RTHEAPSIMPLEBLOCK_IS_VALID(pBlock)  \
    90     ( ((pBlock)->fFlags & RTHEAPSIMPLEBLOCK_FLAGS_MAGIC_MASK) == RTHEAPSIMPLEBLOCK_FLAGS_MAGIC )
     88 * @param   pBlock      Pointer to a RTHEAPOFFSETBLOCK structure.
     89 */
     90#define RTHEAPOFFSETBLOCK_IS_VALID(pBlock)  \
     91    ( ((pBlock)->fFlags & RTHEAPOFFSETBLOCK_FLAGS_MAGIC_MASK) == RTHEAPOFFSETBLOCK_FLAGS_MAGIC )
    9192
    9293/**
    9394 * Checks if the specified block is valid and in use.
    9495 * @returns boolean answer.
    95  * @param   pBlock      Pointer to a RTHEAPSIMPLEBLOCK structure.
    96  */
    97 #define RTHEAPSIMPLEBLOCK_IS_VALID_USED(pBlock)  \
    98     ( ((pBlock)->fFlags & (RTHEAPSIMPLEBLOCK_FLAGS_MAGIC_MASK | RTHEAPSIMPLEBLOCK_FLAGS_FREE)) \
    99        == RTHEAPSIMPLEBLOCK_FLAGS_MAGIC )
     96 * @param   pBlock      Pointer to a RTHEAPOFFSETBLOCK structure.
     97 */
     98#define RTHEAPOFFSETBLOCK_IS_VALID_USED(pBlock)  \
     99    ( ((pBlock)->fFlags & (RTHEAPOFFSETBLOCK_FLAGS_MAGIC_MASK | RTHEAPOFFSETBLOCK_FLAGS_FREE)) \
     100       == RTHEAPOFFSETBLOCK_FLAGS_MAGIC )
    100101
    101102/**
    102103 * Checks if the specified block is valid and free.
    103104 * @returns boolean answer.
    104  * @param   pBlock      Pointer to a RTHEAPSIMPLEBLOCK structure.
    105  */
    106 #define RTHEAPSIMPLEBLOCK_IS_VALID_FREE(pBlock)  \
    107     ( ((pBlock)->fFlags & (RTHEAPSIMPLEBLOCK_FLAGS_MAGIC_MASK | RTHEAPSIMPLEBLOCK_FLAGS_FREE)) \
    108        == (RTHEAPSIMPLEBLOCK_FLAGS_MAGIC | RTHEAPSIMPLEBLOCK_FLAGS_FREE) )
     105 * @param   pBlock      Pointer to a RTHEAPOFFSETBLOCK structure.
     106 */
     107#define RTHEAPOFFSETBLOCK_IS_VALID_FREE(pBlock)  \
     108    ( ((pBlock)->fFlags & (RTHEAPOFFSETBLOCK_FLAGS_MAGIC_MASK | RTHEAPOFFSETBLOCK_FLAGS_FREE)) \
     109       == (RTHEAPOFFSETBLOCK_FLAGS_MAGIC | RTHEAPOFFSETBLOCK_FLAGS_FREE) )
    109110
    110111/**
    111112 * Checks if the specified block is free or not.
    112113 * @returns boolean answer.
    113  * @param   pBlock      Pointer to a valid RTHEAPSIMPLEBLOCK structure.
    114  */
    115 #define RTHEAPSIMPLEBLOCK_IS_FREE(pBlock)   (!!((pBlock)->fFlags & RTHEAPSIMPLEBLOCK_FLAGS_FREE))
     114 * @param   pBlock      Pointer to a valid RTHEAPOFFSETBLOCK structure.
     115 */
     116#define RTHEAPOFFSETBLOCK_IS_FREE(pBlock)   (!!((pBlock)->fFlags & RTHEAPOFFSETBLOCK_FLAGS_FREE))
    116117
    117118/**
    118119 * A free heap block.
    119  * This is an extended version of RTHEAPSIMPLEBLOCK that takes the unused
     120 * This is an extended version of RTHEAPOFFSETBLOCK that takes the unused
    120121 * user data to store free list pointers and a cached size value.
    121122 */
    122 typedef struct RTHEAPSIMPLEFREE
     123typedef struct RTHEAPOFFSETFREE
    123124{
    124125    /** Core stuff. */
    125     RTHEAPSIMPLEBLOCK       Core;
     126    RTHEAPOFFSETBLOCK               Core;
    126127    /** Pointer to the next free block. */
    127     PRTHEAPSIMPLEFREE       pNext;
     128    uint32_t /*PRTHEAPOFFSETFREE*/  offNext;
    128129    /** Pointer to the previous free block. */
    129     PRTHEAPSIMPLEFREE       pPrev;
    130     /** The size of the block (excluding the RTHEAPSIMPLEBLOCK part). */
    131     size_t                  cb;
    132     /** An alignment filler to make it a multiple of (sizeof(void *) * 2). */
    133     size_t                  Alignment;
    134 } RTHEAPSIMPLEFREE;
     130    uint32_t /*PRTHEAPOFFSETFREE*/  offPrev;
     131    /** The size of the block (excluding the RTHEAPOFFSETBLOCK part). */
     132    uint32_t                        cb;
     133    /** An alignment filler to make it a multiple of 16 bytes. */
     134    uint32_t                        Alignment;
     135} RTHEAPOFFSETFREE;
     136AssertCompileSizeAlignment(RTHEAPOFFSETFREE, 16);
    135137
    136138
    137139/**
    138140 * The heap anchor block.
    139  * This structure is placed at the head of the memory block specified to RTHeapSimpleInit(),
    140  * which means that the first RTHEAPSIMPLEBLOCK appears immediately after this structure.
    141  */
    142 typedef struct RTHEAPSIMPLEINTERNAL
    143 {
    144     /** The typical magic (RTHEAPSIMPLE_MAGIC). */
    145     size_t                  uMagic;
     141 * This structure is placed at the head of the memory block specified to RTHeapOffsetInit(),
     142 * which means that the first RTHEAPOFFSETBLOCK appears immediately after this structure.
     143 */
     144typedef struct RTHEAPOFFSETINTERNAL
     145{
     146    /** The typical magic (RTHEAPOFFSET_MAGIC). */
     147    uint32_t                        u32Magic;
    146148    /** The heap size. (This structure is included!) */
    147     size_t                  cbHeap;
    148     /** Pointer to the end of the heap. */
    149     void                   *pvEnd;
     149    uint32_t                        cbHeap;
    150150    /** The amount of free memory in the heap. */
    151     size_t                  cbFree;
     151    uint32_t                        cbFree;
    152152    /** Free head pointer. */
    153     PRTHEAPSIMPLEFREE       pFreeHead;
     153    uint32_t /*PRTHEAPOFFSETFREE*/  offFreeHead;
    154154    /** Free tail pointer. */
    155     PRTHEAPSIMPLEFREE       pFreeTail;
     155    uint32_t /*PRTHEAPOFFSETFREE*/  offFreeTail;
    156156    /** Make the size of this structure is a multiple of 32. */
    157     size_t                  auAlignment[2];
    158 } RTHEAPSIMPLEINTERNAL;
    159 AssertCompileSizeAlignment(RTHEAPSIMPLEINTERNAL, 32);
     157    uint32_t                        au32Alignment[3];
     158} RTHEAPOFFSETINTERNAL;
     159AssertCompileSizeAlignment(RTHEAPOFFSETINTERNAL, 32);
    160160
    161161
    162162/** The minimum allocation size. */
    163 #define RTHEAPSIMPLE_MIN_BLOCK  (sizeof(RTHEAPSIMPLEBLOCK))
    164 AssertCompile(RTHEAPSIMPLE_MIN_BLOCK >= sizeof(RTHEAPSIMPLEBLOCK));
    165 AssertCompile(RTHEAPSIMPLE_MIN_BLOCK >= sizeof(RTHEAPSIMPLEFREE) - sizeof(RTHEAPSIMPLEBLOCK));
     163#define RTHEAPOFFSET_MIN_BLOCK  (sizeof(RTHEAPOFFSETBLOCK))
     164AssertCompile(RTHEAPOFFSET_MIN_BLOCK >= sizeof(RTHEAPOFFSETBLOCK));
     165AssertCompile(RTHEAPOFFSET_MIN_BLOCK >= sizeof(RTHEAPOFFSETFREE) - sizeof(RTHEAPOFFSETBLOCK));
    166166
    167167/** The minimum and default alignment.  */
    168 #define RTHEAPSIMPLE_ALIGNMENT  (sizeof(RTHEAPSIMPLEBLOCK))
     168#define RTHEAPOFFSET_ALIGNMENT  (sizeof(RTHEAPOFFSETBLOCK))
    169169
    170170
     
    173173*******************************************************************************/
    174174#ifdef RT_STRICT
    175 # define RTHEAPSIMPLE_STRICT 1
    176 #endif
    177 
    178 #define ASSERT_L(a, b)    AssertMsg((uintptr_t)(a) <  (uintptr_t)(b), ("a=%p b=%p\n", (uintptr_t)(a), (uintptr_t)(b)))
    179 #define ASSERT_LE(a, b)   AssertMsg((uintptr_t)(a) <= (uintptr_t)(b), ("a=%p b=%p\n", (uintptr_t)(a), (uintptr_t)(b)))
    180 #define ASSERT_G(a, b)    AssertMsg((uintptr_t)(a) >  (uintptr_t)(b), ("a=%p b=%p\n", (uintptr_t)(a), (uintptr_t)(b)))
    181 #define ASSERT_GE(a, b)   AssertMsg((uintptr_t)(a) >= (uintptr_t)(b), ("a=%p b=%p\n", (uintptr_t)(a), (uintptr_t)(b)))
    182 #define ASSERT_ALIGN(a)   AssertMsg(!((uintptr_t)(a) & (RTHEAPSIMPLE_ALIGNMENT - 1)), ("a=%p\n", (uintptr_t)(a)))
     175# define RTHEAPOFFSET_STRICT 1
     176#endif
     177
     178/**
     179 * Converts RTHEAPOFFSETBLOCK::offSelf into a heap anchor block pointer.
     180 *
     181 * @returns Pointer of given type.
     182 * @param   pBlock          The block to find the heap anchor block for.
     183 */
     184#define RTHEAPOFF_GET_ANCHOR(pBlock)    ( (PRTHEAPOFFSETINTERNAL)((uint8_t *)(pBlock) - (pBlock)->offSelf ) )
     185
     186
     187/**
     188 * Converts an offset to a pointer.
     189 *
     190 * All offsets are relative to the heap to make life simple.
     191 *
     192 * @returns Pointer of given type.
     193 * @param   pHeapInt        Pointer to the heap anchor block.
     194 * @param   off             The offset to convert.
     195 * @param   type            The desired type.
     196 */
     197#ifdef RTHEAPOFFSET_STRICT
     198# define RTHEAPOFF_TO_PTR(pHeapInt, off, type)   ( (type)rtHeapOffCheckedOffToPtr(pHeapInt, off) )
     199#else
     200# define RTHEAPOFF_TO_PTR(pHeapInt, off, type)   ( (type)((off) ? (uint8_t *)(pHeapInt) + (off) : NULL) )
     201#endif
     202
     203/**
     204 * Converts a pointer to an offset.
     205 *
     206 * All offsets are relative to the heap to make life simple.
     207 *
     208 * @returns Offset into the heap.
     209 * @param   pHeapInt        Pointer to the heap anchor block.
     210 * @param   ptr             The pointer to convert.
     211 */
     212#ifdef RTHEAPOFFSET_STRICT
     213# define RTHEAPOFF_TO_OFF(pHeapInt, ptr)    rtHeapOffCheckedPtrToOff(pHeapInt, ptr)
     214#else
     215# define RTHEAPOFF_TO_OFF(pHeapInt, ptr)    ( (uint32_t)((ptr) ? (uintptr_t)(ptr) - (uintptr_t)(pHeapInt) : UINT32_C(0)) )
     216#endif
     217
     218#define ASSERT_L(a, b)    AssertMsg((a) <  (b), ("a=%08x b=%08x\n", (a), (b)))
     219#define ASSERT_LE(a, b)   AssertMsg((a) <= (b), ("a=%08x b=%08x\n", (a), (b)))
     220#define ASSERT_G(a, b)    AssertMsg((a) >  (b), ("a=%08x b=%08x\n", (a), (b)))
     221#define ASSERT_GE(a, b)   AssertMsg((a) >= (b), ("a=%08x b=%08x\n", (a), (b)))
     222#define ASSERT_ALIGN(a)   AssertMsg(!((uintptr_t)(a) & (RTHEAPOFFSET_ALIGNMENT - 1)), ("a=%p\n", (uintptr_t)(a)))
    183223
    184224#define ASSERT_PREV(pHeapInt, pBlock)  \
    185     do { ASSERT_ALIGN((pBlock)->pPrev); \
    186          if ((pBlock)->pPrev) \
     225    do { ASSERT_ALIGN((pBlock)->offPrev); \
     226         if ((pBlock)->offPrev) \
    187227         { \
    188              ASSERT_L((pBlock)->pPrev, (pBlock)); \
    189              ASSERT_GE((pBlock)->pPrev, (pHeapInt) + 1); \
     228             ASSERT_L((pBlock)->offPrev, RTHEAPOFF_TO_OFF(pHeapInt, pBlock)); \
     229             ASSERT_GE((pBlock)->offPrev, sizeof(RTHEAPOFFSETINTERNAL)); \
    190230         } \
    191231         else \
    192              Assert((pBlock) == (PRTHEAPSIMPLEBLOCK)((pHeapInt) + 1)); \
     232             Assert((pBlock) == (PRTHEAPOFFSETBLOCK)((pHeapInt) + 1)); \
    193233    } while (0)
    194234
    195235#define ASSERT_NEXT(pHeap, pBlock) \
    196     do { ASSERT_ALIGN((pBlock)->pNext); \
    197          if ((pBlock)->pNext) \
     236    do { ASSERT_ALIGN((pBlock)->offNext); \
     237         if ((pBlock)->offNext) \
    198238         { \
    199              ASSERT_L((pBlock)->pNext, (pHeapInt)->pvEnd); \
    200              ASSERT_G((pBlock)->pNext, (pBlock)); \
     239             ASSERT_L((pBlock)->offNext, (pHeapInt)->cbHeap); \
     240             ASSERT_G((pBlock)->offNext, RTHEAPOFF_TO_OFF(pHeapInt, pBlock)); \
    201241         } \
    202242    } while (0)
    203243
    204244#define ASSERT_BLOCK(pHeapInt, pBlock) \
    205     do { AssertMsg(RTHEAPSIMPLEBLOCK_IS_VALID(pBlock), ("%#x\n", (pBlock)->fFlags)); \
    206          AssertMsg((pBlock)->pHeap == (pHeapInt), ("%p != %p\n", (pBlock)->pHeap, (pHeapInt))); \
    207          ASSERT_GE((pBlock), (pHeapInt) + 1); \
    208          ASSERT_L((pBlock), (pHeapInt)->pvEnd); \
     245    do { AssertMsg(RTHEAPOFFSETBLOCK_IS_VALID(pBlock), ("%#x\n", (pBlock)->fFlags)); \
     246         AssertMsg(RTHEAPOFF_GET_ANCHOR(pBlock) == (pHeapInt), ("%p != %p\n", RTHEAPOFF_GET_ANCHOR(pBlock), (pHeapInt))); \
     247         ASSERT_GE(RTHEAPOFF_TO_OFF(pHeapInt, pBlock), sizeof(RTHEAPOFFSETINTERNAL)); \
     248         ASSERT_L( RTHEAPOFF_TO_OFF(pHeapInt, pBlock), (pHeapInt)->cbHeap); \
    209249         ASSERT_NEXT(pHeapInt, pBlock); \
    210250         ASSERT_PREV(pHeapInt, pBlock); \
     
    212252
    213253#define ASSERT_BLOCK_USED(pHeapInt, pBlock) \
    214     do { AssertMsg(RTHEAPSIMPLEBLOCK_IS_VALID_USED((pBlock)), ("%#x\n", (pBlock)->fFlags)); \
    215          AssertMsg((pBlock)->pHeap == (pHeapInt), ("%p != %p\n", (pBlock)->pHeap, (pHeapInt))); \
    216          ASSERT_GE((pBlock), (pHeapInt) + 1); \
    217          ASSERT_L((pBlock), (pHeapInt)->pvEnd); \
     254    do { AssertMsg(RTHEAPOFFSETBLOCK_IS_VALID_USED((pBlock)), ("%#x\n", (pBlock)->fFlags)); \
     255         AssertMsg(RTHEAPOFF_GET_ANCHOR(pBlock) == (pHeapInt), ("%p != %p\n", RTHEAPOFF_GET_ANCHOR(pBlock), (pHeapInt))); \
     256         ASSERT_GE(RTHEAPOFF_TO_OFF(pHeapInt, pBlock), sizeof(RTHEAPOFFSETINTERNAL)); \
     257         ASSERT_L( RTHEAPOFF_TO_OFF(pHeapInt, pBlock), (pHeapInt)->cbHeap); \
    218258         ASSERT_NEXT(pHeapInt, pBlock); \
    219259         ASSERT_PREV(pHeapInt, pBlock); \
     
    221261
    222262#define ASSERT_FREE_PREV(pHeapInt, pBlock) \
    223     do { ASSERT_ALIGN((pBlock)->pPrev); \
    224          if ((pBlock)->pPrev) \
     263    do { ASSERT_ALIGN((pBlock)->offPrev); \
     264         if ((pBlock)->offPrev) \
    225265         { \
    226              ASSERT_GE((pBlock)->pPrev, (pHeapInt)->pFreeHead); \
    227              ASSERT_L((pBlock)->pPrev, (pBlock)); \
    228              ASSERT_LE((pBlock)->pPrev, (pBlock)->Core.pPrev); \
     266             ASSERT_GE((pBlock)->offPrev, (pHeapInt)->offFreeHead); \
     267             ASSERT_L((pBlock)->offPrev, RTHEAPOFF_TO_OFF(pHeapInt, pBlock)); \
     268             ASSERT_LE((pBlock)->offPrev, (pBlock)->Core.offPrev); \
    229269         } \
    230270         else \
    231              Assert((pBlock) == (pHeapInt)->pFreeHead); \
     271             Assert((pBlock) == RTHEAPOFF_TO_PTR(pHeapInt, (pHeapInt)->offFreeHead, PRTHEAPOFFSETFREE) ); \
    232272    } while (0)
    233273
    234274#define ASSERT_FREE_NEXT(pHeapInt, pBlock) \
    235     do { ASSERT_ALIGN((pBlock)->pNext); \
    236          if ((pBlock)->pNext) \
     275    do { ASSERT_ALIGN((pBlock)->offNext); \
     276         if ((pBlock)->offNext) \
    237277         { \
    238              ASSERT_LE((pBlock)->pNext, (pHeapInt)->pFreeTail); \
    239              ASSERT_G((pBlock)->pNext, (pBlock)); \
    240              ASSERT_GE((pBlock)->pNext, (pBlock)->Core.pNext); \
     278             ASSERT_LE((pBlock)->offNext, (pHeapInt)->offFreeTail); \
     279             ASSERT_G((pBlock)->offNext, RTHEAPOFF_TO_OFF(pHeapInt, pBlock)); \
     280             ASSERT_GE((pBlock)->offNext, (pBlock)->Core.offNext); \
    241281         } \
    242282         else \
    243              Assert((pBlock) == (pHeapInt)->pFreeTail); \
     283             Assert((pBlock) == RTHEAPOFF_TO_PTR(pHeapInt, (pHeapInt)->offFreeTail, PRTHEAPOFFSETFREE)); \
    244284    } while (0)
    245285
    246 #ifdef RTHEAPSIMPLE_STRICT
     286#ifdef RTHEAPOFFSET_STRICT
    247287# define ASSERT_FREE_CB(pHeapInt, pBlock) \
    248     do { size_t cbCalc = ((pBlock)->Core.pNext ? (uintptr_t)(pBlock)->Core.pNext : (uintptr_t)(pHeapInt)->pvEnd) \
    249                        - (uintptr_t)(pBlock) - sizeof(RTHEAPSIMPLEBLOCK); \
     288    do { size_t cbCalc = ((pBlock)->Core.offNext ? (pBlock)->Core.offNext : (pHeapInt)->cbHeap) \
     289                       - RTHEAPOFF_TO_OFF((pHeapInt), (pBlock)) - sizeof(RTHEAPOFFSETBLOCK); \
    250290         AssertMsg((pBlock)->cb == cbCalc, ("cb=%#zx cbCalc=%#zx\n", (pBlock)->cb, cbCalc)); \
    251291    } while (0)
     
    257297#define ASSERT_BLOCK_FREE(pHeapInt, pBlock) \
    258298    do { ASSERT_BLOCK(pHeapInt, &(pBlock)->Core); \
    259          Assert(RTHEAPSIMPLEBLOCK_IS_VALID_FREE(&(pBlock)->Core)); \
    260          ASSERT_GE((pBlock), (pHeapInt)->pFreeHead); \
    261          ASSERT_LE((pBlock), (pHeapInt)->pFreeTail); \
     299         Assert(RTHEAPOFFSETBLOCK_IS_VALID_FREE(&(pBlock)->Core)); \
     300         ASSERT_GE(RTHEAPOFF_TO_OFF(pHeapInt, pBlock), (pHeapInt)->offFreeHead); \
     301         ASSERT_LE(RTHEAPOFF_TO_OFF(pHeapInt, pBlock), (pHeapInt)->offFreeTail); \
    262302         ASSERT_FREE_NEXT(pHeapInt, pBlock); \
    263303         ASSERT_FREE_PREV(pHeapInt, pBlock); \
     
    268308#define ASSERT_ANCHOR(pHeapInt) \
    269309    do { AssertPtr(pHeapInt);\
    270          Assert((pHeapInt)->uMagic == RTHEAPSIMPLE_MAGIC); \
     310         Assert((pHeapInt)->u32Magic == RTHEAPOFFSET_MAGIC); \
    271311    } while (0)
    272312
     
    275315*   Internal Functions                                                         *
    276316*******************************************************************************/
    277 #ifdef RTHEAPSIMPLE_STRICT
    278 static void rtHeapSimpleAssertAll(PRTHEAPSIMPLEINTERNAL pHeapInt);
    279 #endif
    280 static PRTHEAPSIMPLEBLOCK rtHeapSimpleAllocBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, size_t cb, size_t uAlignment);
    281 static void rtHeapSimpleFreeBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, PRTHEAPSIMPLEBLOCK pBlock);
    282 
    283 
    284 RTDECL(int) RTHeapSimpleInit(PRTHEAPSIMPLE phHeap, void *pvMemory, size_t cbMemory)
    285 {
    286     PRTHEAPSIMPLEINTERNAL pHeapInt;
    287     PRTHEAPSIMPLEFREE pFree;
     317#ifdef RTHEAPOFFSET_STRICT
     318static void rtHeapOffsetAssertAll(PRTHEAPOFFSETINTERNAL pHeapInt);
     319#endif
     320static PRTHEAPOFFSETBLOCK rtHeapOffsetAllocBlock(PRTHEAPOFFSETINTERNAL pHeapInt, size_t cb, size_t uAlignment);
     321static void rtHeapOffsetFreeBlock(PRTHEAPOFFSETINTERNAL pHeapInt, PRTHEAPOFFSETBLOCK pBlock);
     322
     323#ifdef RTHEAPOFFSET_STRICT
     324
     325/** Checked version of RTHEAPOFF_TO_PTR. */
     326DECLINLINE(void *) rtHeapOffCheckedOffToPtr(PRTHEAPOFFSETINTERNAL pHeapInt, uint32_t off)
     327{
     328    if (!off)
     329        return NULL;
     330    AssertMsg(off < pHeapInt->cbHeap,   ("%#x %#x\n", off, pHeapInt->cbHeap));
     331    AssertMsg(off >= sizeof(*pHeapInt), ("%#x %#x\n", off, sizeof(*pHeapInt)));
     332    return (uint8_t *)pHeapInt + off;
     333}
     334
     335/** Checked version of RTHEAPOFF_TO_OFF. */
     336DECLINLINE(uint32_t) rtHeapOffCheckedPtrToOff(PRTHEAPOFFSETINTERNAL pHeapInt, void *pv)
     337{
     338    if (!pv)
     339        return 0;
     340    uintptr_t off = (uintptr_t)pv - (uintptr_t)pHeapInt;
     341    AssertMsg(off < pHeapInt->cbHeap,   ("%#x %#x\n", off, pHeapInt->cbHeap));
     342    AssertMsg(off >= sizeof(*pHeapInt), ("%#x %#x\n", off, sizeof(*pHeapInt)));
     343    return (uint32_t)off;
     344}
     345
     346#endif /* RTHEAPOFFSET_STRICT */
     347
     348
     349
     350RTDECL(int) RTHeapOffsetInit(PRTHEAPOFFSET phHeap, void *pvMemory, size_t cbMemory)
     351{
     352    PRTHEAPOFFSETINTERNAL pHeapInt;
     353    PRTHEAPOFFSETFREE pFree;
    288354    unsigned i;
    289355
     
    299365     * enforce 32 byte alignment of it. Also align the heap size correctly.
    300366     */
    301     pHeapInt = (PRTHEAPSIMPLEINTERNAL)pvMemory;
     367    pHeapInt = (PRTHEAPOFFSETINTERNAL)pvMemory;
    302368    if ((uintptr_t)pvMemory & 31)
    303369    {
    304370        const uintptr_t off = 32 - ((uintptr_t)pvMemory & 31);
    305371        cbMemory -= off;
    306         pHeapInt = (PRTHEAPSIMPLEINTERNAL)((uintptr_t)pvMemory + off);
    307     }
    308     cbMemory &= ~(RTHEAPSIMPLE_ALIGNMENT - 1);
     372        pHeapInt = (PRTHEAPOFFSETINTERNAL)((uintptr_t)pvMemory + off);
     373    }
     374    cbMemory &= ~(RTHEAPOFFSET_ALIGNMENT - 1);
    309375
    310376
    311377    /* Init the heap anchor block. */
    312     pHeapInt->uMagic = RTHEAPSIMPLE_MAGIC;
    313     pHeapInt->pvEnd = (uint8_t *)pHeapInt + cbMemory;
     378    pHeapInt->u32Magic = RTHEAPOFFSET_MAGIC;
    314379    pHeapInt->cbHeap = cbMemory;
    315380    pHeapInt->cbFree = cbMemory
    316                      - sizeof(RTHEAPSIMPLEBLOCK)
    317                      - sizeof(RTHEAPSIMPLEINTERNAL);
    318     pHeapInt->pFreeTail = pHeapInt->pFreeHead = (PRTHEAPSIMPLEFREE)(pHeapInt + 1);
    319     for (i = 0; i < RT_ELEMENTS(pHeapInt->auAlignment); i++)
    320         pHeapInt->auAlignment[i] = ~(size_t)0;
     381                     - sizeof(RTHEAPOFFSETBLOCK)
     382                     - sizeof(RTHEAPOFFSETINTERNAL);
     383    pHeapInt->offFreeTail = pHeapInt->offFreeHead = sizeof(*pHeapInt);
     384    for (i = 0; i < RT_ELEMENTS(pHeapInt->au32Alignment); i++)
     385        pHeapInt->au32Alignment[i] = UINT32_MAX;
    321386
    322387    /* Init the single free block. */
    323     pFree = pHeapInt->pFreeHead;
    324     pFree->Core.pNext = NULL;
    325     pFree->Core.pPrev = NULL;
    326     pFree->Core.pHeap = pHeapInt;
    327     pFree->Core.fFlags = RTHEAPSIMPLEBLOCK_FLAGS_MAGIC | RTHEAPSIMPLEBLOCK_FLAGS_FREE;
    328     pFree->pNext = NULL;
    329     pFree->pPrev = NULL;
     388    pFree = RTHEAPOFF_TO_PTR(pHeapInt, pHeapInt->offFreeHead, PRTHEAPOFFSETFREE);
     389    pFree->Core.offNext = 0;
     390    pFree->Core.offPrev = 0;
     391    pFree->Core.offSelf = pHeapInt->offFreeHead;
     392    pFree->Core.fFlags = RTHEAPOFFSETBLOCK_FLAGS_MAGIC | RTHEAPOFFSETBLOCK_FLAGS_FREE;
     393    pFree->offNext = 0;
     394    pFree->offPrev = 0;
    330395    pFree->cb = pHeapInt->cbFree;
    331396
    332397    *phHeap = pHeapInt;
    333398
    334 #ifdef RTHEAPSIMPLE_STRICT
    335     rtHeapSimpleAssertAll(pHeapInt);
     399#ifdef RTHEAPOFFSET_STRICT
     400    rtHeapOffsetAssertAll(pHeapInt);
    336401#endif
    337402    return VINF_SUCCESS;
    338403}
    339 RT_EXPORT_SYMBOL(RTHeapSimpleInit);
    340 
    341 
    342 RTDECL(int) RTHeapSimpleRelocate(RTHEAPSIMPLE hHeap, uintptr_t offDelta)
    343 {
    344     PRTHEAPSIMPLEINTERNAL   pHeapInt = hHeap;
    345     PRTHEAPSIMPLEFREE       pCur;
    346 
    347     /*
    348      * Validate input.
    349      */
    350     AssertPtrReturn(pHeapInt, VERR_INVALID_HANDLE);
    351     AssertReturn(pHeapInt->uMagic == RTHEAPSIMPLE_MAGIC, VERR_INVALID_HANDLE);
    352     AssertMsgReturn((uintptr_t)pHeapInt - (uintptr_t)pHeapInt->pvEnd + pHeapInt->cbHeap == offDelta,
    353                     ("offDelta=%p, expected=%p\n", offDelta, (uintptr_t)pHeapInt->pvEnd - pHeapInt->cbHeap - (uintptr_t)pHeapInt),
    354                     VERR_INVALID_PARAMETER);
    355 
    356     /*
    357      * Relocate the heap anchor block.
    358      */
    359 #define RELOCATE_IT(var, type, offDelta)    do { if (RT_UNLIKELY((var) != NULL)) { (var) = (type)((uintptr_t)(var) + offDelta); } } while (0)
    360     RELOCATE_IT(pHeapInt->pvEnd,     void *,            offDelta);
    361     RELOCATE_IT(pHeapInt->pFreeHead, PRTHEAPSIMPLEFREE, offDelta);
    362     RELOCATE_IT(pHeapInt->pFreeTail, PRTHEAPSIMPLEFREE, offDelta);
    363 
    364     /*
    365      * Walk the heap blocks.
    366      */
    367     for (pCur = (PRTHEAPSIMPLEFREE)(pHeapInt + 1);
    368          pCur && (uintptr_t)pCur < (uintptr_t)pHeapInt->pvEnd;
    369          pCur = (PRTHEAPSIMPLEFREE)pCur->Core.pNext)
    370     {
    371         RELOCATE_IT(pCur->Core.pNext, PRTHEAPSIMPLEBLOCK,    offDelta);
    372         RELOCATE_IT(pCur->Core.pPrev, PRTHEAPSIMPLEBLOCK,    offDelta);
    373         RELOCATE_IT(pCur->Core.pHeap, PRTHEAPSIMPLEINTERNAL, offDelta);
    374         if (RTHEAPSIMPLEBLOCK_IS_FREE(&pCur->Core))
    375         {
    376             RELOCATE_IT(pCur->pNext, PRTHEAPSIMPLEFREE, offDelta);
    377             RELOCATE_IT(pCur->pPrev, PRTHEAPSIMPLEFREE, offDelta);
    378         }
    379     }
    380 #undef RELOCATE_IT
    381 
    382 #ifdef RTHEAPSIMPLE_STRICT
    383     /*
    384      * Give it a once over before we return.
    385      */
    386     rtHeapSimpleAssertAll(pHeapInt);
    387 #endif
    388     return VINF_SUCCESS;
    389 }
    390 RT_EXPORT_SYMBOL(RTHeapSimpleRelocate);
    391 
    392 
    393 RTDECL(void *) RTHeapSimpleAlloc(RTHEAPSIMPLE hHeap, size_t cb, size_t cbAlignment)
    394 {
    395     PRTHEAPSIMPLEINTERNAL pHeapInt = hHeap;
    396     PRTHEAPSIMPLEBLOCK pBlock;
     404RT_EXPORT_SYMBOL(RTHeapOffsetInit);
     405
     406
     407RTDECL(void *) RTHeapOffsetAlloc(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment)
     408{
     409    PRTHEAPOFFSETINTERNAL pHeapInt = hHeap;
     410    PRTHEAPOFFSETBLOCK pBlock;
    397411
    398412    /*
     
    400414     */
    401415    AssertPtrReturn(pHeapInt, NULL);
    402     if (cb < RTHEAPSIMPLE_MIN_BLOCK)
    403         cb = RTHEAPSIMPLE_MIN_BLOCK;
     416    if (cb < RTHEAPOFFSET_MIN_BLOCK)
     417        cb = RTHEAPOFFSET_MIN_BLOCK;
    404418    else
    405         cb = RT_ALIGN_Z(cb, RTHEAPSIMPLE_ALIGNMENT);
     419        cb = RT_ALIGN_Z(cb, RTHEAPOFFSET_ALIGNMENT);
    406420    if (!cbAlignment)
    407         cbAlignment = RTHEAPSIMPLE_ALIGNMENT;
     421        cbAlignment = RTHEAPOFFSET_ALIGNMENT;
    408422    else
    409423    {
    410424        Assert(!(cbAlignment & (cbAlignment - 1)));
    411425        Assert((cbAlignment & ~(cbAlignment - 1)) == cbAlignment);
    412         if (cbAlignment < RTHEAPSIMPLE_ALIGNMENT)
    413             cbAlignment = RTHEAPSIMPLE_ALIGNMENT;
     426        if (cbAlignment < RTHEAPOFFSET_ALIGNMENT)
     427            cbAlignment = RTHEAPOFFSET_ALIGNMENT;
    414428    }
    415429
     
    417431     * Do the allocation.
    418432     */
    419     pBlock = rtHeapSimpleAllocBlock(pHeapInt, cb, cbAlignment);
     433    pBlock = rtHeapOffsetAllocBlock(pHeapInt, cb, cbAlignment);
    420434    if (RT_LIKELY(pBlock))
    421435    {
     
    425439    return NULL;
    426440}
    427 RT_EXPORT_SYMBOL(RTHeapSimpleAlloc);
    428 
    429 
    430 RTDECL(void *) RTHeapSimpleAllocZ(RTHEAPSIMPLE hHeap, size_t cb, size_t cbAlignment)
    431 {
    432     PRTHEAPSIMPLEINTERNAL pHeapInt = hHeap;
    433     PRTHEAPSIMPLEBLOCK pBlock;
     441RT_EXPORT_SYMBOL(RTHeapOffsetAlloc);
     442
     443
     444RTDECL(void *) RTHeapOffsetAllocZ(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment)
     445{
     446    PRTHEAPOFFSETINTERNAL pHeapInt = hHeap;
     447    PRTHEAPOFFSETBLOCK pBlock;
    434448
    435449    /*
     
    437451     */
    438452    AssertPtrReturn(pHeapInt, NULL);
    439     if (cb < RTHEAPSIMPLE_MIN_BLOCK)
    440         cb = RTHEAPSIMPLE_MIN_BLOCK;
     453    if (cb < RTHEAPOFFSET_MIN_BLOCK)
     454        cb = RTHEAPOFFSET_MIN_BLOCK;
    441455    else
    442         cb = RT_ALIGN_Z(cb, RTHEAPSIMPLE_ALIGNMENT);
     456        cb = RT_ALIGN_Z(cb, RTHEAPOFFSET_ALIGNMENT);
    443457    if (!cbAlignment)
    444         cbAlignment = RTHEAPSIMPLE_ALIGNMENT;
     458        cbAlignment = RTHEAPOFFSET_ALIGNMENT;
    445459    else
    446460    {
    447461        Assert(!(cbAlignment & (cbAlignment - 1)));
    448462        Assert((cbAlignment & ~(cbAlignment - 1)) == cbAlignment);
    449         if (cbAlignment < RTHEAPSIMPLE_ALIGNMENT)
    450             cbAlignment = RTHEAPSIMPLE_ALIGNMENT;
     463        if (cbAlignment < RTHEAPOFFSET_ALIGNMENT)
     464            cbAlignment = RTHEAPOFFSET_ALIGNMENT;
    451465    }
    452466
     
    454468     * Do the allocation.
    455469     */
    456     pBlock = rtHeapSimpleAllocBlock(pHeapInt, cb, cbAlignment);
     470    pBlock = rtHeapOffsetAllocBlock(pHeapInt, cb, cbAlignment);
    457471    if (RT_LIKELY(pBlock))
    458472    {
     
    463477    return NULL;
    464478}
    465 RT_EXPORT_SYMBOL(RTHeapSimpleAllocZ);
     479RT_EXPORT_SYMBOL(RTHeapOffsetAllocZ);
    466480
    467481
     
    478492 * @param   uAlignment  The alignment specifications for the allocated block.
    479493 */
    480 static PRTHEAPSIMPLEBLOCK rtHeapSimpleAllocBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, size_t cb, size_t uAlignment)
    481 {
    482     PRTHEAPSIMPLEBLOCK  pRet = NULL;
    483     PRTHEAPSIMPLEFREE   pFree;
    484 
    485 #ifdef RTHEAPSIMPLE_STRICT
    486     rtHeapSimpleAssertAll(pHeapInt);
     494static PRTHEAPOFFSETBLOCK rtHeapOffsetAllocBlock(PRTHEAPOFFSETINTERNAL pHeapInt, size_t cb, size_t uAlignment)
     495{
     496    PRTHEAPOFFSETBLOCK  pRet = NULL;
     497    PRTHEAPOFFSETFREE   pFree;
     498
     499    AssertReturn((pHeapInt)->u32Magic == RTHEAPOFFSET_MAGIC, NULL);
     500#ifdef RTHEAPOFFSET_STRICT
     501    rtHeapOffsetAssertAll(pHeapInt);
    487502#endif
    488503
     
    490505     * Search for a fitting block from the lower end of the heap.
    491506     */
    492     for (pFree = pHeapInt->pFreeHead;
     507    for (pFree = RTHEAPOFF_TO_PTR(pHeapInt, pHeapInt->offFreeHead, PRTHEAPOFFSETFREE);
    493508         pFree;
    494          pFree = pFree->pNext)
     509         pFree = RTHEAPOFF_TO_PTR(pHeapInt, pFree->offNext, PRTHEAPOFFSETFREE))
    495510    {
    496511        uintptr_t offAlign;
     
    505520        if (offAlign)
    506521        {
    507             RTHEAPSIMPLEFREE Free;
    508             PRTHEAPSIMPLEBLOCK pPrev;
     522            RTHEAPOFFSETFREE Free;
     523            PRTHEAPOFFSETBLOCK pPrev;
    509524
    510525            offAlign = uAlignment - offAlign;
     
    516531             */
    517532            Free = *pFree;
    518             pFree = (PRTHEAPSIMPLEFREE)((uintptr_t)pFree + offAlign);
     533            pFree = (PRTHEAPOFFSETFREE)((uintptr_t)pFree + offAlign);
    519534
    520535            /*
     
    527542             * for that.)
    528543             */
    529             pPrev = Free.Core.pPrev;
     544            pPrev = RTHEAPOFF_TO_PTR(pHeapInt, Free.Core.offPrev, PRTHEAPOFFSETBLOCK);
    530545            if (pPrev)
    531546            {
    532                 AssertMsg(!RTHEAPSIMPLEBLOCK_IS_FREE(pPrev), ("Impossible!\n"));
    533                 pPrev->pNext = &pFree->Core;
     547                AssertMsg(!RTHEAPOFFSETBLOCK_IS_FREE(pPrev), ("Impossible!\n"));
     548                pPrev->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    534549            }
    535550            else
    536551            {
    537                 pPrev = (PRTHEAPSIMPLEBLOCK)(pHeapInt + 1);
     552                pPrev = (PRTHEAPOFFSETBLOCK)(pHeapInt + 1);
    538553                Assert(pPrev == &pFree->Core);
    539                 pPrev->pPrev = NULL;
    540                 pPrev->pNext = &pFree->Core;
    541                 pPrev->pHeap = pHeapInt;
    542                 pPrev->fFlags = RTHEAPSIMPLEBLOCK_FLAGS_MAGIC;
     554                pPrev->offPrev = 0;
     555                pPrev->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
     556                pPrev->offSelf = RTHEAPOFF_TO_OFF(pHeapInt, pPrev);
     557                pPrev->fFlags = RTHEAPOFFSETBLOCK_FLAGS_MAGIC;
    543558            }
    544559            pHeapInt->cbFree -= offAlign;
     
    548563             */
    549564            *pFree = Free;
     565            pFree->Core.offSelf = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    550566
    551567            /* the core */
    552             if (pFree->Core.pNext)
    553                 pFree->Core.pNext->pPrev = &pFree->Core;
    554             pFree->Core.pPrev = pPrev;
     568            if (pFree->Core.offNext)
     569                RTHEAPOFF_TO_PTR(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = pFree->Core.offSelf;
     570            pFree->Core.offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pPrev);
    555571
    556572            /* the free part */
    557573            pFree->cb -= offAlign;
    558             if (pFree->pNext)
    559                 pFree->pNext->pPrev = pFree;
     574            if (pFree->offNext)
     575                RTHEAPOFF_TO_PTR(pHeapInt, pFree->offNext, PRTHEAPOFFSETFREE)->offPrev = pFree->Core.offSelf;
    560576            else
    561                 pHeapInt->pFreeTail = pFree;
    562             if (pFree->pPrev)
    563                 pFree->pPrev->pNext = pFree;
     577                pHeapInt->offFreeTail = pFree->Core.offSelf;
     578            if (pFree->offPrev)
     579                RTHEAPOFF_TO_PTR(pHeapInt, pFree->offPrev, PRTHEAPOFFSETFREE)->offNext = pFree->Core.offSelf;
    564580            else
    565                 pHeapInt->pFreeHead = pFree;
     581                pHeapInt->offFreeHead = pFree->Core.offSelf;
    566582            ASSERT_BLOCK_FREE(pHeapInt, pFree);
    567583            ASSERT_BLOCK_USED(pHeapInt, pPrev);
     
    571587         * Split off a new FREE block?
    572588         */
    573         if (pFree->cb >= cb + RT_ALIGN_Z(sizeof(RTHEAPSIMPLEFREE), RTHEAPSIMPLE_ALIGNMENT))
     589        if (pFree->cb >= cb + RT_ALIGN_Z(sizeof(RTHEAPOFFSETFREE), RTHEAPOFFSET_ALIGNMENT))
    574590        {
    575591            /*
    576592             * Move the FREE block up to make room for the new USED block.
    577593             */
    578             PRTHEAPSIMPLEFREE   pNew = (PRTHEAPSIMPLEFREE)((uintptr_t)&pFree->Core + cb + sizeof(RTHEAPSIMPLEBLOCK));
    579 
    580             pNew->Core.pNext = pFree->Core.pNext;
    581             if (pFree->Core.pNext)
    582                 pFree->Core.pNext->pPrev = &pNew->Core;
    583             pNew->Core.pPrev = &pFree->Core;
    584             pNew->Core.pHeap = pHeapInt;
    585             pNew->Core.fFlags = RTHEAPSIMPLEBLOCK_FLAGS_MAGIC | RTHEAPSIMPLEBLOCK_FLAGS_FREE;
    586 
    587             pNew->pNext = pFree->pNext;
    588             if (pNew->pNext)
    589                 pNew->pNext->pPrev = pNew;
     594            PRTHEAPOFFSETFREE   pNew = (PRTHEAPOFFSETFREE)((uintptr_t)&pFree->Core + cb + sizeof(RTHEAPOFFSETBLOCK));
     595
     596            pNew->Core.offSelf = RTHEAPOFF_TO_OFF(pHeapInt, pNew);
     597            pNew->Core.offNext = pFree->Core.offNext;
     598            if (pFree->Core.offNext)
     599                RTHEAPOFF_TO_PTR(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = pNew->Core.offSelf;
     600            pNew->Core.offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
     601            pNew->Core.fFlags = RTHEAPOFFSETBLOCK_FLAGS_MAGIC | RTHEAPOFFSETBLOCK_FLAGS_FREE;
     602
     603            pNew->offNext = pFree->offNext;
     604            if (pNew->offNext)
     605                RTHEAPOFF_TO_PTR(pHeapInt, pNew->offNext, PRTHEAPOFFSETFREE)->offPrev = pNew->Core.offSelf;
    590606            else
    591                 pHeapInt->pFreeTail = pNew;
    592             pNew->pPrev = pFree->pPrev;
    593             if (pNew->pPrev)
    594                 pNew->pPrev->pNext = pNew;
     607                pHeapInt->offFreeTail = pNew->Core.offSelf;
     608            pNew->offPrev = pFree->offPrev;
     609            if (pNew->offPrev)
     610                RTHEAPOFF_TO_PTR(pHeapInt, pNew->offPrev, PRTHEAPOFFSETFREE)->offNext = pNew->Core.offSelf;
    595611            else
    596                 pHeapInt->pFreeHead = pNew;
    597             pNew->cb    = (pNew->Core.pNext ? (uintptr_t)pNew->Core.pNext : (uintptr_t)pHeapInt->pvEnd) \
    598                         - (uintptr_t)pNew - sizeof(RTHEAPSIMPLEBLOCK);
     612                pHeapInt->offFreeHead = pNew->Core.offSelf;
     613            pNew->cb    = (pNew->Core.offNext ? pNew->Core.offNext : pHeapInt->cbHeap) \
     614                        - pNew->Core.offSelf - sizeof(RTHEAPOFFSETBLOCK);
    599615            ASSERT_BLOCK_FREE(pHeapInt, pNew);
    600616
     
    602618             * Update the old FREE node making it a USED node.
    603619             */
    604             pFree->Core.fFlags &= ~RTHEAPSIMPLEBLOCK_FLAGS_FREE;
    605             pFree->Core.pNext = &pNew->Core;
     620            pFree->Core.fFlags &= ~RTHEAPOFFSETBLOCK_FLAGS_FREE;
     621            pFree->Core.offNext = pNew->Core.offSelf;
    606622            pHeapInt->cbFree -= pFree->cb;
    607623            pHeapInt->cbFree += pNew->cb;
     
    614630             * Link it out of the free list.
    615631             */
    616             if (pFree->pNext)
    617                 pFree->pNext->pPrev = pFree->pPrev;
     632            if (pFree->offNext)
     633                RTHEAPOFF_TO_PTR(pHeapInt, pFree->offNext, PRTHEAPOFFSETFREE)->offPrev = pFree->offPrev;
    618634            else
    619                 pHeapInt->pFreeTail = pFree->pPrev;
    620             if (pFree->pPrev)
    621                 pFree->pPrev->pNext = pFree->pNext;
     635                pHeapInt->offFreeTail = pFree->offPrev;
     636            if (pFree->offPrev)
     637                RTHEAPOFF_TO_PTR(pHeapInt, pFree->offPrev, PRTHEAPOFFSETFREE)->offNext = pFree->offNext;
    622638            else
    623                 pHeapInt->pFreeHead = pFree->pNext;
     639                pHeapInt->offFreeHead = pFree->offNext;
    624640
    625641            /*
     
    627643             */
    628644            pHeapInt->cbFree -= pFree->cb;
    629             pFree->Core.fFlags &= ~RTHEAPSIMPLEBLOCK_FLAGS_FREE;
     645            pFree->Core.fFlags &= ~RTHEAPOFFSETBLOCK_FLAGS_FREE;
    630646            pRet = &pFree->Core;
    631647            ASSERT_BLOCK_USED(pHeapInt, pRet);
     
    634650    }
    635651
    636 #ifdef RTHEAPSIMPLE_STRICT
    637     rtHeapSimpleAssertAll(pHeapInt);
     652#ifdef RTHEAPOFFSET_STRICT
     653    rtHeapOffsetAssertAll(pHeapInt);
    638654#endif
    639655    return pRet;
     
    641657
    642658
    643 RTDECL(void) RTHeapSimpleFree(RTHEAPSIMPLE hHeap, void *pv)
    644 {
    645     PRTHEAPSIMPLEINTERNAL pHeapInt;
    646     PRTHEAPSIMPLEBLOCK pBlock;
     659RTDECL(void) RTHeapOffsetFree(RTHEAPOFFSET hHeap, void *pv)
     660{
     661    PRTHEAPOFFSETINTERNAL pHeapInt;
     662    PRTHEAPOFFSETBLOCK pBlock;
    647663
    648664    /*
     
    652668        return;
    653669    AssertPtr(pv);
    654     Assert(RT_ALIGN_P(pv, RTHEAPSIMPLE_ALIGNMENT) == pv);
     670    Assert(RT_ALIGN_P(pv, RTHEAPOFFSET_ALIGNMENT) == pv);
    655671
    656672    /*
    657673     * Get the block and heap. If in strict mode, validate these.
    658674     */
    659     pBlock = (PRTHEAPSIMPLEBLOCK)pv - 1;
    660     pHeapInt = pBlock->pHeap;
     675    pBlock = (PRTHEAPOFFSETBLOCK)pv - 1;
     676    pHeapInt = RTHEAPOFF_GET_ANCHOR(pBlock);
    661677    ASSERT_BLOCK_USED(pHeapInt, pBlock);
    662678    ASSERT_ANCHOR(pHeapInt);
    663     Assert(pHeapInt == (PRTHEAPSIMPLEINTERNAL)hHeap || !hHeap);
    664 
    665 #ifdef RTHEAPSIMPLE_FREE_POISON
     679    Assert(pHeapInt == (PRTHEAPOFFSETINTERNAL)hHeap || !hHeap);
     680
     681#ifdef RTHEAPOFFSET_FREE_POISON
    666682    /*
    667683     * Poison the block.
    668684     */
    669685    const size_t cbBlock = (pBlock->pNext ? (uintptr_t)pBlock->pNext : (uintptr_t)pHeapInt->pvEnd)
    670                          - (uintptr_t)pBlock - sizeof(RTHEAPSIMPLEBLOCK);
    671     memset(pBlock + 1, RTHEAPSIMPLE_FREE_POISON, cbBlock);
     686                         - (uintptr_t)pBlock - sizeof(RTHEAPOFFSETBLOCK);
     687    memset(pBlock + 1, RTHEAPOFFSET_FREE_POISON, cbBlock);
    672688#endif
    673689
     
    675691     * Call worker which does the actual job.
    676692     */
    677     rtHeapSimpleFreeBlock(pHeapInt, pBlock);
    678 }
    679 RT_EXPORT_SYMBOL(RTHeapSimpleFree);
     693    rtHeapOffsetFreeBlock(pHeapInt, pBlock);
     694}
     695RT_EXPORT_SYMBOL(RTHeapOffsetFree);
    680696
    681697
     
    686702 * @param   pBlock         The memory block to free.
    687703 */
    688 static void rtHeapSimpleFreeBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, PRTHEAPSIMPLEBLOCK pBlock)
    689 {
    690     PRTHEAPSIMPLEFREE   pFree = (PRTHEAPSIMPLEFREE)pBlock;
    691     PRTHEAPSIMPLEFREE   pLeft;
    692     PRTHEAPSIMPLEFREE   pRight;
    693 
    694 #ifdef RTHEAPSIMPLE_STRICT
    695     rtHeapSimpleAssertAll(pHeapInt);
     704static void rtHeapOffsetFreeBlock(PRTHEAPOFFSETINTERNAL pHeapInt, PRTHEAPOFFSETBLOCK pBlock)
     705{
     706    PRTHEAPOFFSETFREE   pFree = (PRTHEAPOFFSETFREE)pBlock;
     707    PRTHEAPOFFSETFREE   pLeft;
     708    PRTHEAPOFFSETFREE   pRight;
     709
     710#ifdef RTHEAPOFFSET_STRICT
     711    rtHeapOffsetAssertAll(pHeapInt);
    696712#endif
    697713
     
    702718    pLeft = NULL;
    703719    pRight = NULL;
    704     if (pHeapInt->pFreeTail)
    705     {
    706         pRight = (PRTHEAPSIMPLEFREE)pFree->Core.pNext;
    707         while (pRight && !RTHEAPSIMPLEBLOCK_IS_FREE(&pRight->Core))
     720    if (pHeapInt->offFreeTail)
     721    {
     722        pRight = RTHEAPOFF_TO_PTR(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETFREE);
     723        while (pRight && !RTHEAPOFFSETBLOCK_IS_FREE(&pRight->Core))
    708724        {
    709725            ASSERT_BLOCK(pHeapInt, &pRight->Core);
    710             pRight = (PRTHEAPSIMPLEFREE)pRight->Core.pNext;
     726            pRight = RTHEAPOFF_TO_PTR(pHeapInt, pRight->Core.offNext, PRTHEAPOFFSETFREE);
    711727        }
    712728        if (!pRight)
    713             pLeft = pHeapInt->pFreeTail;
     729            pLeft = RTHEAPOFF_TO_PTR(pHeapInt, pHeapInt->offFreeTail, PRTHEAPOFFSETFREE);
    714730        else
    715731        {
    716732            ASSERT_BLOCK_FREE(pHeapInt, pRight);
    717             pLeft = pRight->pPrev;
     733            pLeft = RTHEAPOFF_TO_PTR(pHeapInt, pRight->offPrev, PRTHEAPOFFSETFREE);
    718734        }
    719735        if (pLeft)
     
    721737    }
    722738    AssertMsgReturnVoid(pLeft != pFree, ("Freed twice! pv=%p (pBlock=%p)\n", pBlock + 1, pBlock));
    723     ASSERT_L(pLeft, pFree);
     739    ASSERT_L(RTHEAPOFF_TO_OFF(pHeapInt, pLeft), RTHEAPOFF_TO_OFF(pHeapInt, pFree));
    724740    Assert(!pRight || (uintptr_t)pRight > (uintptr_t)pFree);
    725     Assert(!pLeft || pLeft->pNext == pRight);
     741    Assert(!pLeft || RTHEAPOFF_TO_PTR(pHeapInt, pLeft->offNext, PRTHEAPOFFSETFREE) == pRight);
    726742
    727743    /*
     
    730746    if (!pLeft)
    731747    {
    732         Assert(pRight == pHeapInt->pFreeHead);
    733         pFree->Core.fFlags |= RTHEAPSIMPLEBLOCK_FLAGS_FREE;
    734         pFree->pPrev = NULL;
    735         pFree->pNext = pRight;
     748        Assert(pRight == RTHEAPOFF_TO_PTR(pHeapInt, pHeapInt->offFreeHead, PRTHEAPOFFSETFREE));
     749        pFree->Core.fFlags |= RTHEAPOFFSETBLOCK_FLAGS_FREE;
     750        pFree->offPrev = 0;
     751        pFree->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pRight);
    736752        if (pRight)
    737             pRight->pPrev = pFree;
     753            pRight->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    738754        else
    739             pHeapInt->pFreeTail = pFree;
    740         pHeapInt->pFreeHead = pFree;
     755            pHeapInt->offFreeTail = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
     756        pHeapInt->offFreeHead = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    741757    }
    742758    else
     
    745761         * Can we merge with left hand free block?
    746762         */
    747         if (pLeft->Core.pNext == &pFree->Core)
     763        if (pLeft->Core.offNext == RTHEAPOFF_TO_OFF(pHeapInt, pFree))
    748764        {
    749             pLeft->Core.pNext = pFree->Core.pNext;
    750             if (pFree->Core.pNext)
    751                 pFree->Core.pNext->pPrev = &pLeft->Core;
     765            pLeft->Core.offNext = pFree->Core.offNext;
     766            if (pFree->Core.offNext)
     767                RTHEAPOFF_TO_PTR(pHeapInt, pFree->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pLeft);
    752768            pHeapInt->cbFree -= pLeft->cb;
    753769            pFree = pLeft;
     
    758774        else
    759775        {
    760             pFree->Core.fFlags |= RTHEAPSIMPLEBLOCK_FLAGS_FREE;
    761             pFree->pNext = pRight;
    762             pFree->pPrev = pLeft;
    763             pLeft->pNext = pFree;
     776            pFree->Core.fFlags |= RTHEAPOFFSETBLOCK_FLAGS_FREE;
     777            pFree->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pRight);
     778            pFree->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pLeft);
     779            pLeft->offNext = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    764780            if (pRight)
    765                 pRight->pPrev = pFree;
     781                pRight->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    766782            else
    767                 pHeapInt->pFreeTail = pFree;
     783                pHeapInt->offFreeTail = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    768784        }
    769785    }
     
    773789     */
    774790    if (    pRight
    775         &&  pRight->Core.pPrev == &pFree->Core)
     791        &&  pRight->Core.offPrev == RTHEAPOFF_TO_OFF(pHeapInt, pFree))
    776792    {
    777793        /* core */
    778         pFree->Core.pNext = pRight->Core.pNext;
    779         if (pRight->Core.pNext)
    780             pRight->Core.pNext->pPrev = &pFree->Core;
     794        pFree->Core.offNext = pRight->Core.offNext;
     795        if (pRight->Core.offNext)
     796            RTHEAPOFF_TO_PTR(pHeapInt, pRight->Core.offNext, PRTHEAPOFFSETBLOCK)->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    781797
    782798        /* free */
    783         pFree->pNext = pRight->pNext;
    784         if (pRight->pNext)
    785             pRight->pNext->pPrev = pFree;
     799        pFree->offNext = pRight->offNext;
     800        if (pRight->offNext)
     801            RTHEAPOFF_TO_PTR(pHeapInt, pRight->offNext, PRTHEAPOFFSETFREE)->offPrev = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    786802        else
    787             pHeapInt->pFreeTail = pFree;
     803            pHeapInt->offFreeTail = RTHEAPOFF_TO_OFF(pHeapInt, pFree);
    788804        pHeapInt->cbFree -= pRight->cb;
    789805    }
     
    792808     * Calculate the size and update free stats.
    793809     */
    794     pFree->cb = (pFree->Core.pNext ? (uintptr_t)pFree->Core.pNext : (uintptr_t)pHeapInt->pvEnd)
    795               - (uintptr_t)pFree - sizeof(RTHEAPSIMPLEBLOCK);
     810    pFree->cb = (pFree->Core.offNext ? pFree->Core.offNext : pHeapInt->cbHeap)
     811              - RTHEAPOFF_TO_OFF(pHeapInt, pFree) - sizeof(RTHEAPOFFSETBLOCK);
    796812    pHeapInt->cbFree += pFree->cb;
    797813    ASSERT_BLOCK_FREE(pHeapInt, pFree);
    798814
    799 #ifdef RTHEAPSIMPLE_STRICT
    800     rtHeapSimpleAssertAll(pHeapInt);
    801 #endif
    802 }
    803 
    804 
    805 #ifdef RTHEAPSIMPLE_STRICT
     815#ifdef RTHEAPOFFSET_STRICT
     816    rtHeapOffsetAssertAll(pHeapInt);
     817#endif
     818}
     819
     820
     821#ifdef RTHEAPOFFSET_STRICT
    806822/**
    807823 * Internal consistency check (relying on assertions).
    808824 * @param   pHeapInt
    809825 */
    810 static void rtHeapSimpleAssertAll(PRTHEAPSIMPLEINTERNAL pHeapInt)
    811 {
    812     PRTHEAPSIMPLEFREE pPrev = NULL;
    813     PRTHEAPSIMPLEFREE pPrevFree = NULL;
    814     PRTHEAPSIMPLEFREE pBlock;
    815     for (pBlock = (PRTHEAPSIMPLEFREE)(pHeapInt + 1);
     826static void rtHeapOffsetAssertAll(PRTHEAPOFFSETINTERNAL pHeapInt)
     827{
     828    PRTHEAPOFFSETFREE pPrev = NULL;
     829    PRTHEAPOFFSETFREE pPrevFree = NULL;
     830    PRTHEAPOFFSETFREE pBlock;
     831    for (pBlock = (PRTHEAPOFFSETFREE)(pHeapInt + 1);
    816832         pBlock;
    817          pBlock = (PRTHEAPSIMPLEFREE)pBlock->Core.pNext)
    818     {
    819         if (RTHEAPSIMPLEBLOCK_IS_FREE(&pBlock->Core))
     833         pBlock = RTHEAPOFF_TO_PTR(pHeapInt, pBlock->Core.offNext, PRTHEAPOFFSETFREE))
     834    {
     835        if (RTHEAPOFFSETBLOCK_IS_FREE(&pBlock->Core))
    820836        {
    821837            ASSERT_BLOCK_FREE(pHeapInt, pBlock);
    822             Assert(pBlock->pPrev == pPrevFree);
    823             Assert(pPrevFree || pHeapInt->pFreeHead == pBlock);
     838            Assert(pBlock->offPrev == RTHEAPOFF_TO_OFF(pHeapInt, pPrevFree));
     839            Assert(pPrevFree || pHeapInt->offFreeHead == RTHEAPOFF_TO_OFF(pHeapInt, pBlock));
    824840            pPrevFree = pBlock;
    825841        }
    826842        else
    827843            ASSERT_BLOCK_USED(pHeapInt, &pBlock->Core);
    828         Assert(!pPrev || pPrev == (PRTHEAPSIMPLEFREE)pBlock->Core.pPrev);
     844        Assert(!pPrev || RTHEAPOFF_TO_OFF(pHeapInt, pPrev) == pBlock->Core.offPrev);
    829845        pPrev = pBlock;
    830846    }
    831     Assert(pHeapInt->pFreeTail == pPrevFree);
    832 }
    833 #endif
    834 
    835 
    836 RTDECL(size_t) RTHeapSimpleSize(RTHEAPSIMPLE hHeap, void *pv)
    837 {
    838     PRTHEAPSIMPLEINTERNAL pHeapInt;
    839     PRTHEAPSIMPLEBLOCK pBlock;
     847    Assert(pHeapInt->offFreeTail == RTHEAPOFF_TO_OFF(pHeapInt, pPrevFree));
     848}
     849#endif
     850
     851
     852RTDECL(size_t) RTHeapOffsetSize(RTHEAPOFFSET hHeap, void *pv)
     853{
     854    PRTHEAPOFFSETINTERNAL pHeapInt;
     855    PRTHEAPOFFSETBLOCK pBlock;
    840856    size_t cbBlock;
    841857
     
    846862        return 0;
    847863    AssertPtrReturn(pv, 0);
    848     AssertReturn(RT_ALIGN_P(pv, RTHEAPSIMPLE_ALIGNMENT) == pv, 0);
     864    AssertReturn(RT_ALIGN_P(pv, RTHEAPOFFSET_ALIGNMENT) == pv, 0);
    849865
    850866    /*
    851867     * Get the block and heap. If in strict mode, validate these.
    852868     */
    853     pBlock = (PRTHEAPSIMPLEBLOCK)pv - 1;
    854     pHeapInt = pBlock->pHeap;
     869    pBlock = (PRTHEAPOFFSETBLOCK)pv - 1;
     870    pHeapInt = RTHEAPOFF_GET_ANCHOR(pBlock);
    855871    ASSERT_BLOCK_USED(pHeapInt, pBlock);
    856872    ASSERT_ANCHOR(pHeapInt);
    857     Assert(pHeapInt == (PRTHEAPSIMPLEINTERNAL)hHeap || !hHeap);
     873    Assert(pHeapInt == (PRTHEAPOFFSETINTERNAL)hHeap || !hHeap);
    858874
    859875    /*
    860876     * Calculate the block size.
    861877     */
    862     cbBlock = (pBlock->pNext ? (uintptr_t)pBlock->pNext : (uintptr_t)pHeapInt->pvEnd)
    863             - (uintptr_t)pBlock- sizeof(RTHEAPSIMPLEBLOCK);
     878    cbBlock = (pBlock->offNext ? pBlock->offNext : pHeapInt->cbHeap)
     879            - RTHEAPOFF_TO_OFF(pHeapInt, pBlock) - sizeof(RTHEAPOFFSETBLOCK);
    864880    return cbBlock;
    865881}
    866 RT_EXPORT_SYMBOL(RTHeapSimpleSize);
    867 
    868 
    869 RTDECL(size_t) RTHeapSimpleGetHeapSize(RTHEAPSIMPLE hHeap)
    870 {
    871     PRTHEAPSIMPLEINTERNAL pHeapInt;
    872 
    873     if (hHeap == NIL_RTHEAPSIMPLE)
     882RT_EXPORT_SYMBOL(RTHeapOffsetSize);
     883
     884
     885RTDECL(size_t) RTHeapOffsetGetHeapSize(RTHEAPOFFSET hHeap)
     886{
     887    PRTHEAPOFFSETINTERNAL pHeapInt;
     888
     889    if (hHeap == NIL_RTHEAPOFFSET)
    874890        return 0;
    875891
     
    879895    return pHeapInt->cbHeap;
    880896}
    881 RT_EXPORT_SYMBOL(RTHeapSimpleGetHeapSize);
    882 
    883 
    884 RTDECL(size_t) RTHeapSimpleGetFreeSize(RTHEAPSIMPLE hHeap)
    885 {
    886     PRTHEAPSIMPLEINTERNAL pHeapInt;
    887 
    888     if (hHeap == NIL_RTHEAPSIMPLE)
     897RT_EXPORT_SYMBOL(RTHeapOffsetGetHeapSize);
     898
     899
     900RTDECL(size_t) RTHeapOffsetGetFreeSize(RTHEAPOFFSET hHeap)
     901{
     902    PRTHEAPOFFSETINTERNAL pHeapInt;
     903
     904    if (hHeap == NIL_RTHEAPOFFSET)
    889905        return 0;
    890906
     
    894910    return pHeapInt->cbFree;
    895911}
    896 RT_EXPORT_SYMBOL(RTHeapSimpleGetFreeSize);
    897 
    898 
    899 RTDECL(void) RTHeapSimpleDump(RTHEAPSIMPLE hHeap, PFNRTHEAPSIMPLEPRINTF pfnPrintf)
    900 {
    901     PRTHEAPSIMPLEINTERNAL pHeapInt = (PRTHEAPSIMPLEINTERNAL)hHeap;
    902     PRTHEAPSIMPLEFREE pBlock;
    903 
    904     pfnPrintf("**** Dumping Heap %p - cbHeap=%zx cbFree=%zx ****\n",
     912RT_EXPORT_SYMBOL(RTHeapOffsetGetFreeSize);
     913
     914
     915RTDECL(void) RTHeapOffsetDump(RTHEAPOFFSET hHeap, PFNRTHEAPOFFSETPRINTF pfnPrintf)
     916{
     917    PRTHEAPOFFSETINTERNAL pHeapInt = (PRTHEAPOFFSETINTERNAL)hHeap;
     918    PRTHEAPOFFSETFREE pBlock;
     919
     920    pfnPrintf("**** Dumping Heap %p - cbHeap=%x cbFree=%x ****\n",
    905921              hHeap, pHeapInt->cbHeap, pHeapInt->cbFree);
    906922
    907     for (pBlock = (PRTHEAPSIMPLEFREE)(pHeapInt + 1);
     923    for (pBlock = (PRTHEAPOFFSETFREE)(pHeapInt + 1);
    908924         pBlock;
    909          pBlock = (PRTHEAPSIMPLEFREE)pBlock->Core.pNext)
    910     {
    911         size_t cb = (pBlock->pNext ? (uintptr_t)pBlock->Core.pNext : (uintptr_t)pHeapInt->pvEnd)
    912                   - (uintptr_t)pBlock - sizeof(RTHEAPSIMPLEBLOCK);
    913         if (RTHEAPSIMPLEBLOCK_IS_FREE(&pBlock->Core))
    914             pfnPrintf("%p  %06x FREE pNext=%p pPrev=%p fFlags=%#x cb=%#06x : cb=%#06x pNext=%p pPrev=%p\n",
    915                       pBlock, (uintptr_t)pBlock - (uintptr_t)(pHeapInt + 1), pBlock->Core.pNext, pBlock->Core.pPrev, pBlock->Core.fFlags, cb,
    916                       pBlock->cb, pBlock->pNext, pBlock->pPrev);
     925         pBlock = RTHEAPOFF_TO_PTR(pHeapInt, pBlock->Core.offNext, PRTHEAPOFFSETFREE))
     926    {
     927        size_t cb = (pBlock->offNext ? pBlock->Core.offNext : pHeapInt->cbHeap)
     928                  - RTHEAPOFF_TO_OFF(pHeapInt, pBlock) - sizeof(RTHEAPOFFSETBLOCK);
     929        if (RTHEAPOFFSETBLOCK_IS_FREE(&pBlock->Core))
     930            pfnPrintf("%p  %06x FREE offNext=%06x offPrev=%06x fFlags=%#x cb=%#06x : cb=%#06x offNext=%06x offPrev=%06x\n",
     931                      pBlock, pBlock->Core.offSelf, pBlock->Core.offNext, pBlock->Core.offPrev, pBlock->Core.fFlags, cb,
     932                      pBlock->cb, pBlock->offNext, pBlock->offPrev);
    917933        else
    918             pfnPrintf("%p  %06x USED pNext=%p pPrev=%p fFlags=%#x cb=%#06x\n",
    919                       pBlock, (uintptr_t)pBlock - (uintptr_t)(pHeapInt + 1), pBlock->Core.pNext, pBlock->Core.pPrev, pBlock->Core.fFlags, cb);
     934            pfnPrintf("%p  %06x USED offNext=%06x offPrev=%06x fFlags=%#x cb=%#06x\n",
     935                      pBlock, pBlock->Core.offSelf, pBlock->Core.offNext, pBlock->Core.offPrev, pBlock->Core.fFlags, cb);
    920936    }
    921937    pfnPrintf("**** Done dumping Heap %p ****\n", hHeap);
    922938}
    923 RT_EXPORT_SYMBOL(RTHeapSimpleDump);
    924 
     939RT_EXPORT_SYMBOL(RTHeapOffsetDump);
     940
  • trunk/src/VBox/Runtime/include/internal/magics.h

    r23625 r25059  
    5757/** Magic number for RTHANDLETABLEINT::u32Magic. (Hitomi Kanehara) */
    5858#define RTHANDLETABLE_MAGIC         0x19830808
    59 /** Magic number for RTHEAPSIMPLEINTERNAL::u32Magic. (Kyoichi Katayama) */
     59/** Magic number for RTHEAPOFFSETINTERNAL::u32Magic. (Neal Town Stephenson) */
     60#define RTHEAPOFFSET_MAGIC          0x19591031
     61/** Magic number for RTHEAPSIMPLEINTERNAL::uMagic. (Kyoichi Katayama) */
    6062#define RTHEAPSIMPLE_MAGIC          0x19590105
    6163/** The magic value for RTLDRMODINTERNAL::u32Magic. (Alan Moore) */
  • trunk/src/VBox/Runtime/testcase/Makefile.kmk

    r25057 r25059  
    6868        tstGetOpt \
    6969        tstHandleTable \
     70        tstRTHeapOffset \
    7071        tstRTHeapSimple \
    7172        tstInlineAsm \
     
    201202tstHandleTable_SOURCES = tstHandleTable.cpp
    202203
     204tstRTHeapOffset_TEMPLATE = VBOXR3TSTEXE
     205tstRTHeapOffset_SOURCES = tstRTHeapOffset.cpp
     206
    203207tstRTHeapSimple_TEMPLATE = VBOXR3TSTEXE
    204208tstRTHeapSimple_SOURCES = tstRTHeapSimple.cpp
  • trunk/src/VBox/Runtime/testcase/tstRTHeapOffset.cpp

    r25057 r25059  
    11/* $Id$ */
    22/** @file
    3  * IPRT Testcase - Simple Heap.
     3 * IPRT Testcase - Offset Based Heap.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4949     */
    5050    RTTEST hTest;
    51     int rc = RTTestInitAndCreate("tstRTHeapSimple", &hTest);
     51    int rc = RTTestInitAndCreate("tstRTHeapOffset", &hTest);
    5252    if (rc)
    5353        return rc;
     
    5959    RTTestSub(hTest, "Basics");
    6060    static uint8_t s_abMem[128*1024];
    61     RTHEAPSIMPLE Heap;
    62     RTTESTI_CHECK_RC(rc = RTHeapSimpleInit(&Heap, &s_abMem[1], sizeof(s_abMem) - 1), VINF_SUCCESS);
    63     if (RT_FAILURE(rc)) 
     61    RTHEAPOFFSET Heap;
     62    RTTESTI_CHECK_RC(rc = RTHeapOffsetInit(&Heap, &s_abMem[1], sizeof(s_abMem) - 1), VINF_SUCCESS);
     63    if (RT_FAILURE(rc))
    6464        return RTTestSummaryAndDestroy(hTest);
    6565
     
    6767     * Try allocate.
    6868     */
    69     static struct TstHeapSimpleOps
     69    static struct TstHeapOffsetOps
    7070    {
    7171        size_t      cb;
     
    9898        {        16,          0,    NULL,  7 },
    9999    };
    100     unsigned i;                                   
    101     RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf); /** @todo Add some detail info output with a signature identical to RTPrintf. */
    102     size_t cbBefore = RTHeapSimpleGetFreeSize(Heap);
     100    unsigned i;
     101    RTHeapOffsetDump(Heap, (PFNRTHEAPOFFSETPRINTF)RTPrintf); /** @todo Add some detail info output with a signature identical to RTPrintf. */
     102    size_t cbBefore = RTHeapOffsetGetFreeSize(Heap);
    103103    static char szFill[] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    104104
     
    106106    for (i = 0; i < RT_ELEMENTS(s_aOps); i++)
    107107    {
    108         s_aOps[i].pvAlloc = RTHeapSimpleAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment);
    109         RTTESTI_CHECK_MSG(s_aOps[i].pvAlloc, ("RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i));
     108        s_aOps[i].pvAlloc = RTHeapOffsetAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment);
     109        RTTESTI_CHECK_MSG(s_aOps[i].pvAlloc, ("RTHeapOffsetAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i));
    110110        if (!s_aOps[i].pvAlloc)
    111111            return RTTestSummaryAndDestroy(hTest);
     
    113113        memset(s_aOps[i].pvAlloc, szFill[i], s_aOps[i].cb);
    114114        RTTESTI_CHECK_MSG(RT_ALIGN_P(s_aOps[i].pvAlloc, (s_aOps[i].uAlignment ? s_aOps[i].uAlignment : 8)) == s_aOps[i].pvAlloc,
    115                           ("RTHeapSimpleAlloc(%p, %#x, %#x,) -> %p\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i));
     115                          ("RTHeapOffsetAlloc(%p, %#x, %#x,) -> %p\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i));
    116116        if (!s_aOps[i].pvAlloc)
    117117            return RTTestSummaryAndDestroy(hTest);
     
    124124            continue;
    125125        //RTPrintf("debug: i=%d pv=%#x cb=%#zx align=%#zx cbReal=%#zx\n", i, s_aOps[i].pvAlloc,
    126         //         s_aOps[i].cb, s_aOps[i].uAlignment, RTHeapSimpleSize(Heap, s_aOps[i].pvAlloc));
    127         size_t cbBeforeSub = RTHeapSimpleGetFreeSize(Heap);
    128         RTHeapSimpleFree(Heap, s_aOps[i].pvAlloc);
    129         size_t cbAfterSubFree = RTHeapSimpleGetFreeSize(Heap);
     126        //         s_aOps[i].cb, s_aOps[i].uAlignment, RTHeapOffsetSize(Heap, s_aOps[i].pvAlloc));
     127        size_t cbBeforeSub = RTHeapOffsetGetFreeSize(Heap);
     128        RTHeapOffsetFree(Heap, s_aOps[i].pvAlloc);
     129        size_t cbAfterSubFree = RTHeapOffsetGetFreeSize(Heap);
    130130
    131131        void *pv;
    132         pv = RTHeapSimpleAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment);
    133         RTTESTI_CHECK_MSG(pv, ("RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i));
     132        pv = RTHeapOffsetAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment);
     133        RTTESTI_CHECK_MSG(pv, ("RTHeapOffsetAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i));
    134134        if (!pv)
    135135            return RTTestSummaryAndDestroy(hTest);
    136         //RTPrintf("debug: i=%d pv=%p cbReal=%#zx cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx \n", i, pv, RTHeapSimpleSize(Heap, pv),
    137         //         cbBeforeSub, cbAfterSubFree, RTHeapSimpleGetFreeSize(Heap));
     136        //RTPrintf("debug: i=%d pv=%p cbReal=%#zx cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx \n", i, pv, RTHeapOffsetSize(Heap, pv),
     137        //         cbBeforeSub, cbAfterSubFree, RTHeapOffsetGetFreeSize(Heap));
     138
    138139        if (pv != s_aOps[i].pvAlloc)
    139140            RTTestIPrintf(RTTESTLVL_ALWAYS, "Warning: Free+Alloc returned different address. new=%p old=%p i=%d\n", pv, s_aOps[i].pvAlloc, i);
    140141        s_aOps[i].pvAlloc = pv;
    141         size_t cbAfterSubAlloc = RTHeapSimpleGetFreeSize(Heap);
     142        size_t cbAfterSubAlloc = RTHeapOffsetGetFreeSize(Heap);
    142143        if (cbBeforeSub != cbAfterSubAlloc)
    143144        {
     
    147148        }
    148149    }
    149    
     150
    150151    /* make a copy of the heap and the to-be-freed list. */
    151152    static uint8_t s_abMemCopy[sizeof(s_abMem)];
    152153    memcpy(s_abMemCopy, s_abMem, sizeof(s_abMem));
    153154    uintptr_t    offDelta  = (uintptr_t)&s_abMemCopy[0] - (uintptr_t)&s_abMem[0];
    154     RTHEAPSIMPLE hHeapCopy = (RTHEAPSIMPLE)((uintptr_t)Heap + offDelta);
    155     static struct TstHeapSimpleOps s_aOpsCopy[RT_ELEMENTS(s_aOps)];
     155    RTHEAPOFFSET hHeapCopy = (RTHEAPOFFSET)((uintptr_t)Heap + offDelta);
     156    static struct TstHeapOffsetOps s_aOpsCopy[RT_ELEMENTS(s_aOps)];
    156157    memcpy(&s_aOpsCopy[0], &s_aOps[0], sizeof(s_aOps));
    157158
     
    166167                ||  !s_aOps[j].pvAlloc)
    167168                continue;
    168             //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapSimpleGetFreeSize(Heap), s_aOps[j].cb, s_aOps[j].pvAlloc);
    169             RTHeapSimpleFree(Heap, s_aOps[j].pvAlloc);
     169            //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapOffsetGetFreeSize(Heap), s_aOps[j].cb, s_aOps[j].pvAlloc);
     170            RTHeapOffsetFree(Heap, s_aOps[j].pvAlloc);
    170171            s_aOps[j].pvAlloc = NULL;
    171172            cFreed++;
     
    173174    }
    174175    RTTESTI_CHECK(cFreed == RT_ELEMENTS(s_aOps));
    175     RTTestIPrintf(RTTESTLVL_ALWAYS, "i=done free=%d\n", RTHeapSimpleGetFreeSize(Heap));
     176    RTTestIPrintf(RTTESTLVL_ALWAYS, "i=done free=%d\n", RTHeapOffsetGetFreeSize(Heap));
    176177
    177178    /* check that we're back at the right amount of free memory. */
    178     size_t cbAfter = RTHeapSimpleGetFreeSize(Heap);
     179    size_t cbAfter = RTHeapOffsetGetFreeSize(Heap);
    179180    if (cbBefore != cbAfter)
    180181    {
    181         RTTestIPrintf(RTTESTLVL_ALWAYS, 
     182        RTTestIPrintf(RTTESTLVL_ALWAYS,
    182183                      "Warning: Either we've split out an alignment chunk at the start, or we've got\n"
    183184                      "         an alloc/free accounting bug: cbBefore=%d cbAfter=%d\n", cbBefore, cbAfter);
    184         RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf);
     185        RTHeapOffsetDump(Heap, (PFNRTHEAPOFFSETPRINTF)RTPrintf);
    185186    }
    186187
    187188    /* relocate and free the bits in heap2 now. */
    188     RTTestSub(hTest, "RTHeapSimpleRelocate");
    189     rc = RTHeapSimpleRelocate(hHeapCopy, offDelta);
    190     RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
    191     if (RT_FAILURE(rc))
    192     {
    193         /* free it in a specific order. */
    194         int cFreed2 = 0;
    195         for (i = 0; i < RT_ELEMENTS(s_aOpsCopy); i++)
     189    RTTestSub(hTest, "Relocated Heap");
     190    /* free it in a specific order. */
     191    int cFreed2 = 0;
     192    for (i = 0; i < RT_ELEMENTS(s_aOpsCopy); i++)
     193    {
     194        unsigned j;
     195        for (j = 0; j < RT_ELEMENTS(s_aOpsCopy); j++)
    196196        {
    197             unsigned j;
    198             for (j = 0; j < RT_ELEMENTS(s_aOpsCopy); j++)
    199             {
    200                 if (    s_aOpsCopy[j].iFreeOrder != i
    201                     ||  !s_aOpsCopy[j].pvAlloc)
    202                     continue;
    203                 //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapSimpleGetFreeSize(hHeapCopy), s_aOpsCopy[j].cb, s_aOpsCopy[j].pvAlloc);
    204                 RTHeapSimpleFree(hHeapCopy, (uint8_t *)s_aOpsCopy[j].pvAlloc + offDelta);
    205                 s_aOpsCopy[j].pvAlloc = NULL;
    206                 cFreed++;
    207             }
     197            if (    s_aOpsCopy[j].iFreeOrder != i
     198                ||  !s_aOpsCopy[j].pvAlloc)
     199                continue;
     200            //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapOffsetGetFreeSize(hHeapCopy), s_aOpsCopy[j].cb, s_aOpsCopy[j].pvAlloc);
     201            RTHeapOffsetFree(hHeapCopy, (uint8_t *)s_aOpsCopy[j].pvAlloc + offDelta);
     202            s_aOpsCopy[j].pvAlloc = NULL;
     203            cFreed2++;
    208204        }
    209         RTTESTI_CHECK(cFreed == RT_ELEMENTS(s_aOpsCopy));
    210    
    211         /* check that we're back at the right amount of free memory. */
    212         size_t cbAfterCopy = RTHeapSimpleGetFreeSize(hHeapCopy);
    213         RTTESTI_CHECK_MSG(cbAfterCopy == cbAfter, ("cbAfterCopy=%zu cbAfter=%zu\n", cbAfterCopy, cbAfter));
    214     }
     205    }
     206    RTTESTI_CHECK(cFreed2 == RT_ELEMENTS(s_aOpsCopy));
     207
     208    /* check that we're back at the right amount of free memory. */
     209    size_t cbAfterCopy = RTHeapOffsetGetFreeSize(hHeapCopy);
     210    RTTESTI_CHECK_MSG(cbAfterCopy == cbAfter, ("cbAfterCopy=%zu cbAfter=%zu\n", cbAfterCopy, cbAfter));
    215211
    216212
  • trunk/src/VBox/Runtime/testcase/tstRTHeapSimple.cpp

    r25057 r25059  
    6161    RTHEAPSIMPLE Heap;
    6262    RTTESTI_CHECK_RC(rc = RTHeapSimpleInit(&Heap, &s_abMem[1], sizeof(s_abMem) - 1), VINF_SUCCESS);
    63     if (RT_FAILURE(rc)) 
     63    if (RT_FAILURE(rc))
    6464        return RTTestSummaryAndDestroy(hTest);
    6565
     
    9898        {        16,          0,    NULL,  7 },
    9999    };
    100     unsigned i;                                   
     100    unsigned i;
    101101    RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf); /** @todo Add some detail info output with a signature identical to RTPrintf. */
    102102    size_t cbBefore = RTHeapSimpleGetFreeSize(Heap);
     
    147147        }
    148148    }
    149    
     149
    150150    /* make a copy of the heap and the to-be-freed list. */
    151151    static uint8_t s_abMemCopy[sizeof(s_abMem)];
     
    179179    if (cbBefore != cbAfter)
    180180    {
    181         RTTestIPrintf(RTTESTLVL_ALWAYS, 
     181        RTTestIPrintf(RTTESTLVL_ALWAYS,
    182182                      "Warning: Either we've split out an alignment chunk at the start, or we've got\n"
    183183                      "         an alloc/free accounting bug: cbBefore=%d cbAfter=%d\n", cbBefore, cbAfter);
     
    189189    rc = RTHeapSimpleRelocate(hHeapCopy, offDelta);
    190190    RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
    191     if (RT_FAILURE(rc))
     191    if (RT_SUCCESS(rc))
    192192    {
    193193        /* free it in a specific order. */
     
    204204                RTHeapSimpleFree(hHeapCopy, (uint8_t *)s_aOpsCopy[j].pvAlloc + offDelta);
    205205                s_aOpsCopy[j].pvAlloc = NULL;
    206                 cFreed++;
     206                cFreed2++;
    207207            }
    208208        }
    209         RTTESTI_CHECK(cFreed == RT_ELEMENTS(s_aOpsCopy));
    210    
     209        RTTESTI_CHECK(cFreed2 == RT_ELEMENTS(s_aOpsCopy));
     210
    211211        /* check that we're back at the right amount of free memory. */
    212212        size_t cbAfterCopy = RTHeapSimpleGetFreeSize(hHeapCopy);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette