2008-11-25 15 views

Trả lời

16

Vâng, dwarf2 xây dựng lên bảng cho mỗi chức năng, có chứa những gì callee thanh ghi được và ở đâu trong ngăn xếp chúng được lưu lưu, và nơi con trỏ khung hình/địa chỉ trả lại trong callstack là và một số thứ khác. Nếu bạn sử dụng dwarf2, trình biên dịch có thể sử dụng những thông tin đó và khôi phục lại các thanh ghi hiệu quả, và chuyển lại cho người gọi trong trường hợp ngoại lệ. Các chương trình phụ trợ cần cung cấp thông tin trong mã tạo mã mở đầu của triển khai của chúng, để báo cho GCC biết các thanh ghi nào được lưu trữ, và khi con trỏ khung được lưu và các công cụ như vậy.

Sử dụng setjmp/longjmp chỉ là một hack. Vì setjmp/longjmp không biết về cấu trúc của hàm ném, nó sẽ khôi phục tất cả các thanh ghi được lưu trong bộ đệm nhảy bởi setjmp, ngay cả khi chúng không bị ghi đè bởi hàm ném. Tôi không thực sự là một chuyên gia cho điều này, nhưng tôi nghĩ rằng nó rõ ràng rằng điều này sẽ không hiệu quả. Ngoài ra, mỗi khi bạn bắt đầu một khối thử, setjmp phải được gọi để thiết lập bộ đệm chứa các thanh ghi đã lưu, trong khi khi sử dụng dwarf2, trình biên dịch đã cung cấp tất cả các thông tin cần thiết tại thời gian biên dịch.

Nếu các chương trình phụ trợ không cung cấp thông tin cần thiết, GCC sẽ tự động quay trở lại xử lý ngoại lệ dựa trên setjmp/longjmp.

Lưu ý rằng tôi không phải là chuyên gia về GCC. Tôi vừa chuyển chuỗi công cụ tới một bộ xử lý dễ dàng của giáo sư của tôi, bao gồm GCC. Tôi hy vọng tôi có thể giúp bạn một chút.

+0

Lưu ý rằng có tồn tại http://www.nongnu.org/libunwind/, có triển khai thực hiện 'setjmp' hiệu quả dựa trên bảng lùn. Vì vậy, 'setjmp' sau đó chỉ cần lưu trữ stackpointer và để phần còn lại cho lùn đã được làm việc. –

10

Tránh sjlj. Mỗi khối "thử" sẽ gọi setjmp mà lưu sổ đăng ký, một lần thực hiện ngay cả khi không có ngoại lệ được nâng lên. Sử dụng các bảng, luồng điều khiển bình thường không chịu chi phí thực hiện. Chỉ khi một ngoại lệ được nâng lên thì cơ chế xử lý ngoại lệ phải làm tròn thông qua các bảng để tìm ra việc cần làm.