comparison anagram/support/myalloc.cpp @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 /*
2 * AnaGram, A System for Syntax Directed Programming
3 * Copyright 1993-1999 Parsifal Software. All Rights Reserved.
4 * See the file COPYING for license and usage terms.
5 *
6 * myalloc.cpp - memory allocation wrappers
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "port.h"
13
14 #include "assert.h"
15 #include "myalloc.h"
16
17 //#define INCLUDE_LOGGING
18 #include "log.h"
19
20
21 typedef struct {
22 unsigned size, comp;
23 } fence;
24
25
26 static void check_mem(void *p) {
27 if (p == NULL) {
28 bailOut("Out of memory");
29 }
30 }
31
32 static fence make_fence(int n) {
33 fence f;
34 n -= 2*sizeof(fence);
35 f.size = n;
36 f.comp = ~n;
37 return f;
38 }
39
40
41 static char longjmp_msg[128];
42
43 void *myalloc(unsigned n) {
44 fence *ptr;
45 fence *top, *bot;
46
47 if (n == 0) {
48 return NULL;
49 }
50 //myallocs++;
51 n += 2*sizeof(fence);
52 if (n&1) {
53 n++;
54 }
55 bot = ptr = (fence *) malloc(n);
56 check_mem(ptr);
57 ptr = (bot + 1);
58 top = (fence *)((char *)bot + n - sizeof(fence));
59 //*top = *bot = make_fence(n);
60 *bot = make_fence(n);
61 memcpy(top, bot, sizeof(fence));
62 //myallocBytes += n;
63 return (void *) ptr;
64 }
65
66 void *myzalloc(unsigned n, unsigned size) {
67 unsigned k = n*size;
68 fence *ptr = (fence *) myalloc(k);
69 memset(ptr, 0, k);
70
71 return ptr;
72 }
73
74 static void *ersatz_realloc(void *bot, int n) {
75 int m = *(int *) bot + 2*sizeof(fence);
76 void *old_bot = bot;
77
78 bot = malloc(n);
79 if (bot == NULL) {
80 return bot;
81 }
82 if (n < m) {
83 m = n;
84 }
85 memmove(bot, old_bot, m);
86 free(old_bot);
87 return bot;
88 }
89
90 void *myrealloc(void *p, unsigned n, const char *file, int line) {
91 fence *ptr;
92 fence *top, *bot = (fence *) p; // , *oldbot;
93
94 if (p == NULL) {
95 ptr = (fence *) myalloc(n);
96 return ptr;
97 }
98 ptr_ng(p, file, line);
99 n += 2*sizeof(fence);
100 if (n&1) {
101 n++;
102 }
103 bot--;
104 if (n > 64000) {
105 bot = (fence *) ersatz_realloc(bot, n);
106 }
107 else {
108 //myfreeBytes += bot->size;
109 bot = (fence *) realloc(bot, n);
110 //myallocBytes += n;
111 }
112 check_mem(bot);
113
114 ptr = (bot + 1);
115 top = (fence *)((char *)bot + n - sizeof(fence));
116 //*top = *bot = make_fence(n);
117 *bot = make_fence(n);
118 memcpy(top, bot, sizeof(fence));
119 return ptr;
120 }
121
122 char *mystrdup(const char *s) {
123 assert(s != NULL);
124 int k = strlen(s) + 1;
125 char *c = ALLOCATE(k, char);
126
127 return strcpy(c,s);
128 }
129
130 static int fence_ng(const void *f) {
131 if (f == NULL) {
132 return 3;
133 }
134 const fence *bot=(const fence *)f-1;
135 if (bot->size != ~bot->comp) {
136 return 1;
137 }
138 const fence *top = (const fence *) ((const char *)f + bot->size);
139
140 //if (bot->size != top->size) {
141 // return 2;
142 //}
143 //if (top->size != ~top->comp) {
144 // return 2;
145 //}
146 if (memcmp(top, bot, sizeof(fence))) {
147 return 2;
148 }
149
150 return 0;
151 }
152
153
154
155 int ptr_ok(void *f) {
156 fence *bot=(fence *)f-1, *top;
157
158 if (f == NULL) {
159 return 0;
160 }
161 if (bot->size != ~bot->comp) {
162 return 0;
163 }
164 top = (fence *)((char *)f + bot->size);
165 if ((bot->size ^ top->size) | (bot->comp ^ top->comp)) {
166 return 0;
167 }
168 return 1;
169 }
170
171
172 void ptr_ng(const void *ptr, const char *file, int line) {
173 int flag = fence_ng(ptr);
174 if (flag) {
175 flag = " BTN"[flag];
176 }
177 if (!flag || no_assertions) {
178 return;
179 }
180 no_assertions = 1;
181 snprintf(longjmp_msg, sizeof(longjmp_msg),
182 "AnaGram internal error: bad pointer %p (%c), %s line %d",
183 ptr, flag, file, line);
184 LOGSECTION("Bad array fence");
185 LOGSTACK;
186 LOGV(longjmp_msg);
187 bailOut(longjmp_msg);
188 }
189
190 void size_ok(const void *ptr, unsigned n, const char *file, int line) {
191 const fence *fp = (const fence *) ptr;
192 check_stack;
193 fp--;
194 if (n <= fp->size || no_assertions) {
195 return;
196 }
197 no_assertions = 1;
198 snprintf(longjmp_msg, sizeof(longjmp_msg),
199 "AnaGram internal error: bad size %u, %s line %d", n, file, line);
200 LOGSECTION("size_ok");
201 LOGSTACK;
202 LOGV(longjmp_msg);
203 bailOut(longjmp_msg);
204 }
205
206 void myfree(void *ptr, const char *file, int line) {
207 if (ptr == NULL) {
208 return;
209 }
210 //myfrees++;
211 ptr_ng(ptr, file, line);
212 fence *base = (fence *)ptr - 1;
213 //myfreeBytes += base->size + 2*sizeof(fence);
214 base->size = 0;
215 free(base);
216 }
217
218 #if 0
219 void *operator new(size_t size) {
220 //newCalls++;
221 void *pointer = myalloc(size);
222 return pointer;
223 }
224
225 void operator delete(void *p) {
226 //deleteCalls++;
227 DEALLOCATE(p);
228 }
229
230 void *operator new[](size_t size) {
231 //newArrayCalls++;
232 void *pointer = myalloc(size);
233 return pointer;
234 }
235
236 void operator delete[](void *p) {
237 //deleteArrayCalls++;
238 DEALLOCATE(p);
239 }
240 #endif