]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: introduce, use funcPC to convert Go func to PC
authorRuss Cox <rsc@golang.org>
Wed, 3 Sep 2014 15:10:38 +0000 (11:10 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 3 Sep 2014 15:10:38 +0000 (11:10 -0400)
This removes the ** unsafe hack.

Real bug fixed at chan.go:101.

LGTM=dave, r, iant
R=golang-codereviews, dave, r, iant
CC=dvyukov, golang-codereviews, khr
https://golang.org/cl/140870044

src/pkg/runtime/chan.go
src/pkg/runtime/cpuprof.go
src/pkg/runtime/export_test.go
src/pkg/runtime/hashmap.go
src/pkg/runtime/hashmap_fast.go
src/pkg/runtime/proc.go
src/pkg/runtime/select.go
src/pkg/runtime/slice.go
src/pkg/runtime/string.go

index 77df169399ce66e33dd3cb1b8cbe6a7a005cfdd6..91ade4d37e74477ceb3a0616b8d181db67d84bdd 100644 (file)
@@ -82,9 +82,7 @@ func chansend1(t *chantype, c *hchan, elem unsafe.Pointer) {
  */
 func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
        if raceenabled {
-               fn := chansend
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               raceReadObjectPC(t.elem, ep, callerpc, pc)
+               raceReadObjectPC(t.elem, ep, callerpc, funcPC(chansend))
        }
 
        if c == nil {
@@ -100,9 +98,7 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
        }
 
        if raceenabled {
-               fn := chansend
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(c), pc, callerpc)
+               racereadpc(unsafe.Pointer(c), callerpc, funcPC(chansend))
        }
 
        // Fast path: check for failed non-blocking operation without acquiring the lock.
@@ -269,9 +265,7 @@ func closechan(c *hchan) {
 
        if raceenabled {
                callerpc := getcallerpc(unsafe.Pointer(&c))
-               fn := closechan
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racewritepc(unsafe.Pointer(c), callerpc, pc)
+               racewritepc(unsafe.Pointer(c), callerpc, funcPC(closechan))
                racerelease(unsafe.Pointer(c))
        }
 
index 540c78de8ad298a7f1b9328f086677d842d4d6aa..b397eafbe039bf0aeb5361a83800a9f02b0cbe7c 100644 (file)
@@ -289,8 +289,7 @@ func (p *cpuProfile) flushlog() bool {
        log := &p.log[p.toggle]
        q := uintptr(0)
        if p.lost > 0 {
-               f := lostProfileData
-               lostPC := **(**uintptr)(unsafe.Pointer(&f))
+               lostPC := funcPC(lostProfileData)
                log[0] = p.lost
                log[1] = 1
                log[2] = lostPC
index 5579449c4f90195199628c9b5db07cd66eb05fbd..cce9afbef993d9e26f96d49211772094410e1a4f 100644 (file)
@@ -86,7 +86,7 @@ func ParForSetup(desc *ParFor, nthr, n uint32, ctx *byte, wait bool, body func(*
        mp := acquirem()
        mp.ptrarg[0] = unsafe.Pointer(desc)
        mp.ptrarg[1] = unsafe.Pointer(ctx)
-       mp.ptrarg[2] = **(**unsafe.Pointer)(unsafe.Pointer(&body))
+       mp.ptrarg[2] = unsafe.Pointer(funcPC(body)) // TODO(rsc): Should be a scalar.
        mp.scalararg[0] = uintptr(nthr)
        mp.scalararg[1] = uintptr(n)
        mp.scalararg[2] = 0
index 1bdceab8bb18dfc2906064ab1213e2715ca76878..55287f6ff9d3a8c5c551ca21d36feb1125479724 100644 (file)
@@ -235,8 +235,7 @@ func makemap(t *maptype, hint int64) *hmap {
 func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapaccess1
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
+               pc := funcPC(mapaccess1)
                racereadpc(unsafe.Pointer(h), callerpc, pc)
                raceReadObjectPC(t.key, key, callerpc, pc)
        }
@@ -284,8 +283,7 @@ func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
 func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) {
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapaccess2
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
+               pc := funcPC(mapaccess2)
                racereadpc(unsafe.Pointer(h), callerpc, pc)
                raceReadObjectPC(t.key, key, callerpc, pc)
        }
@@ -379,8 +377,7 @@ func mapassign1(t *maptype, h *hmap, key unsafe.Pointer, val unsafe.Pointer) {
        }
        if raceenabled {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapassign1
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
+               pc := funcPC(mapassign1)
                racewritepc(unsafe.Pointer(h), callerpc, pc)
                raceReadObjectPC(t.key, key, callerpc, pc)
                raceReadObjectPC(t.elem, val, callerpc, pc)
@@ -488,8 +485,7 @@ again:
 func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapdelete
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
+               pc := funcPC(mapdelete)
                racewritepc(unsafe.Pointer(h), callerpc, pc)
                raceReadObjectPC(t.key, key, callerpc, pc)
        }
@@ -545,9 +541,7 @@ func mapiterinit(t *maptype, h *hmap, it *hiter) {
 
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapiterinit
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(h), callerpc, pc)
+               racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapiterinit))
        }
 
        if h == nil || h.count == 0 {
@@ -591,9 +585,7 @@ func mapiternext(it *hiter) {
        h := it.h
        if raceenabled {
                callerpc := getcallerpc(unsafe.Pointer(&it))
-               fn := mapiternext
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(h), callerpc, pc)
+               racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapiternext))
        }
        t := it.t
        bucket := it.bucket
@@ -942,9 +934,7 @@ func reflect_maplen(h *hmap) int {
        }
        if raceenabled {
                callerpc := getcallerpc(unsafe.Pointer(&h))
-               fn := reflect_maplen
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(h), callerpc, pc)
+               racereadpc(unsafe.Pointer(h), callerpc, funcPC(reflect_maplen))
        }
        return h.count
 }
index 7059e22a0b0eceec894e7cf4b807cc6df1deae1a..8e21e02d64e2bc1a1d5f91ce1dc30717946eae38 100644 (file)
@@ -11,9 +11,7 @@ import (
 func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapaccess1_fast32
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(h), callerpc, pc)
+               racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast32))
        }
        if h == nil || h.count == 0 {
                return unsafe.Pointer(t.elem.zero)
@@ -55,9 +53,7 @@ func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
 func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) {
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapaccess2_fast32
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(h), callerpc, pc)
+               racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast32))
        }
        if h == nil || h.count == 0 {
                return unsafe.Pointer(t.elem.zero), false
@@ -99,9 +95,7 @@ func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) {
 func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapaccess1_fast64
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(h), callerpc, pc)
+               racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast64))
        }
        if h == nil || h.count == 0 {
                return unsafe.Pointer(t.elem.zero)
@@ -143,9 +137,7 @@ func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
 func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) {
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapaccess2_fast64
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(h), callerpc, pc)
+               racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast64))
        }
        if h == nil || h.count == 0 {
                return unsafe.Pointer(t.elem.zero), false
@@ -187,9 +179,7 @@ func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) {
 func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer {
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapaccess1_faststr
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(h), callerpc, pc)
+               racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_faststr))
        }
        if h == nil || h.count == 0 {
                return unsafe.Pointer(t.elem.zero)
@@ -291,9 +281,7 @@ dohash:
 func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) {
        if raceenabled && h != nil {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := mapaccess2_faststr
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadpc(unsafe.Pointer(h), callerpc, pc)
+               racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_faststr))
        }
        if h == nil || h.count == 0 {
                return unsafe.Pointer(t.elem.zero), false
index d47503e2301647809e920abb6ea354287ba1c849..a36b931b88a6f922454bb34f533e056f3b150f5f 100644 (file)
@@ -110,3 +110,9 @@ func releaseSudog(s *sudog) {
        s.next = c.sudogcache
        c.sudogcache = s
 }
+
+// funcPC returns the entry PC of the function f.
+// It assumes that f is a func value. Otherwise the behavior is undefined.
+func funcPC(f interface{}) uintptr {
+       return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize))
+}
index dbe0543bf7e72738f89c85fb67321a3844684828..6d2531e7f8a7c5337382e8ad3b0b7f077c518f57 100644 (file)
@@ -13,17 +13,10 @@ const (
 )
 
 var (
-       chansendpc uintptr
-       chanrecvpc uintptr
+       chansendpc = funcPC(chansend)
+       chanrecvpc = funcPC(chanrecv)
 )
 
