📄 table.c
字号:
/* table.c - bookkeeping functions for allocated memory *//* Copyright (C) 2001-2003 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash. If not, see <http://www.gnu.org/licenses/>.*/#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <stdio.h>#include <string.h>#include "imalloc.h"#include "table.h"extern int malloc_register;#ifdef MALLOC_REGISTER#define FIND_ALLOC 0x01 /* allocate new entry or find existing */#define FIND_EXIST 0x02 /* find existing entry */static int table_count = 0;static int table_allocated = 0;static mr_table_t mem_table[REG_TABLE_SIZE];static mr_table_t mem_overflow;/* * NOTE: taken from dmalloc (http://dmalloc.com) and modified. */static unsigned intmt_hash (key) const PTR_T key;{ unsigned int a, b, c; unsigned long x; /* set up the internal state */ a = 0x9e3779b9; /* the golden ratio; an arbitrary value */ x = (unsigned long)key; /* truncation is OK */ b = x >> 8; c = x >> 3; /* XXX - was >> 4 */ HASH_MIX(a, b, c); return c;}#if 0static unsigned intwhich_bucket (mem) PTR_T mem;{ return (mt_hash ((unsigned char *)mem) & (REG_TABLE_SIZE-1));}#else#define which_bucket(mem) (mt_hash ((unsigned char *)(mem)) & (REG_TABLE_SIZE-1));#endifstatic mr_table_t *find_entry (mem, flags) PTR_T mem; int flags;{ unsigned int bucket; register mr_table_t *tp; mr_table_t *endp, *lastp; if (mem_overflow.mem == mem) return (&mem_overflow); bucket = which_bucket (mem); /* get initial hash */ tp = endp = mem_table + bucket; lastp = mem_table + REG_TABLE_SIZE; while (1) { if (tp->mem == mem) return (tp); if (tp->mem == 0 && (flags & FIND_ALLOC)) { table_count++; return (tp); } tp++; if (tp == lastp) /* wrap around */ tp = mem_table; if (tp == endp && (flags & FIND_EXIST)) return ((mr_table_t *)NULL); if (tp == endp && (flags & FIND_ALLOC)) break; } /* oops. table is full. replace an existing free entry. */ do { /* If there are no free entries, punt right away without searching. */ if (table_allocated == REG_TABLE_SIZE) break; if (tp->flags & MT_FREE) { memset(tp, 0, sizeof (mr_table_t)); return (tp); } tp++; if (tp == lastp) tp = mem_table; } while (tp != endp); /* wow. entirely full. return mem_overflow dummy entry. */ tp = &mem_overflow; memset (tp, 0, sizeof (mr_table_t)); return tp;}mr_table_t *mr_table_entry (mem) PTR_T mem;{ return (find_entry (mem, FIND_EXIST));}voidmregister_describe_mem (mem, fp) PTR_T mem; FILE *fp;{ mr_table_t *entry; entry = find_entry (mem, FIND_EXIST); if (entry == 0) return; fprintf (fp, "malloc: %p: %s: last %s from %s:%d\n", mem, (entry->flags & MT_ALLOC) ? "allocated" : "free", (entry->flags & MT_ALLOC) ? "allocated" : "freed", entry->file ? entry->file : "unknown", entry->line);}voidmregister_alloc (tag, mem, size, file, line) const char *tag; PTR_T mem; size_t size; const char *file; int line;{ mr_table_t *tentry; tentry = find_entry (mem, FIND_ALLOC); if (tentry == 0) { /* oops. table is full. punt. */ fprintf (stderr, _("register_alloc: alloc table is full with FIND_ALLOC?\n")); return; } if (tentry->flags & MT_ALLOC) { /* oops. bad bookkeeping. ignore for now */ fprintf (stderr, _("register_alloc: %p already in table as allocated?\n"), mem); } tentry->mem = mem; tentry->size = size; tentry->func = tag; tentry->flags = MT_ALLOC; tentry->file = file; tentry->line = line; tentry->nalloc++; if (tentry != &mem_overflow) table_allocated++;}voidmregister_free (mem, size, file, line) PTR_T mem; int size; const char *file; int line;{ mr_table_t *tentry; tentry = find_entry (mem, FIND_EXIST); if (tentry == 0) { /* oops. not found. */#if 0 fprintf (stderr, "register_free: %p not in allocation table?\n", mem);#endif return; } if (tentry->flags & MT_FREE) { /* oops. bad bookkeeping. ignore for now */ fprintf (stderr, _("register_free: %p already in table as free?\n"), mem); } tentry->flags = MT_FREE; tentry->func = "free"; tentry->file = file; tentry->line = line; tentry->nfree++; if (tentry != &mem_overflow) table_allocated--;}/* If we ever add more flags, this will require changes. */static char *_entry_flags(x) int x;{ if (x & MT_FREE) return "free"; else if (x & MT_ALLOC) return "allocated"; else return "undetermined?";}static void_register_dump_table(fp) FILE *fp;{ register int i; mr_table_t entry; for (i = 0; i < REG_TABLE_SIZE; i++) { entry = mem_table[i]; if (entry.mem) fprintf (fp, "[%d] %p:%d:%s:%s:%s:%d:%d:%d\n", i, entry.mem, entry.size, _entry_flags(entry.flags), entry.func ? entry.func : "unknown", entry.file ? entry.file : "unknown", entry.line, entry.nalloc, entry.nfree); }} voidmregister_dump_table(){ _register_dump_table (stderr);}voidmregister_table_init (){ memset (mem_table, 0, sizeof(mr_table_t) * REG_TABLE_SIZE); memset (&mem_overflow, 0, sizeof (mr_table_t)); table_count = 0;}#endif /* MALLOC_REGISTER */intmalloc_set_register(n) int n;{ int old; old = malloc_register; malloc_register = n; return old;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -