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) {
197 for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].ptr == p) {
198 mm_log((1,"myfree_file_line: pointer %i (%s) freed at %s (%i)\n", i, malloc_pointers[i].comm, file, line));
200 malloc_pointers[i].ptr = NULL;
204 mm_log((1, "myfree_file_line: freeing address %p (real %p)\n", pp, pp-UNDRRNVAL));
207 mm_log((1, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line));
208 fprintf(stderr, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line);
217 (myfree)(void *block) {
218 myfree_file_line(block, "unknown", 0);
223 #define malloc_comm(a,b) (mymalloc(a))
234 fprintf(stderr, "Attempt to allocate size %d\n", size);
238 if ( (buf = malloc(size)) == NULL ) {
239 mm_log((1, "mymalloc: unable to malloc %d\n", size));
240 fprintf(stderr,"Unable to malloc %d.\n", size); exit(3);
242 mm_log((1, "mymalloc(size %d) -> %p\n", size, buf));
247 mymalloc_file_line(size_t size, char *file, int line) {
248 return mymalloc(size);
253 mm_log((1, "myfree(p %p)\n", p));
258 myfree_file_line(void *p, char *file, int line) {
263 myrealloc(void *block, size_t size) {
266 mm_log((1, "myrealloc(block %p, size %u)\n", block, size));
267 if ((result = realloc(block, size)) == NULL) {
268 mm_log((1, "myrealloc: out of memory\n"));
269 fprintf(stderr, "Out of memory.\n");
276 myrealloc_file_line(void *block, size_t newsize, char *file, int size) {
277 return myrealloc(block, newsize);
280 #endif /* IMAGER_MALLOC_DEBUG */
285 /* memory pool implementation */
288 i_mempool_init(i_mempool *mp) {
291 mp->p = mymalloc(sizeof(void*)*mp->alloc);
295 i_mempool_extend(i_mempool *mp) {
296 mp->p = myrealloc(mp->p, mp->alloc * 2);
301 i_mempool_alloc(i_mempool *mp, size_t size) {
302 if (mp->used == mp->alloc) i_mempool_extend(mp);
303 mp->p[mp->used] = mymalloc(size);
305 return mp->p[mp->used-1];
310 i_mempool_destroy(i_mempool *mp) {
312 for(i=0; i<mp->used; i++) myfree(mp->p[i]);
318 /* Should these really be here? */
325 if (a<b) return a; else return b;
330 if (a>b) return a; else return b;
339 struct utf8_size utf8_sizes[] =
348 =item utf8_advance(char **p, int *len)
350 Retreive a UTF8 character from the stream.
352 Modifies *p and *len to indicate the consumed characters.
354 This doesn't support the extended UTF8 encoding used by later versions
357 This doesn't check that the UTF8 charecter is using the shortest
358 possible representation.
364 i_utf8_advance(char const **p, int *len) {
367 unsigned char codes[3];
372 for (i = 0; i < sizeof(utf8_sizes)/sizeof(*utf8_sizes); ++i) {
373 if ((c & utf8_sizes[i].mask) == utf8_sizes[i].expect) {
374 clen = utf8_sizes[i].size;
378 if (clen == 0 || *len < clen-1) {
383 /* check that each character is well formed */
387 if (((*p)[ci] & 0xC0) != 0x80) {
391 codes[ci] = (*p)[ci];
394 *p += clen-1; *len -= clen-1;
396 if ((c & 0xE0) == 0xC0) {
397 return ((c & 0x1F) << 6) + (codes[0] & 0x3F);
399 else if ((c & 0xF0) == 0xE0) {
400 return ((c & 0x0F) << 12) | ((codes[0] & 0x3F) << 6) | (codes[1] & 0x3f);
402 else if ((c & 0xF8) == 0xF0) {
403 return ((c & 0x07) << 18) | ((codes[0] & 0x3F) << 12)
404 | ((codes[1] & 0x3F) << 6) | (codes[2] & 0x3F);
407 *p -= clen; *len += clen;