首页 > 解决方案 > 在 SBCL 中创建数组

问题描述

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

我窥视了源代码,但什么也不懂。

标签: compilationlispcommon-lispvm-implementation

解决方案


当使用从源代码和 Emacs/Slime 等环境编译的 SBCL 时,可以使用M-.(meta-point) 轻松导航代码。基本上,make-array符号绑定到多个事物:deftransform定义和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))

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

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

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

堆上的分配转换为对 的调用calc-size-in-bytes,对allocationand的调用put-header,这很可能会分配内存并对其进行标记(我遵循了 to 的定义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,它们是预定义的汇编指令。一条评论说:

;;; 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代表蹦床

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


推荐阅读