1 void *gc_malloc (size_t size) 2 { 3 list_t *list, *newlist; 4 char *addr, *test; 5 long foo, mask; 6 Tree *alloc_tree; 7 int registers[3]; 8 int top; 9 10 /* start by getting the callee-save registers and the top of the program 11 * stack at this point. Doing this here means that we don't have to search 12 * the stack frame for gc_malloc or anything that it calls when we collect 13 * root pointers. 14 */ 15 GET_CALLEE_REGS(registers); 16 PGM_STACK_TOP(top); 17 18 /* round up size to a multiple of 8 */ 19 size = (size ? ((size>>3) + !!(size & 7)) << 3 : 8); 20 21 /* search un-coalesced free list */ 22 addr = dseg_lo; 23 list = *(list_t **)addr; 24 if (list != NULL) { 25 do { 26 if (list->size >= size) { 27 break; 28 } 29 list = list->next; 30 if (list == *(list_t **)addr) { 31 list = NULL; 32 } 33 } while (list); 34 } 35 36 /* if we couldn't find a fit then try sbrk */ 37 if(list==NULL) { 38 mask = mem_pagesize()-1; 39 size += sizeof(Tree); 40 /* number of pages needed, ceil( size/pagesize ) */ 41 foo = (size & ~mask) + ((!!(size & mask))*mem_pagesize()); 42 size -= sizeof(Tree); 43 list = (list_t *)(dseg_hi+1); 44 test = mem_sbrk(foo); 45 if (!test) 46 return NULL; 47 list->size = foo - sizeof(Tree); 48 gc_add_free(dseg_lo, list); 49 } 50 51 52 /* found a fit */ 53 if (list->size < size + sizeof(list_t) + sizeof(long) ) { 54 /* give them the whole chunk (we need sizeof(list_t) to hold accounting 55 * information, want at least one usable word if we're going to 56 * keep track of this block!) */ 57 gc_remove_free(addr, list); 58 /* put this block in the allocated tree */ 59 addr = dseg_lo + sizeof(long); 60 alloc_tree = *(Tree **)addr; 61 *(Tree **)addr = insert(alloc_tree, (Tree *)list); 62 return (((void *)list) + sizeof(Tree)); 63 } 64 65 /* give them the beginning of the block */ 66 newlist = (list_t *)(((void *)list) + size + sizeof(Tree)); 67 newlist->size = list->size - size - sizeof(Tree); 68 list->size = size; 69 70 if (list->next == list) { 71 newlist->next = newlist->prev = newlist; 72 } else { 73 newlist->prev = list->prev; 74 newlist->next = list->next; 75 newlist->prev->next = newlist->next->prev = newlist; 76 } 77 if (*(list_t **)addr == list) { 78 *(list_t **)addr = newlist; 79 } 80 81 /* put this block in the allocated tree */ 82 addr = dseg_lo + sizeof(long); 83 alloc_tree = *(Tree **)addr; 84 *(Tree **)addr = insert(alloc_tree, (Tree *)list); 85 86 return ((void *)list + sizeof(Tree)); 87 } 88