Remove an undefined behaviour

The initialisation had an awkward sequence that used undefined
behaviour. This fixes this.
This commit is contained in:
Matthew Parkinson
2021-02-09 17:31:56 +00:00
committed by Matthew Parkinson
parent 023290664d
commit e3b3596e32
2 changed files with 20 additions and 17 deletions

View File

@@ -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

View File

@@ -136,30 +136,19 @@ namespace snmalloc
static MemoryProviderStateMixin<PAL>* make() noexcept
{
// Temporary stack-based storage to start the allocator in.
MemoryProviderStateMixin<PAL> local{};
AddressSpaceManager<PAL> local{};
// Allocate permanent storage for the allocator usung temporary allocator
MemoryProviderStateMixin<PAL>* allocated =
local.alloc_chunk<MemoryProviderStateMixin<PAL>, 1>();
reinterpret_cast<MemoryProviderStateMixin<PAL>*>(
local.template reserve<true>(
bits::next_pow2(sizeof(MemoryProviderStateMixin<PAL>))));
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<PAL>));
#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<LowMemoryNotification, PAL>)