The primary aim for this refactor is to use a representation for sizeclasses that uniformly covers both large and small. This allows certain operations such as alloc_size and external_pointer to be uniformly implemented. The additional types make clear which kind of sizeclass is in use. This also tidies up the code for sizeclass based divisible by and modulus. It fixes a bug in rust_realloc that didn't correctly determine a realloc was required for large classes.
54 lines
1.5 KiB
C++
54 lines
1.5 KiB
C++
#include <iostream>
|
|
#include <snmalloc.h>
|
|
#include <test/setup.h>
|
|
using namespace snmalloc;
|
|
|
|
// Check for all sizeclass that we correctly round every offset within
|
|
// a superslab to the correct value, by comparing with the standard
|
|
// unoptimised version using division.
|
|
// Also check we correctly determine multiples using optimized check.
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
setup();
|
|
|
|
UNUSED(argc);
|
|
UNUSED(argv);
|
|
|
|
bool failed = false;
|
|
|
|
for (size_t size_class = 0; size_class < NUM_SMALL_SIZECLASSES; size_class++)
|
|
{
|
|
size_t rsize = sizeclass_to_size((uint8_t)size_class);
|
|
size_t max_offset = sizeclass_to_slab_size(size_class);
|
|
sizeclass_t sc = sizeclass_t::from_small_class(size_class);
|
|
for (size_t offset = 0; offset < max_offset; offset++)
|
|
{
|
|
size_t mod = offset % rsize;
|
|
bool mod_0 = (offset % rsize) == 0;
|
|
|
|
size_t opt_mod = index_in_object(sc, offset);
|
|
if (mod != opt_mod)
|
|
{
|
|
std::cout << "rsize " << rsize << " offset " << offset << " opt "
|
|
<< opt_mod << " correct " << mod << std::endl
|
|
<< std::flush;
|
|
failed = true;
|
|
}
|
|
|
|
bool opt_mod_0 = divisible_by_sizeclass(size_class, offset);
|
|
if (opt_mod_0 != mod_0)
|
|
{
|
|
std::cout << "rsize " << rsize << " offset " << offset
|
|
<< " opt_mod0 " << opt_mod_0 << " correct " << mod_0
|
|
<< std::endl
|
|
<< std::flush;
|
|
failed = true;
|
|
}
|
|
}
|
|
if (failed)
|
|
abort();
|
|
}
|
|
return 0;
|
|
}
|