GS: Fix compiler warning and possible memory leak on exception

This commit is contained in:
TellowKrinkle 2021-11-26 15:50:16 -06:00 committed by lightningterror
parent 31b6ff6046
commit 7a554be7a7
2 changed files with 15 additions and 7 deletions

View File

@ -38,6 +38,12 @@ public:
return ptr; return ptr;
} }
void operator delete(void* ptr, void* placement_ptr)
{
// Just here to satisfy compilers
// Person who calls in-place placement new must handle error case
}
void* operator new[](size_t size) void* operator new[](size_t size)
{ {
return _aligned_malloc(size, i); return _aligned_malloc(size, i);

View File

@ -64,18 +64,18 @@ public:
template <typename T, typename... Args> template <typename T, typename... Args>
T* make(Args&&... args) T* make(Args&&... args)
{ {
void* ptr = alloc(sizeof(T), alignof(T)); std::unique_ptr<void, void(*)(void*)> ptr(alloc(sizeof(T), alignof(T)), GSRingHeap::free);
new (ptr) T(std::forward<Args>(args)...); new (ptr.get()) T(std::forward<Args>(args)...);
return static_cast<T*>(ptr); return static_cast<T*>(ptr.release());
} }
/// Allocate and default-initialize `count` `T`s /// Allocate and default-initialize `count` `T`s
template <typename T> template <typename T>
T* make_array(size_t count) T* make_array(size_t count)
{ {
void* ptr = alloc(sizeof(T) * count, alignof(T)); std::unique_ptr<void, void(*)(void*)> ptr(alloc(sizeof(T) * count, alignof(T)), GSRingHeap::free);
new (ptr) T[count](); new (ptr.get()) T[count]();
return static_cast<T*>(ptr); return static_cast<T*>(ptr.release());
} }
/// Free a pointer allocated with `alloc` /// Free a pointer allocated with `alloc`
@ -207,17 +207,19 @@ public:
SharedPtr<T> make_shared(Args&&... args) SharedPtr<T> make_shared(Args&&... args)
{ {
using Header = typename SharedPtr<T>::AllocationHeader; using Header = typename SharedPtr<T>::AllocationHeader;
constexpr size_t alloc_size = sizeof(T) + sizeof(Header); static constexpr size_t alloc_size = sizeof(T) + sizeof(Header);
static_assert(alignof(Header) <= MIN_ALIGN, "Header alignment too high"); static_assert(alignof(Header) <= MIN_ALIGN, "Header alignment too high");
static_assert(alloc_size <= UINT32_MAX, "Allocation overflow"); static_assert(alloc_size <= UINT32_MAX, "Allocation overflow");
void* ptr = alloc_internal(sizeof(T), getAlignMask(alignof(T)), sizeof(Header)); void* ptr = alloc_internal(sizeof(T), getAlignMask(alignof(T)), sizeof(Header));
std::unique_ptr<void, void(*)(void*)> guard(ptr, [](void* p){ free_internal(p, alloc_size); });
Header* header = static_cast<Header*>(ptr); Header* header = static_cast<Header*>(ptr);
header->size = static_cast<uint32_t>(alloc_size); header->size = static_cast<uint32_t>(alloc_size);
header->refcnt.store(1, std::memory_order_relaxed); header->refcnt.store(1, std::memory_order_relaxed);
T* tptr = reinterpret_cast<T*>(header + 1); T* tptr = reinterpret_cast<T*>(header + 1);
new (tptr) T(std::forward<Args>(args)...); new (tptr) T(std::forward<Args>(args)...);
guard.release();
return SharedPtr<T>(tptr); return SharedPtr<T>(tptr);
} }