Commit ccdbb8a6 authored by Russ Cox's avatar Russ Cox

runtime: more stack split fixes

Found by stkcheck after 6l, 8l bug fixes Luuk is about to submit.

R=lvd
CC=golang-dev
https://golang.org/cl/4306047
parent aa798d26
...@@ -577,19 +577,30 @@ newselect(int32 size, Select **selp) ...@@ -577,19 +577,30 @@ newselect(int32 size, Select **selp)
runtime·printf("newselect s=%p size=%d\n", sel, size); runtime·printf("newselect s=%p size=%d\n", sel, size);
} }
// cut in half to give stack a chance to split
static void selectsend(Select **selp, Hchan *c, void *pc);
// selectsend(sel *byte, hchan *chan any, elem any) (selected bool); // selectsend(sel *byte, hchan *chan any, elem any) (selected bool);
#pragma textflag 7 #pragma textflag 7
void void
runtime·selectsend(Select *sel, Hchan *c, ...) runtime·selectsend(Select *sel, Hchan *c, ...)
{ {
int32 i, eo;
Scase *cas;
byte *ae;
// nil cases do not compete // nil cases do not compete
if(c == nil) if(c == nil)
return; return;
selectsend(&sel, c, runtime·getcallerpc(&sel));
}
static void
selectsend(Select **selp, Hchan *c, void *pc)
{
int32 i, eo;
Scase *cas;
byte *ae;
Select *sel;
sel = *selp;
i = sel->ncase; i = sel->ncase;
if(i >= sel->tcase) if(i >= sel->tcase)
runtime·throw("selectsend: too many cases"); runtime·throw("selectsend: too many cases");
...@@ -597,7 +608,7 @@ runtime·selectsend(Select *sel, Hchan *c, ...) ...@@ -597,7 +608,7 @@ runtime·selectsend(Select *sel, Hchan *c, ...)
cas = runtime·mal(sizeof *cas + c->elemsize - sizeof(cas->u.elem)); cas = runtime·mal(sizeof *cas + c->elemsize - sizeof(cas->u.elem));
sel->scase[i] = cas; sel->scase[i] = cas;
cas->pc = runtime·getcallerpc(&sel); cas->pc = pc;
cas->chan = c; cas->chan = c;
eo = runtime·rnd(sizeof(sel), sizeof(c)); eo = runtime·rnd(sizeof(sel), sizeof(c));
...@@ -605,7 +616,7 @@ runtime·selectsend(Select *sel, Hchan *c, ...) ...@@ -605,7 +616,7 @@ runtime·selectsend(Select *sel, Hchan *c, ...)
cas->so = runtime·rnd(eo+c->elemsize, Structrnd); cas->so = runtime·rnd(eo+c->elemsize, Structrnd);
cas->kind = CaseSend; cas->kind = CaseSend;
ae = (byte*)&sel + eo; ae = (byte*)selp + eo;
c->elemalg->copy(c->elemsize, cas->u.elem, ae); c->elemalg->copy(c->elemsize, cas->u.elem, ae);
if(debug) if(debug)
...@@ -613,35 +624,19 @@ runtime·selectsend(Select *sel, Hchan *c, ...) ...@@ -613,35 +624,19 @@ runtime·selectsend(Select *sel, Hchan *c, ...)
sel, cas->pc, cas->chan, cas->so); sel, cas->pc, cas->chan, cas->so);
} }
// cut in half to give stack a chance to split
static void selectrecv(Select *sel, Hchan *c, void *pc, void *elem, bool*, int32 so);
// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool); // selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
#pragma textflag 7 #pragma textflag 7
void void
runtime·selectrecv(Select *sel, Hchan *c, void *elem, bool selected) runtime·selectrecv(Select *sel, Hchan *c, void *elem, bool selected)
{ {
int32 i;
Scase *cas;
// nil cases do not compete // nil cases do not compete
if(c == nil) if(c == nil)
return; return;
i = sel->ncase; selectrecv(sel, c, runtime·getcallerpc(&sel), elem, nil, (byte*)&selected - (byte*)&sel);
if(i >= sel->tcase)
runtime·throw("selectrecv: too many cases");
sel->ncase = i+1;
cas = runtime·mal(sizeof *cas);
sel->scase[i] = cas;
cas->pc = runtime·getcallerpc(&sel);
cas->chan = c;
cas->so = (byte*)&selected - (byte*)&sel;
cas->kind = CaseRecv;
cas->u.recv.elemp = elem;
cas->u.recv.receivedp = nil;
if(debug)
runtime·printf("selectrecv s=%p pc=%p chan=%p so=%d\n",
sel, cas->pc, cas->chan, cas->so);
} }
// selectrecv2(sel *byte, hchan *chan any, elem *any, received *bool) (selected bool); // selectrecv2(sel *byte, hchan *chan any, elem *any, received *bool) (selected bool);
...@@ -649,33 +644,40 @@ runtime·selectrecv(Select *sel, Hchan *c, void *elem, bool selected) ...@@ -649,33 +644,40 @@ runtime·selectrecv(Select *sel, Hchan *c, void *elem, bool selected)
void void
runtime·selectrecv2(Select *sel, Hchan *c, void *elem, bool *received, bool selected) runtime·selectrecv2(Select *sel, Hchan *c, void *elem, bool *received, bool selected)
{ {
int32 i;
Scase *cas;
// nil cases do not compete // nil cases do not compete
if(c == nil) if(c == nil)
return; return;
selectrecv(sel, c, runtime·getcallerpc(&sel), elem, received, (byte*)&selected - (byte*)&sel);
}
static void
selectrecv(Select *sel, Hchan *c, void *pc, void *elem, bool *received, int32 so)
{
int32 i;
Scase *cas;
i = sel->ncase; i = sel->ncase;
if(i >= sel->tcase) if(i >= sel->tcase)
runtime·throw("selectrecv: too many cases"); runtime·throw("selectrecv: too many cases");
sel->ncase = i+1; sel->ncase = i+1;
cas = runtime·mal(sizeof *cas); cas = runtime·mal(sizeof *cas);
sel->scase[i] = cas; sel->scase[i] = cas;
cas->pc = runtime·getcallerpc(&sel); cas->pc = pc;
cas->chan = c; cas->chan = c;
cas->so = (byte*)&selected - (byte*)&sel; cas->so = so;
cas->kind = CaseRecv; cas->kind = CaseRecv;
cas->u.recv.elemp = elem; cas->u.recv.elemp = elem;
cas->u.recv.receivedp = nil;
cas->u.recv.receivedp = received; cas->u.recv.receivedp = received;
if(debug) if(debug)
runtime·printf("selectrecv2 s=%p pc=%p chan=%p so=%d elem=%p recv=%p\n", runtime·printf("selectrecv s=%p pc=%p chan=%p so=%d\n",
sel, cas->pc, cas->chan, cas->so, cas->u.recv.elemp, cas->u.recv.receivedp); sel, cas->pc, cas->chan, cas->so);
} }
// cut in half to give stack a chance to split
static void selectdefault(Select*, void*, int32); static void selectdefault(Select*, void*, int32);
// selectdefault(sel *byte) (selected bool); // selectdefault(sel *byte) (selected bool);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment