mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-01 17:24:38 +03:00
check all os_commit calls and return NULL on failure
This commit is contained in:
parent
30a17bf1b7
commit
21425bc334
4 changed files with 27 additions and 14 deletions
|
@ -163,13 +163,13 @@ bool _mi_os_has_overcommit(void);
|
||||||
bool _mi_os_has_virtual_reserve(void);
|
bool _mi_os_has_virtual_reserve(void);
|
||||||
|
|
||||||
bool _mi_os_reset(void* addr, size_t size);
|
bool _mi_os_reset(void* addr, size_t size);
|
||||||
bool _mi_os_commit(void* p, size_t size, bool* is_zero);
|
|
||||||
bool _mi_os_commit_ex(void* addr, size_t size, bool* is_zero, size_t stat_size);
|
|
||||||
bool _mi_os_decommit(void* addr, size_t size);
|
bool _mi_os_decommit(void* addr, size_t size);
|
||||||
bool _mi_os_protect(void* addr, size_t size);
|
|
||||||
bool _mi_os_unprotect(void* addr, size_t size);
|
bool _mi_os_unprotect(void* addr, size_t size);
|
||||||
bool _mi_os_purge(void* p, size_t size);
|
bool _mi_os_purge(void* p, size_t size);
|
||||||
bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, size_t stat_size);
|
bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, size_t stat_size);
|
||||||
|
mi_decl_nodiscard bool _mi_os_commit(void* p, size_t size, bool* is_zero);
|
||||||
|
mi_decl_nodiscard bool _mi_os_commit_ex(void* addr, size_t size, bool* is_zero, size_t stat_size);
|
||||||
|
mi_decl_nodiscard bool _mi_os_protect(void* addr, size_t size);
|
||||||
|
|
||||||
void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid);
|
void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid);
|
||||||
void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid);
|
void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid);
|
||||||
|
|
5
src/os.c
5
src/os.c
|
@ -300,7 +300,10 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
|
||||||
|
|
||||||
// explicitly commit only the aligned part
|
// explicitly commit only the aligned part
|
||||||
if (commit) {
|
if (commit) {
|
||||||
_mi_os_commit(p, size, NULL);
|
if (!_mi_os_commit(p, size, NULL)) {
|
||||||
|
mi_os_prim_free(p, over_size, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // mmap can free inside an allocation
|
else { // mmap can free inside an allocation
|
||||||
|
|
22
src/page.c
22
src/page.c
|
@ -37,7 +37,7 @@ static inline mi_block_t* mi_page_block_at(const mi_page_t* page, void* page_sta
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t size, mi_tld_t* tld);
|
static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t size, mi_tld_t* tld);
|
||||||
static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld);
|
static bool mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld);
|
||||||
|
|
||||||
#if (MI_DEBUG>=3)
|
#if (MI_DEBUG>=3)
|
||||||
static size_t mi_page_list_count(mi_page_t* page, mi_block_t* head) {
|
static size_t mi_page_list_count(mi_page_t* page, mi_block_t* head) {
|
||||||
|
@ -630,14 +630,14 @@ static mi_decl_noinline void mi_page_free_list_extend( mi_page_t* const page, co
|
||||||
// Note: we also experimented with "bump" allocation on the first
|
// Note: we also experimented with "bump" allocation on the first
|
||||||
// allocations but this did not speed up any benchmark (due to an
|
// allocations but this did not speed up any benchmark (due to an
|
||||||
// extra test in malloc? or cache effects?)
|
// extra test in malloc? or cache effects?)
|
||||||
static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) {
|
static bool mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) {
|
||||||
mi_assert_expensive(mi_page_is_valid_init(page));
|
mi_assert_expensive(mi_page_is_valid_init(page));
|
||||||
#if (MI_SECURE<=2)
|
#if (MI_SECURE<=2)
|
||||||
mi_assert(page->free == NULL);
|
mi_assert(page->free == NULL);
|
||||||
mi_assert(page->local_free == NULL);
|
mi_assert(page->local_free == NULL);
|
||||||
if (page->free != NULL) return;
|
if (page->free != NULL) return true;
|
||||||
#endif
|
#endif
|
||||||
if (page->capacity >= page->reserved) return;
|
if (page->capacity >= page->reserved) return true;
|
||||||
|
|
||||||
size_t page_size;
|
size_t page_size;
|
||||||
//uint8_t* page_start =
|
//uint8_t* page_start =
|
||||||
|
@ -673,6 +673,7 @@ static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld)
|
||||||
page->capacity += (uint16_t)extend;
|
page->capacity += (uint16_t)extend;
|
||||||
mi_stat_increase(tld->stats.page_committed, extend * bsize);
|
mi_stat_increase(tld->stats.page_committed, extend * bsize);
|
||||||
mi_assert_expensive(mi_page_is_valid_init(page));
|
mi_assert_expensive(mi_page_is_valid_init(page));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize a fresh page
|
// Initialize a fresh page
|
||||||
|
@ -724,9 +725,11 @@ static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t block_size, mi
|
||||||
mi_assert_expensive(mi_page_is_valid_init(page));
|
mi_assert_expensive(mi_page_is_valid_init(page));
|
||||||
|
|
||||||
// initialize an initial free list
|
// initialize an initial free list
|
||||||
mi_page_extend_free(heap,page,tld);
|
if (mi_page_extend_free(heap,page,tld)) {
|
||||||
mi_assert(mi_page_immediate_available(page));
|
mi_assert(mi_page_immediate_available(page));
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------
|
/* -----------------------------------------------------------
|
||||||
|
@ -817,9 +820,14 @@ static mi_page_t* mi_page_queue_find_free_ex(mi_heap_t* heap, mi_page_queue_t* p
|
||||||
if (page_candidate != NULL) {
|
if (page_candidate != NULL) {
|
||||||
page = page_candidate;
|
page = page_candidate;
|
||||||
}
|
}
|
||||||
if (page != NULL && !mi_page_immediate_available(page)) {
|
if (page != NULL) {
|
||||||
|
if (!mi_page_immediate_available(page)) {
|
||||||
mi_assert_internal(mi_page_is_expandable(page));
|
mi_assert_internal(mi_page_is_expandable(page));
|
||||||
mi_page_extend_free(heap, page, heap->tld);
|
if (!mi_page_extend_free(heap, page, heap->tld)) {
|
||||||
|
page = NULL; // failed to extend
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mi_assert_internal(page == NULL || mi_page_immediate_available(page));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
|
|
|
@ -182,7 +182,9 @@ static bool mi_page_not_in_queue(const mi_page_t* page, mi_segments_tld_t* tld)
|
||||||
|
|
||||||
static void mi_segment_protect_range(void* p, size_t size, bool protect) {
|
static void mi_segment_protect_range(void* p, size_t size, bool protect) {
|
||||||
if (protect) {
|
if (protect) {
|
||||||
_mi_os_protect(p, size);
|
if (!_mi_os_protect(p, size)) {
|
||||||
|
_mi_error_message(EFAULT,"unable to protect segment memory at %p\n", p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_mi_os_unprotect(p, size);
|
_mi_os_unprotect(p, size);
|
||||||
|
|
Loading…
Add table
Reference in a new issue