-func init() {
-       f := chansend
-       chansendpc = **(**uintptr)(unsafe.Pointer(&f))
-       g := chanrecv
-       chanrecvpc = **(**uintptr)(unsafe.Pointer(&g))
-}
-
 func selectsize(size uintptr) uintptr {
        selsize := unsafe.Sizeof(_select{}) +
                (size-1)*unsafe.Sizeof(_select{}.scase[0]) +
@@ -286,7 +279,6 @@ func selectgoImpl(sel *_select) (uintptr, uint16) {
                k      *scase
                sglist *sudog
                sgnext *sudog
-               fn     func(*g, *_select) bool
        )
 
 loop:
@@ -371,8 +363,7 @@ loop:
 
        // wait for someone to wake us up
        gp.param = nil
-       fn = selparkcommit
-       gopark(**(**unsafe.Pointer)(unsafe.Pointer(&fn)), unsafe.Pointer(sel), "select")
+       gopark(unsafe.Pointer(funcPC(selparkcommit)), unsafe.Pointer(sel), "select")
 
        // someone woke us up
        sellock(sel)
index c282125b446e1f4fc279499b29174fd7e163d8d0..68a225a5095094b100c6e467beed8ba2e1f1dfcc 100644 (file)
@@ -48,9 +48,7 @@ func growslice(t *slicetype, old sliceStruct, n int64) sliceStruct {
 
        if raceenabled {
                callerpc := getcallerpc(unsafe.Pointer(&t))
-               fn := growslice
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
-               racereadrangepc(old.array, old.len*int(t.elem.size), callerpc, pc)
+               racereadrangepc(old.array, old.len*int(t.elem.size), callerpc, funcPC(growslice))
        }
 
        et := t.elem
@@ -105,8 +103,7 @@ func slicecopy(to sliceStruct, fm sliceStruct, width uintptr) int {
 
        if raceenabled {
                callerpc := getcallerpc(unsafe.Pointer(&to))
-               fn := slicecopy
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
+               pc := funcPC(slicecopy)
                racewriterangepc(to.array, n*int(width), callerpc, pc)
                racereadrangepc(fm.array, n*int(width), callerpc, pc)
        }
@@ -133,8 +130,7 @@ func slicestringcopy(to []byte, fm string) int {
 
        if raceenabled {
                callerpc := getcallerpc(unsafe.Pointer(&to))
-               fn := slicestringcopy
-               pc := **(**uintptr)(unsafe.Pointer(&fn))
+               pc := funcPC(slicestringcopy)
                racewriterangepc(unsafe.Pointer(&to[0]), n, callerpc, pc)
        }
 
index e9ea926dfffa1ca6a37e7c621ebe0a9196c01724..1cefad9671765f6ce51eec01224cc2180fc90f3d 100644 (file)
@@ -61,11 +61,10 @@ func concatstring5(a [5]string) string {
 
 func slicebytetostring(b []byte) string {
        if raceenabled && len(b) > 0 {
-               fn := slicebytetostring
                racereadrangepc(unsafe.Pointer(&b[0]),
                        len(b),
                        getcallerpc(unsafe.Pointer(&b)),
-                       **(**uintptr)(unsafe.Pointer(&fn)))
+                       funcPC(slicebytetostring))
        }
        s, c := rawstring(len(b))
        copy(c, b)
@@ -82,11 +81,10 @@ func slicebytetostringtmp(b []byte) string {
        // m is a string-keyed map and k is a []byte.
 
        if raceenabled && len(b) > 0 {
-               fn := slicebytetostringtmp
                racereadrangepc(unsafe.Pointer(&b[0]),
                        len(b),
                        getcallerpc(unsafe.Pointer(&b)),
-                       **(**uintptr)(unsafe.Pointer(&fn)))
+                       funcPC(slicebytetostringtmp))
        }
        return *(*string)(unsafe.Pointer(&b))
 }
@@ -120,11 +118,10 @@ func stringtoslicerune(s string) []rune {
 
 func slicerunetostring(a []rune) string {
        if raceenabled && len(a) > 0 {
-               fn := slicerunetostring
                racereadrangepc(unsafe.Pointer(&a[0]),
                        len(a)*int(unsafe.Sizeof(a[0])),
                        getcallerpc(unsafe.Pointer(&a)),
-                       **(**uintptr)(unsafe.Pointer(&fn)))
+                       funcPC(slicerunetostring))
        }
        var dum [4]byte
        size1 := 0