Make-массив в SBCL - PullRequest
       41

Make-массив в SBCL

0 голосов
/ 18 октября 2018

Как make-array работает в SBCL?Есть ли какие-нибудь эквиваленты new и delete операторов в C ++ или это что-то еще, возможно, на уровне ассемблера?

Я заглянул в исходный код, но ничего не понял.

1 Ответ

0 голосов
/ 18 октября 2018

При использовании 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.

...