Hello,
I am using gnu lightning to make a compiler for register machines. I would like to have many of these register machines working simultaneously, and throughout time I am interested in adding new register machines to memory (perhaps many thousands of them), destroying & deallocating old register machines (again, by the thousands).
First thing I noticed was that lightning allocates a full page (4k of memory, or whatever) whenever it wants to emit a function, and that it had no way to erase a given piece of code from memory. This wouldn't do, so I decided to try and do the following:
Use lightning to generate the code;
find the code length by surrounding the code by start = jit_node, and end = jit_note, and then do:
length = jit_address(start) - jit_address(end);
Allocate as large block of memory as I need, with read, write and exec permissions;
then copy the code by memcpy(_my_memory_block_code_start, jit_address(start), length);
then I cast _my_memory_block_code_start as a function, and call it.
void (*entryPoint)(void *registers_address); entryPoint = _my_memory_block_code_start;
entryPoint(_my_memory_block_registers_start);
Now the advantage of this is when I want to delete some register machine, I can simply erase it and reuse the space.
Of course, the compiled code would have to access the registers of the machine; and would have to be able to jump around; I could have solved the register access by allocating the register space before jit_emit'ing the code, but how was I going to do the jumping around?
I was hoping that the following would work:
whenever the register machine wanted to jump to
I wasn't sure this was going to work, but my first few tests seemed to do OK.