Lots of windows fixes and some more improvements.

This commit is contained in:
2025-06-24 15:20:42 +02:00
parent 36a908ab8a
commit 573c431dbd
14 changed files with 379 additions and 63 deletions

View File

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