dpd7195 2019-02-01 08:46
浏览 115

为什么在make([] int,14)中有一个runtime.morestack但在make([] int,13)中没有?

I've already known that the runtime.morestack will cause goroutine context switch (If the sysmon goroutine has marked it "has to switch").

And when I do some experiment around this, I've found an interesting fact.

Compare the following codes.

func main() {
    _ = make([]int, 13)
}

func main() {
    _ = make([]int, 14)
}

And compile them by running the following command: (Tried in go1.9 and go 1.11)

$ go build -gcflags "-S -l -N" x.go

You may find a major difference that the first outputs contains CALL runtime.morestack_noctxt(SB) while the second doesn't.

I guess it is an optimization, but why?

  • 写回答

1条回答 默认 最新

  • dtrz17917 2019-02-02 08:58
    关注

    Finally, I got the answer.

    • Making a slice that less than 65,536 bytes and not escaped from the func will be allocated in the stack, not the heap.

    • StackGuard0 will be higher than the stack's lowest address by at least 128 bytes. (Even after downsizing)

    • make([]int, 13) will allocate 128 bytes memories in total.

    sizeof(struct slice) + 13 * 8 = 24 + 104 = 128.

    So the answer is clear, this is an optimization for amd64.

    For a leaf function, if it used less than 128 bytes memories, the compiler wouldn't generate codes that checking if the stack is overflowed (because there are enough spaces).

    Here is the explanation in go/src/runtime/stack.go

    The per-goroutine g->stackguard is set to point StackGuard bytes above the bottom of the stack. Each function compares its stack pointer against g->stackguard to check for overflow. To cut one instruction from the check sequence for functions with tiny frames, the stack is allowed to protrude StackSmall bytes below the stack guard. Functions with large frames don't bother with the check and always call morestack. The sequences are (for amd64, others are similar):

    评论

报告相同问题?

悬赏问题

  • ¥15 怎么获取下面的: glove_word2id.json和 glove_numpy.npy 这两个文件
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug