| 1698 | } |
| 1699 | |
| 1700 | txSlot* fxNewSlot(txMachine* the) |
| 1701 | { |
| 1702 | txSlot* aSlot; |
| 1703 | txBoolean once = 1, allocate; |
| 1704 | |
| 1705 | #if mxStress |
| 1706 | if (fxShouldStress()) { |
| 1707 | fxCollect(the, XS_COMPACT_FLAG | XS_ORGANIC_FLAG); |
| 1708 | once = 0; |
| 1709 | } |
| 1710 | #endif |
| 1711 | again: |
| 1712 | aSlot = the->freeHeap; |
| 1713 | if (aSlot) { |
| 1714 | the->freeHeap = aSlot->next; |
| 1715 | aSlot->next = C_NULL; |
| 1716 | aSlot->ID = XS_NO_ID; |
| 1717 | aSlot->flag = XS_NO_FLAG; |
| 1718 | #ifdef mxSnapshot |
| 1719 | #if mx32bitID |
| 1720 | aSlot->dummy = 0; |
| 1721 | #elif INTPTR_MAX == INT64_MAX |
| 1722 | aSlot->dummy = 0; |
| 1723 | #endif |
| 1724 | #endif |
| 1725 | #if mxPoisonSlots |
| 1726 | ASAN_UNPOISON_MEMORY_REGION(&aSlot->value, sizeof(aSlot->value)); |
| 1727 | #endif |
| 1728 | the->currentHeapCount++; |
| 1729 | if (the->peakHeapCount < the->currentHeapCount) |
| 1730 | the->peakHeapCount = the->currentHeapCount; |
| 1731 | #ifdef mxMetering |
| 1732 | the->meterIndex += XS_SLOT_ALLOCATION_METERING; |
| 1733 | #endif |
| 1734 | return aSlot; |
| 1735 | } |
| 1736 | if (once) { |
| 1737 | txBoolean wasThrashing = ((the->collectFlag & XS_TRASHING_SLOTS_FLAG) != 0), isThrashing; |
| 1738 | |
| 1739 | fxCollect(the, XS_ORGANIC_FLAG); |
| 1740 | |
| 1741 | isThrashing = ((the->collectFlag & XS_TRASHING_SLOTS_FLAG) != 0); |
| 1742 | allocate = wasThrashing && isThrashing; |
| 1743 | |
| 1744 | once = 0; |
| 1745 | } |
| 1746 | else |
| 1747 | allocate = 1; |
| 1748 | if (allocate) { |
| 1749 | if (!the->minimumHeapCount) { |
| 1750 | fxReport(the, "# Slot allocation: failed in fixed size heap\n"); |
| 1751 | fxAbort(the, XS_NOT_ENOUGH_MEMORY_EXIT); |
| 1752 | } |
| 1753 | fxGrowSlots(the, !(the->collectFlag & XS_SKIPPED_COLLECT_FLAG) ? the->minimumHeapCount : 64); |
| 1754 | } |
| 1755 | goto again; |
| 1756 | return C_NULL; |
| 1757 | } |
no test coverage detected