How does make-array work in SBCL? Are there some equivalents of new and delete operators in C++, or is it something else, perhaps assembler level?
I peeked into the source, but didn't understand anything.
How does make-array work in SBCL? Are there some equivalents of new and delete operators in C++, or is it something else, perhaps assembler level?
I peeked into the source, but didn't understand anything.
Copyright © 2021 Jogjafile Inc.
When using SBCL compiled from source and an environment like Emacs/Slime, it is possible to navigate the code quite easily using M-. (meta-point). Basically, the
make-arraysymbol is bound to multiple things:deftransformdefinitions, and adefun. Thedeftransformare used mostly for optimization, so better just follow the function, first.The
make-arrayfunction delegates to an internalmake-array%one, which is quite complex: it checks the parameters, and dispatches to different specialized implementation of arrays, based on those parameters: a bit-vector is implemented differently than a string, for example.If you follow the case for
simple-array, you find a function which callsallocate-vector-with-widetag, which in turn callsallocate-vector.Now,
allocate-vectoris bound to several objects, multipledefoptimizersforms, a function and adefine-vopform.The function is only:
Even if it looks like a recursive call, it isn't.
The
define-vopform is a way to define how to compile a call toallocate-vector. In the function, and anywhere where there is a call toallocate-vector, the compiler knows how to write the assembly that implements the built-in operation. But the function itself is defined so that there is an entry point with the same name, and a function object that wraps over that code.define-voprelies on a Domain Specific Language in SBCL that abstracts over assembly. If you follow the definition, you can find different vops (virtual operations) forallocate-vector, likeallocate-vector-on-heapandallocate-vector-on-stack.Allocation on heap translates into a call to
calc-size-in-bytes, a call toallocationandput-header, which most likely allocates memory and tag it (I followed the definition tosrc/compiler/x86-64/alloc.lisp). How memory is allocated (and garbage collected) is another problem.allocationemits assembly code using%alloc-tramp, which in turns executes the following:There are apparently assembly routines called
alloc-tramp-r11andalloc-tramp, which are predefined assembly instructions. A comment says:There is a base of C code for the runtime, see for example
/src/runtime/alloc.c.The
-trampsuffix stands for trampoline.Have also a look at
src/runtime/x86-assem.S.