对象管理器的主要文件是src/data_type目录下的Variable.cpp和src/vm目录下的ObjectManager.cpp。
其中,ObjectManager.cpp基于Variable.cpp。
Variable
是一个非常简单的类,它有一个名为data
的DataType*
成员,所以对于任意左值,我们只需要得到这个左值的Variable*
值,就可以对这个左值进行赋值(而不需要知道这个左值的具体信息)。
比如,对于一个名为var
的Variable*
对象和一个名为dat
的DataType*
对象,想要把var
(也就是左值)赋值为dat
(也就是右值),只需要这么做:
->data = dat; var
换句话说,每个左值都对应着一个Variable*
对象,而可以通过给这个对象的data成员赋值,从而达到给该左值赋值的目的
ObjectManager.cpp
编写了对象管理器的本体。对象管理器包含了GC机制以及作用域管理功能。虚拟机的对象应向对象管理器申请。
GC所采用的算法是标记-清除法。我用一个栈来维护运行时所有的作用域。新建或退出一个作用域时只需要入栈或出栈即可。寻找某个变量也只需要从栈顶找到栈底就行。
以下是ObjectManager.cpp的核心接口:
函数原型 | 解释 |
---|---|
ObjectManager(bool isGC, unsigned long long mem_limit, int pool_cache_size, STMException* e) |
isGC 代表对象管理器是否执行GC,若执行GC,则mem_limit 有意义,且代表GC的内存限制,若不执行GC,则对象管理器会一直运行直到内存溢出。pool_cache_size代表内存池的缓存大小。对pool_cache_size的具体解释应看MemoryPool.hpp 的实现 |
datatype::NullType* getNullConst() |
获取null 常量 |
template<class T> bool GCConditions(T* object) |
新建对象后,对象管理器会把这个对象交给GCConditions 函数,根据函数返回判断是否需要GC。该函数可交给开发者自定义。虚拟机默认的条件为:对象占用内存+GC预留内存大等于内存限制时。 |
void GC() |
执行GC |
template<class T, typename...Types> T* MallocObject(Types&& ...args) |
申请一个对象,需要提供申请的对象类型和初始化参数,例如MallocObject<IntegerType>(1) 代表申请一个类型为整数,值为1的对象 |
函数原型 | 解释 |
---|---|
Variable* NewVariable(int id) |
新建一个变量,默认为空值 |
Variable* NewVariable(int id, datatype::DataType* val) |
新建一个变量,并赋值为val |
Variable* getVariable(int id) |
获取变量的值 |
void pushScope() |
压入一个空作用域 |
void popScope() |
销毁并弹出一个作用域 |
void pushMemberTabScope(ObjectScope s) |
压入一个指定为s 的作用域,一般用于类对象初始化时 |
void popMemberTabScope() |
弹出一个作用域但不销毁,一般用于类对象初始化时 |
ObjectScope getTopScope() |
获取栈顶的作用域 |