We already check that the allocation class tag passed to slitter_release matches that of the span enclosing the deallocated address. We should also make sure that the deallocated address is at a correct offset from the beginning of the span. We can't assume the first object in a span begins at the first byte of the span, so we'll have to store that initial offset in the span's metadata.
In order to check that the deallocated address is of the form base_offset + object_size * i, for i integer, we will use the old modular multiplicative inverse trick. We still have to handle low bits when object_size is even; rather than shifting low bits, we should rotate them around. We should then be able to perform a range check to make sure the value of i we backed out maps to a valid address.
That check is on the fast path, so we'll probably want to encode the per-object-class magic numbers in the class object itself.
We already check that the allocation class tag passed to
slitter_releasematches that of the span enclosing the deallocated address. We should also make sure that the deallocated address is at a correct offset from the beginning of the span. We can't assume the first object in a span begins at the first byte of the span, so we'll have to store that initial offset in the span's metadata.In order to check that the deallocated address is of the form
base_offset + object_size * i, foriinteger, we will use the old modular multiplicative inverse trick. We still have to handle low bits whenobject_sizeis even; rather than shifting low bits, we should rotate them around. We should then be able to perform a range check to make sure the value ofiwe backed out maps to a valid address.That check is on the fast path, so we'll probably want to encode the per-object-class magic numbers in the class object itself.