¿Por qué el código intentaría activamente evitar la optimización de llamadas de cola?


El título de la pregunta puede ser un poco extraño, pero la cosa es que, por lo que sé, no hay nada que hable en contra de la optimización de llamadas de cola en absoluto. Sin embargo, mientras navegaba por proyectos de código abierto, ya me encontré con algunas funciones que intentan activamente detener al compilador de hacer una optimización de llamada de cola, por ejemplo, la implementación de CFRunLoopRef que está llena de tales hacks. Por ejemplo:

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
}

Me encantaría saber por qué esto es aparentemente tan importante, y hay algunos casos donde yo como desarrollador normal debería mantener esto es mente también? Eg. ¿hay dificultades comunes con la optimización de llamadas de cola?

Author: Jonathan Leffler, 2012-05-29

3 answers

Mi conjetura aquí es que es para asegurarse de que __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ está en el seguimiento de la pila para fines de depuración. Tiene __attribute__((no inline)) que respalda esta idea.

Si te das cuenta, esa función simplemente va y rebota a otra función de todos modos, por lo que es una forma de trampolín que solo puedo pensar que está allí con un nombre tan detallado para ayudar a la depuración. Esto sería especialmente útil dado que la función está llamando a un puntero de función que se ha registrado desde otro lugar y, por lo tanto, esa función puede no tener símbolos de depuración accesibles.

Observe también las otras funciones con nombre similar que hacen cosas similares - realmente parece que está ahí para ayudar a ver lo que ha sucedido desde una traza inversa. Tenga en cuenta que este es el código principal de Mac OS X y se mostrará en los informes de fallos y también procesará los informes de muestra.

 81
Author: mattjgalloway,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-06 12:04:28

Esto es solo una suposición, pero tal vez para evitar un bucle infinito vs bombardeo con un error de desbordamiento de pila.

Dado que el método en cuestión no pone nada en la pila, parecería posible que la optimización de recursión de llamada de cola produzca código que entraría en un bucle infinito en lugar del código no optimizado que pondría la dirección de retorno en la pila que eventualmente se desbordaría en caso de mal uso.

El único otro pensamiento que tengo está relacionado con preservar las llamadas en la pila para la depuración y la impresión de stacktrace.

 33
Author: Andrew White,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-28 21:56:30

Una posible razón es facilitar la depuración y la creación de perfiles (con TCO, el marco de la pila principal desaparece, lo que hace que los rastros de pila sean más difíciles de entender.)

 21
Author: NPE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-28 21:59:49