Files
Fig/src/Utils/Arena.hpp
PuqiAR 0f635ccf2b 重构类型系统并改进诊断功能
- 更新了类型系统,新增了类型并优化了结构。
- 引入了基类型和派生类,用于函数、结构体和接口类型。
- 实现了类型上下文,用于管理内置类型和类型解析。
- 添加了诊断类,用于收集和报告警告和错误。
- 通过改进错误处理增强了虚拟机执行,以应对递归限制问题。
- 实现了反汇编器,将字节码转换为代码,以改善调试和分析。
- 添加了新的抽象语法树节点,用于成员表达式、对象初始化、接口和结构体定义。
- 引入了语义错误测试,包括重定义、未声明的变量和无效的结构字段。
2026-03-10 12:33:17 +08:00

116 lines
3.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*!
@file src/Utils/Arena.hpp
@brief 线性分配内存池,支持非平凡析构对象的自动清理
@author PuqiAR (im@puqiar.top)
@date 2026-03-08
*/
#pragma once
#include <cstddef>
#include <vector>
#include <memory>
#include <type_traits>
namespace Fig
{
class Arena
{
private:
struct DestructorNode
{
void (*destructor)(void *);
void *object;
DestructorNode *next;
};
static constexpr std::size_t CHUNK_SIZE = 64 * 1024; // 64KB 块大小
std::vector<char *> chunks;
char *currentPtr = nullptr;
std::size_t remaining = 0;
DestructorNode *destructorHead = nullptr;
public:
Arena() = default;
~Arena()
{
// 逆序调用析构函数
DestructorNode *node = destructorHead;
while (node)
{
node->destructor(node->object);
node = node->next;
}
// 释放所有分配的内存块
for (char *chunk : chunks)
{
delete[] chunk;
}
}
// 禁止拷贝和移动,防止内存所有权混乱
Arena(const Arena &) = delete;
Arena &operator=(const Arena &) = delete;
template <typename T, typename... Args>
T *Allocate(Args &&...args)
{
std::size_t size = sizeof(T);
std::size_t alignment = alignof(T);
// 在当前块中尝试对齐并分配
void *ptr = allocateRaw(size, alignment);
// 在分配的内存上构造对象
T *obj = new (ptr) T(std::forward<Args>(args)...);
// 如果 T 需要析构(如包含 String注册到销毁链表
if constexpr (!std::is_trivially_destructible_v<T>)
{
// 注意: DestructorNode 本身是 POD直接在 Arena 里分配,不需要注册析构
void *nodeRaw = allocateRaw(sizeof(DestructorNode), alignof(DestructorNode));
DestructorNode *node = new (nodeRaw) DestructorNode();
node->object = obj;
node->destructor = [](void *p) { static_cast<T *>(p)->~T(); };
node->next = destructorHead;
destructorHead = node;
}
return obj;
}
private:
void *allocateRaw(std::size_t size, std::size_t alignment)
{
// 对齐计算
std::size_t adjustment = 0;
std::size_t currentAddr = reinterpret_cast<std::size_t>(currentPtr);
if (alignment > 0 && (currentAddr % alignment) != 0)
{
adjustment = alignment - (currentAddr % alignment);
}
if (remaining < (size + adjustment))
{
// 当前块空间不足,分配新块
std::size_t nextChunkSize = (size > CHUNK_SIZE) ? size : CHUNK_SIZE;
currentPtr = new char[nextChunkSize];
chunks.push_back(currentPtr);
remaining = nextChunkSize;
adjustment = 0; // 新分配的块通常是最大对齐的
}
currentPtr += adjustment;
void *res = currentPtr;
currentPtr += size;
remaining -= (size + adjustment);
return res;
}
};
} // namespace Fig