Ответ 1
Существуют различные уровни, на которых может поддерживаться оптимизация вызовов хвоста. JIT действительно несет ответственность за многие оптимизации, которые происходят. Сам компилятор С# даже не выполняет метод inline, то есть ответственность компилятора JIT. Компилятор С# может использовать код транзакции Tailcall IL, обозначающий вызов как хвостовой вызов, однако я считаю, что никакая версия компилятора С# не делает этого. Компилятору JIT разрешено выполнять оптимизацию хвостовых вызовов всякий раз, когда он сочтет нужным. В частности, я считаю, что только 64-разрядная JIT делает это. В этом сообщении сообщается о нескольких сценариях, в которых JIT64 не может использовать оптимизацию хвостовых вызовов. Я уверен, что критерии могут быть изменены, поскольку они работают над переписыванием JIT-компилятора под кодовым названием RyuJIT.
Если вам нужен короткий пример программы, которая может использовать TCO, попробуйте следующее:
class Program
{
static void Main(string[] args)
{
Test(1);
}
private static void Test(int i)
{
Console.WriteLine(i);
Test(i + 1);
}
}
Задайте проект для сборки Release/x64 (или AnyCPU без предпочтения 32-разрядной версии) и начните без присоединенного отладчика. Программа будет работать вечно. Если я не буду делать все это, я получаю исключение stackoverflow около 20947.