update guarded implementation to use block tags

This commit is contained in:
daanx 2024-11-16 21:15:50 -08:00
parent 0e76fe3798
commit 498c92e348
11 changed files with 161 additions and 108 deletions

View file

@ -368,6 +368,8 @@ typedef enum mi_option_e {
mi_option_visit_abandoned, // allow visiting heap blocks from abandoned threads (=0)
mi_option_debug_guarded_min, // only used when building with MI_DEBUG_GUARDED: minimal rounded object size for guarded objects (=0)
mi_option_debug_guarded_max, // only used when building with MI_DEBUG_GUARDED: maximal rounded object size for guarded objects (=0)
mi_option_debug_guarded_precise, // disregard minimal alignment requirement to always place guarded blocks exactly in front of a guard page (=0)
mi_option_debug_guarded_sample_rate, // 1 out of N allocations in the min/max range will be guarded (=1000)
_mi_option_last,
// legacy option names
mi_option_large_os_pages = mi_option_allow_large_os_pages,

View file

@ -600,16 +600,25 @@ static inline void mi_page_set_has_aligned(mi_page_t* page, bool has_aligned) {
page->flags.x.has_aligned = has_aligned;
}
/* -------------------------------------------------------------------
Guarded objects
------------------------------------------------------------------- */
#if MI_DEBUG_GUARDED
static inline bool mi_page_has_guarded(const mi_page_t* page) {
return page->flags.x.has_guarded;
static inline bool mi_block_ptr_is_guarded(const mi_block_t* block, const void* p) {
const ptrdiff_t offset = (uint8_t*)p - (uint8_t*)block;
return (offset >= (ptrdiff_t)(sizeof(mi_block_t)) && block->next == MI_BLOCK_TAG_GUARDED);
}
static inline void mi_page_set_has_guarded(mi_page_t* page, bool has_guarded) {
page->flags.x.has_guarded = has_guarded;
static inline bool mi_heap_malloc_use_guarded(mi_heap_t* heap, size_t size) {
MI_UNUSED(heap);
return (size <= (size_t)_mi_option_get_fast(mi_option_debug_guarded_max)
&& size >= (size_t)_mi_option_get_fast(mi_option_debug_guarded_min));
}
mi_decl_restrict void* _mi_heap_malloc_guarded(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept;
#endif
/* -------------------------------------------------------------------
Encoding/Decoding the free list next pointers

View file

@ -232,6 +232,13 @@ typedef struct mi_block_s {
mi_encoded_t next;
} mi_block_t;
#if MI_DEBUG_GUARDED
// we always align guarded pointers in a block at an offset
// the block `next` field is then used as a tag to distinguish regular offset aligned blocks from guarded ones
#define MI_BLOCK_TAG_ALIGNED ((mi_encoded_t)(0))
#define MI_BLOCK_TAG_GUARDED (~MI_BLOCK_TAG_ALIGNED)
#endif
// The delayed flags are used for efficient multi-threaded free-ing
typedef enum mi_delayed_e {