cmd/gc, runtime: refactor interface inlining decision into compiler

We need to change the interface value representation for
concurrent garbage collection, so that there is no ambiguity
about whether the data word holds a pointer or scalar.

This CL does NOT make any representation changes.

Instead, it removes representation assumptions from
various pieces of code throughout the tree.
The isdirectiface function in cmd/gc/subr.c is now
the only place that decides that policy.
The policy propagates out from there in the reflect
metadata, as a new flag in the internal kind value.

A follow-up CL will change the representation by
changing the isdirectiface function. If that CL causes
problems, it will be easy to roll back.

Update #8405.

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews, r
https://golang.org/cl/129090043
This commit is contained in:
Russ Cox 2014-08-18 21:13:11 -04:00
parent 2e2beb567c
commit 1806a5732b
18 changed files with 230 additions and 105 deletions

View file

@ -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;