summaryrefslogtreecommitdiff
path: root/src/pkg
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-09-03 11:10:38 -0400
committerRuss Cox <rsc@golang.org>2014-09-03 11:10:38 -0400
commit772338a36fa4195ccd0fcf76fa0eb696d7c3dba0 (patch)
tree5194ab219fc4a685fe62cfe000386d2fc7c88b23 /src/pkg
parent2b83962f41c8b35ea5ee37676d1e4dab2c1e85cc (diff)
downloadgo-772338a36fa4195ccd0fcf76fa0eb696d7c3dba0.tar.gz
runtime: introduce, use funcPC to convert Go func to PC
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://codereview.appspot.com/140870044
Diffstat (limited to 'src/pkg')
-rw-r--r--src/pkg/runtime/chan.go12
-rw-r--r--src/pkg/runtime/cpuprof.go3
-rw-r--r--src/pkg/runtime/export_test.go2
-rw-r--r--src/pkg/runtime/hashmap.go24
-rw-r--r--src/pkg/runtime/hashmap_fast.go24
-rw-r--r--src/pkg/runtime/proc.go6
-rw-r--r--src/pkg/runtime/select.go15
-rw-r--r--src/pkg/runtime/slice.go10
-rw-r--r--src/pkg/runtime/string.go9
9 files changed, 33 insertions, 72 deletions
diff --git a/src/pkg/runtime/chan.go b/src/pkg/runtime/chan.go
index 77df16939..91ade4d37 100644
--- a/src/pkg/runtime/chan.go
+++ b/src/pkg/runtime/chan.go
@@ -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))
}
diff --git a/src/pkg/runtime/cpuprof.go b/src/pkg/runtime/cpuprof.go
index 540c78de8..b397eafbe 100644
--- a/src/pkg/runtime/cpuprof.go
+++ b/src/pkg/runtime/cpuprof.go
@@ -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
diff --git a/src/pkg/runtime/export_test.go b/src/pkg/runtime/export_test.go
index 5579449c4..cce9afbef 100644
--- a/src/pkg/runtime/export_test.go
+++ b/src/pkg/runtime/export_test.go
@@ -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
diff --git a/src/pkg/runtime/hashmap.go b/src/pkg/runtime/hashmap.go
index 1bdceab8b..55287f6ff 100644
--- a/src/pkg/runtime/hashmap.go
+++ b/src/pkg/runtime/hashmap.go
@@ -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
}
diff --git a/src/pkg/runtime/hashmap_fast.go b/src/pkg/runtime/hashmap_fast.go
index 7059e22a0..8e21e02d6 100644
--- a/src/pkg/runtime/hashmap_fast.go
+++ b/src/pkg/runtime/hashmap_fast.go
@@ -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
diff --git a/src/pkg/runtime/proc.go b/src/pkg/runtime/proc.go
index d47503e23..a36b931b8 100644
--- a/src/pkg/runtime/proc.go
+++ b/src/pkg/runtime/proc.go
@@ -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))
+}
diff --git a/src/pkg/runtime/select.go b/src/pkg/runtime/select.go
index dbe0543bf..6d2531e7f 100644
--- a/src/pkg/runtime/select.go
+++ b/src/pkg/runtime/select.go
@@ -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)
diff --git a/src/pkg/runtime/slice.go b/src/pkg/runtime/slice.go
index c282125b4..68a225a50 100644
--- a/src/pkg/runtime/slice.go
+++ b/src/pkg/runtime/slice.go
@@ -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)
}
diff --git a/src/pkg/runtime/string.go b/src/pkg/runtime/string.go
index e9ea926df..1cefad967 100644
--- a/src/pkg/runtime/string.go
+++ b/src/pkg/runtime/string.go
@@ -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