При использовании SBCL, скомпилированного из исходного кода и среды, такой как Emacs / Slime, можно довольно легко перемещаться по коду, используя M -. (мета-точка).По сути, символ 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, который абстрагируется от сборки.Если вы следуете определению, вы можете найти различные 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)
Очевидно, сборкаподпрограммы с именами 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
.