在 SBCL 中创建数组

Make-array in SBCL

make-array 在 SBCL 中如何工作?在 C++ 中是否存在 newdelete 运算符的等价物,或者是其他东西,也许是汇编程序级别?

我看了源码,但是什么都不懂。

当使用从源代码编译的 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 形式是一种定义如何将 调用 编译为 allocate-vector 的方法。在函数中,以及任何调用 allocate-vector 的地方,编译器都知道如何编写实现内置操作的程序集。但是函数本身是这样定义的,所以有一个同名的入口点,以及一个覆盖该代码的函数对象。

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

堆上的分配转换为对 calc-size-in-bytes 的调用,对 allocationput-header 的调用,这很可能分配内存并标记它(我按照 src/compiler/x86-64/alloc.lisp). 如何分配内存(和垃圾收集)是另一个问题。

allocation 使用 %alloc-tramp 发出汇编代码,后者依次执行以下内容:

(invoke-asm-routine 'call (if to-r11 'alloc-tramp-r11 'alloc-tramp) node)

显然有称为 alloc-tramp-r11alloc-tramp 的汇编例程,它们是预定义的汇编指令。评论说:

;;; Most allocation is done by inline code with sometimes help
;;; from the C alloc() function by way of the alloc-tramp
;;; assembly routine.

运行时有一个 C 代码基础,例如 /src/runtime/alloc.c

-tramp后缀代表trampoline

也看看 src/runtime/x86-assem.S