为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 Golang 在切换上下文时只保存 %rsp、%rip 和 %rbp?

为什么 Golang 在切换上下文时只保存 %rsp、%rip 和 %rbp?

Go
拉风的咖菲猫 2022-05-18 09:40:51
在一般的用户线程上下文切换实现(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)。


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 235 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信