aboutsummaryrefslogtreecommitdiff
path: root/src/pkg
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-08-28 10:36:48 -0400
committerRuss Cox <rsc@golang.org>2014-08-28 10:36:48 -0400
commitb53b47f5ac9e11fdcd3f704bc2cb0828bdee6958 (patch)
tree9f5ad86588fa09c9b9a3c4bcb4fccd65077c049a /src/pkg
parent98e5a44a88990b4ed8130056c1d1dec4abc4ecaf (diff)
downloadgo-b53b47f5ac9e11fdcd3f704bc2cb0828bdee6958.tar.xz
runtime: finish converting iface.goc to iface.go
LGTM=bradfitz, dvyukov R=golang-codereviews, bradfitz, dvyukov CC=golang-codereviews, iant, khr https://golang.org/cl/131510043
Diffstat (limited to 'src/pkg')
-rw-r--r--src/pkg/runtime/heapdump.c5
-rw-r--r--src/pkg/runtime/iface.go13
-rw-r--r--src/pkg/runtime/iface.goc155
-rw-r--r--src/pkg/runtime/runtime.h2
4 files changed, 18 insertions, 157 deletions
diff --git a/src/pkg/runtime/heapdump.c b/src/pkg/runtime/heapdump.c
index 09d109199b..fe67e15f35 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 a317628403..3180ea4524 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 440d272382..0000000000
--- 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 72f446f379..90cb3cbd7f 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