RFR: 8131362: aarch64: C2 does not handle large stack offsets

Edward Nevill edward.nevill at gmail.com
Thu Jul 16 08:46:14 UTC 2015



Provides support for large spill offsets in C2 on aarch64.

In general the stack offset is limited to (1<<12) * sizeof(type). This is generally sufficient.

However for 128 bit vectors the limit can be as little as +256 bytes. This is because 128 bit vectors may not be 128 bit aligned, therefore they have to use a different form of load/store which only has a 9 bit signed offset instead of the 12 bit unsigned scaled offset. 

This webrev fixes this by allowing stack offsets up to 1<<24 in all cases.

Tested before and after with jtreg hotspot & langtools. In both cases (before and after) the results were:-

Hotspot: passed: 876; failed: 3; error: 7
Langtools: Test results: passed: 3,246; error: 2

I have also tested to ensure that code sequence for large offsets is correct by artificially reducing the limit at which the large code sequence is triggered.

The spill calculation is now done in spill_address in macroAssembler_aarch64.cpp and this is called in all cases.

Address MacroAssembler::spill_address(int size, int offset)
  assert(offset >= 0, "spill to negative address?");
  // Offset reachable ?
  //   Not aligned - 9 bits signed offset
  //   Aligned - 12 bits unsigned offset shifted
  Register base = sp;
  if ((offset & (size-1)) && offset >= (1<<8)) {
    add(rscratch2, base, offset & ((1<<12)-1));
    base = rscratch2;
    offset &= ~((1<<12)-1);

  if (offset >= (1<<12) * size) {
    add(rscratch2, base, offset & (((1<<12)-1)<<12));
    base = rscratch2;
    offset &= ~(((1<<12)-1)<<12);

  return Address(base, offset);

This can generate up to two additional instructions in the most degenerate cases (an unaligned offset larger than (1<<12) * size).

Thanks for the review,

More information about the hotspot-compiler-dev mailing list