79 votes

Pourquoi code serait activement essayer afin d’éviter l’optimisation d’appels terminaux ?

Le titre de la question peut-être un peu étrange, mais le truc, c'est que, autant que je sache, il n'y a rien qui parle contre la queue d'appel de l'optimisation à tout. Cependant, lors de la navigation sur des projets open source, je suis déjà tombé sur quelques fonctions qui cherchent activement à arrêter le compilateur de faire une queue appel d'optimisation, par exemple la mise en œuvre de CFRunLoopRef qui est pleine de ces hacks. Par exemple:

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
}

J'aimerais savoir pourquoi c'est apparemment si important, et sont en tout cas moi, en tant que normale développeur doit garder cela à l'esprit? Par exemple. sont là les pièges les plus courants avec la queue d'appel d'optimisation?

82voto

mattjgalloway Points 24217

Ma conjecture est qu'ici c'est pour s'assurer qu' __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ est dans la trace de la pile à des fins de débogage. Il a __attribute__((no inline)) qui conforte cette idée.

Si vous remarquez que la fonction va juste et rebondit à une autre fonction, de toute façon, donc c'est une forme de trampoline qui je ne peux que penser est là, avec une telle verbose nom à l'aide de débogage. Ce serait particulièrement utile étant donné que la fonction est d'appeler un pointeur de fonction qui a été enregistré ailleurs et, par conséquent, cette fonction peut ne pas les symboles de débogage sont accessibles.

Remarquez également les autres nommés de la même façon fonctions qui font des choses similaires - on dirait vraiment que c'est là pour l'aide à voir ce qui s'est passé à partir d'une trace. Gardez à l'esprit que ce qui est le noyau de Mac OS X code, et s'affichera dans les rapports de plantage et de processus exemples de rapports de trop.

33voto

Andrew White Points 23508

Ce n'est qu'une supposition, mais peut-être pour éviter une boucle infinie vs bombardement avec une erreur de dépassement de pile.

Puisque la méthode en question n'est pas de mettre quoi que ce soit sur la pile, il semblerait possible de la queue-d'appel de la récursivité d'optimisation pour produire du code qui permettrait d'entrer dans une boucle infinie, par opposition à la non-optimisé le code qui permettrait de mettre l'adresse de retour sur la pile, ce qui finirait par débordement en cas d'utilisation abusive.

La seule autre pensée que j'ai est liée à la préservation des appels sur la pile pour le débogage et la stacktrace l'impression.

21voto

NPE Points 169956

Une des raisons possibles sont de rendre le débogage et profilage plus facile (avec TCO, le frame de pile de parent disparaît, ce qui rend les traces de la pile plus difficile de donner un sens.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X