RFR: JDK-8080627: JavaThread::satb_mark_queue_offset() is too big for an ARM ldrsb instruction

Bengt Rutisson bengt.rutisson at oracle.com
Wed May 20 08:15:33 UTC 2015


Hi everyone,

This is a fix for the C1 generated G1 write barriers. It is a bit 
unclear if this is compiler or GC code, so I'm using the broader mailing 
list for this review.

http://cr.openjdk.java.net/~brutisso/8080627/webrev.00/
https://bugs.openjdk.java.net/browse/JDK-8080627

The problem is that on ARM the T_BYTE type will boil down to using the 
ldrsb instruction, which has a limitation on the offset it can load 
from. It can only load from offsets -256 to 256. But in the G1 pre 
barrier we want to load the _satb_mark_queue field in JavaThread, which 
is on offset 760.

Changing the type from T_BYTE to T_BOOLEAN will use the unsigned 
instruction ldrb instead, which can handle offsets up to 4096. Ideally 
we would have a T_UBYTE type to use unsigned instructions for this load, 
but that does not exist.

On the other platforms (x86 and Sparc) we treat T_BYTE and T_BOOLEAN the 
same, it is only on ARM that we have the distinction between these to 
types. I assume that is to get the sign extension for free when we use 
T_BYTE type. The fact that we treat T_BYTE and T_BOOLEAN the same on the 
other platforms makes it safe to do this change.

I got some great help with this change from Dean Long. Thanks, Dean!

I tried a couple of different solutions. Moving the _satb_mark_queue 
field earlier in JavaThread did not help since the Thread superclass 
already has enough members to exceed the 256 limit for offsets. It also 
didn't seem like a stable solution. Loading the field into a register 
would work, but keeping the load an immediate seems like a nicer 
solution. Changing to treat T_BYTE and T_BOOLEAN the same on ARM 
(similarly to x86 and Sparc) would mean to have to do explicit sign 
extension, which seems like a more complex solution than just switching 
the type in this case.

Bengt


More information about the hotspot-dev mailing list