Upstream version 1.3.40
[profile/ivi/swig.git] / Source / DOH / memory.c
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
13 char 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
21 static int PoolSize = DOH_POOL_SIZE;
22
23 DOH *DohNone = 0;               /* The DOH None object */
24
25 typedef 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
35 static DohBase *FreeList = 0;   /* List of free objects */
36 static Pool *Pools = 0;
37 static int pools_initialized = 0;
38
39 /* ----------------------------------------------------------------------
40  * CreatePool() - Create a new memory pool 
41  * ---------------------------------------------------------------------- */
42
43 static 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
63 static 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
78 int 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
96 void 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
107 DOH *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
136 void 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
157 void 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 }