[LLVMdev] Dynamic (JIT) type resolution

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue Nov 6 08:21:20 PST 2007


Chris Lattner wrote:
>
> I don't think this is really the right way to go.  Can you give an  
> example snippet of Java code that would need this and what you are  
> proposing?  With a concrete example that shows how the lazy class  
> loading stuff works we can talk about different possibilities,
>
>   

Field operations in Java (getfield, putfield, getstatic, putstatic) do
_not_ need what I'm proposing. What I'm proposing is just performance
related (just like method patching in callbacks is an optimization in
order to not call the callback everytime).

Here's a simple example: consider class One:

public class One {
  double a;
}

and class Two:
public class Two {
   static double getDoubleFromOne(One arg) {
        return One.a;
   }
}


Here's the bytecode generated for the getDoubleFromOne method:

ldarg 0
getfield "One", "a"
return

What happens in Java is that types are created lazily. Which means you
can compile getDoubleFromOne without knowing the layout of the class
One. Therefore, if you compile getDoubleFromOne without the layout
information, the compiler will generate the code:

r2 = arg0
r1 = getElementOffsetOf("One", "a");
return r1(r2);

getElementOffsetOf will trigger resolution of the class "One" and return
some offset for "a".

My goal here is to avoid having the call to getElementOffsetOf for the
next executions of getDoubleFromOne. One solution is to recompile
getDoubleFromOne, now that we have the layout information, but this may
not be desirable (increase of compilation time or what if we have many
getElementOffsetOf calls in one method which belong to "if" statements,
etc).

What I would like to do is for getElementOffsetOf to dynamically patch
the native code so that after the execution of getElementOffsetOf in the
getDoubleFromOne method the native code looks like:

r2 = arg0
nop
return offset(r2)

The problem is that getElementOffsetOf does not know where is the code
for loading the field. The compiler may have move it after some
instructions, or there may be some move instructions due to register
spills, etc.

Thus the introduction of the llvm.getfield* intrinsic :-)



More information about the llvm-dev mailing list