Improve codegen for sized free. (#115)

For languages like Verona or Rust, the deallocation calls know the
size of the object originally requested.  This change optimises that
code path to create a much better fast path.
This commit is contained in:
Matthew Parkinson
2020-01-22 17:41:08 +00:00
committed by GitHub
parent dbfb645732
commit 4212ac8e4e

View File

@@ -237,41 +237,44 @@ namespace snmalloc
* Free memory of a dynamically known size. Must be called with an
* external pointer.
*/
void dealloc(void* p, size_t size)
SNMALLOC_FAST_PATH void dealloc(void* p, size_t size)
{
#ifdef USE_MALLOC
UNUSED(size);
return free(p);
#else
handle_message_queue();
sizeclass_t sizeclass = size_to_sizeclass(size);
if (sizeclass < NUM_SMALL_CLASSES)
if (likely((size - 1) <= (sizeclass_to_size(NUM_SMALL_CLASSES - 1) - 1)))
{
Superslab* super = Superslab::get(p);
RemoteAllocator* target = super->get_allocator();
if (target == public_state())
sizeclass_t sizeclass = size_to_sizeclass(size);
if (likely(target == public_state()))
small_dealloc(super, p, sizeclass);
else
remote_dealloc(target, p, sizeclass);
return;
}
else if (sizeclass < NUM_SIZECLASSES)
dealloc_sized_slow(p, size);
#endif
}
SNMALLOC_SLOW_PATH void dealloc_sized_slow(void* p, size_t size)
{
if (size == 0)
dealloc(p, 1);
if (likely(size <= sizeclass_to_size(NUM_SIZECLASSES - 1)))
{
Mediumslab* slab = Mediumslab::get(p);
RemoteAllocator* target = slab->get_allocator();
if (target == public_state())
sizeclass_t sizeclass = size_to_sizeclass(size);
if (likely(target == public_state()))
medium_dealloc(slab, p, sizeclass);
else
remote_dealloc(target, p, sizeclass);
return;
}
else
{
large_dealloc(p, size);
}
#endif
large_dealloc(p, size);
}
/*