/*convenient function that find the correct free list and insert that free block*/ void insertToFreeList(void* bp) { size_t size = GET_SIZE(HDRP(bp)); int which = getWhichFreeList(size); //get the fit free list void* freeListHead = free_lists[which]; void* next = getNextFreeBlock(freeListHead); if (next == NULL) { //if the list is empty just insert to head insertFreeBlock(bp, freeListHead, NULL); return; } else { //find the correct position to insert using ordered address policy void* last = NULL; while (next != NULL) { if (bp > next) { void* prev = getPrevFreeBlock(next); insertFreeBlock(bp, prev, next); return; } void* nextnext = getNextFreeBlock(next); if (nextnext == NULL) { last = next; break; } next = nextnext; } //insert at the end of the free list insertFreeBlock(bp, last, NULL); return; } }
void CBasicBlocksBuilder::SortBlocks() { assert( blocks.size() > 0 ); std::vector<bool> used( blocks.size(), false ); CBasicBlock currBlock = blocks[labelToBlock[firstLabel->label]]; used[labelToBlock[firstLabel->label]] = true; sortedBlocks.push_back( currBlock ); const IIRStm* jump = currBlock.Last(); size_t numOfFreeBlocks = used.size() - 1; while( numOfFreeBlocks > 0 ) { if( IsInstanceOf<CIRJump>( const_cast< IIRStm* >( jump ) ) ) { // За ним просто должен идти блок с меткой, куда прыгаем const Temp::CLabel* nextLabel = getNextLabel( jump ); if( nextLabel->Name() == "done_label" || used[labelToBlock[nextLabel]] ) { // Если блок конца фрейма, или же след ведет в посещенный блок // Значит нужно взять непосещенный и с ним строить след int position = 0; if( getNextFreeBlock( used, currBlock, position ) ) { sortedBlocks.push_back( currBlock ); used[position] = true; --numOfFreeBlocks; jump = currBlock.Last(); continue; } else { // Свободных блоков не осталось break; } } currBlock = blocks[labelToBlock[nextLabel]]; sortedBlocks.push_back( currBlock ); used[labelToBlock[nextLabel]] = true; --numOfFreeBlocks; } else if( IsInstanceOf<CIRCJump>( const_cast< IIRStm* >( jump ) ) ) { // За ним должен идти блок с меткой на false const Temp::CLabel* nextLabel = getNextConditionalLabel( jump ); if( nextLabel->Name() == "done_label" || used[labelToBlock[nextLabel]] ) { int position = 0; if( getNextFreeBlock( used, currBlock, position ) ) { sortedBlocks.push_back( currBlock ); used[position] = true; --numOfFreeBlocks; jump = currBlock.Last(); continue; } else { // Свободных блоков не осталось break; } } currBlock = blocks[labelToBlock[nextLabel]]; sortedBlocks.push_back( currBlock ); used[labelToBlock[nextLabel]] = true; --numOfFreeBlocks; } else { assert( false ); } jump = currBlock.Last(); } }
//helper function for check if block in free list int isInFreeList(void* bp) { int i; for (i = 0; i < FREE_LIST_NUM; i++) { void* b = getNextFreeBlock(free_lists[i]); while (b != NULL) { if (b == bp) { return 1; } b = getNextFreeBlock(b); } } printf("not inside free lists!%p\n", bp); return 0; }
/********************************************************** * find_fit * Traverse the segregated free lists searching for a block to fit asize * Return NULL if no free blocks can handle that size * Assumed that asize is aligned **********************************************************/ void * find_fit(size_t asize) { int which = getWhichFreeList(asize); while (which < FREE_LIST_NUM) { void* freeList = free_lists[which]; void* freeListNext = getNextFreeBlock(freeList); //go through the free list to find the fit sized free block for (; freeListNext != NULL; freeListNext = getNextFreeBlock(freeListNext)) { if (asize <= GET_SIZE(HDRP(freeListNext))) { return freeListNext; } } //else then go to next level of free list if not found this level which++; } return NULL; }
/*remove the given free block from the free list*/ void removeFromFreeList(void* bp) { void* next = getNextFreeBlock(bp); void* prev = getPrevFreeBlock(bp); setFreeBlockNext(prev, next); if (next != NULL) { setFreeBLockPrev(next, prev); } setFreeBlockPrevNext(bp, NULL, NULL); //clear removed block's link }
int mm_check(int i) { void* base = heap_listp; // Print Entire Heap starting from prologue upto eplilogue if (i == 1) { printf("Address : %p Allocated: %ld Size:%ld <----- PROLOGUE\n", base, GET_ALLOC(HDRP(base)), GET_SIZE(HDRP(base))); base = NEXT_BLKP(base); while (GET_SIZE(HDRP(base)) != 0) { printf("Address : %p Allocated: %ld Size:%ld\n", base, GET_ALLOC(HDRP(base)), GET_SIZE(HDRP(base))); base = NEXT_BLKP(base); } printf("Address : %p Allocated: %ld Size:%ld <----- EPILOGUE\n", base, GET_ALLOC(HDRP(base)), GET_SIZE(HDRP(base))); } // Print 12 Segregated Free List. Very helpful at early stage. if (i == 2) { int i; for (i = 0; i < FREE_LIST_NUM; i++) { printf("Free List #%d [%ld-%ld]\n", i, MIN_BLOCK_SIZE / 2 << i, MIN_BLOCK_SIZE / 2 << (i + 1)); void* next = getNextFreeBlock(free_lists[i]); while (next != NULL) { printf("Address:%p Alloc:%ld Size:%ld\n", next, GET_ALLOC(HDRP(next)), GET_SIZE(HDRP(next))); next = getNextFreeBlock(next); } } } // Check if there are any contiguous free blocks and print address of two (if exists) if (i == 3) { int z = 0; while (GET_SIZE(HDRP(base)) != 0) { if ((GET_ALLOC(HDRP(base))) == 0 && (GET_ALLOC(HDRP(NEXT_BLKP(base))) == 0)) { z = 1; printf("Address: %p (alloc:%ld) and Address: %p (alloc:%ld) are contiguous FREE BLOCKS!\n", base, GET_ALLOC(HDRP(NEXT_BLKP(base))), base, GET_ALLOC(HDRP(NEXT_BLKP(base)))); } base = NEXT_BLKP(base); } if (z == 0) { printf("\tVERIFIED. There aren't any contiguous FREE Blocks in your heap.\n"); } } //Check if every free blocks are in the free list if (i == 4) { void* bp = heap_listp; //terminate at the epilogue where size is 0 while (GET_SIZE(HDRP(bp)) != 0) { if (GET_ALLOC(HDRP(bp)) == 0) { isInFreeList(bp); printf("VERIFIED. ALL free blocks exist within free list\n"); } bp = NEXT_BLKP(bp); } } //Check if free block pointer(s) (in free list) points to valid free block in heap. if (i == 5) { int i; for (i = 0; i < FREE_LIST_NUM; i++) { printf("Free List #%d [%ld-%ld]\n", i, MIN_BLOCK_SIZE / 2 << i, MIN_BLOCK_SIZE / 2 << (i + 1)); base = heap_listp; void* next = getNextFreeBlock(free_lists[i]); while (next != NULL) { //check if the free block in free list is in heap so that it is valid find_element(next); next = getNextFreeBlock(next); } } } //Check if all pointers in heap point to valid heap address. if (i == 6) { int z = 0; void* cur = heap_listp; while (GET_SIZE(HDRP(cur)) != 0) { if ((base > cur) || (cur > mem_heap_hi())) { z = 1; printf("\tERROR: Address: %p is not a valid heap address.\n", cur); } cur = NEXT_BLKP(cur); } if (z == 0) printf("\tVERIFIED. ALL pointers in heap block point to valid heap address\n"); } //check if there is overlap by checking that block's next point to next block and //next block's previous point to that block too if (i == 7) { void* node = heap_listp; while (GET_SIZE(HDRP(node)) != 0) { void* next = NEXT_BLKP(node); if (GET_SIZE(HDRP(node)) != 0) { if (PREV_BLKP(next) != node) { //not matched we have overlapped block printf("There are overlapped blocks!\n "); return 0; } } node = next; } printf("There is no overlapping!\n "); } return 1; }