Explanation on the anatomy of a JNI call and return
Doug Simon @ Oracle
doug.simon at oracle.com
Fri Jan 25 00:12:44 PST 2013
Although it differs from HotSpot, looking *visually* at the stack frames in an execution of Maxine[1] may be instructive. You can use the Inspector to see the interleaving of native and Java stack frames by inspecting an execution of test.output.MixedFrames as follows:
hg clone https://kenai.com/hg/maxine~maxine maxine
cd maxine
echo "JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_07.jdk/Contents/Home" >mx/env
mxtool/mx build
mxtool/mx image
mxtool/mx inspect -cp com.oracle.max.tests/bin test.output.MixedFrames
Once the Inspector GUI comes up, set a breakpoint in MixedFrames.testNative:
Debug -> Break at method entry -> Method on class path, by name
Class Name: MixedFrames
Select
Method Name: testNative
Set Breakpoint
Debug -> Resume (do this 3 times to get a deeper stack)
You should now see something like this: https://dl.dropbox.com/u/3072238/Inspector.jpg
You can then inspect any state of interest by clicking around in the GUI.
If you have further questions specific to Maxine, please ask them on the Maxine mailing list (users at maxine.kenai.com).
-Doug
[1] https://wikis.oracle.com/display/MaxineVM/Home
On Jan 25, 2013, at 6:28 AM, David Holmes <david.holmes at oracle.com> wrote:
> On 25/01/2013 4:01 AM, Fiterau Paul wrote:
>> Hello guys. Sorry for the intrusion. Looked everywhere for this information, no luck. Browsed the code, very difficult to get an idea from it. 20 hours of search with no result. Also posted on StackOverflow, http://stackoverflow.com/questions/14497754/the-jni-call-its-effect-on-the-two-stacks, got no response. If someone could explain to me the evolution of the native and the java stack during a JNI call invocation, I'd be very appreciative.
>>
>> What I could find over the internet is this: http://weblogs.java.net/blog/mlam/archive/2006/12/a_tale_of_two_s.html . But this is not Hotspot. Plus, I'm doubtful on whether the information is accurate, since, in a native to native call, you'd get a recurse in executeJava, the interpreter (like shown bellow) and I suspect the interpreter does not have the lightest of stack frames.
>> * native stack: executeJava -> mNa -> executeJava -> mNb
>>
>> * Java stack: mNa -> mNb
>> My question is, what's the anatomy of a java to native, native to native call and native to java in terms of stack frames. The purpose is, for a School project I have involving static analysis, where I should infer a very conservative upper bound for both the Java stack and the native stack. Right now there's a tool inferring the upper bound for the Java stack, but it doesn't take into account that some methods might already be compiled. I can use that measure in my inference.
>
> Not a simple question to answer as the details are very complex.
>
> The Java stack and the native stack are quite distinct and the details depend on whether you are running in interpreted code or compiled code. The Java stack is a logical stack of linked frames. The native stack frames need to be linked to the Java stack frames by some mechanism so that we can do stack walking.
>
> When you hit an invocation bytecode for a native method you call into a stub routine that prepares the Java stack and native stack so that the native method can be called directly. This involves marshalling arguments and performing thread-state transitions to mark the thread as executing native code. When the native method returns it marshalls any return value, cleans up the stack and returns to the point where you can execute the next bytecode.
>
> If your native method wants to call a Java method then it needs to use the JNI API, so that adds further marshalling etc and prepares the thread to recommence executing bytecodes.
>
>> I'm especially interested in what would be the worst case with regards to stack consumption in a call chain. Let's say A calls B which calls C which calls D.
>> Would it be more stack consuming if B, C and D were all native or it's more consuming if they are interleaved (one native one not).
>> From what tests I made, it seems that having all of them native does seem to yield the highest consumption. On the Native stack and on the java stack.
>
> I'm not completely clear on what you mean with the interleaving. Once you are in a native method then you can call another native method directly - not via JNI - so that yields minimum stack usage. Going back and forth between Java and native would consume the most stack as you have a lot of "management" code around the transitions.
>
> There is some information here:
>
> https://wikis.oracle.com/display/HotSpotInternals/Home
>
> but unfortunately most of the CallingSequence information is missing.
>
> David Holmes
> ------------
>
>> Thanks for any input! And sorry for the not really dev oriented post.
>> Paul.
More information about the hotspot-dev
mailing list