2008-11-25 9 views
14

GCC obsługuje modele obsługi wyjątków Setjump-longjump (sjlj) i Dwarf2 oparte na tabelach (dw2). Jaka jest różnica między tymi dwoma modelami i jak wybrać odpowiedni model? Dlaczego odwijanie w oparciu o tabelę Dwarf2 (dw2) jest bardziej wydajnym modelem? Rozumiem, że tych dwóch modeli nie można mieszać.Modele obsługi wyjątków GCC

referencyjny: Technology Preview: gcc-4.2.1-sjlj -2

Odpowiedz

16

Well, dwarf2 buduje tabele dla każdej funkcji, które zawierają co wywoływany zapisane rejestry są i gdzie w stosie są one zapisane, a gdzie wskaźnik ramki/adres zwrotny w callstack jest i kilka innych rzeczy. Jeśli użyjesz dwarf2, kompilator może użyć tych informacji i skutecznie przywrócić rejestry i odskoczyć do rozmówców w przypadku wyjątku. Operatorzy zaplecza muszą dostarczyć informacji w swoim kodzie generowania prologów ich implementacji, aby poinformować GCC, które rejestry są zapisywane w pamięci i kiedy wskaźnik ramki został zapisany i takie rzeczy.

Użycie setjmp/longjmp jest po prostu hackerem. Ponieważ setjmp/longjmp nie wie o strukturze rzucania funkcją, przywróci wszystkie rejestry zapisane w buforze skoku przez setjmp, nawet jeśli nie zostały one nadpisane przez funkcję rzucania. Naprawdę nie jestem ekspertem w tej dziedzinie, ale myślę, że to oczywiste, że nie będzie to skuteczne. Ponadto za każdym razem, gdy uruchamiasz blok try, należy wywołać setjmp, aby skonfigurować bufor zawierający zapisane rejestry, podczas gdy przy użyciu dwarf2 kompilator już dostarcza wszystkie niezbędne informacje w czasie kompilacji.

Jeśli backend nie dostarczy niezbędnych informacji, GCC automatycznie powróci do obsługi wyjątków opartej na setjmp/longjmp.

Uwaga Nie jestem ekspertem GCC. Właśnie przeportowałem toolchain na jakimś łatwym procesorze mojego profesora, w tym GCC. Mam nadzieję, że mogę ci trochę pomóc.

+0

Zauważ, że istnieje http://www.nongnu.org/libunwind/, który ma wydajną implementację 'setjmp', która sama jest oparta na tabelach karłów. Tak więc 'setjmp' po prostu musi przechowywać stackpointer i pozostawić resztę do już działającego odwijaka karłów. –

10

Unikaj sjlj. Każdy blok "try" wywoła setjmp, który zapisuje rejestry o wartości , a wydajność osiąga, nawet jeśli nie zostaną podnoszone wyjątki . Korzystanie z tabel, normalny przepływ kontroli nie powoduje żadnych kosztów wykonania. Tylko wtedy, gdy zostanie zgłoszony wyjątek , mechanizm obsługi wyjątków musi przechodzić przez tabele , aby dowiedzieć się, co należy zrobić.

Powiązane problemy