1. UCC编译器介绍
UCC是国人开源的C编译器,完全遵循C89标准,整个项目约15000行代码,大小适中,非常适合程序员作为学习编译原理的材料。
UCC采用标准的C编写,包括简单的设计文档和使用手册,易学易用。该项目还包括一个编译驱动,使用已有的编译预处理,UCC, 汇编器,
连接器生成linux/windows上的可执行文件。
2. UCC的内存管理
UCC使用堆的方式管理内存,当需要内存时,从堆中分配内存;释放堆时,将堆中的内存放到空闲内存链表中,以备将来分配使用。
2.1 内存管理数据结构
struct mblock
{
struct mblock *next;
char *begin;
char *avail;
char *end;
};
内存块的数据结构,
next, 指向下一个内存块。
begin, 内存块的起始地址。
avail, 内存块可用的起始地址。
end, 内存块的结束地址。
typedef struct heap
{
struct mblock *last;
struct mblock head;
} *Heap;
last, 堆的最后一个内存块指针。
head, 堆的第一个内存块。
ucc的内存由堆Heap分配,一个Heap管理着当前的内存块。
2.2 堆得初始化
将head清空,同时将last指向head, 此时Heap中没有内存块。
2.3 堆分配内存
程序维护一个空闲的内存块链表,其中放置释放的内存块。
static struct mblock *FreeBlocks;
总的内存管理框架如图所示,
从Heap中分配size大小的内存,首先将size大小做对齐,然后在last指向的最后一个内存块中,将avail开始的size大小的内存
返回。如果avail开始的内存不足size, 则优先从freelist中取得空闲的内存块并加入heap的内存集合中并分配内存。如果freelist
中没有空闲的内存,则使用malloc向系统生成新的mblock加入heap的内存集合并分配内存。
2.3 堆得释放
将堆中的所有内存块放到应用的空闲内存链表中,Heap的last指向自身的head.