In my on-again-off-again compiler project, I've implemented closures as allocated memory with an executable prefix. So a closure is allocated like this:
c = make_closure(code_ptr, env_size, env_data);
c
is a pointer to a block of allocated memory, which looks like this:
movl $closure_call, %eax
call *%eax
.align 4
; size of environment
; environment data
; pointer to closure code
closure_call is a helper function that looks at the address most recently placed on the stack and uses it to find the closure data and code pointer. Boehm GC is used for general memory management, and when the closure is no longer referenced it can be deallocated by the GC.
Anyway this allocated memory needs to be marked as executable; in fact the entire pages it spans get marked. As closures are created and deallocated, more and more heap memory in the process will be executable.
For defensive programming reasons I'd prefer to minimise the amount of executable heap. My plan is to try to keep all closures together on the same page(s), and to allocate and deallocate executable pages as needed; i.e. to implement a custom allocator for closures. (This is easier if all closures are the same size; so the first step is moving the environment data into a separate non-executable allocation that can be managed normally. It also makes defensive programming sense.)
But the remaining issue is GC. Boehm already does this! What I want is to somehow tell Boehm about my custom allocations, and get Boehm to tell me when they're able to be GC'd, but to leave it up to me to deallocate them.
So my question is, are there hooks in Boehm that provide for custom allocations like this?