8 /* FIXME: make allocation dynamic */
11 #ifdef IMAGER_DEBUG_MALLOC
22 static int malloc_need_init = 1;
30 malloc_entry malloc_pointers[MAXMAL];
35 /* Utility functions */
42 for(i=0; i<MAXMAL; i++) malloc_pointers[i].ptr = NULL;
53 if (malloc_pointers[i].ptr == p)
59 /* Takes a pointer to real start of array,
60 * sets the entries in the table, returns
61 * the offset corrected pointer */
65 set_entry(int i, char *buf, size_t size, char *file, int line) {
66 memset( buf, PADBYTE, UNDRRNVAL );
67 memset( &buf[UNDRRNVAL+size], PADBYTE, OVERRNVAL );
69 malloc_pointers[i].ptr = buf;
70 malloc_pointers[i].size = size;
71 sprintf(malloc_pointers[i].comm,"%s (%d)", file, line);
80 mm_log((0,"malloc_state()\n"));
82 for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].ptr != NULL) {
83 mm_log((0,"%d: %d (0x%x) : %s\n", i, malloc_pointers[i].size, malloc_pointers[i].ptr, malloc_pointers[i].comm));
84 total += malloc_pointers[i].size;
86 if (total == 0) mm_log((0,"No memory currently used!\n"))
87 else mm_log((0,"total: %d\n",total));
93 mymalloc_file_line(size_t size, char* file, int line) {
96 if (malloc_need_init) malloc_init();
98 /* bndcheck_all(); Uncomment for LOTS OF THRASHING */
100 if ( (i = find_ptr(NULL)) < 0 ) {
101 mm_log((0,"more than %d segments allocated at %s (%d)\n", MAXMAL, file, line));
105 if ( (buf = malloc(size+UNDRRNVAL+OVERRNVAL)) == NULL ) {
106 mm_log((1,"Unable to allocate %i for %s (%i)\n", size, file, line));
110 buf = set_entry(i, buf, size, file, line);
111 mm_log((1,"mymalloc_file_line: slot <%d> %d bytes allocated at %p for %s (%d)\n", i, size, buf, file, line));
116 (mymalloc)(int size) {
117 return mymalloc_file_line(size, "unknown", 0);
121 myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) {
125 if (malloc_need_init) malloc_init();
126 /* bndcheck_all(); ACTIVATE FOR LOTS OF THRASHING */
129 mm_log((1, "realloc called with ptr = NULL, sending request to malloc\n"));
130 return mymalloc_file_line(newsize, file, line);
134 mm_log((1, "newsize = 0, sending request to free\n"));
135 myfree_file_line(ptr, file, line);
139 if ( (i = find_ptr(ptr)) == -1) {
140 mm_log((0, "Unable to find %p in realloc for %s (%i)\n", ptr, file, line));
144 if ( (buf = realloc(((char *)ptr)-UNDRRNVAL, UNDRRNVAL+OVERRNVAL+newsize)) == NULL ) {
145 mm_log((1,"Unable to reallocate %i bytes at %p for %s (%i)\n", newsize, ptr, file, line));
149 buf = set_entry(i, buf, newsize, file, line);
150 mm_log((1,"realloc_file_line: slot <%d> %d bytes allocated at %p for %s (%d)\n", i, newsize, buf, file, line));
155 (myrealloc)(void *ptr, size_t newsize) {
156 return myrealloc_file_line(ptr, newsize, "unknown", 0);
163 size_t s = malloc_pointers[idx].size;
164 unsigned char *pp = malloc_pointers[idx].ptr;
166 mm_log((1, "bndcheck: No pointer in slot %d\n", idx));
170 for(i=0;i<UNDRRNVAL;i++)
171 if (pp[-(1+i)] != PADBYTE)
172 mm_log((1,"bndcheck: UNDERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s ));
174 for(i=0;i<OVERRNVAL;i++)
175 if (pp[s+i] != PADBYTE)
176 mm_log((1,"bndcheck: OVERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s ));
182 mm_log((1, "bndcheck_all()\n"));
183 for(idx=0; idx<MAXMAL; idx++)
184 if (malloc_pointers[idx].ptr)
189 myfree_file_line(void *p, char *file, int line) {
194 for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].ptr == p) {
195 mm_log((1,"myfree_file_line: pointer %i (%s) freed at %s (%i)\n", i, malloc_pointers[i].comm, file, line));
197 malloc_pointers[i].ptr = NULL;
201 mm_log((1, "myfree_file_line: freeing address %p (real %p)\n", pp, pp-UNDRRNVAL));
204 mm_log((1, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line));
205 fprintf(stderr, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line);
214 (myfree)(void *block) {
215 myfree_file_line(block, "unknown", 0);
220 #define malloc_comm(a,b) (mymalloc(a))
231 fprintf(stderr, "Attempt to allocate size %d\n", size);
235 if ( (buf = malloc(size)) == NULL ) {
236 mm_log((1, "mymalloc: unable to malloc %d\n", size));
237 fprintf(stderr,"Unable to malloc %d.\n", size); exit(3);
239 mm_log((1, "mymalloc(size %d) -> %p\n", size, buf));
244 mymalloc_file_line(size_t size, char *file, int line) {
245 return mymalloc(size);
250 mm_log((1, "myfree(p %p)\n", p));
255 myfree_file_line(void *p, char *file, int line) {
260 myrealloc(void *block, size_t size) {
263 mm_log((1, "myrealloc(block %p, size %u)\n", block, size));
264 if ((result = realloc(block, size)) == NULL) {
265 mm_log((1, "myrealloc: out of memory\n"));
266 fprintf(stderr, "Out of memory.\n");
273 myrealloc_file_line(void *block, size_t newsize, char *file, int size) {
274 return myrealloc(block, newsize);
277 #endif /* IMAGER_MALLOC_DEBUG */
282 /* memory pool implementation */
285 i_mempool_init(i_mempool *mp) {
288 mp->p = mymalloc(sizeof(void*)*mp->alloc);
292 i_mempool_extend(i_mempool *mp) {
293 mp->p = myrealloc(mp->p, mp->alloc * 2);
298 i_mempool_alloc(i_mempool *mp, size_t size) {
299 if (mp->used == mp->alloc) i_mempool_extend(mp);
300 mp->p[mp->used] = mymalloc(size);
302 return mp->p[mp->used-1];
307 i_mempool_destroy(i_mempool *mp) {
309 for(i=0; i<mp->used; i++) myfree(mp->p[i]);
315 /* Should these really be here? */
322 if (a<b) return a; else return b;
327 if (a>b) return a; else return b;
336 struct utf8_size utf8_sizes[] =
345 =item utf8_advance(char **p, int *len)
347 Retreive a UTF8 character from the stream.
349 Modifies *p and *len to indicate the consumed characters.
351 This doesn't support the extended UTF8 encoding used by later versions
354 This doesn't check that the UTF8 charecter is using the shortest
355 possible representation.
361 i_utf8_advance(char const **p, int *len) {
364 unsigned char codes[3];
369 for (i = 0; i < sizeof(utf8_sizes)/sizeof(*utf8_sizes); ++i) {
370 if ((c & utf8_sizes[i].mask) == utf8_sizes[i].expect) {
371 clen = utf8_sizes[i].size;
375 if (clen == 0 || *len < clen-1) {
380 /* check that each character is well formed */
384 if (((*p)[ci] & 0xC0) != 0x80) {
388 codes[ci] = (*p)[ci];
391 *p += clen-1; *len -= clen-1;
393 if ((c & 0xE0) == 0xC0) {
394 return ((c & 0x1F) << 6) + (codes[0] & 0x3F);
396 else if ((c & 0xF0) == 0xE0) {
397 return ((c & 0x0F) << 12) | ((codes[0] & 0x3F) << 6) | (codes[1] & 0x3f);
399 else if ((c & 0xF8) == 0xF0) {
400 return ((c & 0x07) << 18) | ((codes[0] & 0x3F) << 12)
401 | ((codes[1] & 0x3F) << 6) | (codes[2] & 0x3F);
404 *p -= clen; *len += clen;