Lots of windows fixes and some more improvements.
This commit is contained in:
@@ -9,10 +9,24 @@
|
||||
#include "../util/align.hpp"
|
||||
#include "../util/traits.hpp"
|
||||
|
||||
#if !defined(MIJIN_STACK_ALLOCATOR_DEBUG)
|
||||
#if defined(MIJIN_DEBUG)
|
||||
#define MIJIN_STACK_ALLOCATOR_DEBUG 1
|
||||
#else
|
||||
#define MIJIN_STACK_ALLOCATOR_DEBUG 0
|
||||
#endif
|
||||
#endif // !defined(MIJIN_STACK_ALLOCATOR_DEBUG)
|
||||
|
||||
#if MIJIN_STACK_ALLOCATOR_DEBUG > 1
|
||||
#include <print>
|
||||
#include <unordered_map>
|
||||
#include "../debug/stacktrace.hpp"
|
||||
#endif
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
template<typename TValue, typename TStackAllocator>
|
||||
struct StlStackAllocator
|
||||
class StlStackAllocator
|
||||
{
|
||||
public:
|
||||
using value_type = TValue;
|
||||
@@ -21,7 +35,7 @@ private:
|
||||
public:
|
||||
explicit StlStackAllocator(TStackAllocator& base) MIJIN_NOEXCEPT : base_(&base) {}
|
||||
template<typename TOtherValue>
|
||||
StlStackAllocator(const StlStackAllocator<TOtherValue, TStackAllocator>& other) MIJIN_NOEXCEPT : base_(other.base) {}
|
||||
StlStackAllocator(const StlStackAllocator<TOtherValue, TStackAllocator>& other) MIJIN_NOEXCEPT : base_(other.base_) {}
|
||||
|
||||
template<typename TOtherValue>
|
||||
StlStackAllocator& operator=(const StlStackAllocator<TOtherValue, TStackAllocator>& other) MIJIN_NOEXCEPT
|
||||
@@ -35,10 +49,35 @@ public:
|
||||
[[nodiscard]]
|
||||
TValue* allocate(std::size_t count) const
|
||||
{
|
||||
return static_cast<TValue*>(base_->allocate(alignof(TValue), count * sizeof(TValue)));
|
||||
void* result = base_->allocate(alignof(TValue), count * sizeof(TValue));
|
||||
#if MIJIN_STACK_ALLOCATOR_DEBUG == 1
|
||||
++base_->numAllocations_;
|
||||
#elif MIJIN_STACK_ALLOCATOR_DEBUG > 1
|
||||
base_->activeAllocations_.emplace(result, captureStacktrace(1));
|
||||
#endif
|
||||
return static_cast<TValue*>(result);
|
||||
}
|
||||
|
||||
void deallocate(TValue* /* ptr */, std::size_t /* count */) const MIJIN_NOEXCEPT {}
|
||||
void deallocate([[maybe_unused]] TValue* ptr, std::size_t /* count */) const MIJIN_NOEXCEPT
|
||||
{
|
||||
#if MIJIN_STACK_ALLOCATOR_DEBUG == 1
|
||||
MIJIN_ASSERT(base_->numAllocations_ > 0, "Unbalanced allocations in stack allocators!");
|
||||
--base_->numAllocations_;
|
||||
#elif MIJIN_STACK_ALLOCATOR_DEBUG > 1
|
||||
auto it = base_->activeAllocations_.find(ptr);
|
||||
if (it != base_->activeAllocations_.end())
|
||||
{
|
||||
base_->activeAllocations_.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
MIJIN_ERROR("Deallocating invalid pointer from StackAllocator.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename TOtherValue, typename TOtherAllocator>
|
||||
friend class StlStackAllocator;
|
||||
};
|
||||
|
||||
template<std::size_t chunkSize = 4096, template<typename> typename TBacking = MIJIN_DEFAULT_ALLOCATOR> requires (allocator_tmpl<TBacking>)
|
||||
@@ -59,6 +98,12 @@ private:
|
||||
};
|
||||
[[no_unique_address]] TBacking<Chunk> backing_;
|
||||
Chunk* firstChunk_ = nullptr;
|
||||
#if MIJIN_STACK_ALLOCATOR_DEBUG == 1
|
||||
std::size_t numAllocations_ = 0;
|
||||
#elif MIJIN_STACK_ALLOCATOR_DEBUG > 1
|
||||
// just for debugging, so we don't care what memory this uses...
|
||||
std::unordered_map<void*, Result<Stacktrace>> activeAllocations_;
|
||||
#endif
|
||||
public:
|
||||
StackAllocator() MIJIN_NOEXCEPT_IF(std::is_nothrow_default_constructible_v<backing_t>) = default;
|
||||
explicit StackAllocator(backing_t backing) MIJIN_NOEXCEPT_IF((std::is_nothrow_constructible_v<TBacking<Chunk>, backing_t&&>))
|
||||
@@ -146,6 +191,26 @@ public:
|
||||
|
||||
void reset() noexcept
|
||||
{
|
||||
#if MIJIN_STACK_ALLOCATOR_DEBUG == 1
|
||||
MIJIN_ASSERT(numAllocations_ == 0, "Missing deallocation in StackAllocator!");
|
||||
#elif MIJIN_STACK_ALLOCATOR_DEBUG > 1
|
||||
if (!activeAllocations_.empty())
|
||||
{
|
||||
std::println(stderr, "{} active allocations in StackAllocator when resetting!", activeAllocations_.size());
|
||||
for (const auto& [ptr, stack] : activeAllocations_)
|
||||
{
|
||||
if (stack.isError())
|
||||
{
|
||||
std::println(stderr, "at {}, no stacktrace ({})", ptr, stack.getError().message);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::println(stderr, "at 0x{}:\n{}", ptr, stack.getValue());
|
||||
}
|
||||
}
|
||||
MIJIN_TRAP();
|
||||
}
|
||||
#endif
|
||||
for (Chunk* chunk = firstChunk_; chunk != nullptr; chunk = chunk->next)
|
||||
{
|
||||
chunk->allocated = 0;
|
||||
@@ -186,6 +251,9 @@ private:
|
||||
newChunk->next = firstChunk_;
|
||||
firstChunk_ = newChunk;
|
||||
}
|
||||
|
||||
template<typename TValue, typename TStackAllocator>
|
||||
friend class StlStackAllocator;
|
||||
};
|
||||
} // namespace mijin
|
||||
|
||||
|
||||
Reference in New Issue
Block a user