diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-02-14 13:23:51 +0100 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-02-14 13:23:51 +0100 |
commit | 758ff64c69e34965f8af5b2d6ffd65e8d7ab2150 (patch) | |
tree | 6d6b34f8c678862fe9b56c945a7b63f68502c245 /src/pkg/runtime/runtime.h | |
parent | 3e45412327a2654a77944249962b3652e6142299 (diff) | |
download | golang-upstream/2011-02-01.1.tar.gz |
Imported Upstream version 2011-02-01.1upstream/2011-02-01.1
Diffstat (limited to 'src/pkg/runtime/runtime.h')
-rw-r--r-- | src/pkg/runtime/runtime.h | 114 |
1 files changed, 97 insertions, 17 deletions
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index bde62833e..2c19f851e 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -63,7 +63,7 @@ typedef struct Eface Eface; typedef struct Type Type; typedef struct Defer Defer; typedef struct Panic Panic; -typedef struct hash Hmap; +typedef struct Hmap Hmap; typedef struct Hchan Hchan; typedef struct Complex64 Complex64; typedef struct Complex128 Complex128; @@ -199,18 +199,19 @@ struct G int32 sig; uintptr sigcode0; uintptr sigcode1; + uintptr sigpc; }; struct M { // The offsets of these fields are known to (hard-coded in) libmach. G* g0; // goroutine with scheduling stack void (*morepc)(void); - void* morefp; // frame pointer for more stack + void* moreargp; // argument pointer for more stack Gobuf morebuf; // gobuf arg to morestack // Fields not known to debuggers. - uint32 moreframe; // size arguments to morestack - uint32 moreargs; + uint32 moreframesize; // size arguments to morestack + uint32 moreargsize; uintptr cret; // return value from C uint64 procid; // for debuggers, but offset not hard-coded G* gsignal; // signal-handling G @@ -234,7 +235,7 @@ struct M uint32 freghi[16]; // D[i] msb and F[i+16] uint32 fflag; // floating point compare flags #ifdef __WINDOWS__ - void* gostack; // bookmark to keep track of go stack during stdcall + void* sehframe; #endif }; struct Stktop @@ -243,13 +244,10 @@ struct Stktop uint8* stackguard; uint8* stackbase; Gobuf gobuf; - uint32 args; + uint32 argsize; - // Frame pointer: where args start in old frame. - // fp == gobuf.sp except in the case of a reflected - // function call, which uses an off-stack argument frame. - uint8* fp; - bool free; // call stackfree for this frame? + uint8* argp; // pointer to arguments in old frame + uintptr free; // if free>0, call stackfree using free as size bool panic; // is this frame the top of a panic? }; struct Alg @@ -333,7 +331,7 @@ enum { struct Defer { int32 siz; - byte* sp; + byte* argp; // where args were copied from byte* pc; byte* fn; Defer* link; @@ -423,7 +421,7 @@ void runtime·minit(void); Func* runtime·findfunc(uintptr); int32 runtime·funcline(Func*, uint64); void* runtime·stackalloc(uint32); -void runtime·stackfree(void*); +void runtime·stackfree(void*, uintptr); MCache* runtime·allocmcache(void); void runtime·mallocinit(void); bool runtime·ifaceeq_c(Iface, Iface); @@ -438,13 +436,14 @@ void runtime·addfinalizer(void*, void(*fn)(void*), int32); void runtime·walkfintab(void (*fn)(void*)); void runtime·runpanic(Panic*); void* runtime·getcallersp(void*); +int32 runtime·mcount(void); void runtime·exit(int32); void runtime·breakpoint(void); void runtime·gosched(void); void runtime·goexit(void); void runtime·runcgo(void (*fn)(void*), void*); -void runtime·runcgocallback(G*, void*, void (*fn)()); +uintptr runtime·runcgocallback(G*, void*, void (*fn)()); void runtime·entersyscall(void); void runtime·exitsyscall(void); void runtime·startcgocallback(G*); @@ -508,11 +507,11 @@ void runtime·notewakeup(Note*); #define EACCES 13 /* - * low level go-called + * low level C-called */ uint8* runtime·mmap(byte*, uintptr, int32, int32, int32, uint32); void runtime·munmap(uint8*, uintptr); -void runtime·memclr(byte*, uint32); +void runtime·memclr(byte*, uintptr); void runtime·setcallerpc(void*, void*); void* runtime·getcallerpc(void*); @@ -583,10 +582,91 @@ Hmap* runtime·makemap_c(Type*, Type*, int64); Hchan* runtime·makechan_c(Type*, int64); void runtime·chansend(Hchan*, void*, bool*); -void runtime·chanrecv(Hchan*, void*, bool*); +void runtime·chanrecv(Hchan*, void*, bool*, bool*); void runtime·chanclose(Hchan*); bool runtime·chanclosed(Hchan*); int32 runtime·chanlen(Hchan*); int32 runtime·chancap(Hchan*); void runtime·ifaceE2I(struct InterfaceType*, Eface, Iface*); + +/* + * Stack layout parameters. + * Known to linkers. + * + * 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 = 128 bytes + * at the bottom. There may be other sequences lurking or yet to + * be written that require more stack. Morestack checks to make + * sure the stack has not completely overflowed and should catch + * such sequences. + */ +enum +{ +#ifdef __WINDOWS__ + // need enough room in guard area for exception handler. + // use larger stacks to compensate for larger stack guard. + StackSmall = 256, + StackGuard = 2048, + StackBig = 8192, + StackExtra = StackGuard, +#else + // byte offset of stack guard (g->stackguard) above bottom of stack. + StackGuard = 256, + + // checked frames are allowed to protrude below the guard by + // this many bytes. this saves an instruction in the checking + // sequence when the stack frame is tiny. + StackSmall = 128, + + // extra space in the frame (beyond the function for which + // the frame is allocated) is assumed not to be much bigger + // than this amount. it may not be used efficiently if it is. + StackBig = 4096, + + // extra room over frame size when allocating a stack. + StackExtra = 1024, +#endif +}; |