[vmkit-commits] [PATCH] Build vmkit into libjvm.so for dynamic loading

Will Dietz wdietz2 at illinois.edu
Wed Oct 26 12:34:45 PDT 2011


On Tue, Oct 25, 2011 at 7:01 PM, Dietz, William Barrett
<wdietz2 at illinois.edu> wrote:
> Inlined below (with some discussion).
>
> Thanks!
>
> ~Will
>

I've been working hard across the last day to try to either fully
justify this, or to find an alternate way to make use of OpenJDK.

I submitted the patches because this was the 'best' solution I came to
earlier, however I don't like it one bit, and I imagine you're not
especially fond of it either :).  Hence the need to come up with a
compelling argument or an alternative solution.  Here I hope to do a
little bit of both:

Firstly, a little background (so we're on the same page).

Like GNU Classpath, OpenJDK's runtime libraries are defined in various
jar files as well as a number of native ".so" files.  Curiously,
unlike the GNU implementation, OpenJDK's jar files never actually load
the native files, namely libjava.so.  Instead, it's expected the JVM
already has loaded libjava.so before using those jar files (see
http://blog.fuseyism.com/index.php/2008/07/28/comparing-and-contrasting-vm-interfaces/
for information/citation).

Okay, no big deal.  Just dlopen() libjava.so (see "Hook
JnjvmClassLoader" patch for the straightforward implementation of
this) early on, and away we go.

But wait! libjava.so needs some friends to be loaded, namely
libjvm.so--where libjvm.so, as the name suggests, is a dynamic library
that contains the JVM's interface to the runtime libraries (primarily
through a number of JVM_* methods).  libjava.so even insists on having
these JVM_* symbols have a particular version, otherwise it refuses to
load at all.

The approach I took in this patch (and the corresponding symbol
versioning patch) was to wrap up enough of VMKit (mostly
J3Classpath.a) into a libjvm.so (and masquerade it happily with the
right versions) so that when libjava.so went looking for its libjvm.so
it found and used our implementation.  After all, it would be rather
nice for the runtime libraries to call into /our/ JVM not into the
default libjvm.so, Hotspot :).

That works, and these patches make that happen.  And I think it might
even be the "right" way to do this, given all the above.  It's lame,
but that's how things go sometimes.

There is an alternative, however, and it makes different trade-offs,
but might be more agreeable.  The idea here is what JamVM does when
using it's own launchers ('jamvm', etc), although I can't find any
documentation suggesting this is intentional: just let libjava.so load
its own libjvm.so anyway, don't bother with our own libjvm.
Interestingly, this works fine as long as we're careful to define all
the entry points into libjvm.so (which should be the set of JVM_*
methods, which means we already do this) due to the way symbols are
resolved (dlopen()'d library won't override symbols defined in the
calling process).  To be honest, I'd expect that with symbol
versioning requirements, libjava.so would use those versioned symbols
despite what the host process contains, however apparently that's not
the case.  This is dirty for a few reasons, both because if relies on
some tricky symbol magic (magic to me anyway, since versioned symbols
aren't familiar territory for me) and because it counts on us
essentially masking the loaded libjvm.so--if we miss one, the result
might be a hard-to-debug mess.  I'd much prefer never having the
hotspot libjvm.so in our process to begin with.

I just changed the code (dropped this patch and the symbol versioning
patch), ensured my JRE's libjvm.so was on the LD_LIBRARY_PATH (due to
the way I have OpenJDK installed this isn't the case already) and the
result works just as well as it did before (with respect with the
subset of mauve I've been playing with).

Given all this, I'm actually inclined to do this latter approach,
because it requires fewer (no) changes to VMKit's
organization/building, and simply because it seems to work fine.
Additionally the libjvm stuff never played nicely on 64bit regarding
relocatable GC object files--something I never resolved.  This dodges
that.

Anyway, hopefully that gives all this a bit more context and if
nothing else can serve as a more useful discussion point :).

Please let me know your thoughts when you get a chance :)

Thanks for your time!
~Will

PS An an aside, eventually we probably *will* want to build *all* of
VMKit into a libjvm.so so that we can drop it into an icedtea/openjdk
installation and a)make vmkit more accessible to many people and
b)leverage the tools/testing/etc from IcedTea (a java installation is
more than the JVM, after all).  However that's a goal for later, and
not a solution for the issues described here because our internal
tools still need to work (vmjc, etc) and using OpenJDK's 'java'
launcher won't help that.  But thought it might be worth mentioning.



More information about the vmkit-commits mailing list