mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-06 19:38:41 +03:00
merge from dev3
This commit is contained in:
commit
b920fc1b72
14 changed files with 103 additions and 42 deletions
45
src/arena.c
45
src/arena.c
|
@ -581,10 +581,16 @@ static mi_page_t* mi_arena_page_try_find_abandoned(mi_subproc_t* subproc, size_t
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if MI_SECURE < 2
|
||||
#define MI_ARENA_GUARD_PAGE_SIZE (0)
|
||||
#else
|
||||
#define MI_ARENA_GUARD_PAGE_SIZE (4*MI_KiB)
|
||||
#endif
|
||||
|
||||
static mi_page_t* mi_arena_page_alloc_fresh(mi_subproc_t* subproc, size_t slice_count, size_t block_size, size_t block_alignment,
|
||||
mi_arena_t* req_arena, size_t tseq)
|
||||
{
|
||||
const bool allow_large = true;
|
||||
const bool allow_large = (MI_SECURE < 2); // 2 = guard page at end of each arena page
|
||||
const bool commit = true;
|
||||
const bool os_align = (block_alignment > MI_PAGE_MAX_OVERALLOC_ALIGN);
|
||||
const size_t page_alignment = MI_ARENA_SLICE_ALIGN;
|
||||
|
@ -619,6 +625,14 @@ static mi_page_t* mi_arena_page_alloc_fresh(mi_subproc_t* subproc, size_t slice_
|
|||
mi_assert_internal(_mi_is_aligned(page, MI_PAGE_ALIGN));
|
||||
mi_assert_internal(!os_align || _mi_is_aligned((uint8_t*)page + page_alignment, block_alignment));
|
||||
|
||||
// guard page at the end
|
||||
const size_t page_body_size = mi_size_of_slices(slice_count) - MI_ARENA_GUARD_PAGE_SIZE;
|
||||
#if MI_SECURE >= 2
|
||||
if (memid.initially_committed && !memid.is_pinned) {
|
||||
_mi_os_decommit((uint8_t*)page + page_body_size, MI_ARENA_GUARD_PAGE_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
// claimed free slices: initialize the page partly
|
||||
if (!memid.initially_zero) {
|
||||
mi_track_mem_undefined(page, slice_count * MI_ARENA_SLICE_SIZE);
|
||||
|
@ -629,7 +643,7 @@ static mi_page_t* mi_arena_page_alloc_fresh(mi_subproc_t* subproc, size_t slice_
|
|||
}
|
||||
#if MI_DEBUG > 1
|
||||
if (memid.initially_zero) {
|
||||
if (!mi_mem_is_zero(page, mi_size_of_slices(slice_count))) {
|
||||
if (!mi_mem_is_zero(page, page_body_size)) {
|
||||
_mi_error_message(EFAULT, "internal error: page memory was not zero initialized.\n");
|
||||
memid.initially_zero = false;
|
||||
_mi_memzero_aligned(page, sizeof(*page));
|
||||
|
@ -659,7 +673,7 @@ static mi_page_t* mi_arena_page_alloc_fresh(mi_subproc_t* subproc, size_t slice_
|
|||
// otherwise start after the info
|
||||
block_start = mi_page_info_size();
|
||||
}
|
||||
const size_t reserved = (os_align ? 1 : (mi_size_of_slices(slice_count) - block_start) / block_size);
|
||||
const size_t reserved = (os_align ? 1 : (page_body_size - block_start) / block_size);
|
||||
mi_assert_internal(reserved > 0 && reserved <= UINT16_MAX);
|
||||
page->reserved = (uint16_t)reserved;
|
||||
page->page_start = (uint8_t*)page + block_start;
|
||||
|
@ -712,7 +726,11 @@ static mi_page_t* mi_singleton_page_alloc(mi_heap_t* heap, size_t block_size, si
|
|||
mi_tld_t* const tld = heap->tld;
|
||||
const bool os_align = (block_alignment > MI_PAGE_MAX_OVERALLOC_ALIGN);
|
||||
const size_t info_size = (os_align ? MI_PAGE_ALIGN : mi_page_info_size());
|
||||
#if MI_ARENA_GUARD_PAGE_SIZE == 0
|
||||
const size_t slice_count = mi_slice_count_of_size(info_size + block_size);
|
||||
#else
|
||||
const size_t slice_count = mi_slice_count_of_size(_mi_align_up(info_size + block_size, MI_ARENA_GUARD_PAGE_SIZE) + MI_ARENA_GUARD_PAGE_SIZE);
|
||||
#endif
|
||||
|
||||
mi_page_t* page = mi_arena_page_alloc_fresh(tld->subproc, slice_count, block_size, block_alignment, req_arena, tld->thread_seq);
|
||||
if (page == NULL) return NULL;
|
||||
|
@ -721,6 +739,7 @@ static mi_page_t* mi_singleton_page_alloc(mi_heap_t* heap, size_t block_size, si
|
|||
mi_assert(page->reserved == 1);
|
||||
mi_assert_internal(_mi_ptr_page(page)==page);
|
||||
mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);
|
||||
_mi_page_init(heap, page);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
@ -778,6 +797,13 @@ void _mi_arena_page_free(mi_page_t* page) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// recommit guard page at the end?
|
||||
#if MI_SECURE >= 2
|
||||
if (!page->memid.is_pinned) {
|
||||
_mi_os_commit((uint8_t*)page + mi_memid_size(page->memid) - MI_ARENA_GUARD_PAGE_SIZE, MI_ARENA_GUARD_PAGE_SIZE, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
// unregister page
|
||||
_mi_page_map_unregister(page);
|
||||
if (page->memid.memkind == MI_MEM_ARENA) {
|
||||
|
@ -1124,12 +1150,17 @@ static bool mi_manage_os_memory_ex2(mi_subproc_t* subproc, void* start, size_t s
|
|||
mi_arena_t* arena = (mi_arena_t*)start;
|
||||
|
||||
// commit & zero if needed
|
||||
bool is_zero = memid.initially_zero;
|
||||
const size_t os_page_size = _mi_os_page_size();
|
||||
if (!memid.initially_committed) {
|
||||
_mi_os_commit(arena, mi_size_of_slices(info_slices), NULL);
|
||||
// security: always leave a guard OS page decommitted at the end (already part of info_slices)
|
||||
_mi_os_commit(arena, mi_size_of_slices(info_slices) - os_page_size, NULL);
|
||||
}
|
||||
if (!is_zero) {
|
||||
_mi_memzero(arena, mi_size_of_slices(info_slices));
|
||||
else if (!memid.is_pinned) {
|
||||
// security: decommit a guard OS page at the end of the arena info
|
||||
_mi_os_decommit((uint8_t*)arena + mi_size_of_slices(info_slices) - os_page_size, os_page_size);
|
||||
}
|
||||
if (!memid.initially_zero) {
|
||||
_mi_memzero(arena, mi_size_of_slices(info_slices) - os_page_size);
|
||||
}
|
||||
|
||||
// init
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue