mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-06 07:29:30 +03:00
add extra checks for valid pointers in the pagemap, add max_vabits and debug_commit_full_pagemap options
This commit is contained in:
parent
3a92c35270
commit
c5a2d11193
6 changed files with 33 additions and 19 deletions
|
@ -58,7 +58,9 @@
|
|||
<ClCompile Include="..\..\src\page-map.c">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\arena-meta.c" />
|
||||
<ClCompile Include="..\..\src\arena-meta.c">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\mimalloc\atomic.h">
|
||||
|
|
|
@ -58,7 +58,9 @@
|
|||
<ClCompile Include="..\..\src\page-map.c">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\arena-meta.c" />
|
||||
<ClCompile Include="..\..\src\arena-meta.c">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\bitmap.h">
|
||||
|
|
|
@ -380,7 +380,9 @@ typedef enum mi_option_e {
|
|||
mi_option_target_segments_per_thread, // experimental (=0)
|
||||
mi_option_reclaim_on_free, // allow to reclaim an abandoned segment on a free (=1)
|
||||
mi_option_full_page_retain, // retain N full pages per size class (=2)
|
||||
mi_option_max_page_candidates, // max candidate pages to consider for allocation (=4)
|
||||
mi_option_max_page_candidates, // max candidate pages to consider for allocation (=4)
|
||||
mi_option_max_vabits, // max virtual address bits to consider in user space (=48)
|
||||
mi_option_debug_commit_full_pagemap, // commit the full pagemap to catch invalid pointer uses (=0)
|
||||
_mi_option_last,
|
||||
// legacy option names
|
||||
mi_option_large_os_pages = mi_option_allow_large_os_pages,
|
||||
|
|
|
@ -459,6 +459,7 @@ static inline mi_page_t* _mi_checked_ptr_page(const void* p) {
|
|||
}
|
||||
|
||||
static inline mi_page_t* _mi_ptr_page(const void* p) {
|
||||
mi_assert_internal(p==NULL || mi_is_in_heap_region(p));
|
||||
#if MI_DEBUG || defined(__APPLE__)
|
||||
return _mi_checked_ptr_page(p);
|
||||
#else
|
||||
|
|
|
@ -160,6 +160,8 @@ static mi_option_desc_t options[_mi_option_last] =
|
|||
{ 1, UNINIT, MI_OPTION_LEGACY(reclaim_on_free, abandoned_reclaim_on_free) },// reclaim an abandoned segment on a free
|
||||
{ 2, UNINIT, MI_OPTION(full_page_retain) },
|
||||
{ 4, UNINIT, MI_OPTION(max_page_candidates) },
|
||||
{ 0, UNINIT, MI_OPTION(max_vabits) },
|
||||
{ 0, UNINIT, MI_OPTION(debug_commit_full_pagemap) },
|
||||
};
|
||||
|
||||
static void mi_option_init(mi_option_desc_t* desc);
|
||||
|
|
|
@ -20,8 +20,11 @@ static mi_bitmap_t mi_page_map_commit = { MI_ATOMIC_VAR_INIT(MI_BITMAP_DEFAULT_C
|
|||
{ 0 }, { {MI_ATOMIC_VAR_INIT(0)} }, {{{ MI_ATOMIC_VAR_INIT(0) }}} };
|
||||
|
||||
bool _mi_page_map_init(void) {
|
||||
size_t vbits = _mi_os_virtual_address_bits();
|
||||
if (vbits >= 48) vbits = 47;
|
||||
size_t vbits = (size_t)mi_option_get_clamp(mi_option_max_vabits, 0, MI_SIZE_BITS);
|
||||
if (vbits == 0) {
|
||||
vbits = _mi_os_virtual_address_bits();
|
||||
if (vbits >= 48) { vbits = 47; }
|
||||
}
|
||||
// 1 byte per block = 2 GiB for 128 TiB address space (48 bit = 256 TiB address space)
|
||||
// 64 KiB for 4 GiB address space (on 32-bit)
|
||||
mi_page_map_max_address = (void*)(MI_PU(1) << vbits);
|
||||
|
@ -30,7 +33,7 @@ bool _mi_page_map_init(void) {
|
|||
mi_page_map_entries_per_commit_bit = _mi_divide_up(page_map_size, MI_BITMAP_DEFAULT_BIT_COUNT);
|
||||
// mi_bitmap_init(&mi_page_map_commit, MI_BITMAP_MIN_BIT_COUNT, true);
|
||||
|
||||
mi_page_map_all_committed = true; // (page_map_size <= 1*MI_MiB); // _mi_os_has_overcommit(); // commit on-access on Linux systems?
|
||||
mi_page_map_all_committed = (page_map_size <= 1*MI_MiB || mi_option_is_enabled(mi_option_debug_commit_full_pagemap)); // _mi_os_has_overcommit(); // commit on-access on Linux systems?
|
||||
_mi_page_map = (uint8_t*)_mi_os_alloc_aligned(page_map_size, 1, mi_page_map_all_committed, true, &mi_page_map_memid);
|
||||
if (_mi_page_map==NULL) {
|
||||
_mi_error_message(ENOMEM, "unable to reserve virtual memory for the page map (%zu KiB)\n", page_map_size / MI_KiB);
|
||||
|
@ -52,26 +55,28 @@ bool _mi_page_map_init(void) {
|
|||
}
|
||||
|
||||
static void mi_page_map_ensure_committed(size_t idx, size_t slice_count) {
|
||||
// is the page map area that contains the page address committed?
|
||||
if (!mi_page_map_all_committed) {
|
||||
const size_t commit_bit_idx_lo = idx / mi_page_map_entries_per_commit_bit;
|
||||
const size_t commit_bit_idx_hi = (idx + slice_count - 1) / mi_page_map_entries_per_commit_bit;
|
||||
for (size_t i = commit_bit_idx_lo; i <= commit_bit_idx_hi; i++) { // per bit to avoid crossing over bitmap chunks
|
||||
if (mi_bitmap_is_clearN(&mi_page_map_commit, i, 1)) {
|
||||
// this may race, in which case we do multiple commits (which is ok)
|
||||
// is the page map area that contains the page address committed?
|
||||
// we always set the commit bits so we can track what ranges are in-use.
|
||||
// we only actually commit if the map wasn't committed fully already.
|
||||
const size_t commit_bit_idx_lo = idx / mi_page_map_entries_per_commit_bit;
|
||||
const size_t commit_bit_idx_hi = (idx + slice_count - 1) / mi_page_map_entries_per_commit_bit;
|
||||
for (size_t i = commit_bit_idx_lo; i <= commit_bit_idx_hi; i++) { // per bit to avoid crossing over bitmap chunks
|
||||
if (mi_bitmap_is_clearN(&mi_page_map_commit, i, 1)) {
|
||||
// this may race, in which case we do multiple commits (which is ok)
|
||||
if (!mi_page_map_all_committed) {
|
||||
bool is_zero;
|
||||
uint8_t* const start = _mi_page_map + (i*mi_page_map_entries_per_commit_bit);
|
||||
const size_t size = mi_page_map_entries_per_commit_bit;
|
||||
_mi_os_commit(start, size, &is_zero);
|
||||
if (!is_zero && !mi_page_map_memid.initially_zero) { _mi_memzero(start,size); }
|
||||
mi_bitmap_set(&mi_page_map_commit, i);
|
||||
if (!is_zero && !mi_page_map_memid.initially_zero) { _mi_memzero(start, size); }
|
||||
}
|
||||
mi_bitmap_set(&mi_page_map_commit, i);
|
||||
}
|
||||
#if MI_DEBUG > 0
|
||||
_mi_page_map[idx] = 0;
|
||||
_mi_page_map[idx+slice_count-1] = 0;
|
||||
#endif
|
||||
}
|
||||
#if MI_DEBUG > 0
|
||||
_mi_page_map[idx] = 0;
|
||||
_mi_page_map[idx+slice_count-1] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static size_t mi_page_map_get_idx(mi_page_t* page, uint8_t** page_start, size_t* slice_count) {
|
||||
|
|
Loading…
Add table
Reference in a new issue