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:
committed by
Nathaniel Wesley Filardo
parent
59d5b0b9b3
commit
8390a70a48
@@ -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
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user