chunk分配完成,管理每一页的mapbits和misc信息设置完成,然后就是分配一块内存放tcache相关的信息了
tcache相关信息的大小前面已经计算过,经过对齐和sa2u,大小是32768,0x8000,需要8页,但是arena_malloc_large函数分配时加上了large_pad
这个大小是1页,所以总共使用了9页,大小是0x9000,36864
这就是arena_run_split_large(arena, run, size, zero)的工作
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); 地址对齐,得到chunk地址
miscelm = arena_run_to_miscelm(run); 通过run字段得到所在的misc的地址
run_ind = arena_miscelm_to_pageind(miscelm); 得到这个miscelm对应的页序号(13)
flag_dirty = arena_mapbits_dirty_get(chunk, run_ind); 得到这个miscelm的各种标记以及total_pages(通过页序号得到对应的mapbits)
flag_decommitted = arena_mapbits_decommitted_get(chunk, run_ind); 第13页对应第0个mapbits
arena_run_split_remove(arena, chunk, run_ind, flag_dirty, flag_decommitted, need_pages);
arena_avail_remove(arena, chunk, run_ind, total_pages); 先从arena的runs_avail树中移除run_ind对应的misc
arena_mapbits_unallocated_set(chunk, run_ind+need_pages, (rem_pages << LG_PAGE), flags | ...) 设置第22页misc(大小和标志)
arena_mapbits_unallocated_set(chunk, run_ind+total_pages-1, (rem_pages << LG_PAGE), flags | ...) total_pages=499,设置第511页,第498个mapbits
arena_avail_insert(arena, chunk, run_ind+need_pages, rem_pages);
将该chunk的第run_ind+need_pages对应的misc存入arena的runs_avail树,下次再分配拿到的misc就是第22页对应的misc了
arena_mapbits_large_set(chunk, run_ind+need_pages-1, 0, flag_dirty | ...) 设置第21页misc(大小0和标志)
arena_mapbits_large_set(chunk, run_ind, size, flag_dirty | ...) 设置第13页misc(大小为9页的大小和标志)
返回第13页对应的misc的run
外面再通过run得到misc的地址,再根据chunk的地址和misc的偏移,
ret = (void *)((uintptr_t)arena_miscelm_to_rpages(miscelm) + random_offset);得到分配的内存的起始地址
这个返回地址就作为tcache结构体的地址,tcache的内存布局前面已讲,tcahce创建完毕,下面就是用tcache来分配内存
tcache相关信息的大小前面已经计算过,经过对齐和sa2u,大小是32768,0x8000,需要8页,但是arena_malloc_large函数分配时加上了large_pad
这个大小是1页,所以总共使用了9页,大小是0x9000,36864
这就是arena_run_split_large(arena, run, size, zero)的工作
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); 地址对齐,得到chunk地址
miscelm = arena_run_to_miscelm(run); 通过run字段得到所在的misc的地址
run_ind = arena_miscelm_to_pageind(miscelm); 得到这个miscelm对应的页序号(13)
flag_dirty = arena_mapbits_dirty_get(chunk, run_ind); 得到这个miscelm的各种标记以及total_pages(通过页序号得到对应的mapbits)
flag_decommitted = arena_mapbits_decommitted_get(chunk, run_ind); 第13页对应第0个mapbits
arena_run_split_remove(arena, chunk, run_ind, flag_dirty, flag_decommitted, need_pages);
arena_avail_remove(arena, chunk, run_ind, total_pages); 先从arena的runs_avail树中移除run_ind对应的misc
arena_mapbits_unallocated_set(chunk, run_ind+need_pages, (rem_pages << LG_PAGE), flags | ...) 设置第22页misc(大小和标志)
arena_mapbits_unallocated_set(chunk, run_ind+total_pages-1, (rem_pages << LG_PAGE), flags | ...) total_pages=499,设置第511页,第498个mapbits
arena_avail_insert(arena, chunk, run_ind+need_pages, rem_pages);
将该chunk的第run_ind+need_pages对应的misc存入arena的runs_avail树,下次再分配拿到的misc就是第22页对应的misc了
arena_mapbits_large_set(chunk, run_ind+need_pages-1, 0, flag_dirty | ...) 设置第21页misc(大小0和标志)
arena_mapbits_large_set(chunk, run_ind, size, flag_dirty | ...) 设置第13页misc(大小为9页的大小和标志)
返回第13页对应的misc的run
外面再通过run得到misc的地址,再根据chunk的地址和misc的偏移,
ret = (void *)((uintptr_t)arena_miscelm_to_rpages(miscelm) + random_offset);得到分配的内存的起始地址
这个返回地址就作为tcache结构体的地址,tcache的内存布局前面已讲,tcahce创建完毕,下面就是用tcache来分配内存