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 static char cvsroot[] = "$Header: /cvs/projects/SWILL/Source/Objects/memory.c,v 1.3 2002/03/10 04:30:14 beazley Exp $";
14 
15 #include "dohint.h"
16 
17 #ifndef DOH_POOL_SIZE
18 #define DOH_POOL_SIZE         512
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   struct  pool  *next;           /* Next pool */
31 } Pool;
32 
33 static DohBase  *FreeList = 0;          /* List of free objects */
34 static Pool    *Pools = 0;
35 static int      pools_initialized = 0;
36 
37 /* ----------------------------------------------------------------------
38  * CreatePool() - Create a new memory pool
39  * ---------------------------------------------------------------------- */
40 
41 static void
CreatePool()42 CreatePool() {
43   Pool *p = 0;
44   p = (Pool *) DohMalloc(sizeof(Pool));
45   assert(p);
46   p->ptr = (DohBase *) DohMalloc(sizeof(DohBase)*PoolSize);
47   assert(p->ptr);
48   p->len = PoolSize;
49   p->blen = PoolSize*sizeof(DohBase);
50   p->current = 0;
51   p->next = Pools;
52   Pools = p;
53 }
54 
55 /* ----------------------------------------------------------------------
56  * InitPools() - Initialize the memory allocator
57  * ---------------------------------------------------------------------- */
58 
59 static void
InitPools()60 InitPools() {
61   if (pools_initialized) return;
62   CreatePool();                       /* Create initial pool */
63   pools_initialized = 1;
64   DohNone = NewVoid(0,0);             /* Create the None object */
65   DohIntern(DohNone);
66 }
67 
68 /* ----------------------------------------------------------------------
69  * DohCheck()
70  *
71  * Returns 1 if an arbitrary pointer is a DOH object.
72  * ---------------------------------------------------------------------- */
73 
74 int
DohCheck(const DOH * ptr)75 DohCheck(const DOH *ptr) {
76   Pool *p = Pools;
77   register char *cptr = (char *) ptr;
78   register char *pptr;
79   while (p) {
80     pptr = (char *) p->ptr;
81     if ((cptr >= pptr) && (cptr < (pptr + p->blen))) return 1;
82     /*
83     pptr = (char *) p->ptr;
84     if ((cptr >= pptr) && (cptr < (pptr+(p->current*sizeof(DohBase))))) return 1; */
85     p = p->next;
86   }
87   return 0;
88 }
89 
90 /* -----------------------------------------------------------------------------
91  * DohIntern()
92  * ----------------------------------------------------------------------------- */
93 
94 void
DohIntern(DOH * obj)95 DohIntern(DOH *obj) {
96   DohBase *b = (DohBase *) obj;
97   b->flag_intern = 1;
98 }
99 
100 /* ----------------------------------------------------------------------
101  * DohObjMalloc()
102  *
103  * Allocate memory for a new object.
104  * ---------------------------------------------------------------------- */
105 
106 DOH *
DohObjMalloc(DohObjInfo * type,void * data)107 DohObjMalloc(DohObjInfo *type, void *data) {
108   DohBase *obj;
109   if (!pools_initialized) InitPools();
110   if (FreeList) {
111     obj = FreeList;
112     FreeList = (DohBase *) obj->data;
113   } else {
114     while (Pools->current == Pools->len) {
115       PoolSize *= 2;
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   return (DOH *) obj;
128 }
129 
130 /* ----------------------------------------------------------------------
131  * DohObjFree() - Free a DOH object
132  * ---------------------------------------------------------------------- */
133 
134 void
DohObjFree(DOH * ptr)135 DohObjFree(DOH *ptr) {
136   DohBase  *b;
137   b = (DohBase *) ptr;
138   if (b->flag_intern) return;
139   b->data = (void *) FreeList;
140   if (b->meta) {
141     Delete(b->meta);
142     b->meta = 0;
143   }
144   b->type = 0;
145   FreeList = b;
146 }
147 
148