2008-11-25 7 views
14

GCC prend en charge les modèles de gestion des exceptions Setjump-longjump (sjlj) et Dwarf2 à base de table (dw2). Quelle est la différence entre les deux modèles et comment choisir le modèle approprié? Pourquoi le Dwarf2 est-il le modèle le plus efficace? Je comprends que les deux modèles ne peuvent pas être mélangés.Modèles de gestion des exceptions de GCC

Référence: Technology Preview: gcc-4.2.1-sjlj -2

Répondre

16

Eh bien, DWARF2 construit des tables pour toutes les fonctions, qui contiennent ce que les registres sauvés callee sont et où dans la pile, ils sont enregistrés, et où le pointeur de trame/adresse de retour dans le callstack est et quelques autres trucs. Si vous utilisez dwarf2, le compilateur peut utiliser ces informations et restaurer efficacement les registres, et revenir aux appelants en cas d'exception. Les backends doivent fournir des informations dans le code de génération de prologue de leurs implémentations, pour indiquer à GCC quels registres sont sauvegardés en mode callee, et quand le pointeur de frame a été sauvegardé et ainsi de suite. L'utilisation de setjmp/longjmp est juste un hack. Comme setjmp/longjmp ne connaît pas la structure du lancement de la fonction, il restaurera tous les registres sauvegardés dans le jump-buffer par setjmp, même s'ils n'ont pas été écrasés par la fonction de lancement. Je ne suis pas vraiment un expert pour ça, mais je pense qu'il est évident que cela ne sera pas efficace. De plus, chaque fois que vous lancez un bloc try, setjmp doit être appelé pour configurer le tampon contenant les registres sauvegardés, tandis que lorsque vous utilisez dwarf2, le compilateur fournit déjà toutes les informations nécessaires au moment de la compilation. Si les backends ne fournissent pas les informations nécessaires, GCC retournera automatiquement à la gestion des exceptions basée sur setjmp/longjmp.

Notez que je ne suis pas un expert GCC. J'ai juste porté la chaîne d'outils à un processeur facile de mon professeur, y compris GCC. J'espère que je pourrais vous aider un peu.

+0

Notez qu'il existe http://www.nongnu.org/libunwind/, qui possède une implémentation 'setjmp' efficace qui est elle-même basée sur des tables naines. Donc 'setjmp' a juste besoin de stocker le stackpointer et de laisser le reste au dérouteur nain déjà actif. –

10

Évitez sjlj. Chaque bloc "try" appellera setjmp qui enregistre les registres , un hit de performance même si aucune exception n'est levée. En utilisant des tables, le flux normal de contrôle n'entraîne aucun coût d'exécution. Ce n'est que lorsqu'une exception est levée que le mécanisme de gestion des exceptions doit appliquer à travers les tables pour déterminer ce qu'il faut faire.

Questions connexes