Changeset 104109 in vbox
- Timestamp:
- Mar 28, 2024 10:19:21 PM (8 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r104108 r104109 59 59 #include <VBox/param.h> 60 60 #include <iprt/assert.h> 61 #include <iprt/heap.h>62 61 #include <iprt/mem.h> 63 62 #include <iprt/string.h> … … 142 141 * Executable Memory Allocator * 143 142 *********************************************************************************************************************************/ 144 /** @def IEMEXECMEM_USE_ALT_SUB_ALLOCATOR145 * Use an alternative chunk sub-allocator that does store internal data146 * in the chunk.147 *148 * Using the RTHeapSimple is not practial on newer darwin systems where149 * RTMEM_PROT_WRITE and RTMEM_PROT_EXEC are mutually exclusive in process150 * memory. We would have to change the protection of the whole chunk for151 * every call to RTHeapSimple, which would be rather expensive.152 *153 * This alternative implemenation let restrict page protection modifications154 * to the pages backing the executable memory we just allocated.155 */156 #define IEMEXECMEM_USE_ALT_SUB_ALLOCATOR157 143 /** The chunk sub-allocation unit size in bytes. */ 158 144 #define IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE 128 … … 274 260 typedef struct IEMEXECMEMCHUNK 275 261 { 276 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR277 262 /** Number of free items in this chunk. */ 278 263 uint32_t cFreeUnits; 279 264 /** Hint were to start searching for free space in the allocation bitmap. */ 280 265 uint32_t idxFreeHint; 281 #else282 /** The heap handle. */283 RTHEAPSIMPLE hHeap;284 #endif285 266 /** Pointer to the chunk. */ 286 267 void *pvChunk; … … 334 315 uint64_t cbAllocated; 335 316 336 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR337 317 /** Pointer to the allocation bitmaps for all the chunks (follows aChunks). 338 318 * … … 348 328 * portion corresponding to an chunk). */ 349 329 uint32_t cBitmapElementsPerChunk; 350 # 330 #ifdef VBOX_WITH_STATISTICS 351 331 STAMPROFILE StatAlloc; 352 # endif353 #else354 /** @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 the357 * request memory size to make sure there is exacly enough room for a header at358 * 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 first361 * allocation is correctly aligned. */362 uint32_t cbHeapAlignTweak;363 /** The alignment tweak allocation address. */364 void *pvAlignTweak;365 /** @} */366 332 #endif 367 333 … … 418 384 pExecMemAllocator->cAllocations += 1; 419 385 pExecMemAllocator->cbAllocated += cbReq; 420 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR421 386 pExecMemAllocator->cbFree -= cbReq; 422 #else423 pExecMemAllocator->cbFree -= RT_ALIGN_32(cbReq, 64);424 #endif425 387 pExecMemAllocator->idxChunkHint = idxChunk; 426 388 … … 445 407 446 408 447 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR448 409 static void *iemExecMemAllocatorAllocInChunkInt(PIEMEXECMEMALLOCATOR pExecMemAllocator, uint64_t *pbmAlloc, uint32_t idxFirst, 449 410 uint32_t cToScan, uint32_t cReqUnits, uint32_t idxChunk, PIEMTB pTb) … … 497 458 return NULL; 498 459 } 499 #endif /* IEMEXECMEM_USE_ALT_SUB_ALLOCATOR */500 460 501 461 … … 503 463 iemExecMemAllocatorAllocInChunk(PIEMEXECMEMALLOCATOR pExecMemAllocator, uint32_t idxChunk, uint32_t cbReq, PIEMTB pTb) 504 464 { 505 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR506 465 /* 507 466 * Figure out how much to allocate. 508 467 */ 509 # 468 #ifdef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER 510 469 uint32_t const cReqUnits = (cbReq + sizeof(IEMEXECMEMALLOCHDR) + IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE - 1) 511 # 470 #else 512 471 uint32_t const cReqUnits = (cbReq + IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE - 1) 513 # 472 #endif 514 473 >> IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT; 515 474 if (cReqUnits <= pExecMemAllocator->aChunks[idxChunk].cFreeUnits) … … 529 488 cReqUnits, idxChunk, pTb); 530 489 } 531 #else532 void *pvRet = RTHeapSimpleAlloc(pExecMemAllocator->aChunks[idxChunk].hHeap, cbReq, 32);533 if (pvRet)534 return iemExecMemAllocatorAllocTailCode(pExecMemAllocator, pvRet, cbReq, idxChunk);535 RT_NOREF(pTb);536 #endif537 490 return NULL; 538 539 491 } 540 492 … … 558 510 559 511 /* 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 */ 569 516 cbReq = RT_ALIGN_32(cbReq, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE); 570 #else571 cbReq = RT_ALIGN_32(cbReq + pExecMemAllocator->cbHeapBlockHdr, 64) - pExecMemAllocator->cbHeapBlockHdr;572 #endif573 574 517 for (unsigned iIteration = 0;; iIteration++) 575 518 { … … 660 603 Assert(pExecMemAllocator && pExecMemAllocator->uMagic == IEMEXECMEMALLOCATOR_MAGIC); 661 604 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 666 606 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 668 612 PIEMEXECMEMALLOCHDR pHdr = (PIEMEXECMEMALLOCHDR)pv - 1; 669 613 Assert(!((uintptr_t)pHdr & (IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE - 1))); … … 672 616 AssertReturnVoid(idxChunk < pExecMemAllocator->cChunks); 673 617 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); 682 621 #endif 683 622 684 623 /* Free it / assert sanity. */ 685 #if defined(VBOX_STRICT) || defined(IEMEXECMEM_USE_ALT_SUB_ALLOCATOR)686 624 bool fFound = false; 687 625 uint32_t const cbChunk = pExecMemAllocator->cbChunk; 688 # 626 #ifndef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER 689 627 uint32_t const cChunks = pExecMemAllocator->cChunks; 690 628 for (uint32_t idxChunk = 0; idxChunk < cChunks; idxChunk++) 691 # 629 #endif 692 630 { 693 631 uintptr_t const offChunk = (uintptr_t)pv - (uintptr_t)pExecMemAllocator->aChunks[idxChunk].pvChunk; … … 695 633 if (fFound) 696 634 { 697 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR698 635 uint32_t const idxFirst = (uint32_t)offChunk >> IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT; 699 636 uint32_t const cReqUnits = (uint32_t)cb >> IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT; … … 705 642 AssertReturnVoid(ASMBitTest(pbmAlloc, idxFirst + i)); 706 643 ASMBitClearRange(pbmAlloc, idxFirst, idxFirst + cReqUnits); 707 # 644 #ifdef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER 708 645 pHdr->uMagic = 0; 709 646 pHdr->idxChunk = 0; 710 647 pHdr->pTb = NULL; 711 # 648 #endif 712 649 pExecMemAllocator->aChunks[idxChunk].cFreeUnits += cReqUnits; 713 650 pExecMemAllocator->aChunks[idxChunk].idxFreeHint = idxFirst; … … 718 655 pExecMemAllocator->cAllocations -= 1; 719 656 return; 720 #else721 Assert(RTHeapSimpleSize(pExecMemAllocator->aChunks[idxChunk].hHeap, pv) == cb);722 break;723 #endif724 657 } 725 658 } 726 # ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR727 659 AssertFailed(); 728 # else729 Assert(fFound);730 # endif731 #endif732 733 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR734 /* 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 #endif742 660 } 743 661 … … 808 726 unsigned const cbUnwindInfo = sizeof(s_aOpcodes) + RT_UOFFSETOF(IMAGE_UNWIND_INFO, aOpcodes); 809 727 unsigned const cbNeeded = sizeof(IMAGE_RUNTIME_FUNCTION_ENTRY) * cFunctionEntries + cbUnwindInfo; 810 # ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR811 unsigned const cbNeededAligned = RT_ALIGN_32(cbNeeded, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE);812 728 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); 820 730 AssertReturn(paFunctions, VERR_INTERNAL_ERROR_5); 821 731 pExecMemAllocator->aChunks[idxChunk].pvUnwindInfo = paFunctions; … … 1052 962 * This seems to work best with ET_DYN. 1053 963 */ 1054 unsigned const cbNeeded = sizeof(GDBJITSYMFILE);1055 # ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR1056 unsigned const cbNeededAligned = RT_ALIGN_32(cbNeeded, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE);1057 964 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); 1064 966 AssertReturn(pSymFile, VERR_INTERNAL_ERROR_5); 1065 967 unsigned const offSymFileInChunk = (uintptr_t)pSymFile - (uintptr_t)pvChunk; … … 1398 1300 AssertLogRelReturn(pvChunk, VERR_NO_EXEC_MEMORY); 1399 1301 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); 1407 1329 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; 1516 1347 } 1517 1348 … … 1574 1405 */ 1575 1406 size_t cbNeeded = RT_UOFFSETOF_DYN(IEMEXECMEMALLOCATOR, aChunks[cMaxChunks]); 1576 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR1577 1407 size_t const offBitmaps = RT_ALIGN_Z(cbNeeded, RT_CACHELINE_SIZE); 1578 1408 size_t const cbBitmap = cbChunk >> (IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT + 3); … … 1580 1410 AssertCompile(IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT <= 10); 1581 1411 Assert(cbChunk > RT_BIT_32(IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT + 3)); 1582 #endif1583 1412 #if defined(IN_RING3) && !defined(RT_OS_WINDOWS) 1584 1413 size_t const offEhFrames = RT_ALIGN_Z(cbNeeded, RT_CACHELINE_SIZE); … … 1597 1426 pExecMemAllocator->cbFree = 0; 1598 1427 pExecMemAllocator->cbAllocated = 0; 1599 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR1600 1428 pExecMemAllocator->pbmAlloc = (uint64_t *)((uintptr_t)pExecMemAllocator + offBitmaps); 1601 1429 pExecMemAllocator->cUnitsPerChunk = cbChunk >> IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT; 1602 1430 pExecMemAllocator->cBitmapElementsPerChunk = cbChunk >> (IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT + 6); 1603 1431 memset(pExecMemAllocator->pbmAlloc, 0xff, cbBitmap); /* Mark everything as allocated. Clear when chunks are added. */ 1604 #endif1605 1432 #if defined(IN_RING3) && !defined(RT_OS_WINDOWS) 1606 1433 pExecMemAllocator->paEhFrames = (PIEMEXECMEMCHUNKEHFRAME)((uintptr_t)pExecMemAllocator + offEhFrames); … … 1608 1435 for (uint32_t i = 0; i < cMaxChunks; i++) 1609 1436 { 1610 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR1611 1437 pExecMemAllocator->aChunks[i].cFreeUnits = 0; 1612 1438 pExecMemAllocator->aChunks[i].idxFreeHint = 0; 1613 #else1614 pExecMemAllocator->aChunks[i].hHeap = NIL_RTHEAPSIMPLE;1615 #endif1616 1439 pExecMemAllocator->aChunks[i].pvChunk = NULL; 1617 1440 #ifdef IN_RING0
Note:
See TracChangeset
for help on using the changeset viewer.