Fix static-sized alloc paths, add compilation test

The CapPtr refactoring was largely compiler guided; unfortunately, it turns out
that the static-sized alloc function is not well exercised.  As such, some type
errors and unnecessary unsafety lurked behind missing template instantiation.

Correct those and add calls to the test harness to make sure we always generate
at least one instance of each small/medium/large case.  While here, it doesn't
hurt to make sure that we call all three possible dealloc() flavors as well.
This will, if nothing else, force instantiation of the static-sized dealloc
template as well.
This commit is contained in:
Nathaniel Filardo
2021-04-19 21:01:26 +01:00
committed by Nathaniel Wesley Filardo
parent 59d5b0b9b3
commit 8390a70a48
2 changed files with 43 additions and 3 deletions

View File

@@ -139,18 +139,18 @@ namespace snmalloc
if constexpr (sizeclass < NUM_SMALL_CLASSES)
{
return small_alloc<zero_mem>(size);
return capptr_reveal(small_alloc<zero_mem>(size));
}
else if constexpr (sizeclass < NUM_SIZECLASSES)
{
handle_message_queue();
constexpr size_t rsize = sizeclass_to_size(sizeclass);
return medium_alloc<zero_mem>(sizeclass, rsize, size);
return capptr_reveal(medium_alloc<zero_mem>(sizeclass, rsize, size));
}
else
{
handle_message_queue();
return large_alloc<zero_mem>(size).unsafe_capptr;
return capptr_reveal(large_alloc<zero_mem>(size));
}
#endif
}

View File

@@ -381,6 +381,45 @@ void test_calloc_large_bug()
alloc->dealloc(p1);
}
template<size_t asz, int dealloc>
void test_static_sized_alloc()
{
auto alloc = ThreadAlloc::get();
auto p = alloc->alloc<asz>();
static_assert((dealloc >= 0) && (dealloc <= 2), "bad dealloc flavor");
switch (dealloc)
{
case 0:
alloc->dealloc(p);
break;
case 1:
alloc->dealloc(p, asz);
break;
case 2:
alloc->dealloc<asz>(p);
break;
}
}
void test_static_sized_allocs()
{
// For each small, medium, and large class, do each kind dealloc. This is
// mostly to ensure that all of these forms compile.
test_static_sized_alloc<sizeclass_to_size(1), 0>();
test_static_sized_alloc<sizeclass_to_size(1), 1>();
test_static_sized_alloc<sizeclass_to_size(1), 2>();
test_static_sized_alloc<sizeclass_to_size(NUM_SMALL_CLASSES + 1), 0>();
test_static_sized_alloc<sizeclass_to_size(NUM_SMALL_CLASSES + 1), 1>();
test_static_sized_alloc<sizeclass_to_size(NUM_SMALL_CLASSES + 1), 2>();
test_static_sized_alloc<large_sizeclass_to_size(0), 0>();
test_static_sized_alloc<large_sizeclass_to_size(0), 1>();
test_static_sized_alloc<large_sizeclass_to_size(0), 2>();
}
int main(int argc, char** argv)
{
setup();
@@ -412,6 +451,7 @@ int main(int argc, char** argv)
test_calloc();
test_double_alloc();
#ifndef SNMALLOC_PASS_THROUGH // Depends on snmalloc specific features
test_static_sized_allocs();
test_calloc_large_bug();
test_external_pointer_dealloc_bug();
test_external_pointer_large();