(Very) small patch for the jit event listener

Yaron Keren yaron.keren at gmail.com
Wed Nov 13 15:03:50 PST 2013


Gael, anyone who dynamically un/loads functions will face these problems.
You have certainly gone much further than me trying to solve them!

Yaron



2013/11/14 Gaël Thomas <gael.thomas at lip6.fr>

> Hi Andrew, hi all,
>
> I already saw that the old jit was (almost) deprecated. So, I'm
> currently playing with the new jit and it's look very interesting.
> (I'm working locally and I haven't pushed anything new on VMKit
> because I'm also changing a little the design vmkit). For the moment,
> MCJIT does not work with VMKit (but I haven't yet tested the
> safepoint/stackmap patch), I don't know if it comes from what I'm
> doing or if something is still missing in MCJIT.
>
> Sorry, my mail will be too long, but I want first to explain what I'm
> currently doing and then open the discussion to explain what I would
> like to see in MCJIT :) Of course, I can help to develop something or
> to give feed back, I'm hardly working on vmkit currently and I have
> time to spend on that (but I'm far from an expert in compilation
> stuffs!).
>
> Basically, I want to compile lazily my functions (we have a Java
> virtual machine built upon vmkit and compiling all the rt.jar during
> the bootstrap is not very realistic:)). So, by lazy compilation, I
> mean that I want to compile (and even resolve) a function only when it
> is used. For example, during the compilation of
> void f() { g() }
> I don't want to compile g(). I will only compile g() when it will be
> called.
>
> For the moment, I use a home-made stub (I have attached the asm code,
> it can give you some ideas if you plan to integrate a stub generator
> able to perform dynamic dispatch like virtual call in c++) because
> MCJIT does not provide this facility. So, for each function, I define
> a module. In each module, I have to define the runtime function (such
> as gcmalloc, throwException and this kind of functions). They are
> defined in a separated runtime module populated during the bootstrap.
> I have thus this picture
>
> MCJIT
>   |----------------------------------------------------------
>   |                                    |                        |
> Runtime module     module for f   module for g
>
> When I see that I need g during the compilation of f, I define an
> external symbol g in f's module and I add a global mapping between g
> and its stub in MCJIT. Everything works perfectly in the old JIT, so
> the code is correct in this case. The problem that I face with
> multiple modules in the old JIT is that the symbol g defined in f's
> module and the symbol g defined in g's module are not the same, I thus
> have to define multiple symbol in the old JIT for the same entity,
> which is far from perfect. Anyway, it works.
>
> With MCJIT, I can call f from my C++ code (relatively easy as f is
> defined in its own module),  the stub of g is called and I can
> generate its code (which use other functions). But I can not find a
> way to compile g and to update the mapping between g and the new
> function pointer. When I use recompileAndRelinkFunction, I see that it
> is not implemented in MCJIT, and when I use getFunctionPointer, I
> obtain.... a null pointer? I have not investigated further, but
> probably, having two symbols g in the same MCJIT does not work. And I
> don't see what I can do at this step? Maybe that I have missed
> something?
>
> Otherwise, I already predict that I will also have one big problem
> latter: I would like to inline functions from the runtime module in f
> or g, and I would like to inline the code of an already compiled
> function h in g. So, I would like to inline functions that comes from
> different modules. It means that I would like to see MCJIT working
> like an llvm::Linker, able to resolve the h symbol during the
> compilation of g. And for the moment, as MCJIT can not see that the g
> defined in f's module and the g defined in g's module represent the
> same function, I think that I will have a problem latter.
>
> So, for the moment, I'm a little bit stuck with MCJIT. Something that
> could be really useful could be a mcjit that acts as a linker. If
> MCJIT could have a map like this (I give a pseudo-c++ code)
>
> class FnDescriptor {
>   StringRef name;
>   FunctionType fnType;
>   LinkageType linkage;
> };
>
> class FnState {
>   llvm::Module* definedModule;
> /* maybe a  llvm::ObjectImage* ? */
>   List<RelocationTable*>* users,
>   void* currentPointer
> };
>
> map<FnDescriptor, FnState>
>
> it could be really useful. Let's imagine the same scenario with f that
> calls g while g is not yet compiled. At the beginning of this
> scenario, "g" "void ()" could simply be associated to a FnState with
>
> <null, List<>, stubForG>.
>
> After f's compilation, it could be something like that
>
> <null, List<RelocationTable-of-module-f>, stubForG>.
>
> And after the compilation of g, something like
>
> <moduleOfG, List<Reloc-f, Reloc-g>, compiledCode-of-g>
>
> with the relocation entries updated?
>
> Otherwise, for safepoints, and for exception tables, it could be also
> really useful to install call backs to let VMKit manages them itself
> (but it's maybe provided by the safepoint/patchpoint patch?)? (with
> something that can make the association between a MCSymbol and it's
> actual address of course :) )
>
> See you!
> Gaël
>
> PS: by the way, Yaron, we currently face almost the same problems
>
>
> 2013/11/13 Yaron Keren <yaron.keren at gmail.com>:
> > Hi Andy,
> >
> > We had previous discussions about this, I'd like to state more exactly
> what
> > features would make MCJIT a replacement for the JIT.
> > After putting significant effort trying to move to MCJIT, I'm currently
> back
> > with the JIT. This is in a REPL environment where functions are added and
> > removed dynamically and response time is important. The issue is the
> legacy
> > JIT provides great flexibility for this use case which is currently
> missing
> > from MCJIT because of their very different design and goals.
> >
> > With JIT, you can modify Function(s) in an already-compiled Module,
> unload
> > the machine code and the JIT will automatically recompile and relink the
> > function next time it is called. To make MCJIT work like that it would
> need
> > at least :
> >
> > 1) Automatic module splitting into function-modules.
> > 2) Module delete: from module list, from linker namespace, machine code
> > unload, unregister EH and debuginfo.
> > 3) Stub functions.
> > 4) Relinking with stub functions so that new modules are relinked without
> > changing already-finalized modules. This is critical to response time as
> you
> > may change just one function out of 1000.
> > 5) Module addition should register EH and debuginfo (this is not done
> with
> > current JIT but while at it...).
> >
> > REPL environments using the LLVM JIT would likely encounter great
> difficulty
> > moving to the current MCJIT without the above. 1) could be done by the
> > programmer but the a helper function should provide this service. 2)-4)
> > could be done only in the MCJIT. 5) is a bonus.
> >
> > Until MCJIT has this kind of flexibility, I hope the JIT would be kept
> > alive.
> >
> > Yaron
> >
> >
> >
> >
> >
> >
> > 2013/11/13 Kaylor, Andrew <andrew.kaylor at intel.com>
> >>
> >> Hi Gaël,
> >>
> >> I'm not familiar enough with the details of the old JIT engine and its
> >> event interface to comment on whether or not your changes are
> appropriate,
> >> but I'm not sure anyone is so the patch is probably OK as is.  I don't
> see
> >> any obvious problems with it.
> >>
> >> However, your description of the changes raises a bigger issue in my
> mind.
> >> I'm not sure if you are aware of this, but we're planning to deprecate
> the
> >> old JIT engine in a future release -- possibly as soon as LLVM 3.5.  In
> >> order to do so we need to make sure the MCJIT engine is capable of
> meeting
> >> the needs of current JIT users, and I'm not sure we've got your case
> fully
> >> covered yet.
> >>
> >> Can you tell me a little bit more about the details of how you are using
> >> the JIT engine?  I'm putting together a document describing various
> models
> >> for MCJIT use and if your model isn't covered by one of the cases I've
> got
> >> now I'd like to add it.
> >>
> >> Also, have you looked at the recently added Stackmap and Patchpoint
> >> intrinsics.  Without knowing a lot about either your case or those
> >> intrinsics, I think that there may be a possible match there.  The thing
> >> that raised a red flag for me in your message was that MCJIT doesn't
> >> maintain mappings between the generated code and the LLVM classes from
> which
> >> it is produced, so we'll probably need a different way to handle your
> >> safepoints.
> >>
> >> (BTW, it's probably appropriate to move further discussion to the
> LLVMDev
> >> list rather than llvm-commits.)
> >>
> >> Thanks,
> >> Andy
> >>
> >>
> >> -----Original Message-----
> >> From: llvm-commits-bounces at cs.uiuc.edu
> >> [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Gaël Thomas
> >> Sent: Wednesday, November 13, 2013 6:09 AM
> >> To: llvm-commits at cs.uiuc.edu
> >> Subject: (Very) small patch for the jit event listener
> >>
> >> Hi all,
> >>
> >> We have a small problem for vmkit. We rely on the JITEventListener to
> >> register the safepoints generated for the garbage collector, and for
> that
> >> purpose, we have to use the JITCodeEmitter (the
> >> MachineCodeEmitter) that was used to generate the MachineFunction in
> order
> >> to find the physical address of the safepoints (aka, the MCSymbols). A
> long
> >> time ago, it was not a problem as the JIT class was in the llvm
> interface,
> >> but today, the header is hidden inside the lib directory and not
> installed
> >> by llvm. Currently, we directly use this header, but it means that
> during
> >> the compilation of vmkit, we need the sources of llvm. But, as we are
> >> currently developing a debian package of vmkit, we would like to avoid
> the
> >> installation of the llvm sources to compile vmkit.
> >>
> >> So, I made a small patch that just adds a new MachineCodeEmitter field
> in
> >> JITEvent_EmittedFunctionDetails and fill it in JITCodeEmitter. As the
> patch
> >> only adds a new field in the JITEvent_EmittedFunctionDetails, it should
> not
> >> break anything. At least, my llvm and my vmkit are still running :) (by
> the
> >> way, I had to execute a make clean before recompiling llvm because I
> think
> >> that a dependency is missing)
> >>
> >> As it is my first patch, I hope that I have used the llvm coding
> style...
> >>
> >> See you,
> >> Gaël
> >>
> >>
> >>
> >>
> >>
> >>
> >> --
> >> -------------------------------------------------------------------
> >> Gaël Thomas, Associate Professor, UPMC
> >> http://pagesperso-systeme.lip6.fr/Gael.Thomas/
> >> -------------------------------------------------------------------
> >>
> >> _______________________________________________
> >> llvm-commits mailing list
> >> llvm-commits at cs.uiuc.edu
> >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> >
> >
>
>
>
> --
> -------------------------------------------------------------------
> Gaël Thomas, Associate Professor, UPMC
> http://pagesperso-systeme.lip6.fr/Gael.Thomas/
> -------------------------------------------------------------------
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131114/afb89951/attachment.html>


More information about the llvm-commits mailing list