Commit ec5d7ba9 authored by Dave Cheney's avatar Dave Cheney

runtime: add throwgo

Fixes #8380.

Also update hashmap.go to use throwgo rather than panic.

LGTM=khr
R=khr, rsc
CC=golang-codereviews
https://golang.org/cl/115860045
parent f378f300
...@@ -153,9 +153,8 @@ func evacuated(b *bmap) bool { ...@@ -153,9 +153,8 @@ func evacuated(b *bmap) bool {
} }
func makemap(t *maptype, hint int64) *hmap { func makemap(t *maptype, hint int64) *hmap {
if unsafe.Sizeof(hmap{}) > 48 { if unsafe.Sizeof(hmap{}) > 48 {
panic("hmap too large") throwgo("hmap too large")
} }
if hint < 0 || int64(int32(hint)) != hint { if hint < 0 || int64(int32(hint)) != hint {
...@@ -164,7 +163,7 @@ func makemap(t *maptype, hint int64) *hmap { ...@@ -164,7 +163,7 @@ func makemap(t *maptype, hint int64) *hmap {
} }
if !ismapkey(t.key) { if !ismapkey(t.key) {
panic("runtime.makemap: unsupported map key type") throwgo("runtime.makemap: unsupported map key type")
} }
flags := uint32(0) flags := uint32(0)
...@@ -182,32 +181,31 @@ func makemap(t *maptype, hint int64) *hmap { ...@@ -182,32 +181,31 @@ func makemap(t *maptype, hint int64) *hmap {
} }
bucketsize := dataOffset + bucketCnt*(keysize+valuesize) bucketsize := dataOffset + bucketCnt*(keysize+valuesize)
if bucketsize != uintptr(t.bucket.size) { if bucketsize != uintptr(t.bucket.size) {
panic("bucketsize wrong") throwgo("bucketsize wrong")
} }
// invariants we depend on. We should probably check these at compile time // invariants we depend on. We should probably check these at compile time
// somewhere, but for now we'll do it here. // somewhere, but for now we'll do it here.
// TODO: make these throw(), not panic()
if t.key.align > bucketCnt { if t.key.align > bucketCnt {
panic("key align too big") throwgo("key align too big")
} }
if t.elem.align > bucketCnt { if t.elem.align > bucketCnt {
panic("value align too big") throwgo("value align too big")
} }
if uintptr(t.key.size)%uintptr(t.key.align) != 0 { if uintptr(t.key.size)%uintptr(t.key.align) != 0 {
panic("key size not a multiple of key align") throwgo("key size not a multiple of key align")
} }
if uintptr(t.elem.size)%uintptr(t.elem.align) != 0 { if uintptr(t.elem.size)%uintptr(t.elem.align) != 0 {
panic("value size not a multiple of value align") throwgo("value size not a multiple of value align")
} }
if bucketCnt < 8 { if bucketCnt < 8 {
panic("bucketsize too small for proper alignment") throwgo("bucketsize too small for proper alignment")
} }
if dataOffset%uintptr(t.key.align) != 0 { if dataOffset%uintptr(t.key.align) != 0 {
panic("need padding in bucket (key)") throwgo("need padding in bucket (key)")
} }
if dataOffset%uintptr(t.elem.align) != 0 { if dataOffset%uintptr(t.elem.align) != 0 {
panic("need padding in bucket (value)") throwgo("need padding in bucket (value)")
} }
// find size parameter which will hold the requested # of elements // find size parameter which will hold the requested # of elements
...@@ -570,7 +568,7 @@ func mapiterinit(t *maptype, h *hmap, it *hiter) { ...@@ -570,7 +568,7 @@ func mapiterinit(t *maptype, h *hmap, it *hiter) {
} }
if unsafe.Sizeof(hiter{})/ptrSize != 10 { if unsafe.Sizeof(hiter{})/ptrSize != 10 {
panic("hash_iter size incorrect") // see ../../cmd/gc/reflect.c throwgo("hash_iter size incorrect") // see ../../cmd/gc/reflect.c
} }
it.t = t it.t = t
it.h = h it.h = h
...@@ -738,7 +736,7 @@ next: ...@@ -738,7 +736,7 @@ next:
func hashGrow(t *maptype, h *hmap) { func hashGrow(t *maptype, h *hmap) {
if h.oldbuckets != nil { if h.oldbuckets != nil {
panic("evacuation not done in time") throwgo("evacuation not done in time")
} }
oldbuckets := h.buckets oldbuckets := h.buckets
if checkgc { if checkgc {
...@@ -798,7 +796,7 @@ func evacuate(t *maptype, h *hmap, oldbucket uintptr) { ...@@ -798,7 +796,7 @@ func evacuate(t *maptype, h *hmap, oldbucket uintptr) {
continue continue
} }
if top < minTopHash { if top < minTopHash {
panic("bad map state") throwgo("bad map state")
} }
k2 := k k2 := k
if h.flags&indirectKey != 0 { if h.flags&indirectKey != 0 {
......
...@@ -524,6 +524,18 @@ runtime·throw(int8 *s) ...@@ -524,6 +524,18 @@ runtime·throw(int8 *s)
runtime·exit(1); // even more not reached runtime·exit(1); // even more not reached
} }
void
runtime·throwgo(String s)
{
if(g->m->throwing == 0)
g->m->throwing = 1;
runtime·startpanic();
runtime·printf("fatal error: %S\n", s);
runtime·dopanic(0);
*(int32*)0 = 0; // not reached
runtime·exit(1); // even more not reached
}
void void
runtime·panicstring(int8 *s) runtime·panicstring(int8 *s)
{ {
......
...@@ -82,3 +82,7 @@ func gomemeq(a, b unsafe.Pointer, size uintptr) bool ...@@ -82,3 +82,7 @@ func gomemeq(a, b unsafe.Pointer, size uintptr) bool
// Code pointer for the nohash algorithm. Used for producing better error messages. // Code pointer for the nohash algorithm. Used for producing better error messages.
var nohashcode uintptr var nohashcode uintptr
// Go version of runtime.throw.
// in panic.c
func throwgo(s string)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment