aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/alg.go8
-rw-r--r--src/pkg/runtime/heapdump.c4
-rw-r--r--src/pkg/runtime/iface.go12
-rw-r--r--src/pkg/runtime/malloc.c8
-rw-r--r--src/pkg/runtime/malloc.go9
-rw-r--r--src/pkg/runtime/mgc0.c6
-rw-r--r--src/pkg/runtime/stack.c4
-rw-r--r--src/pkg/runtime/typekind.go44
-rw-r--r--src/pkg/runtime/typekind.h3
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,
};