rem: int32 i;
add: uint32 i;
context: free(void *address){	struct heap_page *page;	struct heap_bin *bin;	unsigned int i;	if (!kernel_startup && !are_interrupts_enabled())		panic("free: called with interrupts disabled\n");	if (address == NULL)		return;	if ((addr)address < heap_base || (addr)address >= (heap_base + heap_size))		panic("free: asked to free invalid address %p\n", address);#if USE_WALL	{		uint32 *wall = (uint32 *)((uint8 *)address - 12);		uint32 size = wall[0];		if (wall[1] != 0xabadcafe || wall[2] != 0xabadcafe)			panic("free: front wall was overwritten (allocation at %p, %lu bytes): %08lx %08lx\n", address, size, wall[1], wall[2]);		wall = (uint32 *)((uint8 *)address + size);		if (wall[0] != 0xabadcafe || wall[1] != 0xabadcafe)			panic("free: back wall was overwritten (allocation at %p, %lu bytes): %08lx %08lx\n", address, size, wall[0], wall[1]);		address = (uint8 *)address - 12;	}#endif#if PARANOID_POINTER_CHECK	if (!ptrchecklist_remove(address))		panic("free(): asked to free invalid pointer %p\n", address);#endif	mutex_lock(&heap_lock);	TRACE(("free(): asked to free at ptr = %p\n", address));	page = &heap_alloc_table[((unsigned)address - heap_base) / PAGE_SIZE];	TRACE(("free(): page %p: bin_index %d, free_count %d\n", page, page->bin_index, page->free_count));	if (page[0].bin_index >= bin_count)		panic("free(): page %p: invalid bin_index %d\n", page, page->bin_index);	bin = &bins[page[0].bin_index];	if (bin->element_size <= PAGE_SIZE && (addr)address % bin->element_size != 0)		panic("kfree: passed invalid pointer %p! Supposed to be in bin for esize 0x%x\n", address, bin->element_size);#if PARANOID_KFREE	// mark the free space as freed	{		uint32 deadbeef = 0xdeadbeef;		uint8 *dead = (uint8 *)address;		int32 i;		// the first 4 bytes are overwritten with the next free list pointer later		for (i = 4; i < bin->element_size; i++)			dead[i] = ((uint8 *)&deadbeef)[i % 4];	}#endif	for (i = 0; i < bin->element_size / PAGE_SIZE; i++) {		if (page[i].bin_index != page[0].bin_index)			panic("free(): not all pages in allocation match bin_index\n");		page[i].free_count++;	}#if PARANOID_KFREE	// walk the free list on this bin to make sure this address doesn't exist already	{		unsigned int *temp;		for (temp = bin->free_list; temp != NULL; temp = (unsigned int *)*temp) {			if (temp == (unsigned int *)address)				panic("free(): address %p already exists in bin free list\n", address);		}	}#endif	*(unsigned int *)address = (unsigned int)bin->free_list;	bin->free_list = address;	bin->alloc_count--;	bin->free_count++;	mutex_unlock(&heap_lock);}