> While I'm on the subject of shared libraries,why is it that the Win32
> distribution of GHC includes the RTS, Prelude, and perhaps other
> libraries, as DLL's, but (as far as I can tell) none of the 
> distributions
> for Unix-like platforms include any of these as shared libraries? Is
> there some fundamental obstacle to building these as shared libraries
> under, say, Linux or Solaris, or is including this capability just a
> low priority item that no one has had time to take care of 
> yet?

I've spent quite a lot of time looking into this.  Firstly, it's not simply
a case of adding -fPIC to the gcc command line and recompiling all the
libraries; Unix-style shared libraries go to a lot of effort to make sure
that object files are independent of the kind of library they are going to
be linked against, and this results in a lot of C-specific stuff creeping
in, for example the assumption that  a data object consists of a symbol
followed by a fixed amount of data, so that certain data objects can be
copied into the binary's data segment at runtime.  GHC's object files don't
follow these rules, so can't be made into shared objects easily.

DLL's don't suffer from the same problems, because they rely on knowing at
compile-time whether a given symbol is going to be statically or dynamically
linked: this means you can have separate calling conventions for static and
dynamic functions, and makes everything a lot simpler.  We still have to
make some compromises for DLL-style linking, though: the garbage collector
needs to know whether a given symbol is in text or data space, which is much
harder to do when there are multiple text/data segments in the running
binary (as is the case when several DLLs are loaded).  This is done by a
particularly gruesome hack at the moment, basically adding an extra word to
each static closure in the program.

I think the upshot is this: to get Unix-style shared libraries to work, we'd
need to drop some of the optimisations that GHC does to make its binaries
smaller and faster.  This would amount to about a performance and
binary-size loss somewhere in the 20-40% range, at a guess (for the whole
program, because the calling convention would have to be changed).  And it's
not a trivial undertaking, because the assembly mangler would have to be
taught about the extra annotations (.size directives and the like) needed
for PIC code.

A better solution, which Julian & I have discussed, is to go for dynamicly
linked but UNSHARED libraries.  That is, doing static linking but at
runtime.  You don't get the advantages of shared libraries - i.e. several
programs being able to share the text of the library, but we wouldn't have
to compromise on any optimisations, and you can still do on-demand linking
using clever VM tricks.  Julian already has a standalone linker written, as
part of the Hugs/GHC merger.

Hope this answers the question :)

Cheers,
        Simon

Reply via email to