/* memmap_free_t* merge_block(memmap_free_t* mmap_left, memmap_free_t* mmap_right) Merges two contiguous block of free memory. */ memmap_free_t* merge_block(memmap_free_t* mmap_left, memmap_free_t* mmap_right) { memmap_t* mmap_left_alloc = (memmap_t*) mmap_left; memmap_t* mmap_right_alloc = (memmap_t*) mmap_right; if(is_last_in_memory(mmap_right_alloc)) { set_next_block(mmap_left_alloc, mmap_left_alloc); } else { set_next_block(mmap_left_alloc, get_next_block(mmap_right_alloc)); set_prev_block(get_next_block(mmap_right_alloc), mmap_left_alloc); } #ifdef DEBUG_MEMORY printf("Left: %d, right: %d ,", get_block_size(mmap_left_alloc), get_block_size(mmap_right_alloc)); #endif remove_free_block(mmap_right); remove_free_block(mmap_left); set_block_size(mmap_left_alloc, get_block_size(mmap_left_alloc) + get_block_size(mmap_right_alloc)); #ifdef DEBUG_MEMORY printf("new left: %d\n", get_block_size(mmap_left_alloc)); #endif return mmap_left; }
memmap_free_t* split_block(memmap_free_t* mmap_free, U32 required_size ) { memmap_t* mmap_alloc = (memmap_t*) mmap_free; U32 old_size; memmap_free_t* new_mmap_free; memmap_t* new_mmap_alloc; /* splitting is only possible if the required size of the block is less than CEIL32((current size of the block) + 32 (minimum block size) + HEADER_SIZE (for the new block)) */ if (get_block_size(mmap_alloc) < required_size + BLOCK_SIZE_MULTIPLE) return NULL; old_size = get_block_size(mmap_alloc); new_mmap_free = (memmap_free_t*) (CEIL32((U32)mmap_alloc + required_size)); new_mmap_alloc = (memmap_t*) new_mmap_free; /* If mmap_alloc wasn't the last block in memory before splitting, we need to link the newly created block to whatever used to be after mmap_alloc in memory */ if (!is_last_in_memory(mmap_alloc)) { set_next_block(new_mmap_alloc, get_next_block(mmap_alloc)); set_prev_block((memmap_t*) get_next_block(mmap_alloc), new_mmap_alloc); } // Otherwise, just link the newly created block to itself (i.e. terminate) else { set_next_block(new_mmap_alloc, new_mmap_alloc); } // Linking mmap_alloc and the newly created new_mmap_alloc set_prev_block(new_mmap_alloc, mmap_alloc); set_next_block(mmap_alloc, new_mmap_alloc); // Finally, block sizes (only mmap_alloc and new_mmap_alloc are affected) set_block_size(mmap_alloc, required_size); set_block_size(new_mmap_alloc, old_size - required_size); set_allocated(new_mmap_alloc, __FALSE); #ifdef DEBUG_MEMORY printf("split_block | old size: %d, required: %d, new sizes: %d and %d\n", old_size, required_size, get_block_size(mmap_alloc), get_block_size(new_mmap_alloc)); #endif return new_mmap_free; }
/* void memmap_init(emmap_t* const mmap, U32 size) Initializes a struct of type `memmap` with a given size. */ void memmap_init(memmap_t* const mmap, U32 size) { // Initialize the values for the fields set_prev_block(mmap, mmap); set_next_block(mmap, mmap); set_block_size(mmap, size); set_allocated(mmap, __FALSE); }
void* allocate_block(void * ptr, size_t size){ size_t ex_size = BLOCK_SIZE(ptr); set_used(ptr); set_block_size(ptr, size); set_next_block(ptr, ex_size, size); return ptr + sizeof(header); }
void placeBlock(BlockInfo * ptrFreeBlock, size_t reqSize){ printf("Placing block\n"); BlockInfo * nextBlock = NULL; size_t blockSize; size_t precedingBlockUseTag; blockSize = SIZE(ptrFreeBlock->sizeAndTags); precedingBlockUseTag = (ptrFreeBlock->sizeAndTags) & TAG_PRECEDING_USED; if (blockSize - reqSize >= MIN_BLOCK_SIZE){ ptrFreeBlock->sizeAndTags = reqSize | TAG_USED |precedingBlockUseTag; split_block(ptrFreeBlock, blockSize, precedingBlockUseTag); } else{ ptrFreeBlock->sizeAndTags = blockSize | TAG_USED | precedingBlockUseTag; nextBlock = (BlockInfo *) UNSCALED_POINTER_ADD(ptrFreeBlock, SIZE(ptrFreeBlock->sizeAndTags)); set_next_block(nextBlock, TAG_PRECEDING_USED); } }
/* Free the block referenced by ptr. */ void mm_free (void *ptr) { printf("Begin free\n"); size_t payloadSize; BlockInfo * blockInfo; BlockInfo * footer; BlockInfo * nextBlock; size_t precedingBlockUseTag; blockInfo = (BlockInfo *) UNSCALED_POINTER_SUB(ptr, WORD_SIZE); payloadSize = SIZE(blockInfo->sizeAndTags); precedingBlockUseTag = blockInfo->sizeAndTags & TAG_PRECEDING_USED; blockInfo->sizeAndTags = (payloadSize & ~TAG_USED) | precedingBlockUseTag; footer = (BlockInfo *) UNSCALED_POINTER_ADD(blockInfo, payloadSize - WORD_SIZE); footer->sizeAndTags = blockInfo->sizeAndTags; nextBlock = (BlockInfo *) UNSCALED_POINTER_ADD(ptr, payloadSize); set_next_block(nextBlock, precedingBlockUseTag); insertFreeBlock(blockInfo); coalesceFreeBlock(blockInfo); }
void split_block(BlockInfo * ptrFreeBlock, size_t totalSize, size_t precedingBlockUseTag){ printf("Splitting\n"); BlockInfo * splitBlock = NULL; BlockInfo * splitBlockFooter = NULL; BlockInfo * nextBlock = NULL; size_t splitBlockSize; size_t ptrFreeBlockSize; ptrFreeBlockSize = SIZE(ptrFreeBlock->sizeAndTags); splitBlock = (BlockInfo *) UNSCALED_POINTER_ADD(ptrFreeBlock, ptrFreeBlockSize); splitBlockSize = totalSize - ptrFreeBlockSize; splitBlock->sizeAndTags = splitBlockSize | TAG_PRECEDING_USED; splitBlockFooter = (BlockInfo *) UNSCALED_POINTER_ADD((void*)splitBlock, splitBlockSize - WORD_SIZE); splitBlockFooter->sizeAndTags = splitBlock->sizeAndTags; nextBlock = (BlockInfo *) UNSCALED_POINTER_ADD((void *) splitBlock, splitBlockSize); set_next_block(nextBlock, 0); insertFreeBlock(splitBlock); coalesceFreeBlock(splitBlock); examine_heap(); }
cfg_t::cfg_t(exec_list *instructions) { mem_ctx = ralloc_context(NULL); block_list.make_empty(); blocks = NULL; num_blocks = 0; bblock_t *cur = NULL; int ip = 0; bblock_t *entry = new_block(); bblock_t *cur_if = NULL; /**< BB ending with IF. */ bblock_t *cur_else = NULL; /**< BB ending with ELSE. */ bblock_t *cur_endif = NULL; /**< BB starting with ENDIF. */ bblock_t *cur_do = NULL; /**< BB starting with DO. */ bblock_t *cur_while = NULL; /**< BB immediately following WHILE. */ exec_list if_stack, else_stack, do_stack, while_stack; bblock_t *next; set_next_block(&cur, entry, ip); entry->start = (backend_instruction *) instructions->get_head(); foreach_list(node, instructions) { backend_instruction *inst = (backend_instruction *)node; cur->end = inst; /* set_next_block wants the post-incremented ip */ ip++; switch (inst->opcode) { case BRW_OPCODE_IF: /* Push our information onto a stack so we can recover from * nested ifs. */ if_stack.push_tail(link(mem_ctx, cur_if)); else_stack.push_tail(link(mem_ctx, cur_else)); cur_if = cur; cur_else = NULL; cur_endif = NULL; /* Set up our immediately following block, full of "then" * instructions. */ next = new_block(); next->start = (backend_instruction *)inst->next; cur_if->add_successor(mem_ctx, next); set_next_block(&cur, next, ip); break; case BRW_OPCODE_ELSE: cur_else = cur; next = new_block(); next->start = (backend_instruction *)inst->next; cur_if->add_successor(mem_ctx, next); set_next_block(&cur, next, ip); break; case BRW_OPCODE_ENDIF: { if (cur->start == inst) { /* New block was just created; use it. */ cur_endif = cur; } else { cur_endif = new_block(); cur_endif->start = inst; cur->end = (backend_instruction *)inst->prev; cur->add_successor(mem_ctx, cur_endif); set_next_block(&cur, cur_endif, ip - 1); } backend_instruction *else_inst = NULL; if (cur_else) { else_inst = (backend_instruction *)cur_else->end; cur_else->add_successor(mem_ctx, cur_endif); } else { cur_if->add_successor(mem_ctx, cur_endif); } assert(cur_if->end->opcode == BRW_OPCODE_IF); assert(!else_inst || else_inst->opcode == BRW_OPCODE_ELSE); assert(inst->opcode == BRW_OPCODE_ENDIF); cur_if->if_inst = cur_if->end; cur_if->else_inst = else_inst; cur_if->endif_inst = inst; if (cur_else) { cur_else->if_inst = cur_if->end; cur_else->else_inst = else_inst; cur_else->endif_inst = inst; } cur->if_inst = cur_if->end; cur->else_inst = else_inst; cur->endif_inst = inst; /* Pop the stack so we're in the previous if/else/endif */ cur_if = pop_stack(&if_stack); cur_else = pop_stack(&else_stack); break; } case BRW_OPCODE_DO: /* Push our information onto a stack so we can recover from * nested loops. */ do_stack.push_tail(link(mem_ctx, cur_do)); while_stack.push_tail(link(mem_ctx, cur_while)); /* Set up the block just after the while. Don't know when exactly * it will start, yet. */ cur_while = new_block(); if (cur->start == inst) { /* New block was just created; use it. */ cur_do = cur; } else { cur_do = new_block(); cur_do->start = inst; cur->end = (backend_instruction *)inst->prev; cur->add_successor(mem_ctx, cur_do); set_next_block(&cur, cur_do, ip - 1); } break; case BRW_OPCODE_CONTINUE: cur->add_successor(mem_ctx, cur_do); next = new_block(); next->start = (backend_instruction *)inst->next; if (inst->predicate) cur->add_successor(mem_ctx, next); set_next_block(&cur, next, ip); break; case BRW_OPCODE_BREAK: cur->add_successor(mem_ctx, cur_while); next = new_block(); next->start = (backend_instruction *)inst->next; if (inst->predicate) cur->add_successor(mem_ctx, next); set_next_block(&cur, next, ip); break; case BRW_OPCODE_WHILE: cur_while->start = (backend_instruction *)inst->next; cur->add_successor(mem_ctx, cur_do); set_next_block(&cur, cur_while, ip); /* Pop the stack so we're in the previous loop */ cur_do = pop_stack(&do_stack); cur_while = pop_stack(&while_stack); break; default: break; } }
void cfg_t::create(void *parent_mem_ctx, exec_list *instructions) { mem_ctx = ralloc_context(NULL); block_list.make_empty(); blocks = NULL; num_blocks = 0; ip = 0; cur = NULL; bblock_t *entry = new_block(); bblock_t *cur_if = NULL, *cur_else = NULL, *cur_endif = NULL; bblock_t *cur_do = NULL, *cur_while = NULL; exec_list if_stack, else_stack, endif_stack, do_stack, while_stack; bblock_t *next; set_next_block(entry); entry->start = (backend_instruction *) instructions->get_head(); foreach_list(node, instructions) { backend_instruction *inst = (backend_instruction *)node; cur->end = inst; /* set_next_block wants the post-incremented ip */ ip++; switch (inst->opcode) { case BRW_OPCODE_IF: /* Push our information onto a stack so we can recover from * nested ifs. */ if_stack.push_tail(cur_if->make_list(mem_ctx)); else_stack.push_tail(cur_else->make_list(mem_ctx)); endif_stack.push_tail(cur_endif->make_list(mem_ctx)); cur_if = cur; cur_else = NULL; /* Set up the block just after the endif. Don't know when exactly * it will start, yet. */ cur_endif = new_block(); /* Set up our immediately following block, full of "then" * instructions. */ next = new_block(); next->start = (backend_instruction *)inst->next; cur_if->add_successor(mem_ctx, next); set_next_block(next); break; case BRW_OPCODE_ELSE: cur->add_successor(mem_ctx, cur_endif); next = new_block(); next->start = (backend_instruction *)inst->next; cur_if->add_successor(mem_ctx, next); cur_else = next; set_next_block(next); break; case BRW_OPCODE_ENDIF: cur_endif->start = (backend_instruction *)inst->next; cur->add_successor(mem_ctx, cur_endif); set_next_block(cur_endif); if (!cur_else) cur_if->add_successor(mem_ctx, cur_endif); /* Pop the stack so we're in the previous if/else/endif */ cur_if = pop_stack(&if_stack); cur_else = pop_stack(&else_stack); cur_endif = pop_stack(&endif_stack); break; case BRW_OPCODE_DO: /* Push our information onto a stack so we can recover from * nested loops. */ do_stack.push_tail(cur_do->make_list(mem_ctx)); while_stack.push_tail(cur_while->make_list(mem_ctx)); /* Set up the block just after the while. Don't know when exactly * it will start, yet. */ cur_while = new_block(); /* Set up our immediately following block, full of "then" * instructions. */ next = new_block(); next->start = (backend_instruction *)inst->next; cur->add_successor(mem_ctx, next); cur_do = next; set_next_block(next); break; case BRW_OPCODE_CONTINUE: cur->add_successor(mem_ctx, cur_do); next = new_block(); next->start = (backend_instruction *)inst->next; if (inst->predicate) cur->add_successor(mem_ctx, next); set_next_block(next); break; case BRW_OPCODE_BREAK: cur->add_successor(mem_ctx, cur_while); next = new_block(); next->start = (backend_instruction *)inst->next; if (inst->predicate) cur->add_successor(mem_ctx, next); set_next_block(next); break; case BRW_OPCODE_WHILE: cur_while->start = (backend_instruction *)inst->next; cur->add_successor(mem_ctx, cur_do); set_next_block(cur_while); /* Pop the stack so we're in the previous loop */ cur_do = pop_stack(&do_stack); cur_while = pop_stack(&while_stack); break; default: break; } }