summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/runtime.h
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
committerOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
commit758ff64c69e34965f8af5b2d6ffd65e8d7ab2150 (patch)
tree6d6b34f8c678862fe9b56c945a7b63f68502c245 /src/pkg/runtime/runtime.h
parent3e45412327a2654a77944249962b3652e6142299 (diff)
downloadgolang-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.h114
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
+};