diff options
Diffstat (limited to 'gcc-4.8.1/libgo/runtime/mfinal.c')
-rw-r--r-- | gcc-4.8.1/libgo/runtime/mfinal.c | 213 |
1 files changed, 0 insertions, 213 deletions
diff --git a/gcc-4.8.1/libgo/runtime/mfinal.c b/gcc-4.8.1/libgo/runtime/mfinal.c deleted file mode 100644 index 7c906daf3..000000000 --- a/gcc-4.8.1/libgo/runtime/mfinal.c +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2010 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. - -#include "runtime.h" -#include "arch.h" -#include "malloc.h" - -enum { debug = 0 }; - -typedef struct Fin Fin; -struct Fin -{ - void (*fn)(void*); - const struct __go_func_type *ft; -}; - -// Finalizer hash table. Direct hash, linear scan, at most 3/4 full. -// Table size is power of 3 so that hash can be key % max. -// Key[i] == (void*)-1 denotes free but formerly occupied entry -// (doesn't stop the linear scan). -// Key and val are separate tables because the garbage collector -// must be instructed to ignore the pointers in key but follow the -// pointers in val. -typedef struct Fintab Fintab; -struct Fintab -{ - Lock; - void **fkey; - Fin *val; - int32 nkey; // number of non-nil entries in key - int32 ndead; // number of dead (-1) entries in key - int32 max; // size of key, val allocations -}; - -#define TABSZ 17 -#define TAB(p) (&fintab[((uintptr)(p)>>3)%TABSZ]) - -static struct { - Fintab; - uint8 pad[0 /* CacheLineSize - sizeof(Fintab) */]; -} fintab[TABSZ]; - -static void -addfintab(Fintab *t, void *k, void (*fn)(void*), const struct __go_func_type *ft) -{ - int32 i, j; - - i = (uintptr)k % (uintptr)t->max; - for(j=0; j<t->max; j++) { - if(t->fkey[i] == nil) { - t->nkey++; - goto ret; - } - if(t->fkey[i] == (void*)-1) { - t->ndead--; - goto ret; - } - if(++i == t->max) - i = 0; - } - - // cannot happen - table is known to be non-full - runtime_throw("finalizer table inconsistent"); - -ret: - t->fkey[i] = k; - t->val[i].fn = fn; - t->val[i].ft = ft; -} - -static bool -lookfintab(Fintab *t, void *k, bool del, Fin *f) -{ - int32 i, j; - - if(t->max == 0) - return false; - i = (uintptr)k % (uintptr)t->max; - for(j=0; j<t->max; j++) { - if(t->fkey[i] == nil) - return false; - if(t->fkey[i] == k) { - if(f) - *f = t->val[i]; - if(del) { - t->fkey[i] = (void*)-1; - t->val[i].fn = nil; - t->val[i].ft = nil; - t->ndead++; - } - return true; - } - if(++i == t->max) - i = 0; - } - - // cannot happen - table is known to be non-full - runtime_throw("finalizer table inconsistent"); - return false; -} - -static void -resizefintab(Fintab *tab) -{ - Fintab newtab; - void *k; - int32 i; - - runtime_memclr((byte*)&newtab, sizeof newtab); - newtab.max = tab->max; - if(newtab.max == 0) - newtab.max = 3*3*3; - else if(tab->ndead < tab->nkey/2) { - // grow table if not many dead values. - // otherwise just rehash into table of same size. - newtab.max *= 3; - } - - newtab.fkey = runtime_mallocgc(newtab.max*sizeof newtab.fkey[0], FlagNoPointers, 0, 1); - newtab.val = runtime_mallocgc(newtab.max*sizeof newtab.val[0], 0, 0, 1); - - for(i=0; i<tab->max; i++) { - k = tab->fkey[i]; - if(k != nil && k != (void*)-1) - addfintab(&newtab, k, tab->val[i].fn, tab->val[i].ft); - } - - runtime_free(tab->fkey); - runtime_free(tab->val); - - tab->fkey = newtab.fkey; - tab->val = newtab.val; - tab->nkey = newtab.nkey; - tab->ndead = newtab.ndead; - tab->max = newtab.max; -} - -bool -runtime_addfinalizer(void *p, void (*f)(void*), const struct __go_func_type *ft) -{ - Fintab *tab; - byte *base; - - if(debug) { - if(!runtime_mlookup(p, &base, nil, nil) || p != base) - runtime_throw("addfinalizer on invalid pointer"); - } - - tab = TAB(p); - runtime_lock(tab); - if(f == nil) { - lookfintab(tab, p, true, nil); - runtime_unlock(tab); - return true; - } - - if(lookfintab(tab, p, false, nil)) { - runtime_unlock(tab); - return false; - } - - if(tab->nkey >= tab->max/2+tab->max/4) { - // keep table at most 3/4 full: - // allocate new table and rehash. - resizefintab(tab); - } - - addfintab(tab, p, f, ft); - runtime_setblockspecial(p, true); - runtime_unlock(tab); - return true; -} - -// get finalizer; if del, delete finalizer. -// caller is responsible for updating RefHasFinalizer (special) bit. -bool -runtime_getfinalizer(void *p, bool del, void (**fn)(void*), const struct __go_func_type **ft) -{ - Fintab *tab; - bool res; - Fin f; - - tab = TAB(p); - runtime_lock(tab); - res = lookfintab(tab, p, del, &f); - runtime_unlock(tab); - if(res==false) - return false; - *fn = f.fn; - *ft = f.ft; - return true; -} - -void -runtime_walkfintab(void (*fn)(void*), void (*addroot)(Obj)) -{ - void **key; - void **ekey; - int32 i; - - for(i=0; i<TABSZ; i++) { - runtime_lock(&fintab[i]); - key = fintab[i].fkey; - ekey = key + fintab[i].max; - for(; key < ekey; key++) - if(*key != nil && *key != ((void*)-1)) - fn(*key); - addroot((Obj){(byte*)&fintab[i].fkey, sizeof(void*), 0}); - addroot((Obj){(byte*)&fintab[i].val, sizeof(void*), 0}); - runtime_unlock(&fintab[i]); - } -} |