smcc/lib/rt/rt_alloc.c
ZZY 05c637e594 refactor: 重构前端代码并添加日志功能
- 重命名和重构了多个文件,包括 lexer、parser 和 AST 相关代码
- 添加了日志功能,使用 LOG_* 宏替代原有的 error 和 warn 函数
- 优化了错误处理和内存分配方式
- 调整了代码结构,提高了模块化和可读性
2025-03-19 12:22:55 +08:00

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;
}
}