Interpreter calling a C method

steve goldman Steve.Goldman at Sun.COM
Tue Oct 9 08:44:43 PDT 2007


Peter Helfer wrote:
> Hi all
> 
> I would like to call a C function in the interpreter when I invoke a new
> method; I assume I have to change the TemplateTable::invokeZZZ, by inserting
> some assembly instructions. I figured out the calls are finally done by
> InterpreterMacroAssembler::jump_from_interpreted(Register method, Register
> temp).

You do want to modify TemplateTable::invokeZZZ.

> 
> I thought I could use call_VM_leaf(CAST_FROM_FN_PTR(address,
> SharedRuntime::do_funnymethod), 0) - but I get the error message
> 'InterpreterMacroAssembler::call_VM_leaf_base: last_sp != NULL'.

First you need to understand the difference between leaf calls and 
non-leaf call_VM's. You only can do a call_VM_leaf if there is no 
possibility of blocking for a safepoint. So if do_funnymethod does much 
in the vm you don't want to be using leaf.

The next thing to learn about is what is called the frame anchor (or 
last Java frame). Whenever we are leaving Java mode for either the vm or 
native (jni) we need to store a description of where the last Java frame 
was so that the stack walker can find all the frames should a safepoint 
occur while in vm/native. This is will happen automatically when you use 
call_VM (call_VM_leaf doesn't do this because you promised not to block).

There error you are getting appears to be happing because you tried to 
jam you call_VM_leaf into jump_from_interpreted after this code:

// set sender sp
   leal(rsi, Address(rsp, wordSize));
   // record last_sp
   movl(Address(rbp, frame::interpreter_frame_last_sp_offset * 
wordSize), rsi);

which is incorrect. call_VM_leaf expects that no blocking will occur and 
to that no one will need to see last_sp for the interpreter frame and so 
it complains. This assert is mostly there to ensure that the interpreter 
frame's last_sp is properly set/cleared around Java calls.

If you moved your code ahead of the leal then it should work  as long as 
you don't destroy the register "method".

> 
> Now the questions..
> a) how can I call a C method from the runtime-generated assembly without
> destroying the current frame ?

call_VM or call_VM_leaf
> 
> b) how do I figure out which regs are used for what ? Do I have to go with
> that OopMap and let it iterate over the frames ?

I don't begin to really understand the question. So I'll ask more,

what regs are we talking about where? Since you are calling C the only 
regs you care about are the ones the interpreter is already using. 
call_VM* will save/restore them around the call. If do_funnymethod takes 
any parameters you'll need to develop them into regs that the 
interpreter isn't using. (rsi/rdi should be avoided).

You don't have to worry about oopMaps. For interpreter frame there is a 
fixed layout and the jvm figures out what is live based on the bci 
(bytecode index) stored in the frame. oopMaps are typically used for 
stubs and for jit compiled code.

> 
> c) is there a definite 'calling convention guide' for Java ? I have found
> some information dispersed in serveral places (ok, they are at least all in
> the same folder) about the frame layout = stack layout, about some regs and
> their usage
> 

I don't think so. There's some stuff in my blog 
(http://blogs.sun.com/fatcatair) about calling conventions but I don't 
think it is exactly what you want.


-- 
Steve



More information about the hotspot-runtime-dev mailing list