Back to libjit hacking

Right now I have more free time than I had during last 2 years so perhaps I will be able to contribute something new to libjit.

Currently I’m trying to improve libjit memory management. There is a proposed patch for pluggable memory allocator from Patrick van Beem ( I fully recognize the need for some applications to perform custom memory allocation. However I would like to have more elaborate solution for this problem than that found in the provided patch. First of all, libjit’s own memory manager (jit/jit-cache.[hc]) is not so good. For instance, the way it allocates function redirectors may result in memory leaks. The patch supposedly resolves this problem but only if pluggable memory manager supports some¬†extra¬†feature not available for libjit default manager. This is clearly not how it should be done. The leak should be fixed in the way not dependent on which memory manager is used.

So I try to find appropriate solution that would fix this problem for all libjit users whereas Patrick’s patch keeps libjit logic mostly intact and “solves” the problem by letting third-party allocator do something that normal libjit users will not have ability to do.

Another thing to consider is that libjit allocates code space in relatively small chunks. If at the compile time libjit figures that the code for a function doesn’t fit to the allocated chunk then a bigger chunk is allocated and the compilation is restarted. However on systems with virtual memory (pretty much any modern system where libjit is likely to be ever used) a program can reserve very large amounts of memory in the first place. The system allocates physical memory page for a virtual memory page only when it is really accessed, not when it is reserved. Hence there should be no need for code space reallocation and recompilation. Normally, the way to go is to reserve memory block with size, say, 0.5 GB and all the code generated during lifetime of libjit application should go there. Initially we can commit only few pages from this amount and commit more on demand. If this block ever becomes full then we report error and just quit. Of course, the the size of allocated block should be configurable.

It might be that some application will not be happy with such allocation scheme. For instance, it might target an embedded system where the old allocation scheme works better. Or the application has tight control over the lifetime of JITed functions and it can tell if particular function is no longer needed so the space occupied by the function’s code could be reclaimed and used for something else. And this is exactly what pluggable memory manger interface is for.

So for me the first goal is to provide better internal memory manager for libjit and the second goal provider interface to plug custom managers. Along the way I should figure out the most flexible interface that will allow application to do whatever it wants.

Leave a Reply

Your email address will not be published. Required fields are marked *