diff options
author | Russ Cox <rsc@golang.org> | 2013-10-31 17:18:57 +0000 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2013-10-31 17:18:57 +0000 |
commit | c46a59a5450c27897c1974efa539ef29a890a04b (patch) | |
tree | 18973818a812dc26e3b47f77c7aef157aa6aab40 /src/cmd/5l/noop.c | |
parent | cb254af149624d08d6549f3a921eae4019560656 (diff) | |
download | go-c46a59a5450c27897c1974efa539ef29a890a04b.tar.gz |
undo CL 19810043 / 352f3b7c9664
The CL causes misc/cgo/test to fail randomly.
I suspect that the problem is the use of a division instruction
in usleep, which can be called while trying to acquire an m
and therefore cannot store the denominator in m.
The solution to that would be to rewrite the code to use a
magic multiply instead of a divide, but now we're getting
pretty far off the original code.
Go back to the original in preparation for a different,
less efficient but simpler fix.
??? original CL description
cmd/5l, runtime: make ARM integer division profiler-friendly
The implementation of division constructed non-standard
stack frames that could not be handled by the traceback
routines.
CL 13239052 left the frames non-standard but fixed them
for the specific case of a divide-by-zero panic.
A profiling signal can arrive at any time, so that fix
is not sufficient.
Change the division to store the extra argument in the M struct
instead of in a new stack slot. That keeps the frames bog standard
at all times.
Also fix a related bug in the traceback code: when starting
a traceback, the LR register should be ignored if the current
function has already allocated its stack frame and saved the
original LR on the stack. The stack copy should be used, as the
LR register may have been modified.
Combined, these make the torture test from issue 6681 pass.
Fixes issue 6681.
R=golang-dev, r, josharian
CC=golang-dev
https://codereview.appspot.com/19810043
???
TBR=r
CC=golang-dev
https://codereview.appspot.com/20350043
Diffstat (limited to 'src/cmd/5l/noop.c')
-rw-r--r-- | src/cmd/5l/noop.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/src/cmd/5l/noop.c b/src/cmd/5l/noop.c index 70cec1f9c..fb70599b5 100644 --- a/src/cmd/5l/noop.c +++ b/src/cmd/5l/noop.c @@ -60,7 +60,7 @@ linkcase(Prog *casep) void noops(void) { - Prog *p, *q, *q1, *q2, orig; + Prog *p, *q, *q1, *q2; int o; Sym *tlsfallback, *gmsym; @@ -401,27 +401,26 @@ noops(void) break; if(p->to.type != D_REG) break; - - orig = *p; + q1 = p; - /* MOV a,4(M) */ + /* MOV a,4(SP) */ + p = appendp(p); p->as = AMOVW; - p->line = orig.line; + p->line = q1->line; p->from.type = D_REG; - p->from.reg = orig.from.reg; - p->reg = NREG; + p->from.reg = q1->from.reg; p->to.type = D_OREG; - p->to.reg = REGM; + p->to.reg = REGSP; p->to.offset = 4; /* MOV b,REGTMP */ p = appendp(p); p->as = AMOVW; - p->line = orig.line; + p->line = q1->line; p->from.type = D_REG; - p->from.reg = orig.reg; - if(orig.reg == NREG) - p->from.reg = orig.to.reg; + p->from.reg = q1->reg; + if(q1->reg == NREG) + p->from.reg = q1->to.reg; p->to.type = D_REG; p->to.reg = REGTMP; p->to.offset = 0; @@ -429,7 +428,7 @@ noops(void) /* CALL appropriate */ p = appendp(p); p->as = ABL; - p->line = orig.line; + p->line = q1->line; p->to.type = D_BRANCH; p->cond = p; switch(o) { @@ -454,12 +453,34 @@ noops(void) /* MOV REGTMP, b */ p = appendp(p); p->as = AMOVW; - p->line = orig.line; + p->line = q1->line; p->from.type = D_REG; p->from.reg = REGTMP; p->from.offset = 0; p->to.type = D_REG; - p->to.reg = orig.to.reg; + p->to.reg = q1->to.reg; + + /* ADD $8,SP */ + p = appendp(p); + p->as = AADD; + p->line = q1->line; + p->from.type = D_CONST; + p->from.reg = NREG; + p->from.offset = 8; + p->reg = NREG; + p->to.type = D_REG; + p->to.reg = REGSP; + p->spadj = -8; + + /* SUB $8,SP */ + q1->as = ASUB; + q1->from.type = D_CONST; + q1->from.offset = 8; + q1->from.reg = NREG; + q1->reg = NREG; + q1->to.type = D_REG; + q1->to.reg = REGSP; + q1->spadj = 8; break; case AMOVW: |