JVM이 다중 언어를 생각하고 디자인된 IR은 아니다보니 많은 문제점이 있습니다. 특히 함수 언어 구현할 때 tail call을 구현할 방법이 없다는 게 문제입니다. tail call을 하려면 stack을 제거해야 하는데 일반적인 invokevirtual 같은 걸로는 구현할 수가 없으니깐요. 그래서 함수 언어하는 애들이 bytecode에 tail recursion하는 invoke instruction 넣어달라고 애걸복걸했는데 안 넣어줬다죠.
자바 bytecode 단에서는 callstack을 조작할 수 있는 방법이 없습니다. 하지만 tail recursion이 완전히 불가능하지는 않을 겁니다. invokevirtual이나 invokestatic 같은 bytecode로 구현 안 하고 다른 복잡한 방법으로 했겠지요.
가장 쉬운 방법으로는 전체 프로그램을 하나의 큰 함수로 만들고 모든 함수 호출을 jump나 switch 문으로 만드는 방법을 쓸 수 있겠죠. 그닥 실용적이지는 않겠지만.
JavaVM을 대상으로 언어를 만들면 이런저런 이점이 많으니까요.
JVM이 다중 언어를 생각하고 디자인된 IR은 아니다보니 많은 문제점이 있습니다. 특히 함수 언어 구현할 때 tail call을 구현할 방법이 없다는 게 문제입니다. tail call을 하려면 stack을 제거해야 하는데 일반적인 invokevirtual 같은 걸로는 구현할 수가 없으니깐요. 그래서 함수 언어하는 애들이 bytecode에 tail recursion하는 invoke instruction 넣어달라고 애걸복걸했는데 안 넣어줬다죠.
(예) http://blogs.sun.com/jrose/entry/tailcallsinthevm
Sun 입장에서야 하위 호환성도 문제도 있고, tailcall 같은 거 bytecode에 더해지면 bytecode verifier 로직도 다 바뀌어어야 하고, 쉬운 일이 아니긴 합니다.
JVM 명세상 꼬리 재귀 최적화가 불가능한 건가요? 처음 알았어요.
자바 bytecode 단에서는 callstack을 조작할 수 있는 방법이 없습니다. 하지만 tail recursion이 완전히 불가능하지는 않을 겁니다. invokevirtual이나 invokestatic 같은 bytecode로 구현 안 하고 다른 복잡한 방법으로 했겠지요.
가장 쉬운 방법으로는 전체 프로그램을 하나의 큰 함수로 만들고 모든 함수 호출을 jump나 switch 문으로 만드는 방법을 쓸 수 있겠죠. 그닥 실용적이지는 않겠지만.
아래 논문 보면 몇 가지 방법이 더 소개되어 있으니 참고하세요.
http://citeseer.ist.psu.edu/523470.html
내용과는 관계 없지만. IR은 무엇의 약자인가요?;
IR은 intermediate representation의 약자입니다. 컴파일러가 최종 코드 뱉어내기 전에 만드는 중간 언어를 지칭합니다. 자바 컴파일러 입장에서는 IR을 최종 코드로 볼 수도 있지만, 큰 맥락에서는 보통 바이트코드를 일종의 IR로 봅니다.