This optimization is simply a goto to the start of the function, and reassignment of the arguments. It doesn't prevent exception handling in any way. It doesn't interfere with debugging tools.
The point is that when your program throws an exception, and prints the stacktrace, you will only see a single stack frame for your method. Even if it recursively descended into itself multiple times. This is counter-intuitive as you don't see the evidence of the recursive calls in the stack trace. If you're unaware that tail recursion optimization was performed, you won't know why it seems like your method was only called once.
The program flow stays the same, only the diagnostic information of the program changes.
This optimization messes with the stack trace, so if you throw an exception in one of the recursively called methods, it will only show up only once in the stack trace. This may very well cause confusion in cases where the developer is not aware that such optimizations have been performed.
However, you can still perform the optimization on your Java bytecode classes, and then pass them to Graal. (If I understand Graal correctly.)
Hey HN! Over the past few years, I've developed saker.build and decided to open-source it. It supports all features that a modern build system should, it's language idependent, performs fast incremental and clean builds, allows distributed compilation, and supports build cache (WIP).
It was designed to be extensible, you can create your own build tasks or even replace and mix different scripting languages for your build. There's an Eclipse plug-in with support for writing build scripts (content assist, inline documentation, outline).
It may still have some rough edges, but I'm curious what you think!
The point is that when your program throws an exception, and prints the stacktrace, you will only see a single stack frame for your method. Even if it recursively descended into itself multiple times. This is counter-intuitive as you don't see the evidence of the recursive calls in the stack trace. If you're unaware that tail recursion optimization was performed, you won't know why it seems like your method was only called once.
The program flow stays the same, only the diagnostic information of the program changes.