mirror of
https://github.com/golang/go
synced 2024-11-12 10:20:27 -07:00
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
This commit is contained in:
parent
f378f30034
commit
ec5d7ba95c
@ -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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
}
|
}
|
||||||
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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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:
|
|||||||
|
|
||||||
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) {
|
|||||||
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)
|
|||||||
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
|
|||||||
|
|
||||||
// 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)
|
||||||
|
Loading…
Reference in New Issue
Block a user