diff --git a/src/pkg/runtime/heapdump.c b/src/pkg/runtime/heapdump.c index 09d109199b7..fe67e15f35f 100644 --- a/src/pkg/runtime/heapdump.c +++ b/src/pkg/runtime/heapdump.c @@ -584,7 +584,10 @@ itab_callback(Itab *tab) static void dumpitabs(void) { - runtime·iterate_itabs(itab_callback); + void (*fn)(Itab*); + + fn = itab_callback; + runtime·iterate_itabs(&fn); } static void diff --git a/src/pkg/runtime/iface.go b/src/pkg/runtime/iface.go index a3176284035..3180ea45243 100644 --- a/src/pkg/runtime/iface.go +++ b/src/pkg/runtime/iface.go @@ -425,3 +425,16 @@ func efacethash(e interface{}) uint32 { } return t.hash } + +func iterate_itabs(fn func(*itab)) { + for _, h := range hash { + for ; h != nil; h = h.link { + fn(h) + } + } +} + +func ifaceE2I2(inter *interfacetype, e interface{}, r *fInterface) (ok bool) { + *r, ok = assertE2I2(inter, e) + return +} diff --git a/src/pkg/runtime/iface.goc b/src/pkg/runtime/iface.goc deleted file mode 100644 index 440d272382b..00000000000 --- a/src/pkg/runtime/iface.goc +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright 2009 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 -#include "runtime.h" -#include "arch_GOARCH.h" -#include "type.h" -#include "typekind.h" -#include "malloc.h" -#include "../../cmd/ld/textflag.h" - -extern Itab* runtime·hash[1009]; -extern Mutex runtime·ifaceLock; - -// TODO: delete this when no longer used (ifaceE2I2 is all that's left) -static Itab* -itab(InterfaceType *inter, Type *type, int32 canfail) -{ - int32 locked; - int32 ni; - Method *t, *et; - IMethod *i, *ei; - uint32 h; - String *iname, *ipkgPath; - Itab *m; - UncommonType *x; - Type *itype; - Eface err; - - if(inter->mhdr.len == 0) - runtime·throw("internal error - misuse of itab"); - - locked = 0; - - // easy case - x = type->x; - if(x == nil) { - if(canfail) - return nil; - iname = inter->m[0].name; - goto throw; - } - - // compiler has provided some good hash codes for us. - h = inter->typ.hash; - h += 17 * type->hash; - // TODO(rsc): h += 23 * x->mhash ? - h %= nelem(runtime·hash); - - // look twice - once without lock, once with. - // common case will be no lock contention. - for(locked=0; locked<2; locked++) { - if(locked) - runtime·lock(&runtime·ifaceLock); - for(m=runtime·atomicloadp(&runtime·hash[h]); m!=nil; m=m->link) { - if(m->inter == inter && m->type == type) { - if(m->bad) { - m = nil; - if(!canfail) { - // this can only happen if the conversion - // was already done once using the , ok form - // and we have a cached negative result. - // the cached result doesn't record which - // interface function was missing, so jump - // down to the interface check, which will - // do more work but give a better error. - goto search; - } - } - if(locked) - runtime·unlock(&runtime·ifaceLock); - return m; - } - } - } - - ni = inter->mhdr.len; - m = runtime·persistentalloc(sizeof(*m) + ni*sizeof m->fun[0], 0, &mstats.other_sys); - m->inter = inter; - m->type = type; - -search: - // both inter and type have method sorted by name, - // and interface names are unique, - // so can iterate over both in lock step; - // the loop is O(ni+nt) not O(ni*nt). - i = inter->m; - ei = i + inter->mhdr.len; - t = x->m; - et = t + x->mhdr.len; - for(; i < ei; i++) { - itype = i->type; - iname = i->name; - ipkgPath = i->pkgPath; - for(;; t++) { - if(t >= et) { - if(!canfail) { - throw: - // didn't find method - runtime·newTypeAssertionError( - nil, type->string, inter->typ.string, - iname, &err); - if(locked) - runtime·unlock(&runtime·ifaceLock); - runtime·panic(err); - return nil; // not reached - } - m->bad = 1; - goto out; - } - if(t->mtyp == itype && t->name == iname && t->pkgPath == ipkgPath) - break; - } - if(m) - m->fun[i - inter->m] = t->ifn; - } - -out: - if(!locked) - runtime·panicstring("invalid itab locking"); - m->link = runtime·hash[h]; - runtime·atomicstorep(&runtime·hash[h], m); - runtime·unlock(&runtime·ifaceLock); - if(m->bad) - return nil; - return m; -} - -// call the callback for every itab that is currently allocated. -void -runtime·iterate_itabs(void (*callback)(Itab*)) -{ - int32 i; - Itab *tab; - - for(i = 0; i < nelem(runtime·hash); i++) { - for(tab = runtime·hash[i]; tab != nil; tab = tab->link) { - callback(tab); - } - } -} - -// Still in C because it is called from C for finalizers. This will -// get converted to Go in a separate CL. This is the last user of -// the C version of itab(). -bool -runtime·ifaceE2I2(InterfaceType *inter, Eface e, Iface *ret) -{ - ret->tab = itab(inter, e.type, 1); - if(ret->tab == nil) - return false; - ret->data = e.data; - return true; -} diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 72f446f3797..90cb3cbd7f9 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -959,7 +959,7 @@ void _rt0_go(void); void* runtime·funcdata(Func*, int32); void runtime·setmaxthreads_m(void); G* runtime·timejump(void); -void runtime·iterate_itabs(void (*callback)(Itab*)); +void runtime·iterate_itabs(void (**callback)(Itab*)); void runtime·iterate_finq(void (*callback)(FuncVal*, byte*, uintptr, Type*, PtrType*)); #pragma varargck argpos runtime·printf 1