SBCL中的阵列

时间:2018-10-18 14:45:19

标签: compilation lisp common-lisp vm-implementation

make-array在SBCL中如何工作?在C ++中是否有newdelete运算符的等效项,还是汇编程序级别的其他东西?

我偷看了源,但一无所知。

1 个答案:

答案 0 :(得分:7)

当使用从源代码编译的SBCL以及Emacs / Slime之类的环境时,可以使用 M-。(元点)非常轻松地浏览代码。基本上,make-array符号绑定到多个事物:deftransform定义和defundeftransform主要用于优化,因此最好先遵循该功能。

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))

即使看起来像递归调用,也不是。

define-vop格式是一种定义如何将 call 编译为allocate-vector的方法。在函数中以及调用allocate-vector的任何地方,编译器都知道如何编写实现内置操作的程序集。但是定义函数本身,以便有一个同名的入口点和一个包装该代码的函数对象。

define-vop依赖于SBCL中的特定于域的语言,该语言对汇编进行抽象。如果遵循该定义,则可以为allocate-vector找到不同的vops(虚拟操作),例如allocate-vector-on-heapallocate-vector-on-stack

堆上的分配转换为对calc-size-in-bytes的调用,对allocationput-header的调用,这很可能会分配内存并对其进行标记(我遵循对{{1}的定义}。 内存如何分配(和回收垃圾)是另一个问题。

src/compiler/x86-64/alloc.lisp使用allocation发出汇编代码,该代码依次执行以下操作:

%alloc-tramp

显然有称为(invoke-asm-routine 'call (if to-r11 'alloc-tramp-r11 'alloc-tramp) node) alloc-tramp-r11的汇编例程,它们是预定义的汇编指令。评论说:

alloc-tramp

运行时具有C代码基础,例如,参见;;; Most allocation is done by inline code with sometimes help ;;; from the C alloc() function by way of the alloc-tramp ;;; assembly routine.

后缀/src/runtime/alloc.c代表trampoline

也来看看-tramp