Your observation is actually correct - the initial transition from the interpreter to JIT'ed code requires the the Dalvik PC to be executed for at least 2N + 1 times. N is the profiling threshold as you observed, and the extra 1 is from using the debugging interpreter to build and execute the trace to make sure that the trace can be executed once successfully without throwing any exceptions. Checking the existence of translations too often will slow down the overall performance of the interpreter, so the lookup frequency is governed by the threshold.
If a JIT'ed trace reaches its exit point but the subsequent code is not compiled yet (ie not chained), it returns to the interpreter via a variety of dvmJitToInterp* entry points.The two main ones are dvmJitToInterpNormal and dvmJitToInterpTraceSelect. Both will invoke dvmJitGetCodeAddr to see if the compiled trace exists or not every time the interpreter is re-entered; if so the subsequent one will be chained to the previous trace's exist point so that next time around the code execution will stay with the JIT'ed version. The difference between these two entry points is dvmJitToInterpNormal will request a new trace based on the profiling threshold (eg the previous exit point is a conditional branch) while dvmJitToInterpTraceSelect will request the compilation for the subsequent code address directly (eg the previous exit point is an unconditional branch or invoke-direct call).
In summary, the initial transition barrier from the interpreter to JIT'ed code is higher, but once such a path is entered subsequent translations can be requested and discovered more easily.
-Ben
- 받은메일 숨기기 -
On Thu, Nov 11, 2010 at 12:19 AM, yang chang
<
changy...@gmail.com
> wrote:
- 받은메일 숨기기 -
Hi,
I am trying to understand how the dalvik interpreters interact with the Jit world. With a bit of work, I found that "common_updateProfile" is a main portal to the Jit world. It updates the profile of a potential trace head and if the count reaches zero, it resets the count and then checks if this has already been translated. If so, the interpreter jumps to JITed code. Otherwise, it switches to the debug interpreter to build the trace.
In the fast interpreter code, I didn't find any other place where the interpreter can jump to JITed code (though some "dvmJitToInterp****" functions do jump to JITed code).
This confused me because according to "common_updateProfile", the fast interpreter can only jump to the translation of a trace after:
1) the trace has been translated, and
2) the profile count of the trace head is decreased to zero again after the interpreter decided to compile this trace.
So my understanding is that if the the threshold of a trace head is 100, then the fast interpreter has to come to it 100 times before it decides to compile this trace. The interpreter has to come to this trace head another 100 times before it can jump to the corresponding translation.
This doesn't seem to be right.
Thanks a lot for any advice.
yang