Skip to content

Commit 0609df1

Browse files
committed
add runtime.gogo
1 parent 7a4fc21 commit 0609df1

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

scheduler.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,38 @@ goexit0 --> schedule
11931193

11941194
#### gogo
11951195

1196-
TODO
1196+
runtime.gogo 是汇编完成的,功能就是执行 `go func()` 的这个 `func()`,可以看到功能主要是把 g 对象的 gobuf 里的内容搬到寄存器里。然后从 `gobuf.pc` 寄存器存储的指令位置开始继续向后执行。
1197+
1198+
```go
1199+
// void gogo(Gobuf*)
1200+
// restore state from Gobuf; longjmp
1201+
TEXT runtime·gogo(SB), NOSPLIT, $16-8
1202+
MOVQ buf+0(FP), BX // gobuf
1203+
MOVQ gobuf_g(BX), DX
1204+
MOVQ 0(DX), CX // make sure g != nil
1205+
get_tls(CX)
1206+
MOVQ DX, g(CX)
1207+
MOVQ gobuf_sp(BX), SP // restore SP
1208+
MOVQ gobuf_ret(BX), AX
1209+
MOVQ gobuf_ctxt(BX), DX
1210+
MOVQ gobuf_bp(BX), BP
1211+
MOVQ $0, gobuf_sp(BX) // clear to help garbage collector
1212+
MOVQ $0, gobuf_ret(BX)
1213+
MOVQ $0, gobuf_ctxt(BX)
1214+
MOVQ $0, gobuf_bp(BX)
1215+
MOVQ gobuf_pc(BX), BX
1216+
JMP BX
1217+
```
1218+
1219+
当然,这里还是有一些和手写汇编不太一样的,看着比较奇怪的地方,`gobuf_sp(BX)` 这种写法按说标准 plan9 汇编中 `gobuf_sp` 只是个 `symbol`,没有任何偏移量的意思,但这里却用名字来代替了其偏移量,这是怎么回事呢?
1220+
1221+
实际上这是 runtime 的特权,是需要链接器配合完成的,再来看看 gobuf 在 runtime 中的 struct 定义开头部分的注释:
1222+
1223+
```go
1224+
// The offsets of sp, pc, and g are known to (hard-coded in) libmach.
1225+
```
1226+
1227+
这下知道怎么回事了吧,链接器会补助我们把这个换成偏移量。。
11971228

11981229
#### execute
11991230

0 commit comments

Comments
 (0)