繁体   English   中英

为什么 Golang 在切换上下文时只保存 %rsp、%rip 和 %rbp(没有其他被调用者保存的寄存器)?

[英]Why does Golang only save %rsp, %rip and %rbp(no other callee-saved registers) when switch context?

在一般用户线程上下文切换实现(像setjmp/longjmpfunction return方式),我们保存和恢复被调用者被保存的寄存器,但只有golang保存和恢复%rsp%rip%rbpgobuf

以x86_64的为例,golang保存与够程范围内runtime.gosave与恢复的goroutine背景runtime.gogo

那为什么golang会这样呢?

显然 GoLang 仍然使用低效的调用约定,其中唯一保留调用(又名非易失性)的寄存器是 RSP 和 RBP。

runtime.gosave的调用在编译器看来就像任何其他函数调用一样(即它最终在执行某些操作后返回,并且不会修改其自身堆栈框架之上的任何内容)。 像任何其他函数调用一样,调用者必须假设它破坏了所有调用破坏的(易失性)寄存器(除 RSP 和 RBP 之外的所有内容)。 因此,它想要在调用中幸存下来的任何值都必须溢出到堆栈槽(或它们所属的其他内存位置)。

出于同样的原因,C setjmp只需保存调用保留的寄存器。 和内核上下文切换功能是一样的。


这篇 2017 年的google 组帖子说这就是它的调用约定/ABI 的工作原理,从链接的代码来看,这似乎仍未得到改进。

Go 的调用约定也低效地传递堆栈上的所有参数,这与 x86-64 System V ABI 不同,后者传递寄存器中的前 6 个整数参数(和前 8 个 FP)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM