diff options
author | Russ Cox <rsc@golang.org> | 2014-03-04 13:53:08 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-03-04 13:53:08 -0500 |
commit | 342e17648d01ae1bca36494a61c19a09592c4d6d (patch) | |
tree | e79ee1d7e9465644fba07a3a6fd6f490c0764e8f /src/liblink | |
parent | 410479feaf8f12c564464a2d4734021d21d54ef9 (diff) | |
download | go-342e17648d01ae1bca36494a61c19a09592c4d6d.tar.gz |
cmd/ld: clear unused ctxt before morestack
For non-closure functions, the context register is uninitialized
on entry and will not be used, but morestack saves it and then the
garbage collector treats it as live. This can be a source of memory
leaks if the context register points at otherwise dead memory.
Avoid this by introducing a parallel set of morestack functions
that clear the context register, and use those for the non-closure functions.
I hope this will help with some of the finalizer flakiness, but it probably won't.
Fixes issue 7244.
LGTM=dvyukov
R=khr, dvyukov
CC=golang-codereviews
https://codereview.appspot.com/71030044
Diffstat (limited to 'src/liblink')
-rw-r--r-- | src/liblink/obj5.c | 14 | ||||
-rw-r--r-- | src/liblink/obj6.c | 26 | ||||
-rw-r--r-- | src/liblink/obj8.c | 12 |
3 files changed, 33 insertions, 19 deletions
diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c index ce9d4f654..91d13d8c1 100644 --- a/src/liblink/obj5.c +++ b/src/liblink/obj5.c @@ -194,7 +194,7 @@ prg(void) return p; } -static Prog* stacksplit(Link*, Prog*, int32); +static Prog* stacksplit(Link*, Prog*, int32, int); static void initdiv(Link*); static void softfloat(Link*, LSym*); @@ -237,9 +237,11 @@ addstacksplit(Link *ctxt, LSym *cursym) autosize = 0; - if(ctxt->symmorestack[0] == nil) + if(ctxt->symmorestack[0] == nil) { ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0); - + ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0); + } + q = nil; ctxt->cursym = cursym; @@ -409,7 +411,7 @@ addstacksplit(Link *ctxt, LSym *cursym) } if(!(p->reg & NOSPLIT)) - p = stacksplit(ctxt, p, autosize); // emit split check + p = stacksplit(ctxt, p, autosize, !(cursym->text->from.scale&NEEDCTXT)); // emit split check // MOVW.W R14,$-autosize(SP) p = appendp(ctxt, p); @@ -727,7 +729,7 @@ softfloat(Link *ctxt, LSym *cursym) } static Prog* -stacksplit(Link *ctxt, Prog *p, int32 framesize) +stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt) { int32 arg; @@ -851,7 +853,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize) p->as = ABL; p->scond = C_SCOND_LS; p->to.type = D_BRANCH; - p->to.sym = ctxt->symmorestack[0]; + p->to.sym = ctxt->symmorestack[noctxt]; // BLS start p = appendp(ctxt, p); diff --git a/src/liblink/obj6.c b/src/liblink/obj6.c index 9b99a5995..036e20c8d 100644 --- a/src/liblink/obj6.c +++ b/src/liblink/obj6.c @@ -342,20 +342,30 @@ static char* morename[] = { "runtime.morestack00", + "runtime.morestack00_noctxt", "runtime.morestack10", + "runtime.morestack10_noctxt", "runtime.morestack01", + "runtime.morestack01_noctxt", "runtime.morestack11", + "runtime.morestack11_noctxt", "runtime.morestack8", + "runtime.morestack8_noctxt", "runtime.morestack16", + "runtime.morestack16_noctxt", "runtime.morestack24", + "runtime.morestack24_noctxt", "runtime.morestack32", + "runtime.morestack32_noctxt", "runtime.morestack40", + "runtime.morestack40_noctxt", "runtime.morestack48", + "runtime.morestack48_noctxt", }; static Prog* load_g_cx(Link*, Prog*); -static Prog* stacksplit(Link*, Prog*, int32, int32, Prog**); +static Prog* stacksplit(Link*, Prog*, int32, int32, int, Prog**); static void indir_cx(Link*, Addr*); static void @@ -419,7 +429,7 @@ addstacksplit(Link *ctxt, LSym *cursym) p = load_g_cx(ctxt, p); // load g into CX } if(!(cursym->text->from.scale & NOSPLIT)) - p = stacksplit(ctxt, p, autoffset, textarg, &q); // emit split check + p = stacksplit(ctxt, p, autoffset, textarg, !(cursym->text->from.scale&NEEDCTXT), &q); // emit split check if(autoffset) { if(autoffset%ctxt->arch->regsize != 0) @@ -674,7 +684,7 @@ load_g_cx(Link *ctxt, Prog *p) // On return, *jmpok is the instruction that should jump // to the stack frame allocation if no split is needed. static Prog* -stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, Prog **jmpok) +stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, int noctxt, Prog **jmpok) { Prog *q, *q1; uint32 moreconst1, moreconst2, i; @@ -822,7 +832,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, Prog **jmpok) if(moreconst1 == 0 && moreconst2 == 0) { p->as = ACALL; p->to.type = D_BRANCH; - p->to.sym = ctxt->symmorestack[0]; + p->to.sym = ctxt->symmorestack[0*2+noctxt]; } else if(moreconst1 != 0 && moreconst2 == 0) { p->as = AMOVL; @@ -833,13 +843,13 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, Prog **jmpok) p = appendp(ctxt, p); p->as = ACALL; p->to.type = D_BRANCH; - p->to.sym = ctxt->symmorestack[1]; + p->to.sym = ctxt->symmorestack[1*2+noctxt]; } else if(moreconst1 == 0 && moreconst2 <= 48 && moreconst2%8 == 0) { i = moreconst2/8 + 3; p->as = ACALL; p->to.type = D_BRANCH; - p->to.sym = ctxt->symmorestack[i]; + p->to.sym = ctxt->symmorestack[i*2+noctxt]; } else if(moreconst1 == 0 && moreconst2 != 0) { p->as = AMOVL; @@ -850,7 +860,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, Prog **jmpok) p = appendp(ctxt, p); p->as = ACALL; p->to.type = D_BRANCH; - p->to.sym = ctxt->symmorestack[2]; + p->to.sym = ctxt->symmorestack[2*2+noctxt]; } else { p->as = mov; p->from.type = D_CONST; @@ -861,7 +871,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, Prog **jmpok) p = appendp(ctxt, p); p->as = ACALL; p->to.type = D_BRANCH; - p->to.sym = ctxt->symmorestack[3]; + p->to.sym = ctxt->symmorestack[3*2+noctxt]; } p = appendp(ctxt, p); diff --git a/src/liblink/obj8.c b/src/liblink/obj8.c index adee8c6c5..6e40d04a5 100644 --- a/src/liblink/obj8.c +++ b/src/liblink/obj8.c @@ -256,7 +256,7 @@ prg(void) } static Prog* load_g_cx(Link*, Prog*); -static Prog* stacksplit(Link*, Prog*, int32, Prog**); +static Prog* stacksplit(Link*, Prog*, int32, int, Prog**); static void addstacksplit(Link *ctxt, LSym *cursym) @@ -265,8 +265,10 @@ addstacksplit(Link *ctxt, LSym *cursym) int32 autoffset, deltasp; int a; - if(ctxt->symmorestack[0] == nil) + if(ctxt->symmorestack[0] == nil) { ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0); + ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0); + } if(ctxt->headtype == Hplan9 && ctxt->plan9tos == nil) ctxt->plan9tos = linklookup(ctxt, "_tos", 0); @@ -291,7 +293,7 @@ addstacksplit(Link *ctxt, LSym *cursym) p = load_g_cx(ctxt, p); // load g into CX } if(!(cursym->text->from.scale & NOSPLIT)) - p = stacksplit(ctxt, p, autoffset, &q); // emit split check + p = stacksplit(ctxt, p, autoffset, !(cursym->text->from.scale&NEEDCTXT), &q); // emit split check if(autoffset) { p = appendp(ctxt, p); @@ -499,7 +501,7 @@ load_g_cx(Link *ctxt, Prog *p) // On return, *jmpok is the instruction that should jump // to the stack frame allocation if no split is needed. static Prog* -stacksplit(Link *ctxt, Prog *p, int32 framesize, Prog **jmpok) +stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) { Prog *q, *q1; int arg; @@ -642,7 +644,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, Prog **jmpok) p = appendp(ctxt, p); p->as = ACALL; p->to.type = D_BRANCH; - p->to.sym = ctxt->symmorestack[0]; + p->to.sym = ctxt->symmorestack[noctxt]; p = appendp(ctxt, p); p->as = AJMP; |