If the first slab in the list of slabs which share the same chunk size has no more room, it means that all other slabs following it have no room either. This speeds up the test to find a slab with free space, which can now abort and directly proceed to allocate memory for a new slab.
If an empty slab's decay count hits zero, it is moved to the front of the empty slab list to be reclaimed more quickly.
Allocations made from the slab now carry a pointer back to the slab which they are a part of. This speeds up deallocation but has the downside of making the smallest usable slab chunk size 64 bytes, which is double what used to be the minimum before.
The maximum slab size is now 2^17 bytes (= 131072). If you request a slab size larger than this, you will get slab sizes of 131072 bytes instead.
Enabling the memory management debugging code no longer produces compiler errors.
Added a slab allocator which replaces the use of memory pools or the plain AllocMem() operations, respectively. In order to activate the slab allocator, choose a slab size (e.g. 2048 bytes or 4096 bytes) and declare a global variable like this:
ULONG __slab_max_size = 2048;
Memory allocations smaller than the slab size will be made from "slabs", i.e. large chunks of memory of the given size. Larger allocations will be managed separately.