From 874d1f14cb47658c27bb4a08c22e1ab6af9a5d77 Mon Sep 17 00:00:00 2001 From: CHatingPython Date: Wed, 10 Jun 2026 15:09:35 +0200 Subject: [PATCH] refactor(furvm): use an arena allocator for thing data Refs: #10 --- furvm/include/furvm/context.hpp | 4 ++++ furvm/src/thing.cpp | 25 +++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/furvm/include/furvm/context.hpp b/furvm/include/furvm/context.hpp index e475d0e..06bc379 100644 --- a/furvm/include/furvm/context.hpp +++ b/furvm/include/furvm/context.hpp @@ -1,6 +1,7 @@ #ifndef FURVM_CONTEXT_HPP #define FURVM_CONTEXT_HPP +#include "furlang/arena.hpp" #include "furvm/fwd.hpp" #include "furvm/module.hpp" @@ -95,6 +96,9 @@ private: std::vector m_modules; std::vector m_things; std::vector m_executors; + + std::vector m_deadThings; + furlang::arena m_thingArena; }; } // namespace furvm diff --git a/furvm/src/thing.cpp b/furvm/src/thing.cpp index 80fbd0e..32dc7b0 100644 --- a/furvm/src/thing.cpp +++ b/furvm/src/thing.cpp @@ -5,6 +5,8 @@ #include "furvm/context.hpp" // IWYU pragma: keep #include +#include +#include namespace furvm { @@ -16,10 +18,29 @@ std::size_t thing_type_size(thing_t type) { } thing::thing(rzecz, thing_handle id, thing_t type, const context_p& context) - : m_id(id), m_type(type), m_context(context), m_data(std::calloc(1, thing_type_size(type))) {} + : m_id(id), m_type(type), m_context(context) { + std::size_t size = thing_type_size(type); + std::byte* data = nullptr; + if (!m_context->m_deadThings.empty()) { + thing_t itType{}; + for (auto it = m_context->m_deadThings.rbegin(); it != m_context->m_deadThings.rend(); ++it) { + std::memcpy(&itType, static_cast(*it) - sizeof(itType), sizeof(itType)); + if (size == thing_type_size(itType)) { + data = static_cast(*it); + break; + } + } + } + if (data == nullptr) data = m_context->m_thingArena.allocate(sizeof(type) + size); + + if (data == nullptr) throw std::runtime_error("failed to allocate data for new thing"); + std::memcpy(data, &type, sizeof(type)); + m_data = data + sizeof(type); + std::memset(m_data, 0, size); +} thing::~thing() { - std::free(m_data); + m_context->m_deadThings.push_back(m_data); } thing_p thing::create(const context_p& context, thing_t type) {