And*_* S. 2 lisp compilation common-lisp vm-implementation
如何make-array在SBCL工作?在C++中是否有一些等价物new和delete运算符,或者它是否是其他东西,也许是汇编程度?
我偷看了源头,却什么都不懂.
当使用从源和Emacs/Slime这样的环境编译的SBCL时,可以使用M-.(元点)非常容易地导航代码.基本上,make-array符号绑定到多个东西:deftransform定义和a defun.在deftransform大多用于优化,所以最好只跟随功能,首先.
该make-array函数委托给一个内部函数make-array%,它非常复杂:它检查参数,并根据这些参数调度到不同的数组专用实现:例如,位向量的实现方式与字符串不同.
如果你遵循这个案例simple-array,你会找到一个调用的函数,allocate-vector-with-widetag然后调用它allocate-vector.
现在,allocate-vector绑定了几个对象,多个defoptimizers表单,一个函数和一个define-vop表单.
该功能仅限于:
(defun allocate-vector (type length words)
(allocate-vector type length words))
Run Code Online (Sandbox Code Playgroud)
即使它看起来像一个递归调用,它也不是.
该define-vop形式是一种定义如何编译调用到allocate-vector.在函数和调用的任何地方allocate-vector,编译器都知道如何编写实现内置操作的程序集.但是函数本身的定义是为了有一个具有相同名称的入口点,以及一个包装该代码的函数对象.
define-vop依赖于SBCL中的域特定语言,它抽象了汇编.如果您遵循定义,您可以找到不同的vops(虚拟操作)allocate-vector,例如allocate-vector-on-heap和allocate-vector-on-stack.
堆上的分配转换为对calc-size-in-bytes,调用allocation和调用put-header,最有可能分配内存并标记它(我遵循定义src/compiler/x86-64/alloc.lisp).如何分配内存(以及垃圾收集)是另一个问题.
allocation使用发出汇编代码%alloc-tramp,然后执行以下操作:
(invoke-asm-routine 'call (if to-r11 'alloc-tramp-r11 'alloc-tramp) node)
Run Code Online (Sandbox Code Playgroud)
有明显汇编程序叫alloc-tramp-r11和alloc-tramp,这是预定义的汇编指令.评论说:
;;; Most allocation is done by inline code with sometimes help
;;; from the C alloc() function by way of the alloc-tramp
;;; assembly routine.
Run Code Online (Sandbox Code Playgroud)
运行时有一个C代码基础,例如,请参阅/src/runtime/alloc.c.
该-tramp后缀代表蹦床.
还看一看src/runtime/x86-assem.S.