summaryrefslogtreecommitdiff
path: root/src/liblink
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-03-04 13:53:08 -0500
committerRuss Cox <rsc@golang.org>2014-03-04 13:53:08 -0500
commit342e17648d01ae1bca36494a61c19a09592c4d6d (patch)
treee79ee1d7e9465644fba07a3a6fd6f490c0764e8f /src/liblink
parent410479feaf8f12c564464a2d4734021d21d54ef9 (diff)
downloadgo-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.c14
-rw-r--r--src/liblink/obj6.c26
-rw-r--r--src/liblink/obj8.c12
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;