-
Notifications
You must be signed in to change notification settings - Fork 32
PetitLarceny
One of the LarcenyVariants; this one was meant to be less coupled to one particular host architecture (see SparcNativeLarceny).
In its original conception, it compiled Scheme to C source code, which the host system was then responsible for compiling into a object code. This object code could take the form of a final executable, or a shared object file which could then be dynamically loaded.
In the PetitLarceny/Nasm variant, it compiled Scheme to Intel assembly (using NasmSyntax, as opposed to GnuSyntax).
In all of these variants, code is no longer allocated on the heap; instead, we output code into the text segment, which is not traced by the garbage collector. How do we ensure that the code is not traced? Well, as it turns out, the representation for fixnums in Larceny is to give the two low-order bits zero values; this happens to coincide with 4-byte aligned memory addresses. So, if all of your code is 4-byte aligned, then it seems like you can take advantage of the representation by just putting the code pointer directly, and the garbage collector will assume that the slot is a fixnum and skip over it during the course of garbage collection.
Of course, the devil's in the details: how can you ensure that your code is 4-byte aligned? Some architectures give you this for free (e.g. SPARC, PPC). But Intel in particular does not align its machine instructions, so for that backend, you need to do something to make sure that those two low-order bits are zeros.
- One approach is to left shift your code pointers by 2 before storing them in the procedure's code pointer slot, and then right shift back by 2 each time you need to dereference the pointer. This was the approach that we used on Windows to target Intel.
- Another approach is to ensure that certain elements of the text segment are kept at 4-byte alignment boundaries. For example, function entry points would need start at 4-byte aligned addresses. By a lucky architectural accident, it can be more efficient to fetch from such addresses, and so the GCC family of compilers would perform such alignment for you if you had a certain optimization level turned on. So this was the approach that we used on Linux to target Intel.