Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
public class Simple {
  public static int tailcaller(int x) {
    if (x==0) return x+1;
      
    return goto tailcaller(x-1);
  }
}

Implementation

Compiler

Example used for illustration. We assume that all parameters are passed on stack (normaly some registers would be used for passing arguments).

Code Block


public class Example {

  public static in tailcaller(int a, int b, int c, int d) {
    if (a==0) return b+c+d;
  
    // Tail call. (Sibling tail call - caller's  incomming argument area large enough to hold tailcallee's parameters.)
    return goto tailcallee(a, b+c+d);
  }

  public static int tailcallee(int a, int b) {
    if (a==0) return b;
    
    // Tail call. (Not sibling tail call - caller's incoming argument area is only guarantee to have two stack slots.)
    return goto tailcaller(a, b-2, 1, 1);
  }
}

There currently exist two branches .

  • hotspottailc-eager.patch: Compiled code (by server, client compiler) moves the callee's arguments to their actual position at the call site as part of the argument lowering. -XX:+TailCallsStackCompression is currently not supported.
  • hotspottailc-lazy.patch: Compiled code moves the callee's arguments to their actual position at the callee's method entry. Hence arguments are moved twice. First to the outgoing argument of the caller area at the call site. Later the tail call method entry code moves the arguments to the caller's incoming argument area.