root/trunk/src/ph.c

Revision 428, 6.8 kB (checked in by walter, 2 years ago)

remove tabs, any trailing spaces

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2009 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include        <stdio.h>
11 #include        <time.h>
12 #include        <string.h>
13 #include        <stdlib.h>
14
15 #if __DMC__
16 #include        <new.h>
17 #else
18 #include        <new>
19 #endif
20
21 #include        "cc.h"
22 #include        "global.h"
23
24 static char __file__[] = __FILE__;      /* for tassert.h                */
25 #include        "tassert.h"
26
27 /**********************************************
28  * Do our own storage allocator, a replacement
29  * for malloc/free.
30  */
31
32 struct Heap
33 {
34     Heap *prev;         // previous heap
35     unsigned char *buf; // buffer
36     unsigned char *p;   // high water mark
37     unsigned nleft;     // number of bytes left
38 };
39
40 Heap *heap=NULL;
41
42 void ph_init()
43 {
44     if (!heap) {
45         heap = (Heap *)calloc(1,sizeof(Heap));
46     }
47     assert(heap);
48 }
49
50
51
52 void ph_term()
53 {
54     //printf("ph_term()\n");
55 #if _WINDLL || DEBUG
56     Heap *h;
57     Heap *hprev;
58
59     for (h = heap; h; h = hprev)
60     {
61         hprev = h->prev;
62         free(h->buf);
63         free(h);
64     }
65 #endif
66 }
67
68 void ph_newheap(size_t nbytes)
69 {   unsigned newsize;
70     Heap *h;
71
72     h = (Heap *) malloc(sizeof(Heap));
73     if (!h)
74         err_nomem();
75
76     newsize = (nbytes > 0xFF00) ? nbytes : 0xFF00;
77     h->buf = (unsigned char *) malloc(newsize);
78     if (!h->buf)
79     {
80         free(h);
81         err_nomem();
82     }
83     h->nleft = newsize;
84     h->p = h->buf;
85     h->prev = heap;
86     heap = h;
87 }
88
89 void *ph_malloc(size_t nbytes)
90 {   unsigned char *p;
91
92 #ifdef DEBUG
93     util_progress();
94 #endif
95     nbytes += sizeof(unsigned) * 2;
96     nbytes &= ~(sizeof(unsigned) - 1);
97
98     if (nbytes >= heap->nleft)
99         ph_newheap(nbytes);
100     p = heap->p;
101     heap->p += nbytes;
102     heap->nleft -= nbytes;
103     *(unsigned *)p = nbytes - sizeof(unsigned);
104     p += sizeof(unsigned);
105     return p;
106 }
107
108 #if ASM86
109 __declspec(naked) void *ph_calloc(size_t nbytes)
110 {
111     _asm
112     {
113         push    dword ptr 4[ESP]
114         call    ph_malloc
115         test    EAX,EAX
116         je      L25
117         push    dword ptr 4[ESP]
118         push    0
119         push    EAX
120         call    memset
121         add     ESP,0Ch
122 L25:    ret     4
123     }
124 }
125 #else
126 void *ph_calloc(size_t nbytes)
127 {   void *p;
128
129     p = ph_malloc(nbytes);
130     return p ? memset(p,0,nbytes) : p;
131 }
132 #endif
133
134 void ph_free(void *p)
135 {
136 }
137
138 void * __cdecl ph_realloc(void *p,size_t nbytes)
139 {   void *newp;
140     unsigned i;
141
142     //dbg_printf("ph_realloc(%p,%d)\n",p,nbytes);
143     if (!p)
144         return ph_malloc(nbytes);
145     if (!nbytes)
146     {   ph_free(p);
147         return NULL;
148     }
149     newp = ph_malloc(nbytes);
150     if (newp)
151     {   unsigned oldsize = ((unsigned *)p)[-1];
152         memcpy(newp,p,oldsize);
153         ph_free(p);
154     }
155     return newp;
156 }
157
158 void err_nomem()
159 {
160     printf("Error: out of memory\n");
161     err_exit();
162 }
163
164 #if !MEM_DEBUG
165
166
167 /***********************
168  * Replacement for the standard C++ library operator delete().
169  */
170
171 #if 0
172 #undef delete
173 void __cdecl operator delete(void *p)
174 {
175 }
176 #endif
177
178 #if 0
179
180 /*****************************************
181  * Using this for array allocations gives
182  * us an easy way to get at the array dimension.
183  * Overloading operator new[]() doesn't work because that
184  * gives us the array allocated size, but we need the dimension.
185  */
186
187 #ifdef DEBUG
188 #define ARRAY_PROLOG    'prol'
189 #define ARRAY_EPILOG    'epil'
190 #define ARRAY_FILL      'f'
191 static int array_max_dim;
192
193 /*********************************
194  * Run "reasonableness" checks on array.
195  */
196
197 void array_debug(void *a)
198 {   size_t *p = (size_t *)a;
199
200     assert(p);
201     assert(p[-2] == ARRAY_PROLOG);
202     int length = p[-1];
203     assert(length >= 0 && length <= array_max_dim);
204     assert(p[length] == ARRAY_EPILOG);
205
206     // Since array contents are aligned pointers or NULL...
207     for (int i = 0; i < length; i++)
208         assert((p[i] & 3) == 0);
209 }
210
211 #endif
212
213 #undef array_new
214 void *array_new(int sizelem, int dim)
215 {   size_t *p;
216     size_t sz;
217
218 #ifdef DEBUG
219     assert(sizelem == sizeof(void *));  // must be array of pointers
220     if (!(dim >= 0 && dim < 10000))
221         printf("dim = %d\n",dim);
222     assert(dim >= 0 && dim < 10000);
223     if (dim > array_max_dim)
224         array_max_dim = dim;
225
226     sz = sizeof(size_t) * (3 + dim);
227     p = ph_calloc(sz);
228     if (p)
229     {   p[0] = ARRAY_PROLOG;            // leading sentinel
230         p[1] = dim;
231         p[2 + dim] = ARRAY_EPILOG;      // trailing sentinel
232         p += 2;
233         array_debug(p);
234     }
235 #else
236
237     sz = sizeof(size_t) * (1 + dim);
238     p = ph_calloc(sz);
239     if (p)
240         *p++ = dim;
241 #endif
242     return (void *)p;
243 }
244
245 #undef array_delete
246 void array_delete(void *a, int sizelem)
247 {
248     size_t *p = (size_t *)a;
249 #ifdef DEBUG
250
251     array_debug(p);
252     assert(sizelem == sizeof(size_t));
253     memset(p - 2,ARRAY_FILL,sizeof(size_t *) * (3 + p[-1]));
254     ph_free(p - 2);
255 #else
256     ((size_t *)p)--;
257     ph_free(p);
258 #endif
259 }
260
261 size_t array_length(void *p)
262 {
263     array_debug(p);
264     return ((size_t *)p)[-1];
265 }
266
267 /********************************
268  * Same as System.arraycopy()
269  */
270
271 void array_copy(void *f,int fi,void *t,int ti,int length)
272 {
273 #ifdef DEBUG
274     assert(length >= 0 && length <= array_max_dim);
275     int f_length = array_length(f);
276     int t_length = array_length(t);
277     assert(fi >= 0 && fi + length <= f_length);
278     assert(ti >= 0 && ti + length <= t_length);
279 #endif
280     memcpy(&((void **)t)[ti],&((void **)f)[fi],length * sizeof(void *));
281 }
282
283 /************************************
284  * Reallocate.
285  */
286
287 #undef array_renew
288 void **array_renew(void *a,int newlength)
289 {   int sz = sizeof(void *);
290     int hsz = sizeof(void *);
291
292     if (!a)
293         a = array_new(sz,newlength);
294     else
295     {
296         int oldlength = array_length(a);
297 #ifdef DEBUG
298         void *b = array_new(sizeof(void *),newlength);
299         int len = (oldlength < newlength) ? oldlength : newlength;
300         array_copy(a,0,b,0,len);
301         array_delete(a,sizeof(void *));
302         a = b;
303 #else
304         if (oldlength < newlength)
305         {
306             (char *)a -= hsz;
307             a = ph_realloc(a,hsz + newlength * sz);
308             if (!a)
309                 goto Lret;
310             (char *)a += hsz;
311             memset(&((void **)a)[oldlength],0,(newlength - oldlength) * sz);
312         }
313         else if (oldlength > newlength)
314         {
315             ;
316         }
317         ((size_t *)a)[-1] = newlength;
318 #endif
319     }
320 Lret:
321     return a;
322 }
323
324 /******************************************
325  * Sort an array.
326  */
327
328 #if MACINTOSH
329 extern "C" int acompare(const void *e1,const void *e2)
330 #else
331 int __cdecl acompare(const void *e1,const void *e2)
332 #endif
333 {
334     Object *o1 = *(Object **)e1;
335     Object *o2 = *(Object **)e2;
336
337     return o1->compare(o2);
338 }
339
340 void array_sort(void *a)
341 {
342     qsort(a,array_length(a),sizeof(void *),acompare);
343 }
344
345 #endif
346 #endif
Note: See TracBrowser for help on using the browser.