코드가 테일콜 최적화를 적극적으로 막으려고 하는 이유는 무엇입니까?
질문의 제목은 조금 이상할 수 있지만, 제가 알기론 테일콜 최적화에 반대되는 것은 전혀 없습니다.그러나 오픈소스 프로젝트를 브라우징하던 중 컴파일러가 테일콜 최적화를 하지 못하도록 적극적으로 시도하는 몇 가지 함수를 발견했다.예를 들어, 그러한 해킹으로 가득 찬 CFRunLoopRef의 구현이다.예를 들어 다음과 같습니다.
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline));
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
if (func) {
func(observer, activity, info);
}
getpid(); // thwart tail-call optimization
}
이것이 왜 그렇게 중요한지 알고 싶습니다만, 일반 개발자로서 이 점에 유의해야 할 경우가 있습니까?예를 들어 테일콜 최적화에 공통적인 함정이 있습니까?
제 추측으로는, 그 목적은__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
는 디버깅을 위해 스택트레이스에 있어요정말 그랬어요.__attribute__((no inline))
이 아이디어를 뒷받침하는 거죠.
이 함수는 다른 함수로 바운스되기 때문에 디버깅에 도움이 되는 자세한 이름을 가진 트램펄린밖에 없다고 생각합니다.이는 함수가 다른 곳에서 등록된 함수 포인터를 호출하고 있기 때문에 해당 함수가 디버깅 심볼에 액세스할 수 없는 경우 특히 유용합니다.
유사한 기능을 수행하는 다른 유사한 이름들도 주목하십시오. 역추적에서 무슨 일이 일어났는지 볼 수 있는 것처럼 보입니다.이것은 핵심 Mac OS X 코드이며 크래시 보고서 및 처리 샘플 보고서에도 표시됩니다.
이는 추측에 불과하지만 무한 루프 대 스택오버플로우 에러로 인한 폭탄아웃을 피하기 위해서입니다.
문제의 메서드는 스택에 아무것도 배치하지 않기 때문에 테일콜 재귀 최적화는 최적화되지 않은 코드와 반대로 무한 루프에 들어가는 코드를 생성할 수 있습니다.이 코드는, 오용시에 스택에 리턴 주소가 오버플로우 됩니다.
디버깅과 스택트레이스 인쇄를 위해 스택에 콜을 보관하는 것 외에 생각할 수 있는 것은 없습니다.
잠재적인 이유 중 하나는 디버깅과 프로파일링을 쉽게 하기 위함입니다(TCO를 사용하면 부모 스택프레임이 사라지기 때문에 스택트레이스를 이해하기 어려워집니다).
언급URL : https://stackoverflow.com/questions/10790737/why-would-code-actively-try-to-prevent-tail-call-optimization
'IT이야기' 카테고리의 다른 글
Meteor + Vue + Typescript 프로젝트에 ESLint 추가 (0) | 2022.06.22 |
---|---|
런타임에 Java 주석 검색 (0) | 2022.06.22 |
vue 라우터가 쿼리 매개 변수를 변경할 때 맨 위로 스크롤 방지 (0) | 2022.06.21 |
Vue 캔버스 구성 요소를 JS 개체에서 분리하는 중 (0) | 2022.06.21 |
상태를 사용하여 형식을 바인딩하는 동안 Nuxt JS에서 변환 오류를 가져오는 중 (0) | 2022.06.21 |