分段栈的重要意义就在于,栈空间初始分配很小的大小,然后可以随便需要自动地增长栈空间.这样在多线程环境中就可以开千千万万个线程或协程而不至于耗尽内存.
基本实现
%gs寄存器存一个tcb结构的地址,go语言中是G这个结构体.这个结构中存了栈基址和stack_guard
对于使用分段栈的函数,每次进入函数后,前几条指令就是先检测%esp跟stack_guard比较,如果超了就要扩展栈空间
扩展栈
所有用于分配栈空间的函数本身不能使用分段栈.引入一个属性来控制函数的生成.当然,还要保证有足够的空间来调用分配函数。编译器在编译阶段加入特殊的标识.note.GNU-split-stack,链接时对于检测到有这些标签的函数,就会插入特殊指令。扩展完之后,使用新栈之间,需要一些处理
基于原栈%esp的数据都可以直接复制到新栈中来.对于栈中存的是对象的地址,这样做不会造成问题。对于带参函数,因为参数不能直接搬,编译时要特殊处理.函数使用的参数指针不是基于栈帧的.对于在栈中返回对象的函数,对象必须返回到原栈上
扩展栈时,函数的返回地址会被修改成一个函数,这个函数会释放分配的栈块,将栈指针重新设置成调用者旧栈块的地址,栈指针等,需要在新栈空间中的某处保存着.
Read full article from 分段栈技术
No comments:
Post a Comment