Erlang虚拟机源码阅读笔录(二)虚拟机的指令集
在具体分析erlang进程的调度和执行过程前,我们需要简单的了解下erlang虚拟机的指令集的几种形式。
2.1. Erlang程序的内存结构
??? Erlang程序beam文件是需要虚拟机解释执行的字节码文件,因此Erlang的进程结构不同于普通的操作系统进程,Erlang的所有进程数据包括代码,堆栈结构都是存放在数据区里,Erlang进程并没有普通进程拥有的代码区。Erlang进程的stack结构包含了函数调用帧的临时变量和返回地址,heap包含了Erlang进程执行过程中创建的数据。Erlang进程的堆栈总是同时被分配的,并且始终是在同一块区域,并且栈顶和堆顶都朝对方相向增长,当栈顶和堆顶相遇了,就进行垃圾回收。堆的大小增长在一定范围内是按Fibonacci数列增长。
??? 每个Erlang的call frame在栈中都是以一个返回地址开始,后面紧跟是临时变量。每个Erlang的term用一个32位的unsigned word类型数据代表,每个term包含值和一个tag,tag占用4位,并且存在最小有效位中,tag用来标识term的类型,tag的定义如图2.1.1:

图2.1.1
2.2. Erlang虚拟机的寄存器
The BEAM Virtual Machine uses the following registers:
? fcalls?- number of reductions done (to check for suspension while doing function call)
2.3. Erlang虚拟机的指令格式
?? Erlang源程序文件在经过编译后生成对应的字节码文件,其格式为:

?
?
在这种格式中的opcode_value小于255的占用一个字节,大于255的将占用两个字节。
字节码语法图形式比较复杂,操作数按他们的类型大致可以分为以下几种:
8-bit long
16-bit long
24-bit long
32-bit long
除此之外,其它的操作数都是16位长。
然后字节码文件不能被直接执行,需要由erlang虚拟机解释执行。Erlang虚拟机加载字节码文件后会将字节码映射成虚拟机能识别的指令集,虚拟机指令集是使用C代码来定义的,称为threaded-code。其格式如下:

?
?
threaded-code的每一行都占用4个字节。threaded-code的定义在process_main()函数中。
Erlang虚拟机的指令集十分强大,除了普通的运算指令集还有丰富的Test Instructions、Exception Handling以及进程间消息通信的Send,Receive原语。除此之外,Erlang虚拟机还提供了丰富的内建函数功能,内建函数主要是对那些访问频繁的函数进行优化处理。关于Erlang虚拟机指令集的详细说明,请参见这篇论文:The Erlang BEAM Virtual Machine Specification。