![]() |
1
16
那么,dwarf2为每个函数构建表,这些表包含被调用方保存的寄存器以及它们保存在堆栈中的位置,以及调用堆栈中的帧指针/返回地址,以及其他一些内容。如果使用dwarf2,编译器可以使用这些信息并有效地恢复寄存器,并在发生异常时跳转回调用方。后端需要在其实现的序言生成代码中提供信息,告诉GCC哪些寄存器是被调用保存的,什么时候保存了帧指针等等。 使用setjmp/longjmp仅仅是一种黑客行为。因为setjmp/longjmp不知道函数抛出的结构,所以它将恢复setjmp保存在跳转缓冲区中的所有寄存器,即使它们没有被抛出函数覆盖。我并不是这方面的专家,但我认为很明显这是不有效的。此外,每次启动一个try块时,都必须调用setjmp来设置包含保存寄存器的缓冲区,而当使用dwarf2时,编译器在编译时已经提供了所有必要的信息。 如果后端没有提供必要的信息,gcc将自动返回到基于setjmp/longjmp的异常处理。 注意,我不是海湾合作委员会的专家。我刚把工具链移植到我教授的一些简单的处理器上,包括gcc。希望我能帮你一点忙。 |
![]() |
2
10
避开SJLJ。每个“try”块都将调用setjmp, 保存寄存器,即使没有异常也会影响性能 提高了。使用表格,控制的正常流程 不产生执行成本。仅当引发异常时 异常处理机制必须卑躬屈膝吗 通过表格来找出要做什么。 |