VirtualBox

Changeset 104109 in vbox


Ignore:
Timestamp:
Mar 28, 2024 10:19:21 PM (8 months ago)
Author:
vboxsync
Message:

VMM/IEM: Kicked out the RTHeapSimple based exec mem allocator code as it is unsuitable for darwin. bugref:10370

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r104108 r104109  
    5959#include <VBox/param.h>
    6060#include <iprt/assert.h>
    61 #include <iprt/heap.h>
    6261#include <iprt/mem.h>
    6362#include <iprt/string.h>
     
    142141*   Executable Memory Allocator                                                                                                  *
    143142*********************************************************************************************************************************/
    144 /** @def IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    145  * Use an alternative chunk sub-allocator that does store internal data
    146  * in the chunk.
    147  *
    148  * Using the RTHeapSimple is not practial on newer darwin systems where
    149  * RTMEM_PROT_WRITE and RTMEM_PROT_EXEC are mutually exclusive in process
    150  * memory.  We would have to change the protection of the whole chunk for
    151  * every call to RTHeapSimple, which would be rather expensive.
    152  *
    153  * This alternative implemenation let restrict page protection modifications
    154  * to the pages backing the executable memory we just allocated.
    155  */
    156 #define IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    157143/** The chunk sub-allocation unit size in bytes. */
    158144#define IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE      128
     
    274260typedef struct IEMEXECMEMCHUNK
    275261{
    276 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    277262    /** Number of free items in this chunk. */
    278263    uint32_t                cFreeUnits;
    279264    /** Hint were to start searching for free space in the allocation bitmap. */
    280265    uint32_t                idxFreeHint;
    281 #else
    282     /** The heap handle. */
    283     RTHEAPSIMPLE            hHeap;
    284 #endif
    285266    /** Pointer to the chunk. */
    286267    void                   *pvChunk;
     
    334315    uint64_t                cbAllocated;
    335316
    336 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    337317    /** Pointer to the allocation bitmaps for all the chunks (follows aChunks).
    338318     *
     
    348328     * portion corresponding to an chunk). */
    349329    uint32_t                cBitmapElementsPerChunk;
    350 # ifdef VBOX_WITH_STATISTICS
     330#ifdef VBOX_WITH_STATISTICS
    351331    STAMPROFILE             StatAlloc;
    352 # endif
    353 #else
    354     /** @name Tweaks to get 64 byte aligned allocats w/o unnecessary fragmentation.
    355      * @{ */
    356     /** The size of the heap internal block header.   This is used to adjust the
    357      * request memory size to make sure there is exacly enough room for a header at
    358      * the end of the blocks we allocate before the next 64 byte alignment line. */
    359     uint32_t                cbHeapBlockHdr;
    360     /** The size of initial heap allocation required make sure the first
    361      *  allocation is correctly aligned. */
    362     uint32_t                cbHeapAlignTweak;
    363     /** The alignment tweak allocation address. */
    364     void                   *pvAlignTweak;
    365     /** @} */
    366332#endif
    367333
     
    418384    pExecMemAllocator->cAllocations += 1;
    419385    pExecMemAllocator->cbAllocated  += cbReq;
    420 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    421386    pExecMemAllocator->cbFree       -= cbReq;
    422 #else
    423     pExecMemAllocator->cbFree       -= RT_ALIGN_32(cbReq, 64);
    424 #endif
    425387    pExecMemAllocator->idxChunkHint  = idxChunk;
    426388
     
    445407
    446408
    447 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    448409static void *iemExecMemAllocatorAllocInChunkInt(PIEMEXECMEMALLOCATOR pExecMemAllocator, uint64_t *pbmAlloc, uint32_t idxFirst,
    449410                                                uint32_t cToScan, uint32_t cReqUnits, uint32_t idxChunk, PIEMTB pTb)
     
    497458    return NULL;
    498459}
    499 #endif /* IEMEXECMEM_USE_ALT_SUB_ALLOCATOR */
    500460
    501461
     
    503463iemExecMemAllocatorAllocInChunk(PIEMEXECMEMALLOCATOR pExecMemAllocator, uint32_t idxChunk, uint32_t cbReq, PIEMTB pTb)
    504464{
    505 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    506465    /*
    507466     * Figure out how much to allocate.
    508467     */
    509 # ifdef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
     468#ifdef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
    510469    uint32_t const cReqUnits = (cbReq + sizeof(IEMEXECMEMALLOCHDR) + IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE - 1)
    511 # else
     470#else
    512471    uint32_t const cReqUnits = (cbReq + IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE - 1)
    513 # endif
     472#endif
    514473                            >> IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT;
    515474    if (cReqUnits <= pExecMemAllocator->aChunks[idxChunk].cFreeUnits)
     
    529488                                                  cReqUnits, idxChunk, pTb);
    530489    }
    531 #else
    532     void *pvRet = RTHeapSimpleAlloc(pExecMemAllocator->aChunks[idxChunk].hHeap, cbReq, 32);
    533     if (pvRet)
    534         return iemExecMemAllocatorAllocTailCode(pExecMemAllocator, pvRet, cbReq, idxChunk);
    535     RT_NOREF(pTb);
    536 #endif
    537490    return NULL;
    538 
    539491}
    540492
     
    558510
    559511    /*
    560      * Adjust the request size so it'll fit the allocator alignment/whatnot.
    561      *
    562      * For the RTHeapSimple allocator this means to follow the logic described
    563      * in iemExecMemAllocatorGrow and attempt to allocate it from one of the
    564      * existing chunks if we think we've got sufficient free memory around.
    565      *
    566      * While for the alternative one we just align it up to a whole unit size.
    567      */
    568 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
     512     * Adjust the request size so it'll accomodate a header, the aligned it
     513     * up to a whole unit size.
     514     */
     515/** @todo this aint right wrt header. See iemExecMemAllocatorAllocInChunk   */
    569516    cbReq = RT_ALIGN_32(cbReq, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE);
    570 #else
    571     cbReq = RT_ALIGN_32(cbReq + pExecMemAllocator->cbHeapBlockHdr, 64) - pExecMemAllocator->cbHeapBlockHdr;
    572 #endif
    573 
    574517    for (unsigned iIteration = 0;; iIteration++)
    575518    {
     
    660603    Assert(pExecMemAllocator && pExecMemAllocator->uMagic == IEMEXECMEMALLOCATOR_MAGIC);
    661604    AssertPtr(pv);
    662 #ifndef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    663     Assert(!((uintptr_t)pv & 63));
    664 #else
    665 # ifndef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
     605#ifndef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
    666606    Assert(!((uintptr_t)pv & (IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE - 1)));
    667 # else
     607
     608    /* Align the size as we did when allocating the block. */
     609    cb = RT_ALIGN_Z(cb, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE);
     610
     611#else
    668612    PIEMEXECMEMALLOCHDR pHdr = (PIEMEXECMEMALLOCHDR)pv - 1;
    669613    Assert(!((uintptr_t)pHdr & (IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE - 1)));
     
    672616    AssertReturnVoid(idxChunk < pExecMemAllocator->cChunks);
    673617    pv = pHdr;
    674 # endif
    675 #endif
    676 
    677     /* Align the size as we did when allocating the block. */
    678 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    679     cb = RT_ALIGN_Z(cb, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE);
    680 #else
    681     cb = RT_ALIGN_Z(cb + pExecMemAllocator->cbHeapBlockHdr, 64) - pExecMemAllocator->cbHeapBlockHdr;
     618
     619    /* Adjust and align the size to cover the whole allocation area. */
     620    cb = RT_ALIGN_Z(cb + sizeof(*pHdr), IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE);
    682621#endif
    683622
    684623    /* Free it / assert sanity. */
    685 #if defined(VBOX_STRICT) || defined(IEMEXECMEM_USE_ALT_SUB_ALLOCATOR)
    686624    bool           fFound  = false;
    687625    uint32_t const cbChunk = pExecMemAllocator->cbChunk;
    688 # ifndef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
     626#ifndef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
    689627    uint32_t const cChunks = pExecMemAllocator->cChunks;
    690628    for (uint32_t idxChunk = 0; idxChunk < cChunks; idxChunk++)
    691 # endif
     629#endif
    692630    {
    693631        uintptr_t const offChunk = (uintptr_t)pv - (uintptr_t)pExecMemAllocator->aChunks[idxChunk].pvChunk;
     
    695633        if (fFound)
    696634        {
    697 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    698635            uint32_t const idxFirst  = (uint32_t)offChunk >> IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT;
    699636            uint32_t const cReqUnits = (uint32_t)cb       >> IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT;
     
    705642                AssertReturnVoid(ASMBitTest(pbmAlloc, idxFirst + i));
    706643            ASMBitClearRange(pbmAlloc, idxFirst, idxFirst + cReqUnits);
    707 # ifdef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
     644#ifdef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
    708645            pHdr->uMagic    = 0;
    709646            pHdr->idxChunk  = 0;
    710647            pHdr->pTb       = NULL;
    711 # endif
     648#endif
    712649            pExecMemAllocator->aChunks[idxChunk].cFreeUnits  += cReqUnits;
    713650            pExecMemAllocator->aChunks[idxChunk].idxFreeHint  = idxFirst;
     
    718655            pExecMemAllocator->cAllocations -= 1;
    719656            return;
    720 #else
    721             Assert(RTHeapSimpleSize(pExecMemAllocator->aChunks[idxChunk].hHeap, pv) == cb);
    722             break;
    723 #endif
    724657        }
    725658    }
    726 # ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    727659    AssertFailed();
    728 # else
    729     Assert(fFound);
    730 # endif
    731 #endif
    732 
    733 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    734     /* Update stats while cb is freshly calculated.*/
    735     pExecMemAllocator->cbAllocated  -= cb;
    736     pExecMemAllocator->cbFree       += RT_ALIGN_Z(cb, 64);
    737     pExecMemAllocator->cAllocations -= 1;
    738 
    739     /* Free it. */
    740     RTHeapSimpleFree(NIL_RTHEAPSIMPLE, pv);
    741 #endif
    742660}
    743661
     
    808726    unsigned const cbUnwindInfo     = sizeof(s_aOpcodes) + RT_UOFFSETOF(IMAGE_UNWIND_INFO, aOpcodes);
    809727    unsigned const cbNeeded         = sizeof(IMAGE_RUNTIME_FUNCTION_ENTRY) * cFunctionEntries + cbUnwindInfo;
    810 #  ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    811     unsigned const cbNeededAligned  = RT_ALIGN_32(cbNeeded, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE);
    812728    PIMAGE_RUNTIME_FUNCTION_ENTRY const paFunctions
    813         = (PIMAGE_RUNTIME_FUNCTION_ENTRY)iemExecMemAllocatorAllocInChunk(pExecMemAllocator, idxChunk, cbNeededAligned, NULL);
    814 #  else
    815     unsigned const cbNeededAligned  = RT_ALIGN_32(cbNeeded + pExecMemAllocator->cbHeapBlockHdr, 64)
    816                                     - pExecMemAllocator->cbHeapBlockHdr;
    817     PIMAGE_RUNTIME_FUNCTION_ENTRY const paFunctions = (PIMAGE_RUNTIME_FUNCTION_ENTRY)RTHeapSimpleAlloc(hHeap, cbNeededAligned,
    818                                                                                                        32 /*cbAlignment*/);
    819 #  endif
     729        = (PIMAGE_RUNTIME_FUNCTION_ENTRY)iemExecMemAllocatorAllocInChunk(pExecMemAllocator, idxChunk, cbNeeded, NULL);
    820730    AssertReturn(paFunctions, VERR_INTERNAL_ERROR_5);
    821731    pExecMemAllocator->aChunks[idxChunk].pvUnwindInfo = paFunctions;
     
    1052962     * This seems to work best with ET_DYN.
    1053963     */
    1054     unsigned const cbNeeded        = sizeof(GDBJITSYMFILE);
    1055 #   ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    1056     unsigned const cbNeededAligned = RT_ALIGN_32(cbNeeded, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE);
    1057964    GDBJITSYMFILE * const pSymFile = (GDBJITSYMFILE *)iemExecMemAllocatorAllocInChunk(pExecMemAllocator, idxChunk,
    1058                                                                                       cbNeededAligned, NULL);
    1059 #   else
    1060     unsigned const cbNeededAligned = RT_ALIGN_32(cbNeeded + pExecMemAllocator->cbHeapBlockHdr, 64)
    1061                                    - pExecMemAllocator->cbHeapBlockHdr;
    1062     GDBJITSYMFILE * const pSymFile = (PIMAGE_RUNTIME_FUNCTION_ENTRY)RTHeapSimpleAlloc(hHeap, cbNeededAligned, 32 /*cbAlignment*/);
    1063 #   endif
     965                                                                                      sizeof(GDBJITSYMFILE), NULL);
    1064966    AssertReturn(pSymFile, VERR_INTERNAL_ERROR_5);
    1065967    unsigned const offSymFileInChunk = (uintptr_t)pSymFile - (uintptr_t)pvChunk;
     
    13981300    AssertLogRelReturn(pvChunk, VERR_NO_EXEC_MEMORY);
    13991301
    1400 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    1401     int rc = VINF_SUCCESS;
    1402 #else
    1403     /* Initialize the heap for the chunk. */
    1404     RTHEAPSIMPLE hHeap = NIL_RTHEAPSIMPLE;
    1405     int rc = RTHeapSimpleInit(&hHeap, pvChunk, pExecMemAllocator->cbChunk);
    1406     AssertRC(rc);
     1302    /*
     1303     * Add the chunk.
     1304     *
     1305     * This must be done before the unwind init so windows can allocate
     1306     * memory from the chunk when using the alternative sub-allocator.
     1307     */
     1308    pExecMemAllocator->aChunks[idxChunk].pvChunk      = pvChunk;
     1309#ifdef IN_RING3
     1310    pExecMemAllocator->aChunks[idxChunk].pvUnwindInfo = NULL;
     1311#endif
     1312    pExecMemAllocator->aChunks[idxChunk].cFreeUnits   = pExecMemAllocator->cUnitsPerChunk;
     1313    pExecMemAllocator->aChunks[idxChunk].idxFreeHint  = 0;
     1314    memset(&pExecMemAllocator->pbmAlloc[pExecMemAllocator->cBitmapElementsPerChunk * idxChunk],
     1315           0, sizeof(pExecMemAllocator->pbmAlloc[0]) * pExecMemAllocator->cBitmapElementsPerChunk);
     1316
     1317    pExecMemAllocator->cChunks      = idxChunk + 1;
     1318    pExecMemAllocator->idxChunkHint = idxChunk;
     1319
     1320    pExecMemAllocator->cbTotal     += pExecMemAllocator->cbChunk;
     1321    pExecMemAllocator->cbFree      += pExecMemAllocator->cbChunk;
     1322
     1323#ifdef IN_RING3
     1324    /*
     1325     * Initialize the unwind information (this cannot really fail atm).
     1326     * (This sets pvUnwindInfo.)
     1327     */
     1328    int rc = iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(pVCpu, pExecMemAllocator, pvChunk, idxChunk);
    14071329    if (RT_SUCCESS(rc))
    1408     {
    1409         /*
    1410          * We want the memory to be aligned on 64 byte, so the first time thru
    1411          * here we do some exploratory allocations to see how we can achieve this.
    1412          * On subsequent runs we only make an initial adjustment allocation, if
    1413          * necessary.
    1414          *
    1415          * Since we own the heap implementation, we know that the internal block
    1416          * header is 32 bytes in size for 64-bit systems (see RTHEAPSIMPLEBLOCK),
    1417          * so all we need to wrt allocation size adjustments is to add 32 bytes
    1418          * to the size, align up by 64 bytes, and subtract 32 bytes.
    1419          *
    1420          * The heap anchor block is 8 * sizeof(void *) (see RTHEAPSIMPLEINTERNAL),
    1421          * which mean 64 bytes on a 64-bit system, so we need to make a 64 byte
    1422          * allocation to force subsequent allocations to return 64 byte aligned
    1423          * user areas.
    1424          */
    1425         if (!pExecMemAllocator->cbHeapBlockHdr)
    1426         {
    1427             pExecMemAllocator->cbHeapBlockHdr   = sizeof(void *) * 4; /* See RTHEAPSIMPLEBLOCK. */
    1428             pExecMemAllocator->cbHeapAlignTweak = 64;
    1429             pExecMemAllocator->pvAlignTweak     = RTHeapSimpleAlloc(hHeap, pExecMemAllocator->cbHeapAlignTweak,
    1430                                                                     32 /*cbAlignment*/);
    1431             AssertStmt(pExecMemAllocator->pvAlignTweak, rc = VERR_INTERNAL_ERROR_2);
    1432 
    1433             void *pvTest1 = RTHeapSimpleAlloc(hHeap,
    1434                                                 RT_ALIGN_32(256 + pExecMemAllocator->cbHeapBlockHdr, 64)
    1435                                               - pExecMemAllocator->cbHeapBlockHdr, 32 /*cbAlignment*/);
    1436             AssertStmt(pvTest1, rc = VERR_INTERNAL_ERROR_2);
    1437             AssertStmt(!((uintptr_t)pvTest1 & 63), rc = VERR_INTERNAL_ERROR_3);
    1438 
    1439             void *pvTest2 = RTHeapSimpleAlloc(hHeap,
    1440                                                 RT_ALIGN_32(687 + pExecMemAllocator->cbHeapBlockHdr, 64)
    1441                                               - pExecMemAllocator->cbHeapBlockHdr, 32 /*cbAlignment*/);
    1442             AssertStmt(pvTest2, rc = VERR_INTERNAL_ERROR_2);
    1443             AssertStmt(!((uintptr_t)pvTest2 & 63), rc = VERR_INTERNAL_ERROR_3);
    1444 
    1445             RTHeapSimpleFree(hHeap, pvTest2);
    1446             RTHeapSimpleFree(hHeap, pvTest1);
    1447         }
    1448         else
    1449         {
    1450             pExecMemAllocator->pvAlignTweak = RTHeapSimpleAlloc(hHeap,  pExecMemAllocator->cbHeapAlignTweak, 32 /*cbAlignment*/);
    1451             AssertStmt(pExecMemAllocator->pvAlignTweak, rc = VERR_INTERNAL_ERROR_4);
    1452         }
    1453         if (RT_SUCCESS(rc))
    1454 #endif /* !IEMEXECMEM_USE_ALT_SUB_ALLOCATOR */
    1455         {
    1456             /*
    1457              * Add the chunk.
    1458              *
    1459              * This must be done before the unwind init so windows can allocate
    1460              * memory from the chunk when using the alternative sub-allocator.
    1461              */
    1462             pExecMemAllocator->aChunks[idxChunk].pvChunk      = pvChunk;
    1463 #ifdef IN_RING3
    1464             pExecMemAllocator->aChunks[idxChunk].pvUnwindInfo = NULL;
    1465 #endif
    1466 #ifndef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    1467             pExecMemAllocator->aChunks[idxChunk].hHeap        = hHeap;
    1468 #else
    1469             pExecMemAllocator->aChunks[idxChunk].cFreeUnits   = pExecMemAllocator->cUnitsPerChunk;
    1470             pExecMemAllocator->aChunks[idxChunk].idxFreeHint  = 0;
    1471             memset(&pExecMemAllocator->pbmAlloc[pExecMemAllocator->cBitmapElementsPerChunk * idxChunk],
    1472                    0, sizeof(pExecMemAllocator->pbmAlloc[0]) * pExecMemAllocator->cBitmapElementsPerChunk);
    1473 #endif
    1474 
    1475             pExecMemAllocator->cChunks      = idxChunk + 1;
    1476             pExecMemAllocator->idxChunkHint = idxChunk;
    1477 
    1478 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    1479             pExecMemAllocator->cbTotal     += pExecMemAllocator->cbChunk;
    1480             pExecMemAllocator->cbFree      += pExecMemAllocator->cbChunk;
    1481 #else
    1482             size_t const cbFree = RTHeapSimpleGetFreeSize(hHeap);
    1483             pExecMemAllocator->cbTotal     += cbFree;
    1484             pExecMemAllocator->cbFree      += cbFree;
    1485 #endif
    1486 
    1487 #ifdef IN_RING3
    1488             /*
    1489              * Initialize the unwind information (this cannot really fail atm).
    1490              * (This sets pvUnwindInfo.)
    1491              */
    1492             rc = iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(pVCpu, pExecMemAllocator, pvChunk, idxChunk);
    1493             if (RT_SUCCESS(rc))
    1494 #endif
    1495             {
    1496                 return VINF_SUCCESS;
    1497             }
    1498 
    1499 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    1500             /* Just in case the impossible happens, undo the above up: */
    1501             pExecMemAllocator->cbTotal -= pExecMemAllocator->cbChunk;
    1502             pExecMemAllocator->cbFree  -= pExecMemAllocator->aChunks[idxChunk].cFreeUnits << IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT;
    1503             pExecMemAllocator->cChunks  = idxChunk;
    1504             memset(&pExecMemAllocator->pbmAlloc[pExecMemAllocator->cBitmapElementsPerChunk * idxChunk],
    1505                    0xff, sizeof(pExecMemAllocator->pbmAlloc[0]) * pExecMemAllocator->cBitmapElementsPerChunk);
    1506             pExecMemAllocator->aChunks[idxChunk].pvChunk    = NULL;
    1507             pExecMemAllocator->aChunks[idxChunk].cFreeUnits = 0;
    1508 #endif
    1509         }
    1510 #ifndef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    1511     }
    1512 #endif
    1513     RTMemPageFree(pvChunk, pExecMemAllocator->cbChunk);
    1514     RT_NOREF(pVCpu);
    1515     return rc;
     1330    { /* likely */ }
     1331    else
     1332    {
     1333        /* Just in case the impossible happens, undo the above up: */
     1334        pExecMemAllocator->cbTotal -= pExecMemAllocator->cbChunk;
     1335        pExecMemAllocator->cbFree  -= pExecMemAllocator->aChunks[idxChunk].cFreeUnits << IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT;
     1336        pExecMemAllocator->cChunks  = idxChunk;
     1337        memset(&pExecMemAllocator->pbmAlloc[pExecMemAllocator->cBitmapElementsPerChunk * idxChunk],
     1338               0xff, sizeof(pExecMemAllocator->pbmAlloc[0]) * pExecMemAllocator->cBitmapElementsPerChunk);
     1339        pExecMemAllocator->aChunks[idxChunk].pvChunk    = NULL;
     1340        pExecMemAllocator->aChunks[idxChunk].cFreeUnits = 0;
     1341
     1342        RTMemPageFree(pvChunk, pExecMemAllocator->cbChunk);
     1343        return rc;
     1344    }
     1345#endif
     1346    return VINF_SUCCESS;
    15161347}
    15171348
     
    15741405     */
    15751406    size_t       cbNeeded   = RT_UOFFSETOF_DYN(IEMEXECMEMALLOCATOR, aChunks[cMaxChunks]);
    1576 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    15771407    size_t const offBitmaps = RT_ALIGN_Z(cbNeeded, RT_CACHELINE_SIZE);
    15781408    size_t const cbBitmap   = cbChunk >> (IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT + 3);
     
    15801410    AssertCompile(IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT <= 10);
    15811411    Assert(cbChunk > RT_BIT_32(IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT + 3));
    1582 #endif
    15831412#if defined(IN_RING3) && !defined(RT_OS_WINDOWS)
    15841413    size_t const offEhFrames = RT_ALIGN_Z(cbNeeded, RT_CACHELINE_SIZE);
     
    15971426    pExecMemAllocator->cbFree       = 0;
    15981427    pExecMemAllocator->cbAllocated  = 0;
    1599 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    16001428    pExecMemAllocator->pbmAlloc                 = (uint64_t *)((uintptr_t)pExecMemAllocator + offBitmaps);
    16011429    pExecMemAllocator->cUnitsPerChunk           = cbChunk >> IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT;
    16021430    pExecMemAllocator->cBitmapElementsPerChunk  = cbChunk >> (IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT + 6);
    16031431    memset(pExecMemAllocator->pbmAlloc, 0xff, cbBitmap); /* Mark everything as allocated. Clear when chunks are added. */
    1604 #endif
    16051432#if defined(IN_RING3) && !defined(RT_OS_WINDOWS)
    16061433    pExecMemAllocator->paEhFrames = (PIEMEXECMEMCHUNKEHFRAME)((uintptr_t)pExecMemAllocator + offEhFrames);
     
    16081435    for (uint32_t i = 0; i < cMaxChunks; i++)
    16091436    {
    1610 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR
    16111437        pExecMemAllocator->aChunks[i].cFreeUnits   = 0;
    16121438        pExecMemAllocator->aChunks[i].idxFreeHint  = 0;
    1613 #else
    1614         pExecMemAllocator->aChunks[i].hHeap        = NIL_RTHEAPSIMPLE;
    1615 #endif
    16161439        pExecMemAllocator->aChunks[i].pvChunk      = NULL;
    16171440#ifdef IN_RING0
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