/* * mm_check - check basic heap consistency. * * Check 1 : Is every block in the free list marked as free? * Check 2 : Are there any contiguous free blocks that somehow escaped coalescing? * Check 3 : Is every free block except 8byte actually in the free list? * */ int mm_check() { int flag = 0; //printf("Heap Consistency Checker : starts checking\n"); // Check 1 : Is every block in the free list marked as free? // 1-1 Checking for 16-list FREE prev = NULL; FREE iter = address_list; while(iter) { if(!checkMarkedAsFree(iter)) { printf("Heap Consistency Checker : %x is not marked as free though it's in free-list(16Byte)\n", (size_t)iter); int size = FSIZE(iter); printf("Heap Consistency Checker : Value of Header = %x, Value of Footer = %x\n", *(size_t*)iter, *(size_t*)((char *)iter+size-HEADER_SIZE)); flag=1; } iter=right(iter); } // 1-2 Checking for tree flag=flag|checkTreeMakredAsFree(address_tree); // Check 2 : Are there any contiguous free blocks that somehow escaped coalescing? iter=getLeftBlock((FREE)((char*)mem_heap_hi()+1)); while(iter) { if (prev&&checkMarkedAsFree(prev)&&checkMarkedAsFree(iter)) { printf("Heap Consistency Checker : %x and %x are contigous free block\n", (size_t)prev, (size_t)iter); flag=1; } prev=iter; iter=getLeftBlock(iter); } // Check 3 : Is every free block except 8byte actually in the free list? iter=getLeftBlock((FREE)((char*)mem_heap_hi()+1)); while(iter) { if (checkMarkedAsFree(iter) && FSIZE(iter) != 2 * HEADER_SIZE) { if (!checkContainedInList(iter)&&!checkContainedInTree(iter)) { printf("Heap Consistency Checker : %x : %08x is not contained in any list or tree\n", (size_t)iter, (size_t)FSIZE(iter)); flag = 1; } } iter=getLeftBlock(iter); } return flag; }
/* * merge_free - merging two nodes * delete two nodes and re-insert left. * */ void merge_free(FREE left, FREE right) { if(left == right) return; delete_free(left); delete_free(right); insert_free(left, FSIZE(left) + FSIZE(right)); return; }
/* * delete_ - recursively delete X in T. * * if X is right at T, right(T) = deleted right(T). * if X is left at T, left(T) = deleted lett(T). * * if X is T, change X and its successor/predecessor * and goto childs. * * after delete, re-balance AA tree. * */ FREE delete_(void* X, FREE T) { FREE P = T; if(!T) return T; else if ((FSIZE(X) > FSIZE(T)) || ((FSIZE(X) == FSIZE(T)) && X > T)) { right(T) = delete_(X, right(T)); } else if (X != T) { left(T) = delete_(X, left(T)); } else { if (!left(T) && !right(T)) { if(!parent(T)) { address_tree = NULL; } else if (left(parent(T)) == T) { left(parent(T)) = NULL; } else { right(parent(T)) = NULL; } return NULL; }else if (!left(T)) { P = change_successor(T); right(P) = delete_(X, right(P)); }else { P = change_predecessor(T); left(P) = delete_(X, left(P)); } } T = P; T = decrease_level(T); T = skew(T); right(T) = skew(right(T)); if(right(T)){ right(right(T)) = skew(right(right(T))); } T = split(T); right(T) = split(right(T)); return T; }
//テキストファイルの読み込み bool TextAnalyseW::load( const char *path ) { FILEPOINTER fp; unsigned char temp[2]; if( enable ) release(); fp = FOPEN( path ); if( fp == 0 ) return false; FREAD( temp, 2, fp ); if( temp[0] != 0xff || temp[1] != 0xfe ) { FCLOSE( fp ); return false; } FSIZE( path, fp, strsize ); strsize = ( strsize - 2 ) / sizeof( wchar_t ); buffer = new wchar_t[strsize + 1]; FREAD( buffer, strsize * sizeof( wchar_t ), fp ); FSEEK( fp, 2, SEEK_SET ); FCLOSE( fp ); buffer[strsize] = L'\0'; enable = true; mem = false; pos = buffer; last = buffer + strsize; return true; }
/* * getRightBlock - returns a block on the right side of target * returns NULL if doens't exists. * */ void* getRightBlock(void* target) { void* rightBlock = (FREE)((void*)target+FSIZE(target)); if (rightBlock<mem_heap_hi()+1) { return rightBlock; } return NULL; }
/* * divide_freeNode - make * |FREE| -> |empty(newsize)|FREE|. * * empty spaces will be used for malloc. * */ void divide_freeNode(FREE target, size_t newsize) { size_t oldsize = FSIZE(target); if(newsize >= oldsize) return; void* newtarget = (char*)target + newsize; delete_free(target); insert_free(target,newsize); insert_free(newtarget,oldsize-newsize); return; }
/* * insert_ - insert node recursively. * * if node is not right position, goto subtree and call recursively. * * if it is right position, set left, right, level and return. * */ FREE insert_(void* X, FREE T) { if(!address_tree) { left(X) = NULL; right(X) = NULL; parent(X) = NULL; level(X) = 1; address_tree = X; return X; } if(!T) { left(X) = NULL; right(X) = NULL; level(X) = 1; return X; } else if (FSIZE(X) < FSIZE(T) || ((FSIZE(X) == FSIZE(T)) && X < T)) { if(!left(T)) { parent(X) = T; } left(T) = insert_(X,left(T)); } else { if(!right(T)) { parent(X) = T; } right(T) = insert_(X, right(T)); } T = skew(T); T = split(T); return T; }
/* * try_realloc_right - if heap is * |MALLOC|FREE and size is enough, then make as * |REALLOC |FRE and return same pointer. * */ void* try_realloc_right(MALLOC target,void* origin, FREE right, size_t realsize) { size_t rightnewF; if(MSIZE(target) + FSIZE(right) >= realsize) { rightnewF = realsize - MSIZE(target); divide_freeNode(right,rightnewF); delete_free(right); setAllocatedBlockSize(target,realsize); return M_TO_P(target); } return NULL; }
/* * create_space_at_endHeap - create new MALLOC chunk at end. * if last chunk is free, then delete that and use to malloc chunk. * */ void *create_space_at_endHeap(size_t size) { FREE last; int lastSize = *((size_t*)((char*)mem_heap_hi()+1-HEADER_SIZE)); if(lastSize&1) { last = (FREE)((char*)mem_heap_hi()+1-(lastSize&-2)); delete_free(last); mem_sbrk(size - FSIZE(last)); return last; } return mem_sbrk(size); }
/* * debug_tree_r - print node,level,parent,size of node. * */ void debug_tree_r(FREE a, size_t d) { size_t i = 0; for(i = 0; i < d; i++) { printf("\t"); } if(!a) { printf("-\n"); return; } printf("%08x(%d)[%08x]-%04x\n",(size_t)a,level(a), (size_t)parent(a),FSIZE(a)); debug_tree_r(left(a),d+1); debug_tree_r(right(a),d+1); }
/* * delete_free - get size and call different * function for size. * */ void delete_free(FREE target) { size_t size = FSIZE(target); if (size == 2*HEADER_SIZE) { } else if (size == 4*HEADER_SIZE) { delete_16_free(target); } else if (size > 4*HEADER_SIZE) { delete_big_free(target); } return; // it can't happen // (querry size is multiple of 2*HEADER_SIZE) }
struct mapping * allocate_map(short msize) { struct mapping *m; unsigned u; short size; for(size = 1, u = (msize*100)/FILL_FACTOR; u && size < MAX_MAPPING_SIZE; size <<= 1, u >>= 1) ; num_mappings++; m = (struct mapping *) xalloc(sizeof(struct mapping)); m->pairs = (struct apair **) xalloc(sizeof(struct apair *) * size); (void)memset(m->pairs, 0, sizeof(struct apair *) * size); total_mapping_size += sizeof(struct mapping) + sizeof(struct apair *) * size; m->ref = 1; m->card = 0; m->size = size; m->mcard = FSIZE(m->size); return m; }
/* * find_big_tree_size - find appropriate node * with restriction. * * doing tree search and save minimum-size node, * and return at last. * */ FREE find_big_free_size(size_t size) { FREE iter = address_tree; size_t temp = 0; size_t mins = ~0; FREE retVal = NULL; while(iter) { temp = FSIZE(iter); if((temp >= size) && (temp < mins)) { retVal = iter; mins = temp; } if(temp < size) iter = right(iter); else iter = left(iter); } return retVal; }
//テキストファイルの読み込み bool TextAnalyse::load( const char *path ) { FILEPOINTER fp; if( enable ) release(); fp = FOPEN( path ); if( fp == 0 ) return false; FSIZE( path, fp, strsize ); buffer = new char[strsize + 1]; FREAD( buffer, strsize, fp ); FCLOSE( fp ); buffer[strsize] = '\0'; enable = true; mem = false; pos = buffer; last = buffer + strsize; return true; }
/* * checkMarkedAsFree - returns 1 if target is free-block, otherwise 0. * 1st bit of every free block is 1, allocated block is 0. * checks both header and footer. * */ int checkMarkedAsFree(FREE target) { int size = FSIZE(target); return (*(size_t*)target&1)&&(*(size_t*)((char *)target+size-HEADER_SIZE)&1); }