diff --git a/src/mem/address_space.h b/src/mem/address_space.h index 9ebfbe3..d416e1c 100644 --- a/src/mem/address_space.h +++ b/src/mem/address_space.h @@ -252,5 +252,19 @@ namespace snmalloc { add_range(base, length); } + + /** + * Move assignment operator. This should only be used during initialisation + * of the system. There should be no concurrency. + */ + AddressSpaceManager& operator=(AddressSpaceManager&& other) noexcept + { + // Lock address space manager. This will prevent it being used by + // mistake. Fails with deadlock with any subsequent caller. + if (other.spin_lock.test_and_set()) + abort(); + ranges = other.ranges; + return *this; + } }; } // namespace snmalloc diff --git a/src/mem/largealloc.h b/src/mem/largealloc.h index 8d714ba..4304751 100644 --- a/src/mem/largealloc.h +++ b/src/mem/largealloc.h @@ -136,30 +136,19 @@ namespace snmalloc static MemoryProviderStateMixin* make() noexcept { // Temporary stack-based storage to start the allocator in. - MemoryProviderStateMixin local{}; + AddressSpaceManager local{}; // Allocate permanent storage for the allocator usung temporary allocator MemoryProviderStateMixin* allocated = - local.alloc_chunk, 1>(); + reinterpret_cast*>( + local.template reserve( + bits::next_pow2(sizeof(MemoryProviderStateMixin)))); if (allocated == nullptr) error("Failed to initialise system!"); -#ifdef GCC_VERSION_EIGHT_PLUS -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wclass-memaccess" -#endif - // Put temporary allocator we have used, into the permanent storage. - // memcpy is safe as this is entirely single threaded: the move - // constructors were removed as unsafe to move std::atomic in a - // concurrent setting. - ::memcpy( - &(allocated->address_space), - &(local.address_space), - sizeof(AddressSpaceManager)); -#ifdef GCC_VERSION_EIGHT_PLUS -# pragma GCC diagnostic pop -#endif + // Move address range inside itself + allocated->address_space = std::move(local); // Register this allocator for low-memory call-backs if constexpr (pal_supports)