- 重命名和重构了多个文件,包括 lexer、parser 和 AST 相关代码 - 添加了日志功能,使用 LOG_* 宏替代原有的 error 和 warn 函数 - 优化了错误处理和内存分配方式 - 调整了代码结构,提高了模块化和可读性
136 lines
3.8 KiB
C
136 lines
3.8 KiB
C
#include "rt_alloc.h"
|
|
|
|
#define ALLOCATOR_PAGE_SIZE (4096)
|
|
|
|
/* Simple / Static Allocator */
|
|
|
|
void* salloc_alloc(int size) {
|
|
// TODO do some trace
|
|
return rt._malloc(size);
|
|
}
|
|
|
|
void* salloc_realloc(void* ptr, int size) {
|
|
return rt._realloc(ptr, size);
|
|
}
|
|
|
|
void salloc_free(void* ptr) {
|
|
// TODO do some trace
|
|
rt._free(ptr);
|
|
}
|
|
|
|
/* Fixed Allocator */
|
|
|
|
#define PAGE_ALIGN(size) (((size) + ALLOCATOR_PAGE_SIZE -1) & ~(ALLOCATOR_PAGE_SIZE-1))
|
|
|
|
void falloc_init(fixed_alloc_t* fa, int fixed_size, int init_blocks) {
|
|
fa->free_list = NULL;
|
|
fa->page_list = NULL;
|
|
|
|
// 确保块大小至少能存放指针(用于空闲链表)
|
|
const int min_size = sizeof(void*);
|
|
fa->block_size = (fixed_size < min_size) ? min_size :
|
|
(fixed_size + 15) & ~15; // 16字节对齐
|
|
|
|
// 计算每页块数(优化缓存利用率)
|
|
const int page_size = ALLOCATOR_PAGE_SIZE - sizeof(void*);
|
|
fa->blocks_per_page = page_size / fa->block_size;
|
|
|
|
// TODO copy paste 需要使用函数抽象 申请过程
|
|
// 预分配初始页
|
|
void* page = salloc_alloc(PAGE_ALIGN(fa->block_size * init_blocks));
|
|
unsigned char* p = (unsigned char*)page;
|
|
for (int i = 0; i < init_blocks; ++i) {
|
|
void** block = (void**)p;
|
|
*block = fa->free_list;
|
|
fa->free_list = block;
|
|
p += fa->block_size;
|
|
}
|
|
|
|
*(void**)page = fa->page_list;
|
|
fa->page_list = page;
|
|
}
|
|
|
|
void* falloc_alloc(fixed_alloc_t* fa) {
|
|
if (!fa->free_list) {
|
|
// 分配新页(带页头保存链表指针)
|
|
void* page = salloc_alloc(ALLOCATOR_PAGE_SIZE);
|
|
unsigned char* p = (unsigned char*)page + sizeof(void*);
|
|
|
|
// 链接新页块到空闲链表
|
|
for (int i = 0; i < fa->blocks_per_page; ++i) {
|
|
void** block = (void**)p;
|
|
*block = fa->free_list;
|
|
fa->free_list = block;
|
|
p += fa->block_size;
|
|
}
|
|
|
|
*(void**)page = fa->page_list;
|
|
fa->page_list = page;
|
|
}
|
|
|
|
void* block = fa->free_list;
|
|
fa->free_list = *(void**)block;
|
|
return (void*)((unsigned char*)block + sizeof(void*)); // 跳过链表指针
|
|
}
|
|
|
|
void falloc_free(fixed_alloc_t* fa, void* ptr) {
|
|
if (!fa || !ptr) return;
|
|
|
|
void** block = (void**)((u8_t*)ptr - sizeof(void*));
|
|
*block = fa->free_list;
|
|
fa->free_list = block;
|
|
}
|
|
|
|
void falloc_destroy(fixed_alloc_t* fa) {
|
|
if (!fa) return;
|
|
|
|
// 逆向释放所有内存页(保持地址连续性)
|
|
void* current_page = fa->page_list;
|
|
while (current_page) {
|
|
void* next_page = *(void**)current_page; // 页头保存了链表指针
|
|
salloc_free(current_page);
|
|
current_page = next_page;
|
|
}
|
|
|
|
// 防御性清零(防止悬垂指针)
|
|
fa->free_list = NULL;
|
|
fa->blocks_per_page = 0;
|
|
fa->block_size = 0;
|
|
fa->page_list = NULL;
|
|
}
|
|
|
|
/* Long Allocator */
|
|
|
|
void lalloc_init(long_alloc_t* la) {
|
|
la->current = NULL;
|
|
la->block_size = ALLOCATOR_PAGE_SIZE; // 初始块大小
|
|
}
|
|
|
|
void* lalloc_alloc(long_alloc_t* la, int size) {
|
|
size = (size + 15) & ~15; // 16字节对齐
|
|
|
|
if (!la->current || (la->current->used + size) > la->block_size) {
|
|
int new_size = la->block_size;
|
|
if (new_size < size + sizeof(long_block_t))
|
|
new_size = size + sizeof(long_block_t);
|
|
|
|
long_block_t* new_block = (long_block_t*)salloc_alloc(new_size);
|
|
new_block->next = la->current;
|
|
new_block->used = sizeof(long_block_t);
|
|
la->current = new_block;
|
|
la->block_size = new_size;
|
|
}
|
|
|
|
void* ptr = (unsigned char*)la->current + la->current->used;
|
|
la->current->used += size;
|
|
return ptr;
|
|
}
|
|
|
|
void lalloc_destroy(long_alloc_t* la) {
|
|
while (la->current) {
|
|
long_block_t* prev = la->current->next;
|
|
salloc_free(la->current);
|
|
la->current = prev;
|
|
}
|
|
}
|