From ce287933d65be61fa45a7633b90a044e2c0b31b2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9my=20Oudompheng?= Date: Thu, 1 Nov 2012 19:43:29 +0100 Subject: [PATCH] cmd/gc, runtime: pass PC directly to racefuncenter. go test -race -run none -bench . encoding/json benchmark old ns/op new ns/op delta BenchmarkCodeEncoder 3207689000 1716149000 -46.50% BenchmarkCodeMarshal 3206761000 1715677000 -46.50% BenchmarkCodeDecoder 8647304000 4482709000 -48.16% BenchmarkCodeUnmarshal 8032217000 3451248000 -57.03% BenchmarkCodeUnmarshalReuse 8016722000 3480502000 -56.58% BenchmarkSkipValue 10340453000 4560313000 -55.90% benchmark old MB/s new MB/s speedup BenchmarkCodeEncoder 0.60 1.13 1.88x BenchmarkCodeMarshal 0.61 1.13 1.85x BenchmarkCodeDecoder 0.22 0.43 1.95x BenchmarkCodeUnmarshal 0.24 0.56 2.33x BenchmarkCodeUnmarshalReuse 0.24 0.56 2.33x BenchmarkSkipValue 0.19 0.44 2.32x Fixes #4248. R=dvyukov, golang-dev, rsc CC=golang-dev https://golang.org/cl/6815066 --- src/cmd/gc/builtin.c | 2 +- src/cmd/gc/racewalk.c | 13 +++++++++---- src/cmd/gc/runtime.go | 2 +- src/pkg/runtime/race.c | 8 +++++--- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c index 197255be4e..d993bc7fc8 100644 --- a/src/cmd/gc/builtin.c +++ b/src/cmd/gc/builtin.c @@ -102,7 +102,7 @@ char *runtimeimport = "func @\"\".int64tofloat64(? int64) (? float64)\n" "func @\"\".uint64tofloat64(? uint64) (? float64)\n" "func @\"\".complex128div(@\"\".num complex128, @\"\".den complex128) (@\"\".quo complex128)\n" - "func @\"\".racefuncenter()\n" + "func @\"\".racefuncenter(? uintptr)\n" "func @\"\".racefuncexit()\n" "func @\"\".raceread(? uintptr)\n" "func @\"\".racewrite(? uintptr)\n" diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c index 3e0feffd5a..034a5a5a34 100644 --- a/src/cmd/gc/racewalk.c +++ b/src/cmd/gc/racewalk.c @@ -33,6 +33,7 @@ racewalk(Node *fn) { int i; Node *nd; + Node *nodpc; char s[1024]; if(myimportpath) { @@ -42,10 +43,14 @@ racewalk(Node *fn) } } - // TODO(dvyukov): ideally this should be: - // racefuncenter(getreturnaddress()) - // because it's much more costly to obtain from runtime library. - nd = mkcall("racefuncenter", T, nil); + // nodpc is the PC of the caller as extracted by + // getcallerpc. We use -widthptr(FP) for x86. + // BUG: this will not work on arm. + nodpc = nod(OXXX, nil, nil); + *nodpc = *nodfp; + nodpc->type = types[TUINTPTR]; + nodpc->xoffset = -widthptr; + nd = mkcall("racefuncenter", T, nil, nodpc); fn->enter = list(fn->enter, nd); nd = mkcall("racefuncexit", T, nil); fn->exit = list(fn->exit, nd); // works fine if (!fn->exit) diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go index cfabbb174b..b8204ebcf3 100644 --- a/src/cmd/gc/runtime.go +++ b/src/cmd/gc/runtime.go @@ -140,7 +140,7 @@ func uint64tofloat64(uint64) float64 func complex128div(num complex128, den complex128) (quo complex128) // race detection -func racefuncenter() +func racefuncenter(uintptr) func racefuncexit() func raceread(uintptr) func racewrite(uintptr) diff --git a/src/pkg/runtime/race.c b/src/pkg/runtime/race.c index 97bfe6864e..bea16cc832 100644 --- a/src/pkg/runtime/race.c +++ b/src/pkg/runtime/race.c @@ -70,11 +70,13 @@ runtime·raceread(uintptr addr) // Called from instrumented code. void -runtime·racefuncenter(void) +runtime·racefuncenter(uintptr pc) { - uintptr pc; + // If the caller PC is lessstack, use slower runtime·callers + // to walk across the stack split to find the real caller. + if(pc == (uintptr)runtime·lessstack) + runtime·callers(2, &pc, 1); - runtime·callers(2, &pc, 1); m->racecall = true; runtime∕race·FuncEnter(g->goid-1, (void*)pc); m->racecall = false; -- 2.48.1