Mercurial > ~dholland > hg > ag > index.cgi
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 |