From 8a39ee361feb9bf46d728ff1ba4f07ca1d9610b1 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Thu, 19 Jun 2014 09:22:53 +0200 Subject: Imported Upstream version 1.3 --- src/pkg/runtime/mfinal.c | 219 ----------------------------------------------- 1 file changed, 219 deletions(-) delete mode 100644 src/pkg/runtime/mfinal.c (limited to 'src/pkg/runtime/mfinal.c') diff --git a/src/pkg/runtime/mfinal.c b/src/pkg/runtime/mfinal.c deleted file mode 100644 index 3e524d3e0..000000000 --- a/src/pkg/runtime/mfinal.c +++ /dev/null @@ -1,219 +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_GOARCH.h" -#include "malloc.h" -#include "type.h" - -enum { debug = 0 }; - -typedef struct Fin Fin; -struct Fin -{ - FuncVal *fn; - uintptr nret; - Type *fint; - PtrType *ot; -}; - -// 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 **key; - 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[CacheLineSize - sizeof(Fintab)]; -} fintab[TABSZ]; - -static void -addfintab(Fintab *t, void *k, FuncVal *fn, uintptr nret, Type *fint, PtrType *ot) -{ - int32 i, j; - - i = (uintptr)k % (uintptr)t->max; - for(j=0; jmax; j++) { - if(t->key[i] == nil) { - t->nkey++; - goto ret; - } - if(t->key[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->key[i] = k; - t->val[i].fn = fn; - t->val[i].nret = nret; - t->val[i].fint = fint; - t->val[i].ot = ot; -} - -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; jmax; j++) { - if(t->key[i] == nil) - return false; - if(t->key[i] == k) { - if(f) - *f = t->val[i]; - if(del) { - t->key[i] = (void*)-1; - t->val[i].fn = nil; - t->val[i].nret = 0; - t->val[i].ot = 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.key = runtime·mallocgc(newtab.max*sizeof newtab.key[0], 0, FlagNoInvokeGC|FlagNoScan); - newtab.val = runtime·mallocgc(newtab.max*sizeof newtab.val[0], 0, FlagNoInvokeGC); - - for(i=0; imax; i++) { - k = tab->key[i]; - if(k != nil && k != (void*)-1) - addfintab(&newtab, k, tab->val[i].fn, tab->val[i].nret, tab->val[i].fint, tab->val[i].ot); - } - - runtime·free(tab->key); - runtime·free(tab->val); - - tab->key = newtab.key; - tab->val = newtab.val; - tab->nkey = newtab.nkey; - tab->ndead = newtab.ndead; - tab->max = newtab.max; -} - -bool -runtime·addfinalizer(void *p, FuncVal *f, uintptr nret, Type *fint, PtrType *ot) -{ - 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, nret, fint, ot); - 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, FuncVal **fn, uintptr *nret, Type **fint, PtrType **ot) -{ - 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; - *nret = f.nret; - *fint = f.fint; - *ot = f.ot; - return true; -} - -void -runtime·walkfintab(void (*fn)(void*)) -{ - void **key; - void **ekey; - int32 i; - - for(i=0; i