diff options
Diffstat (limited to 'src/pkg/runtime')
| -rw-r--r-- | src/pkg/runtime/alg.go | 8 | ||||
| -rw-r--r-- | src/pkg/runtime/heapdump.c | 4 | ||||
| -rw-r--r-- | src/pkg/runtime/iface.go | 12 | ||||
| -rw-r--r-- | src/pkg/runtime/malloc.c | 8 | ||||
| -rw-r--r-- | src/pkg/runtime/malloc.go | 9 | ||||
| -rw-r--r-- | src/pkg/runtime/mgc0.c | 6 | ||||
| -rw-r--r-- | src/pkg/runtime/stack.c | 4 | ||||
| -rw-r--r-- | src/pkg/runtime/typekind.go | 44 | ||||
| -rw-r--r-- | src/pkg/runtime/typekind.h | 3 |
9 files changed, 67 insertions, 31 deletions
diff --git a/src/pkg/runtime/alg.go b/src/pkg/runtime/alg.go index 409f0fa0c5..650f684950 100644 --- a/src/pkg/runtime/alg.go +++ b/src/pkg/runtime/alg.go @@ -117,7 +117,7 @@ func interhash(a *iface, s, h uintptr) uintptr { // but we can print a better error. panic(errorString("hash of unhashable type " + *t._string)) } - if uintptr(t.size) <= ptrSize { + if isDirectIface(t) { return c1 * fn(unsafe.Pointer(&a.data), uintptr(t.size), h^c0) } else { return c1 * fn(a.data, uintptr(t.size), h^c0) @@ -135,7 +135,7 @@ func nilinterhash(a *eface, s, h uintptr) uintptr { // but we can print a better error. panic(errorString("hash of unhashable type " + *t._string)) } - if uintptr(t.size) <= ptrSize { + if isDirectIface(t) { return c1 * fn(unsafe.Pointer(&a.data), uintptr(t.size), h^c0) } else { return c1 * fn(a.data, uintptr(t.size), h^c0) @@ -208,7 +208,7 @@ func efaceeq(p, q interface{}) bool { // but we can print a better error. panic(errorString("comparing uncomparable type " + *t._string)) } - if uintptr(t.size) <= ptrSize { + if isDirectIface(t) { return eq(noescape(unsafe.Pointer(&x.data)), noescape(unsafe.Pointer(&y.data)), uintptr(t.size)) } return eq(x.data, y.data, uintptr(t.size)) @@ -232,7 +232,7 @@ func ifaceeq(p, q interface { // but we can print a better error. panic(errorString("comparing uncomparable type " + *t._string)) } - if uintptr(t.size) <= ptrSize { + if isDirectIface(t) { return eq(noescape(unsafe.Pointer(&x.data)), noescape(unsafe.Pointer(&y.data)), uintptr(t.size)) } return eq(x.data, y.data, uintptr(t.size)) diff --git a/src/pkg/runtime/heapdump.c b/src/pkg/runtime/heapdump.c index aa817fceec..babb32fe5a 100644 --- a/src/pkg/runtime/heapdump.c +++ b/src/pkg/runtime/heapdump.c @@ -196,7 +196,7 @@ dumptype(Type *t) write((byte*)".", 1); write(t->x->name->str, t->x->name->len); } - dumpbool(t->size > PtrSize || (t->kind & KindNoPointers) == 0); + dumpbool((t->kind & KindDirectIface) == 0 || (t->kind & KindNoPointers) == 0); dumpfields((BitVector){0, nil}); } @@ -584,7 +584,7 @@ itab_callback(Itab *tab) dumpint(TagItab); dumpint((uintptr)tab); t = tab->type; - dumpbool(t->size > PtrSize || (t->kind & KindNoPointers) == 0); + dumpbool((t->kind & KindDirectIface) == 0 || (t->kind & KindNoPointers) == 0); } static void diff --git a/src/pkg/runtime/iface.go b/src/pkg/runtime/iface.go index 9bd6fc7617..60dfb49dbe 100644 --- a/src/pkg/runtime/iface.go +++ b/src/pkg/runtime/iface.go @@ -135,7 +135,7 @@ func typ2Itab(t *_type, inter *interfacetype, cache **itab) *itab { func convT2E(t *_type, elem unsafe.Pointer) (e interface{}) { size := uintptr(t.size) ep := (*eface)(unsafe.Pointer(&e)) - if size <= ptrSize { + if isDirectIface(t) { ep._type = t memmove(unsafe.Pointer(&ep.data), elem, size) } else { @@ -157,7 +157,7 @@ func convT2I(t *_type, inter *interfacetype, cache **itab, elem unsafe.Pointer) } size := uintptr(t.size) pi := (*iface)(unsafe.Pointer(&i)) - if size <= ptrSize { + if isDirectIface(t) { pi.tab = tab memmove(unsafe.Pointer(&pi.data), elem, size) } else { @@ -182,7 +182,7 @@ func assertI2T(t *_type, i fInterface) (r struct{}) { panic(&TypeAssertionError{*tab.inter.typ._string, *tab._type._string, *t._string, ""}) } size := uintptr(t.size) - if size <= ptrSize { + if isDirectIface(t) { memmove(unsafe.Pointer(&r), unsafe.Pointer(&ip.data), size) } else { memmove(unsafe.Pointer(&r), ip.data, size) @@ -202,7 +202,7 @@ func assertI2T2(t *_type, i fInterface) (r byte) { return } *ok = true - if size <= ptrSize { + if isDirectIface(t) { memmove(unsafe.Pointer(&r), unsafe.Pointer(&ip.data), size) } else { memmove(unsafe.Pointer(&r), ip.data, size) @@ -226,7 +226,7 @@ func assertE2T(t *_type, e interface{}) (r struct{}) { panic(&TypeAssertionError{"", *ep._type._string, *t._string, ""}) } size := uintptr(t.size) - if size <= ptrSize { + if isDirectIface(t) { memmove(unsafe.Pointer(&r), unsafe.Pointer(&ep.data), size) } else { memmove(unsafe.Pointer(&r), ep.data, size) @@ -245,7 +245,7 @@ func assertE2T2(t *_type, e interface{}) (r byte) { return } *ok = true - if size <= ptrSize { + if isDirectIface(t) { memmove(unsafe.Pointer(&r), unsafe.Pointer(&ep.data), size) } else { memmove(unsafe.Pointer(&r), ep.data, size) diff --git a/src/pkg/runtime/malloc.c b/src/pkg/runtime/malloc.c index 8b9447dad6..f4143669e7 100644 --- a/src/pkg/runtime/malloc.c +++ b/src/pkg/runtime/malloc.c @@ -459,7 +459,7 @@ setFinalizer(Eface obj, Eface finalizer) } if(finalizer.type != nil) { runtime·createfing(); - if(finalizer.type->kind != KindFunc) + if((finalizer.type->kind&KindMask) != KindFunc) goto badfunc; ft = (FuncType*)finalizer.type; if(ft->dotdotdot || ft->in.len != 1) @@ -467,12 +467,12 @@ setFinalizer(Eface obj, Eface finalizer) fint = *(Type**)ft->in.array; if(fint == obj.type) { // ok - same type - } else if(fint->kind == KindPtr && (fint->x == nil || fint->x->name == nil || obj.type->x == nil || obj.type->x->name == nil) && ((PtrType*)fint)->elem == ((PtrType*)obj.type)->elem) { + } else if((fint->kind&KindMask) == KindPtr && (fint->x == nil || fint->x->name == nil || obj.type->x == nil || obj.type->x->name == nil) && ((PtrType*)fint)->elem == ((PtrType*)obj.type)->elem) { // ok - not same type, but both pointers, // one or the other is unnamed, and same element type, so assignable. - } else if(fint->kind == KindInterface && ((InterfaceType*)fint)->mhdr.len == 0) { + } else if((fint->kind&KindMask) == KindInterface && ((InterfaceType*)fint)->mhdr.len == 0) { // ok - satisfies empty interface - } else if(fint->kind == KindInterface && runtime·ifaceE2I2((InterfaceType*)fint, obj, &iface)) { + } else if((fint->kind&KindMask) == KindInterface && runtime·ifaceE2I2((InterfaceType*)fint, obj, &iface)) { // ok - satisfies non-empty interface } else goto badfunc; diff --git a/src/pkg/runtime/malloc.go b/src/pkg/runtime/malloc.go index f116efaba4..ce7e062109 100644 --- a/src/pkg/runtime/malloc.go +++ b/src/pkg/runtime/malloc.go @@ -14,15 +14,6 @@ const ( flagNoScan = 1 << 0 // GC doesn't have to scan object flagNoZero = 1 << 1 // don't zero memory - kindArray = 17 - kindFunc = 19 - kindInterface = 20 - kindPtr = 22 - kindStruct = 25 - kindMask = 1<<6 - 1 - kindGCProg = 1 << 6 - kindNoPointers = 1 << 7 - maxTinySize = 16 tinySizeClass = 2 maxSmallSize = 32 << 10 diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c index ef44d7f786..3583d77d19 100644 --- a/src/pkg/runtime/mgc0.c +++ b/src/pkg/runtime/mgc0.c @@ -367,7 +367,7 @@ scanblock(byte *b, uintptr n, byte *ptrmask) iface = (Iface*)(b+i); if(iface->tab != nil) { typ = iface->tab->type; - if(typ->size > PtrSize || !(typ->kind&KindNoPointers)) + if(!(typ->kind&KindDirectIface) || !(typ->kind&KindNoPointers)) obj = iface->data; } break; @@ -375,7 +375,7 @@ scanblock(byte *b, uintptr n, byte *ptrmask) eface = (Eface*)(b+i); typ = eface->type; if(typ != nil) { - if(typ->size > PtrSize || !(typ->kind&KindNoPointers)) + if(!(typ->kind&KindDirectIface) || !(typ->kind&KindNoPointers)) obj = eface->data; } break; @@ -1675,7 +1675,7 @@ runfinq(void) } if(f->fint == nil) runtime·throw("missing type in runfinq"); - if(f->fint->kind == KindPtr) { + if((f->fint->kind&KindMask) == KindPtr) { // direct use of pointer *(void**)frame = f->arg; } else if(((InterfaceType*)f->fint)->mhdr.len == 0) { diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c index 772080af55..b4e992e658 100644 --- a/src/pkg/runtime/stack.c +++ b/src/pkg/runtime/stack.c @@ -585,7 +585,7 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f) break; case BitsEface: t = (Type*)scanp[i]; - if(t != nil && (t->size > PtrSize || (t->kind & KindNoPointers) == 0)) { + if(t != nil && ((t->kind & KindDirectIface) == 0 || (t->kind & KindNoPointers) == 0)) { p = scanp[i+1]; if(minp <= p && p < maxp) { if(StackDebug >= 3) @@ -602,7 +602,7 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f) if(tab != nil) { t = tab->type; //runtime·printf(" type=%p\n", t); - if(t->size > PtrSize || (t->kind & KindNoPointers) == 0) { + if((t->kind & KindDirectIface) == 0 || (t->kind & KindNoPointers) == 0) { p = scanp[i+1]; if(minp <= p && p < maxp) { if(StackDebug >= 3) diff --git a/src/pkg/runtime/typekind.go b/src/pkg/runtime/typekind.go new file mode 100644 index 0000000000..5985536289 --- /dev/null +++ b/src/pkg/runtime/typekind.go @@ -0,0 +1,44 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +const ( + kindBool = 1 + iota + kindInt + kindInt8 + kindInt16 + kindInt32 + kindInt64 + kindUint + kindUint8 + kindUint16 + kindUint32 + kindUint64 + kindUintptr + kindFloat32 + kindFloat64 + kindComplex64 + kindComplex128 + kindArray + kindChan + kindFunc + kindInterface + kindMap + kindPtr + kindSlice + kindString + kindStruct + kindUnsafePointer + + kindDirectIface = 1 << 5 + kindGCProg = 1 << 6 // Type.gc points to GC program + kindNoPointers = 1 << 7 + kindMask = (1 << 5) - 1 +) + +// isDirectIface reports whether t is stored directly in an interface value. +func isDirectIface(t *_type) bool { + return t.kind&kindDirectIface != 0 +} diff --git a/src/pkg/runtime/typekind.h b/src/pkg/runtime/typekind.h index bf6ade08d6..7c611e8ba6 100644 --- a/src/pkg/runtime/typekind.h +++ b/src/pkg/runtime/typekind.h @@ -33,8 +33,9 @@ enum { KindStruct, KindUnsafePointer, + KindDirectIface = 1<<5, KindGCProg = 1<<6, // Type.gc points to GC program KindNoPointers = 1<<7, - KindMask = (1<<6)-1, + KindMask = (1<<5)-1, }; |
