在一般的用戶線程上下文切換實現(like setjmp/longjmpand the function returnway)中,我們保存和恢復被調用者保存的寄存器,但golang只保存和恢復%rsp,%rip并且%rbp在gobuf中。以 x86_64 為例,golang 用 runtime.gosave 保存 goroutine 上下文,用runtime.gogo恢復goroutine 上下文。那么為什么golang會這樣呢?
1 回答

小怪獸愛吃肉
TA貢獻1852條經驗 獲得超1個贊
顯然,GoLang 仍然使用低效的調用約定,其中唯一保留調用(也稱為非易失性)的寄存器是 RSP 和 RBP。
對編譯器的調用runtime.gosave
與任何其他函數調用一樣(即它最終在執行某些操作后返回,并且不會修改其自己的堆??蚣苤系娜魏蝺热荩?。與任何其他函數調用一樣,調用者必須假定它會破壞所有調用破壞(易失性)寄存器(除了 RSP 和 RBP 之外的所有寄存器)。因此,它希望在調用中存活的任何值都必須溢出到堆棧槽(或它們所屬的其他內存位置)。
出于同樣的原因,Csetjmp
只需要保存調用保留寄存器。和內核上下文切換功能是一樣的。
這篇 2017 年谷歌群組帖子說這就是它的調用約定/ABI 的工作方式,從鏈接的代碼來看,它看起來仍然沒有得到改進。
Go 的調用約定也低效地傳遞堆棧上的所有參數,這與 x86-64 System V ABI 不同,后者傳遞寄存器中的前 6 個整數參數(和前 8 個 FP)。
- 1 回答
- 0 關注
- 266 瀏覽
添加回答
舉報
0/150
提交
取消