对象分配到栈的相关源码

对象分配到栈的相关源码

怎么看对象分配到栈的源码,是反编译后的那些汇编代码吗?

src/runtime/stack.go 这个文件是做什么,和上面问题相关吗?下面注释没看明白。

Stack layout parameters.

Included both by runtime (compiled via 6c) and linkers (compiled via gcc).


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):


guard = g->stackguard

frame = function's stack frame size

argsize = size of function arguments (call + return)


stack frame size <= StackSmall:

CMPQ guard, SP

JHI 3(PC)

MOVQ m->morearg, $(argsize << 32)

CALL morestack(SB)


stack frame size > StackSmall but < StackBig

LEAQ (frame-StackSmall)(SP), R0

CMPQ guard, R0

JHI 3(PC)

MOVQ m->morearg, $(argsize << 32)

CALL morestack(SB)


stack frame size >= StackBig:

MOVQ m->morearg, $((argsize << 32) | frame)

CALL morestack(SB)


The bottom StackGuard - StackSmall bytes are important: there has

to be enough room to execute functions that refuse to check for

stack overflow, either because they need to be adjacent to the

actual caller's frame (deferproc) or because they handle the imminent

stack overflow (morestack).


For example, deferproc might call malloc, which does one of the

above checks (without allocating a full frame), which might trigger

a call to morestack.  This sequence needs to fit in the bottom

section of the stack.  On amd64, morestack's frame is 40 bytes, and

deferproc's frame is 56 bytes.  That fits well within the

StackGuard - StackSmall bytes at the bottom.

The linkers explore all possible call traces involving non-splitting

functions to make sure that this limit cannot be violated.


正在回答

登陆购买课程后可参与讨论,去登陆

1回答

要看和栈分配相关的,能看懂 stack 的操作汇编就行,主要就是 sub rsp,然后在 rsp 范围以内变量搬来搬去


runtime 里这个文件主要是栈空间的管理,不是栈上变量的管理,Go 的栈空间分配走 newstack,morestack 这些逻辑,也是一套比较复杂的流程

  • 快哉快哉 提问者 #1

    正好学习了下 https://xargin.com/plan9-assembly/   ?

    然后正好看到了

    https://draveness.me/golang/docs/part3-runtime/ch07-memory/golang-stack-management/#%E6%A0%88%E5%88%9D%E5%A7%8B%E5%8C%96

    里的栈空间管理,看了下源码, stackinit() 里 stackpool 和 stackLarge 确实都和 mspan有关 ,文章里说到

    “这两个用于分配空间的全局变量都与内存管理单元 runtime.mspan 有关,我们可以认为 Go 语言的栈内存都是分配在堆上的,运行时初始化会调用 runtime.stackinit 初始化这些全局变量”

    我们可以认为 Go 语言的栈内存都是分配在堆上的

    上面这句话是说 栈空间的那块分配地址 其实是放在 堆上面管理的? 有点不太理解,似懂非懂。。。

    2021-06-17 19:04:05
  • Xargin 回复 提问者 快哉快哉 #2

    在操作系统的语境下,栈内存主要指的是线程的栈,

    Go 语言里,goroutine 的栈是另外管理的,


    http://img1.sycdn.imooc.com//climg/60cb4080099e026515381572.jpg

    本质上相当于被分配到了这张图的 Heap 区域,当然,g0 的栈用的还是线程栈~

    2021-06-17 20:31:42
  • Xargin 回复 提问者 快哉快哉 #3

    上面这句话是说 栈空间的那块分配地址 其实是放在 堆上面管理的


    你这个理解没错,普通 goroutine 的栈空间,就是在 Heap 区管理的

    2021-06-17 20:35:01
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师