2008-11-25 12 views
14

GCC unterstützt die Ausnahmebehandlungsmodelle Setjump-longjump (sjlj) und Dwarf2 table-based unwinding (dw2). Was ist der Unterschied zwischen den beiden Modellen und wie wählt man das passende Modell? Warum ist das tabellenbasierte Abwickeln von Dwarf2 (dw2) das effizientere Modell? Ich verstehe, dass die beiden Modelle nicht gemischt werden können.Ausnahmebehandlungsmodelle von GCC

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

Antwort

16

Nun, dwarf2 für jede Funktion baut Tabellen, die das enthalten, was die Angerufene Register gespeichert werden und wo in dem Stapel sie gespeichert werden, und wo die Rahmenzeiger/Rücksendeadresse in der Aufrufliste ist und einige andere Sachen. Wenn Sie zwerg2 verwenden, kann der Compiler diese Informationen verwenden und die Register effektiv wiederherstellen und im Falle einer Ausnahme zu den Aufrufern zurückspringen. Die Backends müssen Informationen im Prolog-erzeugenden Code ihrer Implementierungen bereitstellen, um GCC mitzuteilen, welche Register auf Abruf gespeichert werden und wann der Frame-Zeiger gespeichert wurde und so etwas.

Mit setjmp/longjmp ist nur ein Hack. Da setjmp/longjmp nicht über die Struktur des Funktionsworfens Bescheid weiß, stellt es alle im jump-buffer gespeicherten Register durch setjmp wieder her, auch wenn sie nicht durch die Wurffunktion übersteuert wurden. Ich bin nicht wirklich ein Experte dafür, aber ich denke, es ist offensichtlich, dass dies nicht effizient sein wird. Jedes Mal, wenn Sie einen try-Block starten, muss setjmp aufgerufen werden, um den Puffer mit den gespeicherten Registern einzurichten, während bei Verwendung von dwarf2 der Compiler bereits alle erforderlichen Informationen zur Kompilierungszeit bereitstellt.

Wenn die Backends nicht die erforderlichen Informationen bereitstellen, greift GCC automatisch auf die auf setjmp/longjmp basierende Ausnahmebehandlung zurück.

Hinweis ich bin kein GCC-Experte. Ich habe die Toolchain einfach auf einen einfachen Prozessor meines Professors portiert, inklusive GCC. Ich hoffe ich konnte dir ein bisschen helfen.

+0

Beachten Sie, dass http://www.nongnu.org/libunwind/ vorhanden ist, das über eine effiziente 'setjmp'-Implementierung verfügt, die wiederum auf Zwergtabellen basiert. Also muss 'setjmp' nur den Stackpointer speichern und den Rest dem bereits funktionierenden Zwergabwickler überlassen. –

10

Vermeiden sjlj. Jeder "try" -Block ruft setjmp auf, welches Register speichert, ein Performance-Hit, selbst wenn keine Ausnahmen ausgelöst werden. Bei Verwendung von Tabellen verursacht der normale Ablauf der Steuerung keine Ausführungskosten. Nur wenn eine Exception ausgelöst wird muss der Ausnahmebehandlungsmechanismus durch die Tabellen kriechen, um herauszufinden, was zu tun ist.