1/* ----------------------------------------------------------------------------- 2 * memory.c 3 * 4 * This file implements all of DOH's memory management including allocation 5 * of objects and checking of objects. 6 * 7 * Author(s) : David Beazley (beazley@cs.uchicago.edu) 8 * 9 * Copyright (C) 1999-2000. The University of Chicago 10 * See the file LICENSE for information on usage and redistribution. 11 * ----------------------------------------------------------------------------- */ 12 13char cvsroot_memory_c[] = "$Id: memory.c 9607 2006-12-05 22:11:40Z beazley $"; 14 15#include "dohint.h" 16 17#ifndef DOH_POOL_SIZE 18#define DOH_POOL_SIZE 16384 19#endif 20 21static int PoolSize = DOH_POOL_SIZE; 22 23DOH *DohNone = 0; /* The DOH None object */ 24 25typedef struct pool { 26 DohBase *ptr; /* Start of pool */ 27 int len; /* Length of pool */ 28 int blen; /* Byte length of pool */ 29 int current; /* Current position for next allocation */ 30 char *pbeg; /* Beg of pool */ 31 char *pend; /* End of pool */ 32 struct pool *next; /* Next pool */ 33} Pool; 34 35static DohBase *FreeList = 0; /* List of free objects */ 36static Pool *Pools = 0; 37static int pools_initialized = 0; 38 39/* ---------------------------------------------------------------------- 40 * CreatePool() - Create a new memory pool 41 * ---------------------------------------------------------------------- */ 42 43static void CreatePool() { 44 Pool *p = 0; 45 p = (Pool *) DohMalloc(sizeof(Pool)); 46 assert(p); 47 p->ptr = (DohBase *) DohMalloc(sizeof(DohBase) * PoolSize); 48 assert(p->ptr); 49 memset(p->ptr, 0, sizeof(DohBase) * PoolSize); 50 p->len = PoolSize; 51 p->blen = PoolSize * sizeof(DohBase); 52 p->current = 0; 53 p->pbeg = ((char *) p->ptr); 54 p->pend = p->pbeg + p->blen; 55 p->next = Pools; 56 Pools = p; 57} 58 59/* ---------------------------------------------------------------------- 60 * InitPools() - Initialize the memory allocator 61 * ---------------------------------------------------------------------- */ 62 63static void InitPools() { 64 if (pools_initialized) 65 return; 66 CreatePool(); /* Create initial pool */ 67 pools_initialized = 1; 68 DohNone = NewVoid(0, 0); /* Create the None object */ 69 DohIntern(DohNone); 70} 71 72/* ---------------------------------------------------------------------- 73 * DohCheck() 74 * 75 * Returns 1 if an arbitrary pointer is a DOH object. 76 * ---------------------------------------------------------------------- */ 77 78int DohCheck(const DOH *ptr) { 79 register Pool *p = Pools; 80 register char *cptr = (char *) ptr; 81 while (p) { 82 if ((cptr >= p->pbeg) && (cptr < p->pend)) 83 return 1; 84 /* 85 pptr = (char *) p->ptr; 86 if ((cptr >= pptr) && (cptr < (pptr+(p->current*sizeof(DohBase))))) return 1; */ 87 p = p->next; 88 } 89 return 0; 90} 91 92/* ----------------------------------------------------------------------------- 93 * DohIntern() 94 * ----------------------------------------------------------------------------- */ 95 96void DohIntern(DOH *obj) { 97 DohBase *b = (DohBase *) obj; 98 b->flag_intern = 1; 99} 100 101/* ---------------------------------------------------------------------- 102 * DohObjMalloc() 103 * 104 * Allocate memory for a new object. 105 * ---------------------------------------------------------------------- */ 106 107DOH *DohObjMalloc(DohObjInfo *type, void *data) { 108 DohBase *obj; 109 if (!pools_initialized) 110 InitPools(); 111 if (FreeList) { 112 obj = FreeList; 113 FreeList = (DohBase *) obj->data; 114 } else { 115 while (Pools->current == Pools->len) { 116 CreatePool(); 117 } 118 obj = Pools->ptr + Pools->current; 119 ++Pools->current; 120 } 121 obj->type = type; 122 obj->data = data; 123 obj->meta = 0; 124 obj->refcount = 1; 125 obj->flag_intern = 0; 126 obj->flag_marked = 0; 127 obj->flag_user = 0; 128 obj->flag_usermark = 0; 129 return (DOH *) obj; 130} 131 132/* ---------------------------------------------------------------------- 133 * DohObjFree() - Free a DOH object 134 * ---------------------------------------------------------------------- */ 135 136void DohObjFree(DOH *ptr) { 137 DohBase *b, *meta; 138 b = (DohBase *) ptr; 139 if (b->flag_intern) 140 return; 141 meta = (DohBase *) b->meta; 142 b->data = (void *) FreeList; 143 b->meta = 0; 144 b->type = 0; 145 FreeList = b; 146 if (meta) { 147 Delete(meta); 148 } 149} 150 151/* ---------------------------------------------------------------------- 152 * DohMemoryDebug() 153 * 154 * Display memory usage statistics 155 * ---------------------------------------------------------------------- */ 156 157void DohMemoryDebug(void) { 158 extern DohObjInfo DohStringType; 159 extern DohObjInfo DohListType; 160 extern DohObjInfo DohHashType; 161 162 Pool *p; 163 int totsize = 0; 164 int totused = 0; 165 int totfree = 0; 166 167 int numstring = 0; 168 int numlist = 0; 169 int numhash = 0; 170 171 printf("Memory statistics:\n\n"); 172 printf("Pools:\n"); 173 174 p = Pools; 175 while (p) { 176 /* Calculate number of used, free items */ 177 int i; 178 int nused = 0, nfree = 0; 179 for (i = 0; i < p->len; i++) { 180 if (p->ptr[i].refcount <= 0) 181 nfree++; 182 else { 183 nused++; 184 if (p->ptr[i].type == &DohStringType) 185 numstring++; 186 else if (p->ptr[i].type == &DohListType) 187 numlist++; 188 else if (p->ptr[i].type == &DohHashType) 189 numhash++; 190 } 191 } 192 printf(" Pool %8p: size = %10d. used = %10d. free = %10d\n", (void *) p, p->len, nused, nfree); 193 totsize += p->len; 194 totused += nused; 195 totfree += nfree; 196 p = p->next; 197 } 198 printf("\n Total: size = %10d, used = %10d, free = %10d\n", totsize, totused, totfree); 199 200 printf("\nObject types\n"); 201 printf(" Strings : %d\n", numstring); 202 printf(" Lists : %d\n", numlist); 203 printf(" Hashes : %d\n", numhash); 204 205#if 0 206 p = Pools; 207 while (p) { 208 int i; 209 for (i = 0; i < p->len; i++) { 210 if (p->ptr[i].refcount > 0) { 211 if (p->ptr[i].type == &DohStringType) { 212 Printf(stdout, "%s\n", p->ptr + i); 213 } 214 } 215 } 216 p = p->next; 217 } 218#endif 219 220} 221