summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/mfinal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/mfinal.c')
-rw-r--r--src/pkg/runtime/mfinal.c219
1 files changed, 0 insertions, 219 deletions
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; j<t->max; 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; j<t->max; 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; i<tab->max; 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<TABSZ; i++) {
- runtime·lock(&fintab[i]);
- key = fintab[i].key;
- ekey = key + fintab[i].max;
- for(; key < ekey; key++)
- if(*key != nil && *key != ((void*)-1))
- fn(*key);
- runtime·unlock(&fintab[i]);
- }
-}