incubator-lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marvin Humphrey <mar...@rectangular.com>
Subject Re: [lucy-dev] Host overriding of all non-final methods
Date Fri, 11 Mar 2011 02:02:04 GMT
On Tue, Mar 08, 2011 at 11:51:08PM -0800, Nathan Kurz wrote:
> > If I understand correctly, what LTO can do for us is associate a symbol with a
> > small body of compiled code and inline that compiled code at the site of an
> > invocation.  That's possible if we alias method symbols to real function
> > symbols, but not if the method symbols remain vtable lookup invocations as
> > they are now.
> 
> Yes, I think that's what it can do --- essentially it allows inlines
> across modules.

Well, this is annoying:

  http://gcc.gnu.org/onlinedocs/gccint/LTO.html

  To make the situation even more difficult, many applications organize
  themselves as a set of shared libraries, and the default ELF visibility
  rules allow one to overwrite any externally visible symbol with a different
  symbol at runtime. This basically disables any optimizations across such
  functions and variables, because the compiler cannot be sure that the
  function body it is seeing is the same function body that will be used at
  runtime. Any function or variable not declared static in the sources
  degrades the quality of inter-procedural optimization. 

There's hope here:

  http://software.intel.com/en-us/articles/software-convention-models-using-elf-visibility-attributes/

On a side note, thes articles solve something that baffled me when I was
looking at the assembler generated by our virtual method invocation mechanism.
Regardless of whether the _OFFSET variable was declared "extern const" or
"extern", the assembler didn't change: the symbol was always retrieved from
the GOT and the value fetched each time.  I wound up declaring the _OFFSET
variables as "extern" and leaving off the no-op "const":

  extern size_t Lucy_BitVecDelDocs_Get_OFFSET;

I now understand why those _OFFSET vars are always looked up in the GOT: the
symbol could be overwritten at any time.  The last loaded shared object wins.

The penalty for that lookup seems to be small, and keeping the offset as a
variable is essential for preserving binary compatibility with external
extensions when the Lucy core is updated and vtables are reorganized.
Ideally, Clownfish method invocations would be built at runtime using JIT
compilation, but that's not going to happen.  :)  FWIW, we do have the option
of hard-coding those offsets to constants within the Lucy core, so that only
extensions would pay the penalty.

> > I think GCC or LLVM has a decent shot at figuring out that it should inline
> > the aliased function.  I don't think there's any hope that the virtual method
> > call will be optimized in the same manner.
> 
> I'd have thought so to, but recently I saw a few references to things
> like this: http://www.reddit.com/r/programming/comments/fzwlh/for_c_programmers_that_hate_c/c1jwuxo

Thinking this through, I'm certain that our virtual method invocation
mechanism would foil this optimization.  The compiler can't build the call
graphs because it can't limit the method pointers that would reside in the
vtable to a finite set.  In a Java JIT compiler, it can know all of the
possible paths, because the method invocation mechanism is private -- in a
worst case, all it has to know is how to deal with a lazy-loaded class.

Ours vtables are just ordinary structs, though -- anything at all could be in
there.  Such an optimization would only be theoretically possible under
whole-program compilation -- and even then it would be very impressive if the
compiler could discover it.

Marvin Humphrey


Mime
View raw message