This is a creation in Article, where the information may have evolved or changed.
2012-11-30
Segmented stack Technology
The principle of splitstack technology in GCC
Http://gcc.gnu.org/wiki/SplitStacks
The important meaning of the segmented stack is that the initial allocation of the stack space is small, and then you can automatically grow the stack space arbitrarily. This makes it possible to open tens of thousands of threads or processes in a multithreaded environment without running out of memory.
Basic implementation
%gs registers the address of a TCB structure, which is the G structure in the go language. The stack base and Stack_guard are stored in this structure.
For a function that uses a staging stack, each time the function is entered, the first few instructions are to detect the%ESP compared to the Stack_guard, and if the super is to expand the stack space
Expansion stacks
All functions used to allocate stack space cannot use the staging stack itself. Introduces a property to control the generation of functions. Of course, make sure there is enough room to invoke the allocation function. The compiler adds a special identity to the compilation phase. Note.gnu-split-stack, when linking to a function that detects these tags, a special instruction is inserted. After the expansion, using the new stack requires some processing
Data based on the original stack%esp can be copied directly to the new stack. This does not cause problems with the address of the object that is stored in the stack. For the parameter function, because the parameters cannot be moved directly, compile with special processing. The parameter pointer used by the function is not based on the stack frame. For functions that return objects in the stack, the object must be returned to the original stack
When the stack is extended, the return address of the function is modified into a function that frees the allocated stack, sets the stack pointer back to the address of the caller's old stack block, and the stack pointer, which needs to be saved somewhere in the new stack space.
Compatibility
GCC uses the split stack function to compile the function of the split stack, adding the. Note.gnu-split-stack information. If you have these items on the link, you will be linked to the runtime library of the split stack. In the split stack implemented by GCC, hack the exit function so that the split stack space is processed when the final exit occurs.
Specific implementations in the Go language
The go language uses a segmented stack, which allows for a lot of goroutine.http://blog.nella.org/?p=849
The above-mentioned GCC how to achieve splitstack, its author is the author of Gccgo. In the implementation of the Go language, ideas and methods are consistent with the above.
The first few instructions after entering the function are taking%gs to%ECB and obtaining the address of the struct G. The first two domains of this structure are stackguard and stackbase.
I also observed that, as if go compiled program, did not use%EBP, probably because of the existing stack base in G. Detect Stackguard and%esp, If there is not enough space, it will be called to Runtime.morestack. This is a assembler function that can be found in the Asm386.s file
TEXT Runtime.morestack (SB), 7,$0
One of the 7 is to tell the compiler that this function does not use a staging stack
Runtime.morestack will store some information in the structure m
DX is a frame size, in AX is the arg size, these will be saved to the M struct, and the function return address, after saving these things will be emptied later, and then the new stack and the old stack information can link up.
When the Morestack function saves what is needed, it switches to the stack of the scheduler and then gives the controller to Runtime.newstack
Note that the call to Runtime.newstack is called, and the stack of the scheduler is used, and the exit of the function is a bit special.
The allocation of stack space using the normal go runtime space allocation technology, that is, garbage collection. But there are some special, not entirely directly from the garbage collection of the pond, back to the garbage collection of the pond.
Runtime.newstack does not return to caller morestack. Regardless of reflect related things, it does the thing is to allocate a piece of memory, put a stktop structure in the head, the special way to exit.
When you clear the stack, the information about the stacks that are saved in the new stack will work.
Exit is using Gogocall, which is a function on the scheduler implementation context switch. The equivalent of a direct jump past rather than a function call protocol. The saved function return address is set to a post-processing function, so when encountering the next RET instruction, it will jump to the More.lessstack function, which is exactly the opposite of the Morestack function. Then I went to work in the new stack.
Repeat the process again:
- Use the function header of the segment stack to detect%ESP and Stackguard, and tune to Runtime.morestack
- The main function of the Runtime.more function is to save some information about the current stack. Then switch to the debugger stack to call Runtime.newstack
- The main function of the Runtime.newstack function is to allocate space, decorate this space, and move the old frame and arg to new space
- Use Gogocall to switch to the newly allocated stack, Gogocall used by JMP to return to the interrupted function
- Continue execution when encountering a RET instruction will return to runtime.less,less do things contrary to more, it is necessary to prepare from newstack to old stack the whole process is a bit like an interrupt, interrupt processing when the site was saved, get a new stack, Resumes to the new stack when the interrupt is resumed, and runs back from Runtime.less to return.
Conclusion
This paper is a study of splitstack, mainly the principle of the segmented stack in GCC and the specific implementation of the go language.