merge from dev where huge objects are now part of page queues again

This commit is contained in:
Daan Leijen 2022-11-22 21:54:58 -08:00
commit ed82aa90ea
10 changed files with 104 additions and 30 deletions

View file

@ -388,7 +388,7 @@ static void mi_segment_os_free(mi_segment_t* segment, mi_segments_tld_t* tld) {
// _mi_os_free(segment, mi_segment_size(segment), /*segment->memid,*/ tld->stats);
const size_t size = mi_segment_size(segment);
if (size != MI_SEGMENT_SIZE || segment->mem_align_offset != 0 || // only push regular segments on the cache
if (size != MI_SEGMENT_SIZE || segment->mem_align_offset != 0 || segment->kind == MI_SEGMENT_HUGE || // only push regular segments on the cache
!_mi_segment_cache_push(segment, size, segment->memid, &segment->commit_mask, &segment->decommit_mask, segment->mem_is_large, segment->mem_is_pinned, tld->os))
{
const size_t csize = _mi_commit_mask_committed_size(&segment->commit_mask, size);
@ -515,6 +515,11 @@ static bool mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_
return mi_segment_commitx(segment,true,p,size,stats);
}
static void mi_segment_decommit(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
if (!segment->allow_decommit) return;
mi_segment_commitx(segment, false, p, size, stats);
}
static void mi_segment_perhaps_decommit(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
if (!segment->allow_decommit) return;
if (mi_option_get(mi_option_decommit_delay) == 0) {
@ -1523,18 +1528,21 @@ static mi_page_t* mi_segment_huge_page_alloc(size_t size, size_t page_alignment,
if (segment == NULL || page==NULL) return NULL;
mi_assert_internal(segment->used==1);
mi_assert_internal(mi_page_block_size(page) >= size);
#if MI_HUGE_PAGE_ABANDON
segment->thread_id = 0; // huge segments are immediately abandoned
#endif
if (page_alignment > 0) {
size_t psize;
uint8_t* p = _mi_segment_page_start(segment, page, &psize);
uint8_t* aligned_p = (uint8_t*)_mi_align_up((uintptr_t)p, page_alignment);
mi_assert_internal(_mi_is_aligned(aligned_p, page_alignment));
mi_assert_internal(psize - (aligned_p - p) >= size);
if (!segment->mem_is_pinned && page->is_committed) {
// decommit the part of the page that is unused; this can be quite large (close to MI_SEGMENT_SIZE)
if (!segment->allow_decommit) {
// decommit the part of the page that is unused; this can be quite large (close to MI_SEGMENT_SIZE)
uint8_t* decommit_start = p + sizeof(mi_block_t); // for the free list
ptrdiff_t decommit_size = aligned_p - decommit_start;
_mi_os_decommit(decommit_start, decommit_size, os_tld->stats);
mi_segment_decommit(segment, decommit_start, decommit_size, &_mi_stats_main);
}
}
// for huge pages we initialize the xblock_size as we may
@ -1545,6 +1553,7 @@ static mi_page_t* mi_segment_huge_page_alloc(size_t size, size_t page_alignment,
return page;
}
#if MI_HUGE_PAGE_ABANDON
// free huge block from another thread
void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) {
// huge page segments are always abandoned and can be freed immediately by any thread
@ -1572,6 +1581,24 @@ void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block
#endif
}
#else
// reset memory of a huge block from another thread
void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) {
mi_assert_internal(segment->kind == MI_SEGMENT_HUGE);
mi_assert_internal(segment == _mi_page_segment(page));
mi_assert_internal(page->used == 1); // this is called just before the free
mi_assert_internal(page->free == NULL);
const size_t csize = mi_page_block_size(page) - sizeof(mi_block_t);
uint8_t* p = ( uint8_t*)block + sizeof(mi_block_t);
if (segment->allow_decommit) {
mi_segment_decommit(segment, p, csize, &_mi_stats_main);
}
else {
_mi_os_reset(p, csize, &_mi_stats_main);
}
}
#endif
/* -----------------------------------------------------------
Page allocation and free
----------------------------------------------------------- */