diff --git a/src/snmalloc/aal/aal_cheri.h b/src/snmalloc/aal/aal_cheri.h index 7152e6490..b05bb5fad 100644 --- a/src/snmalloc/aal/aal_cheri.h +++ b/src/snmalloc/aal/aal_cheri.h @@ -86,6 +86,10 @@ namespace snmalloc } void* pb = __builtin_cheri_bounds_set_exact(a.unsafe_ptr(), size); + + SNMALLOC_ASSERT( + __builtin_cheri_tag_get(pb) && "capptr_bound exactness failed."); + return CapPtr::unsafe_from(static_cast(pb)); } diff --git a/src/snmalloc/backend/backend.h b/src/snmalloc/backend/backend.h index 12663be83..855daaa26 100644 --- a/src/snmalloc/backend/backend.h +++ b/src/snmalloc/backend/backend.h @@ -39,7 +39,7 @@ namespace snmalloc * does not avail itself of this degree of freedom. */ template - static capptr::Arena + static capptr::Alloc alloc_meta_data(LocalState* local_state, size_t size) { capptr::Arena p; @@ -61,9 +61,13 @@ namespace snmalloc } if (p == nullptr) + { errno = ENOMEM; + return nullptr; + } - return p; + return capptr_to_user_address_control( + Aal::capptr_bound(p, size)); } /** diff --git a/src/snmalloc/backend_helpers/smallbuddyrange.h b/src/snmalloc/backend_helpers/smallbuddyrange.h index ce540558f..2a3f3a34c 100644 --- a/src/snmalloc/backend_helpers/smallbuddyrange.h +++ b/src/snmalloc/backend_helpers/smallbuddyrange.h @@ -174,13 +174,22 @@ namespace snmalloc base, length, [this](CapPtr base, size_t align, bool) { - CapPtr overflow = - buddy_small - .add_block( - base.template as_reinterpret>(), align) - .template as_reinterpret(); - if (overflow != nullptr) - parent.dealloc_range(overflow, bits::one_at_bit(MIN_CHUNK_BITS)); + if (align < MIN_CHUNK_SIZE) + { + CapPtr overflow = + buddy_small + .add_block( + base.template as_reinterpret>(), + align) + .template as_reinterpret(); + if (overflow != nullptr) + parent.dealloc_range( + overflow, bits::one_at_bit(MIN_CHUNK_BITS)); + } + else + { + parent.dealloc_range(base, align); + } }); } @@ -204,7 +213,8 @@ namespace snmalloc CapPtr alloc_range(size_t size) { - SNMALLOC_ASSERT(size < MIN_CHUNK_SIZE); + if (size >= MIN_CHUNK_SIZE) + return parent.alloc_range(size); auto result = buddy_small.remove_block(size); if (result != nullptr) @@ -218,8 +228,6 @@ namespace snmalloc CapPtr alloc_range_with_leftover(size_t size) { - SNMALLOC_ASSERT(size < MIN_CHUNK_SIZE); - auto rsize = bits::next_pow2(size); auto result = alloc_range(rsize); @@ -236,8 +244,6 @@ namespace snmalloc void dealloc_range(CapPtr base, size_t size) { - SNMALLOC_ASSERT(size < MIN_CHUNK_SIZE); - add_range(base, size); } }; diff --git a/src/snmalloc/mem/backend_concept.h b/src/snmalloc/mem/backend_concept.h index 951762704..215db1caf 100644 --- a/src/snmalloc/mem/backend_concept.h +++ b/src/snmalloc/mem/backend_concept.h @@ -122,7 +122,7 @@ namespace snmalloc { Backend::template alloc_meta_data(local_state, size) } - ->ConceptSame>; + ->ConceptSame>; } &&requires( LocalState& local_state, diff --git a/src/snmalloc/mem/pool.h b/src/snmalloc/mem/pool.h index 0513c141d..537cc5eb5 100644 --- a/src/snmalloc/mem/pool.h +++ b/src/snmalloc/mem/pool.h @@ -137,11 +137,8 @@ namespace snmalloc Config::Pal::error("Failed to initialise thread local allocator."); } - p = capptr_to_user_address_control( - Aal::capptr_bound( - capptr::Arena::unsafe_from(new (raw.unsafe_ptr()) - T(std::forward(args)...)), - sizeof(T))); + p = capptr::Alloc::unsafe_from(new (raw.unsafe_ptr()) + T(std::forward(args)...)); FlagLock f(pool.lock); p->list_next = pool.list; diff --git a/src/test/func/pool/pool.cc b/src/test/func/pool/pool.cc index 7eaca6bcd..c94c793d9 100644 --- a/src/test/func/pool/pool.cc +++ b/src/test/func/pool/pool.cc @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -24,6 +26,23 @@ struct PoolBEntry : Pooled using PoolB = Pool; +struct PoolLargeEntry : Pooled +{ + std::array payload; + + PoolLargeEntry() + { + printf("."); + fflush(stdout); + payload[0] = 1; + printf("first %d\n", payload[0]); + payload[1'999'999] = 1; + printf("last %d\n", payload[1'999'999]); + }; +}; + +using PoolLarge = Pool; + void test_alloc() { auto ptr = PoolA::acquire(); @@ -116,6 +135,18 @@ void test_iterator() PoolA::release(after_iteration_ptr); } +void test_large() +{ + printf("."); + fflush(stdout); + PoolLargeEntry* p = PoolLarge::acquire(); + printf("."); + fflush(stdout); + PoolLarge::release(p); + printf("."); + fflush(stdout); +} + int main(int argc, char** argv) { setup(); @@ -128,10 +159,18 @@ int main(int argc, char** argv) #endif test_alloc(); + std::cout << "test_alloc passed" << std::endl; test_constructor(); + std::cout << "test_constructor passed" << std::endl; test_alloc_many(); + std::cout << "test_alloc_many passed" << std::endl; test_double_alloc(); + std::cout << "test_double_alloc passed" << std::endl; test_different_alloc(); + std::cout << "test_different_alloc passed" << std::endl; test_iterator(); + std::cout << "test_iterator passed" << std::endl; + test_large(); + std::cout << "test_large passed" << std::endl; return 0; }