[maemo-developers] Java acceleration/Jazelle

From: Simon Pickering S.G.Pickering at bath.ac.uk
Date: Thu Jul 12 01:41:28 EEST 2007
Hi all,

If this is all already known please let me know and I'll stop waffling, 
but some Googling couldn't find anything, so I'll present what I've 
found thus far.

> I had a look around for some more information and found the patent 
> for Jazelle: US patent number 7089539.

> Google link here (with figures, which makes understanding it far 
> easier): http://www.google.com/patents?id=iMt6AAAAEBAJ&dq=7089539

I've finally got round to reading all of the patent in question.

I've changed my mind about exception handlers (see my previous posts 
with the same subject line). I believe that the processor internally 
handles any exception caused by an unrecognised Java bytecode, and (and 
this is where a bit of interpretation/reading between the lines comes 
in) automatically switches to ARM mode and jumps to an address 
specified in a pointer table provided by the application running the 
JVM (i.e. us).

If you look at Fig.4 in the patent, for example, you can see a snippet 
of code. This is one of the chunks of code that would be jumped to 
(pointed to by the pointer table, which will be 256 pointers long, one 
for each bytecode) and implements the iadd bytecode.

I've repeated the code fragment below with comments above each line:

/* increment bytecode pointer (R14) and load value pointed to by R14 into R4.
    This is performed so that we have the bytecode value of the *next* bytecode
    (i.e. not the one that couldn't be handled) in R4. We move the Java
    'program counter' register, R14, along by one before we do this (in fact it
    does R4=*(R14+1) then R14=R14+1, but same in the end). */
LDRB R4, [R14, #1]!
/* decrement Rstack by 4, then pop first operand from stack into R1
    This is part of handling the actual instruction, in this case an 
iadd, so we
    need to pop the values from the stack */
LDR R1,[Rstack, #-4]!
/* decrement Rstack by 4, then pop first operand from stack into R0
    As above */
LDR R0,[Rstack, #-4]!
/* Get address of next code fragment for next bytecode
    load into R12 the value from Rexc + (R4 x 2^2).
    In this step we look into the pointer table (which contains pointers to
    ARM code fragments that handle each Java bytecode) and we load the address
    of the code fragment for the next Java instruction (not the one we're
    currently handling) which we loaded into R4 on the first line */
LDR R12,[Rexc, R4, LSL #2]
/* R0 = R0 + R1
    Here we simply perform the add operation that this code fragment is
    handling*/
ADD R0,R0,R1
/* Store R0 in Rstack and increment Rstack by 4 (pre or post? post probably)
    Here we save the results of the add operation that we're handling in this
    code snippet*/
STR R0,[Rstack],#4
/* Branch to Java
    This command takes as its operand the address of the ARM software snippet
    used to handled the bytecode. Not (it would appear) the address of the Java
    bytecode to execute. The address of the bytecode should be in R14. The
    Jazelle hardware decides whether Jazelle is present and enabled and chooses
    whether to jump to the bytecode and enter Java mode, or to stay in ARM mode
    and 'emulate' the instruction */
BXJ R12

Note that the actual implementation of the iadd instruction (popping 
twice, adding then pushing) is mixed in with the preparations to handle 
the next bytecode/re-enter Java mode. Afaiu, this is done to make the 
code more efficient and avoid stalls.

So you can see that the code has already worked out where it needs to 
jump to in  either Java or ARM 'emulation' mode (the latter is done to 
speed up processing should Jazelle be disabled or the bytecode be 
another one that's not handled by the hardware).

One curious point about this code is that I was under the impression 
that the stack was held in registers [1], rather than at some address 
as is indicated by the pop instructions. It may be that the Jazelle 
hardware does in fact hold the top stack elements in registers and 
flushes them to memory when the unrecognised Java bytecode exception is 
caused. The question then is which register actually holds this memory 
address (ie. Rstack in the code above)? The same article says that R6 
holds the stack pointer, so perhaps this is used...?

The other register that needs to be determined is Rexc, which is the 
one that points to the base of the pointer table which contains the 
pointers to the ARM code snippets. But it looks like accesses to this 
table are only handled in the ARM snippets (which 'we' would provide), 
so it then becomes a question of which spare register can be used to 
store this address and won't be overwritten.

There are of course a number of other patents that were from around the 
same time. Not sure whether any of the others will have any useful info 
in them. For that matter I wonder why ARM provided some of the register 
names/numbers, but not others?

Time to brush up on my inline asm, and to dig out my Java 2 Virtual 
Machine book and make up some test (byte)codes...


Simon

1. 
http://www.ftponline.com/javapro/2002_06/magazine/columns/javatogo/page3.aspx


More information about the maemo-developers mailing list