diff options
Diffstat (limited to 'nsprpub/pr/src/malloc/prmalloc.c')
-rw-r--r-- | nsprpub/pr/src/malloc/prmalloc.c | 800 |
1 files changed, 429 insertions, 371 deletions
diff --git a/nsprpub/pr/src/malloc/prmalloc.c b/nsprpub/pr/src/malloc/prmalloc.c index 174d0daf7..c03b7d11e 100644 --- a/nsprpub/pr/src/malloc/prmalloc.c +++ b/nsprpub/pr/src/malloc/prmalloc.c @@ -60,12 +60,12 @@ void *_PR_UnlockedCalloc(size_t n, size_t elsize); # define TRACE(foo) printf foo static int malloc_event; #else -# define TRACE(foo) +# define TRACE(foo) #endif /* XXX Pick a number, any number */ -# define malloc_pagesize 4096UL -# define malloc_pageshift 12UL +# define malloc_pagesize 4096UL +# define malloc_pageshift 12UL #ifdef XP_UNIX #include <stdio.h> @@ -82,61 +82,61 @@ static int malloc_event; */ struct pginfo { - struct pginfo *next; /* next on the free list */ - char *page; /* Pointer to the page */ - u_short size; /* size of this page's chunks */ - u_short shift; /* How far to shift for this size chunks */ - u_short free; /* How many free chunks */ - u_short total; /* How many chunk */ - u_long bits[1]; /* Which chunks are free */ + struct pginfo *next; /* next on the free list */ + char *page; /* Pointer to the page */ + u_short size; /* size of this page's chunks */ + u_short shift; /* How far to shift for this size chunks */ + u_short free; /* How many free chunks */ + u_short total; /* How many chunk */ + u_long bits[1]; /* Which chunks are free */ }; struct pgfree { - struct pgfree *next; /* next run of free pages */ - struct pgfree *prev; /* prev run of free pages */ - char *page; /* pointer to free pages */ - char *end; /* pointer to end of free pages */ - u_long size; /* number of bytes free */ + struct pgfree *next; /* next run of free pages */ + struct pgfree *prev; /* prev run of free pages */ + char *page; /* pointer to free pages */ + char *end; /* pointer to end of free pages */ + u_long size; /* number of bytes free */ }; /* * How many bits per u_long in the bitmap. * Change only if not 8 bits/byte */ -#define MALLOC_BITS (8*sizeof(u_long)) +#define MALLOC_BITS (8*sizeof(u_long)) /* * Magic values to put in the page_directory */ -#define MALLOC_NOT_MINE ((struct pginfo*) 0) -#define MALLOC_FREE ((struct pginfo*) 1) -#define MALLOC_FIRST ((struct pginfo*) 2) -#define MALLOC_FOLLOW ((struct pginfo*) 3) -#define MALLOC_MAGIC ((struct pginfo*) 4) +#define MALLOC_NOT_MINE ((struct pginfo*) 0) +#define MALLOC_FREE ((struct pginfo*) 1) +#define MALLOC_FIRST ((struct pginfo*) 2) +#define MALLOC_FOLLOW ((struct pginfo*) 3) +#define MALLOC_MAGIC ((struct pginfo*) 4) /* * Set to one when malloc_init has been called */ -static unsigned initialized; +static unsigned initialized; /* * The size of a page. * Must be a integral multiplum of the granularity of mmap(2). * Your toes will curl if it isn't a power of two */ -#define malloc_pagemask ((malloc_pagesize)-1) +#define malloc_pagemask ((malloc_pagesize)-1) /* * The size of the largest chunk. * Half a page. */ -#define malloc_maxsize ((malloc_pagesize)>>1) +#define malloc_maxsize ((malloc_pagesize)>>1) /* * malloc_pagesize == 1 << malloc_pageshift */ #ifndef malloc_pageshift -static unsigned malloc_pageshift; +static unsigned malloc_pageshift; #endif /* malloc_pageshift */ /* @@ -144,7 +144,7 @@ static unsigned malloc_pageshift; * Must be power of two */ #ifndef malloc_minsize -static unsigned malloc_minsize; +static unsigned malloc_minsize; #endif /* malloc_minsize */ /* @@ -153,38 +153,38 @@ static unsigned malloc_minsize; * Must be power of two */ #ifndef malloc_maxsize -static unsigned malloc_maxsize; +static unsigned malloc_maxsize; #endif /* malloc_maxsize */ #ifndef malloc_cache -static unsigned malloc_cache; +static unsigned malloc_cache; #endif /* malloc_cache */ /* * The offset from pagenumber to index into the page directory */ -static u_long malloc_origo; +static u_long malloc_origo; /* * The last index in the page directory we care about */ -static u_long last_index; +static u_long last_index; /* * Pointer to page directory. * Allocated "as if with" malloc */ -static struct pginfo **page_dir; +static struct pginfo **page_dir; /* * How many slots in the page directory */ -static unsigned malloc_ninfo; +static unsigned malloc_ninfo; /* - * Free pages line up here + * Free pages line up here */ -static struct pgfree free_list; +static struct pgfree free_list; /* * Abort() if we fail to get VM ? @@ -232,39 +232,39 @@ malloc_dump(FILE *fd) pd = page_dir; /* print out all the pages */ - for(j=0;j<=last_index;j++) { - fprintf(fd,"%08lx %5d ",(j+malloc_origo) << malloc_pageshift,j); - if (pd[j] == MALLOC_NOT_MINE) { - for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++) - ; - j--; - fprintf(fd,".. %5d not mine\n", j); - } else if (pd[j] == MALLOC_FREE) { - for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++) - ; - j--; - fprintf(fd,".. %5d free\n", j); - } else if (pd[j] == MALLOC_FIRST) { - for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++) - ; - j--; - fprintf(fd,".. %5d in use\n", j); - } else if (pd[j] < MALLOC_MAGIC) { - fprintf(fd,"(%p)\n", pd[j]); - } else { - fprintf(fd,"%p %d (of %d) x %d @ %p --> %p\n", - pd[j],pd[j]->free, pd[j]->total, - pd[j]->size, pd[j]->page, pd[j]->next); - } + for(j=0; j<=last_index; j++) { + fprintf(fd,"%08lx %5d ",(j+malloc_origo) << malloc_pageshift,j); + if (pd[j] == MALLOC_NOT_MINE) { + for(j++; j<=last_index && pd[j] == MALLOC_NOT_MINE; j++) + ; + j--; + fprintf(fd,".. %5d not mine\n", j); + } else if (pd[j] == MALLOC_FREE) { + for(j++; j<=last_index && pd[j] == MALLOC_FREE; j++) + ; + j--; + fprintf(fd,".. %5d free\n", j); + } else if (pd[j] == MALLOC_FIRST) { + for(j++; j<=last_index && pd[j] == MALLOC_FOLLOW; j++) + ; + j--; + fprintf(fd,".. %5d in use\n", j); + } else if (pd[j] < MALLOC_MAGIC) { + fprintf(fd,"(%p)\n", pd[j]); + } else { + fprintf(fd,"%p %d (of %d) x %d @ %p --> %p\n", + pd[j],pd[j]->free, pd[j]->total, + pd[j]->size, pd[j]->page, pd[j]->next); + } } for(pf=free_list.next; pf; pf=pf->next) { - fprintf(fd,"Free: @%p [%p...%p[ %ld ->%p <-%p\n", - pf,pf->page,pf->end,pf->size,pf->prev,pf->next); - if (pf == pf->next) { - fprintf(fd,"Free_list loops.\n"); - break; - } + fprintf(fd,"Free: @%p [%p...%p[ %ld ->%p <-%p\n", + pf,pf->page,pf->end,pf->size,pf->prev,pf->next); + if (pf == pf->next) { + fprintf(fd,"Free_list loops.\n"); + break; + } } /* print out various info */ @@ -274,7 +274,7 @@ malloc_dump(FILE *fd) fprintf(fd,"Pageshift\t%ld\n",malloc_pageshift); fprintf(fd,"FirstPage\t%ld\n",malloc_origo); fprintf(fd,"LastPage\t%ld %lx\n",last_index+malloc_pageshift, - (last_index + malloc_pageshift) << malloc_pageshift); + (last_index + malloc_pageshift) << malloc_pageshift); fprintf(fd,"Break\t%ld\n",(u_long)sbrk(0) >> malloc_pageshift); } @@ -323,12 +323,13 @@ map_pages(int pages, int update) result = (caddr_t) ((u_long)result & ~malloc_pagemask); tail = result + (pages << malloc_pageshift); if (!brk(tail)) { - last_index = ((u_long)tail >> malloc_pageshift) - malloc_origo -1; - malloc_brk = tail; - TRACE(("%6d S %p .. %p\n",malloc_event++, result, tail)); - if (!update || last_index < malloc_ninfo || - extend_page_directory(last_index)) - return result; + last_index = ((u_long)tail >> malloc_pageshift) - malloc_origo -1; + malloc_brk = tail; + TRACE(("%6d S %p .. %p\n",malloc_event++, result, tail)); + if (!update || last_index < malloc_ninfo || + extend_page_directory(last_index)) { + return result; + } } TRACE(("%6d s %d %p %d\n",malloc_event++,pages,sbrk(0),errno)); #ifdef EXTRA_SANITY @@ -356,7 +357,7 @@ extend_page_directory(u_long index) int i; TRACE(("%6d E %lu\n",malloc_event++,index)); - + /* Make it this many pages */ i = index * sizeof *page_dir; i /= malloc_pagesize; @@ -364,13 +365,14 @@ extend_page_directory(u_long index) /* Get new pages, if you used this much mem you don't care :-) */ young = (struct pginfo**) map_pages(i,0); - if (!young) - return 0; + if (!young) { + return 0; + } /* Copy the old stuff */ memset(young, 0, i * malloc_pagesize); memcpy(young, page_dir, - malloc_ninfo * sizeof *page_dir); + malloc_ninfo * sizeof *page_dir); /* register the new size */ malloc_ninfo = i * malloc_pagesize / sizeof *page_dir; @@ -383,7 +385,7 @@ extend_page_directory(u_long index) index = ((u_long)young >> malloc_pageshift) - malloc_origo; page_dir[index] = MALLOC_FIRST; while (--i) { - page_dir[++index] = MALLOC_FOLLOW; + page_dir[++index] = MALLOC_FOLLOW; } /* Now free the old stuff */ @@ -400,8 +402,9 @@ set_pgdir(void *ptr, struct pginfo *info) { u_long index = ((u_long)ptr >> malloc_pageshift) - malloc_origo; - if (index >= malloc_ninfo && !extend_page_directory(index)) - return 0; + if (index >= malloc_ninfo && !extend_page_directory(index)) { + return 0; + } page_dir[index] = info; return 1; } @@ -418,17 +421,17 @@ malloc_init (void) TRACE(("%6d I\n",malloc_event++)); #ifdef DEBUG for (p=getenv("MALLOC_OPTIONS"); p && *p; p++) { - switch (*p) { - case 'a': malloc_abort = 0; break; - case 'A': malloc_abort = 1; break; - case 'd': malloc_stats = 0; break; - case 'D': malloc_stats = 1; break; - case 'r': malloc_realloc = 0; break; - case 'R': malloc_realloc = 1; break; - default: - wrtwarning("Unknown chars in MALLOC_OPTIONS\n"); - break; - } + switch (*p) { + case 'a': malloc_abort = 0; break; + case 'A': malloc_abort = 1; break; + case 'd': malloc_stats = 0; break; + case 'D': malloc_stats = 1; break; + case 'r': malloc_realloc = 0; break; + case 'R': malloc_realloc = 1; break; + default: + wrtwarning("Unknown chars in MALLOC_OPTIONS\n"); + break; + } } #endif @@ -439,12 +442,13 @@ malloc_init (void) #ifndef malloc_pageshift /* determine how much we shift by to get there */ - for (i = malloc_pagesize; i > 1; i >>= 1) - malloc_pageshift++; + for (i = malloc_pagesize; i > 1; i >>= 1) { + malloc_pageshift++; + } #endif /* malloc_pageshift */ #ifndef malloc_cache - malloc_cache = 50 << malloc_pageshift; + malloc_cache = 50 << malloc_pageshift; #endif /* malloc_cache */ #ifndef malloc_minsize @@ -455,16 +459,18 @@ malloc_init (void) */ i = 2; for(;;) { - int j; + int j; - /* Figure out the size of the bits */ - j = malloc_pagesize/i; - j /= 8; - if (j < sizeof(u_long)) - j = sizeof (u_long); - if (sizeof(struct pginfo) + j - sizeof (u_long) <= i) - break; - i += i; + /* Figure out the size of the bits */ + j = malloc_pagesize/i; + j /= 8; + if (j < sizeof(u_long)) { + j = sizeof (u_long); + } + if (sizeof(struct pginfo) + j - sizeof (u_long) <= i) { + break; + } + i += i; } malloc_minsize = i; #endif /* malloc_minsize */ @@ -473,8 +479,9 @@ malloc_init (void) /* Allocate one page for the page directory */ page_dir = (struct pginfo **) map_pages(1,0); #ifdef SANITY - if (!page_dir) - wrterror("fatal: my first mmap failed. (check limits ?)\n"); + if (!page_dir) { + wrterror("fatal: my first mmap failed. (check limits ?)\n"); + } #endif /* @@ -493,8 +500,9 @@ malloc_init (void) /* Plug the page directory into itself */ i = set_pgdir(page_dir,MALLOC_FIRST); #ifdef SANITY - if (!i) - wrterror("fatal: couldn't set myself in the page directory\n"); + if (!i) { + wrterror("fatal: couldn't set myself in the page directory\n"); + } #endif /* Been here, done that */ @@ -519,66 +527,75 @@ static void *malloc_pages(size_t size) /* Look for free pages before asking for more */ for(pf = free_list.next; pf; pf = pf->next) { #ifdef EXTRA_SANITY - if (pf->page == pf->end) - wrterror("zero entry on free_list\n"); - if (pf->page > pf->end) { - TRACE(("%6d !s %p %p %p <%d>\n",malloc_event++, - pf,pf->page,pf->end,__LINE__)); - wrterror("sick entry on free_list\n"); - } - if ((void*)pf->page >= (void*)sbrk(0)) - wrterror("entry on free_list past brk\n"); - if (page_dir[((u_long)pf->page >> malloc_pageshift) - malloc_origo] - != MALLOC_FREE) { - TRACE(("%6d !f %p %p %p <%d>\n",malloc_event++, - pf,pf->page,pf->end,__LINE__)); - wrterror("non-free first page on free-list\n"); - } - if (page_dir[((u_long)pf->end >> malloc_pageshift) - 1 - malloc_origo] - != MALLOC_FREE) - wrterror("non-free last page on free-list\n"); + if (pf->page == pf->end) { + wrterror("zero entry on free_list\n"); + } + if (pf->page > pf->end) { + TRACE(("%6d !s %p %p %p <%d>\n",malloc_event++, + pf,pf->page,pf->end,__LINE__)); + wrterror("sick entry on free_list\n"); + } + if ((void*)pf->page >= (void*)sbrk(0)) { + wrterror("entry on free_list past brk\n"); + } + if (page_dir[((u_long)pf->page >> malloc_pageshift) - malloc_origo] + != MALLOC_FREE) { + TRACE(("%6d !f %p %p %p <%d>\n",malloc_event++, + pf,pf->page,pf->end,__LINE__)); + wrterror("non-free first page on free-list\n"); + } + if (page_dir[((u_long)pf->end >> malloc_pageshift) - 1 - malloc_origo] + != MALLOC_FREE) { + wrterror("non-free last page on free-list\n"); + } #endif /* EXTRA_SANITY */ - if (pf->size < size) - continue; - else if (pf->size == size) { - p = pf->page; - if (pf->next) - pf->next->prev = pf->prev; - pf->prev->next = pf->next; - delay_free = pf; - break; - } else { - p = pf->page; - pf->page += size; - pf->size -= size; - break; + if (pf->size < size) { + continue; + } + else if (pf->size == size) { + p = pf->page; + if (pf->next) { + pf->next->prev = pf->prev; + } + pf->prev->next = pf->next; + delay_free = pf; + break; + } else { + p = pf->page; + pf->page += size; + pf->size -= size; + break; } } #ifdef EXTRA_SANITY - if (p && page_dir[((u_long)p >> malloc_pageshift) - malloc_origo] - != MALLOC_FREE) { - wrterror("allocated non-free page on free-list\n"); + if (p && page_dir[((u_long)p >> malloc_pageshift) - malloc_origo] + != MALLOC_FREE) { + wrterror("allocated non-free page on free-list\n"); } #endif /* EXTRA_SANITY */ size >>= malloc_pageshift; /* Map new pages */ - if (!p) - p = map_pages(size,1); + if (!p) { + p = map_pages(size,1); + } if (p) { - /* Mark the pages in the directory */ - index = ((u_long)p >> malloc_pageshift) - malloc_origo; - page_dir[index] = MALLOC_FIRST; - for (i=1;i<size;i++) - page_dir[index+i] = MALLOC_FOLLOW; + /* Mark the pages in the directory */ + index = ((u_long)p >> malloc_pageshift) - malloc_origo; + page_dir[index] = MALLOC_FIRST; + for (i=1; i<size; i++) { + page_dir[index+i] = MALLOC_FOLLOW; + } } if (delay_free) { - if (!px) - px = (struct pgfree*)delay_free; - else - _PR_UnlockedFree(delay_free); + if (!px) { + px = (struct pgfree*)delay_free; + } + else { + _PR_UnlockedFree(delay_free); + } } return p; } @@ -596,26 +613,29 @@ malloc_make_chunks(int bits) /* Allocate a new bucket */ pp = malloc_pages(malloc_pagesize); - if (!pp) - return 0; + if (!pp) { + return 0; + } l = sizeof *bp - sizeof(u_long); l += sizeof(u_long) * - (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS); + (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS); if ((1<<(bits)) <= l+l) { - bp = (struct pginfo *)pp; + bp = (struct pginfo *)pp; } else { - bp = (struct pginfo *)_PR_UnlockedMalloc(l); + bp = (struct pginfo *)_PR_UnlockedMalloc(l); + } + if (!bp) { + return 0; } - if (!bp) - return 0; bp->size = (1<<bits); bp->shift = bits; bp->total = bp->free = malloc_pagesize >> bits; bp->next = page_dir[bits]; bp->page = (char*)pp; i = set_pgdir(pp,bp); - if (!i) - return 0; + if (!i) { + return 0; + } /* We can safely assume that there is nobody in this chain */ page_dir[bits] = bp; @@ -623,22 +643,24 @@ malloc_make_chunks(int bits) /* set all valid bits in the bits */ k = bp->total; i = 0; -/* - for(;k-i >= MALLOC_BITS; i += MALLOC_BITS) - bp->bits[i / MALLOC_BITS] = ~0; -*/ - for(; i < k; i++) - set_bit(bp,i); + /* + for(;k-i >= MALLOC_BITS; i += MALLOC_BITS) + bp->bits[i / MALLOC_BITS] = ~0; + */ + for(; i < k; i++) { + set_bit(bp,i); + } - if (bp != pp) - return 1; + if (bp != pp) { + return 1; + } /* We may have used the first ones already */ - for(i=0;l > 0;i++) { - clr_bit(bp,i); - bp->free--; - bp->total--; - l -= (1 << bits); + for(i=0; l > 0; i++) { + clr_bit(bp,i); + bp->free--; + bp->total--; + l -= (1 << bits); } return 1; } @@ -656,7 +678,7 @@ static void *malloc_bytes(size_t size) /* Don't bother with anything less than this */ if (size < malloc_minsize) { - size = malloc_minsize; + size = malloc_minsize; } /* Find the right bucket */ @@ -667,27 +689,28 @@ static void *malloc_bytes(size_t size) } /* If it's empty, make a page more of that size chunks */ - if (!page_dir[j] && !malloc_make_chunks(j)) - return 0; + if (!page_dir[j] && !malloc_make_chunks(j)) { + return 0; + } /* Find first word of bitmap which isn't empty */ bp = page_dir[j]; for (lp = bp->bits; !*lp; lp++) - ; + ; /* Find that bit */ bf = *lp; k = 0; while ((bf & 1) == 0) { - bf >>= 1; - k++; + bf >>= 1; + k++; } *lp ^= 1L<<k; /* clear it */ bp->free--; if (!bp->free) { - page_dir[j] = bp->next; - bp->next = 0; + page_dir[j] = bp->next; + bp->next = 0; } k += (lp - bp->bits)*MALLOC_BITS; return bp->page + (k << bp->shift); @@ -699,24 +722,29 @@ void *_PR_UnlockedMalloc(size_t size) /* Round up to a multiple of 8 bytes */ if (size & 7) { - size = size + 8 - (size & 7); + size = size + 8 - (size & 7); } - if (!initialized) - malloc_init(); + if (!initialized) { + malloc_init(); + } #ifdef SANITY - if (suicide) - PR_Abort(); + if (suicide) { + PR_Abort(); + } #endif - if (size <= malloc_maxsize) - result = malloc_bytes(size); - else - result = malloc_pages(size); + if (size <= malloc_maxsize) { + result = malloc_bytes(size); + } + else { + result = malloc_pages(size); + } #ifdef SANITY - if (malloc_abort && !result) - wrterror("malloc() returns NULL\n"); + if (malloc_abort && !result) { + wrterror("malloc() returns NULL\n"); + } #endif TRACE(("%6d M %p %d\n",malloc_event++,result,size)); @@ -731,38 +759,47 @@ void *_PR_UnlockedMemalign(size_t alignment, size_t size) * alignment has to be a power of 2 */ - if ((size <= alignment) && (alignment <= malloc_maxsize)) - size = alignment; - else - size += alignment - 1; + if ((size <= alignment) && (alignment <= malloc_maxsize)) { + size = alignment; + } + else { + size += alignment - 1; + } /* Round up to a multiple of 8 bytes */ if (size & 7) { - size = size + 8 - (size & 7); + size = size + 8 - (size & 7); } - if (!initialized) - malloc_init(); + if (!initialized) { + malloc_init(); + } #ifdef SANITY - if (suicide) - abort(); + if (suicide) { + abort(); + } #endif - if (size <= malloc_maxsize) - result = malloc_bytes(size); - else - result = malloc_pages(size); + if (size <= malloc_maxsize) { + result = malloc_bytes(size); + } + else { + result = malloc_pages(size); + } #ifdef SANITY - if (malloc_abort && !result) - wrterror("malloc() returns NULL\n"); + if (malloc_abort && !result) { + wrterror("malloc() returns NULL\n"); + } #endif TRACE(("%6d A %p %d\n",malloc_event++,result,size)); - if ((u_long)result & (alignment - 1)) - return ((void *)(((u_long)result + alignment) & ~(alignment - 1))); - else - return result; + if ((u_long)result & (alignment - 1)) { + return ((void *)(((u_long)result + alignment) & ~(alignment - 1))); + } + else { + return result; + } } void *_PR_UnlockedCalloc(size_t n, size_t nelem) @@ -772,14 +809,14 @@ void *_PR_UnlockedCalloc(size_t n, size_t nelem) /* Compute total size and then round up to a double word amount */ n *= nelem; if (n & 7) { - n = n + 8 - (n & 7); + n = n + 8 - (n & 7); } /* Get the memory */ p = _PR_UnlockedMalloc(n); if (p) { - /* Zero it */ - memset(p, 0, n); + /* Zero it */ + memset(p, 0, n); } return p; } @@ -793,25 +830,27 @@ void *_PR_UnlockedRealloc(void *ptr, size_t size) u_long osize,page,index,tmp_index; struct pginfo **mp; - if (!initialized) - malloc_init(); + if (!initialized) { + malloc_init(); + } #ifdef SANITY - if (suicide) - PR_Abort(); + if (suicide) { + PR_Abort(); + } #endif /* used as free() */ TRACE(("%6d R %p %d\n",malloc_event++, ptr, size)); if (ptr && !size) { - _PR_UnlockedFree(ptr); - return _PR_UnlockedMalloc (1); + _PR_UnlockedFree(ptr); + return _PR_UnlockedMalloc (1); } /* used as malloc() */ if (!ptr) { - p = _PR_UnlockedMalloc(size); - return p; + p = _PR_UnlockedMalloc(size); + return p; } /* Find the page directory entry for the page in question */ @@ -822,50 +861,51 @@ void *_PR_UnlockedRealloc(void *ptr, size_t size) * check if memory was allocated by memalign */ tmp_index = index; - while (page_dir[tmp_index] == MALLOC_FOLLOW) - tmp_index--; + while (page_dir[tmp_index] == MALLOC_FOLLOW) { + tmp_index--; + } if (tmp_index != index) { - /* - * memalign-allocated memory - */ - index = tmp_index; - page = index + malloc_origo; - ptr = (void *) (page << malloc_pageshift); + /* + * memalign-allocated memory + */ + index = tmp_index; + page = index + malloc_origo; + ptr = (void *) (page << malloc_pageshift); } TRACE(("%6d R2 %p %d\n",malloc_event++, ptr, size)); /* make sure it makes sense in some fashion */ if (index < malloc_pageshift || index > last_index) { #ifdef SANITY - wrtwarning("junk pointer passed to realloc()\n"); + wrtwarning("junk pointer passed to realloc()\n"); #endif - return 0; + return 0; } /* find the size of that allocation, and see if we need to relocate */ mp = &page_dir[index]; if (*mp == MALLOC_FIRST) { - osize = malloc_pagesize; - while (mp[1] == MALLOC_FOLLOW) { - osize += malloc_pagesize; - mp++; - } - if (!malloc_realloc && - size < osize && - size > malloc_maxsize && - size > (osize - malloc_pagesize)) { - return ptr; - } + osize = malloc_pagesize; + while (mp[1] == MALLOC_FOLLOW) { + osize += malloc_pagesize; + mp++; + } + if (!malloc_realloc && + size < osize && + size > malloc_maxsize && + size > (osize - malloc_pagesize)) { + return ptr; + } } else if (*mp >= MALLOC_MAGIC) { - osize = (*mp)->size; - if (!malloc_realloc && - size < osize && - (size > (*mp)->size/2 || (*mp)->size == malloc_minsize)) { - return ptr; - } + osize = (*mp)->size; + if (!malloc_realloc && + size < osize && + (size > (*mp)->size/2 || (*mp)->size == malloc_minsize)) { + return ptr; + } } else { #ifdef SANITY - wrterror("realloc() of wrong page.\n"); + wrterror("realloc() of wrong page.\n"); #endif } @@ -873,16 +913,19 @@ void *_PR_UnlockedRealloc(void *ptr, size_t size) p = _PR_UnlockedMalloc(size); if (p) { - /* copy the lesser of the two sizes */ - if (osize < size) - memcpy(p,ptr,osize); - else - memcpy(p,ptr,size); - _PR_UnlockedFree(ptr); + /* copy the lesser of the two sizes */ + if (osize < size) { + memcpy(p,ptr,osize); + } + else { + memcpy(p,ptr,size); + } + _PR_UnlockedFree(ptr); } #ifdef DEBUG - else if (malloc_abort) - wrterror("realloc() returns NULL\n"); + else if (malloc_abort) { + wrterror("realloc() returns NULL\n"); + } #endif return p; @@ -904,100 +947,106 @@ free_pages(char *ptr, u_long page, int index, struct pginfo *info) /* Is it free already ? */ if (info == MALLOC_FREE) { #ifdef SANITY - wrtwarning("freeing free page at %p.\n", ptr); + wrtwarning("freeing free page at %p.\n", ptr); #endif - return; + return; } #ifdef SANITY /* Is it not the right place to begin ? */ - if (info != MALLOC_FIRST) - wrterror("freeing wrong page.\n"); + if (info != MALLOC_FIRST) { + wrterror("freeing wrong page.\n"); + } /* Is this really a pointer to a page ? */ - if ((u_long)ptr & malloc_pagemask) - wrterror("freeing messed up page pointer.\n"); + if ((u_long)ptr & malloc_pagemask) { + wrterror("freeing messed up page pointer.\n"); + } #endif /* Count how many pages it is anyway */ page_dir[index] = MALLOC_FREE; - for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++) - page_dir[index + i] = MALLOC_FREE; + for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++) { + page_dir[index + i] = MALLOC_FREE; + } l = i << malloc_pageshift; tail = ptr+l; /* add to free-list */ - if (!px) - px = (struct pgfree*)_PR_UnlockedMalloc(sizeof *pt); + if (!px) { + px = (struct pgfree*)_PR_UnlockedMalloc(sizeof *pt); + } /* XXX check success */ px->page = ptr; px->end = tail; px->size = l; if (!free_list.next) { - px->next = free_list.next; - px->prev = &free_list; - free_list.next = px; - pf = px; - px = 0; + px->next = free_list.next; + px->prev = &free_list; + free_list.next = px; + pf = px; + px = 0; } else { - tail = ptr+l; - for(pf = free_list.next; pf->next && pf->end < ptr; pf = pf->next) - ; - for(; pf; pf = pf->next) { - if (pf->end == ptr ) { - /* append to entry */ - pf->end += l; - pf->size += l; - if (pf->next && pf->end == pf->next->page ) { - pt = pf->next; - pf->end = pt->end; - pf->size += pt->size; - pf->next = pt->next; - if (pf->next) - pf->next->prev = pf; - _PR_UnlockedFree(pt); - } - } else if (pf->page == tail) { - /* prepend to entry */ - pf->size += l; - pf->page = ptr; - } else if (pf->page > ptr) { - px->next = pf; - px->prev = pf->prev; - pf->prev = px; - px->prev->next = px; - pf = px; - px = 0; - } else if (!pf->next) { - px->next = 0; - px->prev = pf; - pf->next = px; - pf = px; - px = 0; - } else { - continue; - } - break; - } + tail = ptr+l; + for(pf = free_list.next; pf->next && pf->end < ptr; pf = pf->next) + ; + for(; pf; pf = pf->next) { + if (pf->end == ptr ) { + /* append to entry */ + pf->end += l; + pf->size += l; + if (pf->next && pf->end == pf->next->page ) { + pt = pf->next; + pf->end = pt->end; + pf->size += pt->size; + pf->next = pt->next; + if (pf->next) { + pf->next->prev = pf; + } + _PR_UnlockedFree(pt); + } + } else if (pf->page == tail) { + /* prepend to entry */ + pf->size += l; + pf->page = ptr; + } else if (pf->page > ptr) { + px->next = pf; + px->prev = pf->prev; + pf->prev = px; + px->prev->next = px; + pf = px; + px = 0; + } else if (!pf->next) { + px->next = 0; + px->prev = pf; + pf->next = px; + pf = px; + px = 0; + } else { + continue; + } + break; + } } if (!pf->next && - pf->size > malloc_cache && - pf->end == malloc_brk && - malloc_brk == (void*)sbrk(0)) { - pf->end = pf->page + malloc_cache; - pf->size = malloc_cache; - TRACE(("%6d U %p %d\n",malloc_event++,pf->end,pf->end - pf->page)); - brk(pf->end); - malloc_brk = pf->end; - /* Find the page directory entry for the page in question */ - page = (u_long)pf->end >> malloc_pageshift; - index = page - malloc_origo; - /* Now update the directory */ - for(i=index;i <= last_index;) - page_dir[i++] = MALLOC_NOT_MINE; - last_index = index - 1; + pf->size > malloc_cache && + pf->end == malloc_brk && + malloc_brk == (void*)sbrk(0)) { + pf->end = pf->page + malloc_cache; + pf->size = malloc_cache; + TRACE(("%6d U %p %d\n",malloc_event++,pf->end,pf->end - pf->page)); + brk(pf->end); + malloc_brk = pf->end; + /* Find the page directory entry for the page in question */ + page = (u_long)pf->end >> malloc_pageshift; + index = page - malloc_origo; + /* Now update the directory */ + for(i=index; i <= last_index;) { + page_dir[i++] = MALLOC_NOT_MINE; + } + last_index = index - 1; } } @@ -1014,8 +1063,9 @@ free_bytes(void *ptr, u_long page, int index, struct pginfo *info) /* Make sure that pointer is multiplum of chunk-size */ #ifdef SANITY - if ((u_long)ptr & (info->size - 1)) - wrterror("freeing messed up chunk pointer\n"); + if ((u_long)ptr & (info->size - 1)) { + wrterror("freeing messed up chunk pointer\n"); + } #endif /* Find the chunk number on the page */ @@ -1024,9 +1074,9 @@ free_bytes(void *ptr, u_long page, int index, struct pginfo *info) /* See if it's free already */ if (tst_bit(info,i)) { #ifdef SANITY - wrtwarning("freeing free chunk at %p\n", ptr); + wrtwarning("freeing free chunk at %p\n", ptr); #endif - return; + return; } /* Mark it free */ @@ -1035,31 +1085,34 @@ free_bytes(void *ptr, u_long page, int index, struct pginfo *info) /* If the page was full before, we need to put it on the queue now */ if (info->free == 1) { - mp = page_dir + info->shift; - while (*mp && (*mp)->next && (*mp)->next->page < info->page) - mp = &(*mp)->next; - info->next = *mp; - *mp = info; - return; + mp = page_dir + info->shift; + while (*mp && (*mp)->next && (*mp)->next->page < info->page) { + mp = &(*mp)->next; + } + info->next = *mp; + *mp = info; + return; } /* If this page isn't empty, don't do anything. */ - if (info->free != info->total) - return; + if (info->free != info->total) { + return; + } /* We may want to keep at least one page of each size chunks around. */ mp = page_dir + info->shift; - if (0 && (*mp == info) && !info->next) - return; + if (0 && (*mp == info) && !info->next) { + return; + } /* Find & remove this page in the queue */ while (*mp != info) { - mp = &((*mp)->next); + mp = &((*mp)->next); #ifdef EXTRA_SANITY - if (!*mp) { - TRACE(("%6d !q %p\n",malloc_event++,info)); - wrterror("Not on queue\n"); - } + if (!*mp) { + TRACE(("%6d !q %p\n",malloc_event++,info)); + wrterror("Not on queue\n"); + } #endif } *mp = info->next; @@ -1067,11 +1120,11 @@ free_bytes(void *ptr, u_long page, int index, struct pginfo *info) /* Free the page & the info structure if need be */ set_pgdir(info->page,MALLOC_FIRST); if((void*)info->page == (void*)info) { - _PR_UnlockedFree(info->page); + _PR_UnlockedFree(info->page); } else { - vp = info->page; - _PR_UnlockedFree(info); - _PR_UnlockedFree(vp); + vp = info->page; + _PR_UnlockedFree(info); + _PR_UnlockedFree(vp); } } @@ -1083,20 +1136,22 @@ void _PR_UnlockedFree(void *ptr) TRACE(("%6d F %p\n",malloc_event++,ptr)); /* This is legal */ - if (!ptr) - return; + if (!ptr) { + return; + } #ifdef SANITY /* There wouldn't be anything to free */ if (!initialized) { - wrtwarning("free() called before malloc() ever got called\n"); - return; + wrtwarning("free() called before malloc() ever got called\n"); + return; } #endif #ifdef SANITY - if (suicide) - PR_Abort(); + if (suicide) { + PR_Abort(); + } #endif /* Find the page directory entry for the page in question */ @@ -1107,36 +1162,39 @@ void _PR_UnlockedFree(void *ptr) * check if memory was allocated by memalign */ tmp_index = index; - while (page_dir[tmp_index] == MALLOC_FOLLOW) - tmp_index--; + while (page_dir[tmp_index] == MALLOC_FOLLOW) { + tmp_index--; + } if (tmp_index != index) { - /* - * memalign-allocated memory - */ - index = tmp_index; - page = index + malloc_origo; - ptr = (void *) (page << malloc_pageshift); + /* + * memalign-allocated memory + */ + index = tmp_index; + page = index + malloc_origo; + ptr = (void *) (page << malloc_pageshift); } /* make sure it makes sense in some fashion */ if (index < malloc_pageshift) { #ifdef SANITY - wrtwarning("junk pointer %p (low) passed to free()\n", ptr); + wrtwarning("junk pointer %p (low) passed to free()\n", ptr); #endif - return; + return; } if (index > last_index) { #ifdef SANITY - wrtwarning("junk pointer %p (high) passed to free()\n", ptr); + wrtwarning("junk pointer %p (high) passed to free()\n", ptr); #endif - return; + return; } /* handle as page-allocation or chunk allocation */ info = page_dir[index]; - if (info < MALLOC_MAGIC) + if (info < MALLOC_MAGIC) { free_pages((char*)ptr, page, index, info); - else - free_bytes(ptr,page,index,info); + } + else { + free_bytes(ptr,page,index,info); + } return; } #endif /* _PR_OVERRIDE_MALLOC */ |