improve commit chunk alignment

This commit is contained in:
daan 2022-02-05 17:23:28 -08:00
parent 8ec83f6945
commit 47f8caad4d

View file

@ -466,28 +466,35 @@ static void mi_segment_commit_mask(mi_segment_t* segment, bool conservative, uin
mi_assert_internal(segment->kind != MI_SEGMENT_HUGE); mi_assert_internal(segment->kind != MI_SEGMENT_HUGE);
mi_commit_mask_create_empty(cm); mi_commit_mask_create_empty(cm);
if (size == 0 || size > MI_SEGMENT_SIZE || segment->kind == MI_SEGMENT_HUGE) return; if (size == 0 || size > MI_SEGMENT_SIZE || segment->kind == MI_SEGMENT_HUGE) return;
const size_t segstart = mi_segment_info_size(segment);
const size_t segsize = mi_segment_size(segment); const size_t segsize = mi_segment_size(segment);
if (p >= (uint8_t*)segment + segsize) return; if (p >= (uint8_t*)segment + segsize) return;
size_t diff = (p - (uint8_t*)segment); size_t pstart = (p - (uint8_t*)segment);
mi_assert_internal(diff + size <= segsize); mi_assert_internal(pstart + size <= segsize);
size_t start; size_t start;
size_t end; size_t end;
if (conservative) { if (conservative) {
// decommit conservative // decommit conservative
start = _mi_align_up(diff, MI_COMMIT_SIZE); start = _mi_align_up(pstart, MI_COMMIT_SIZE);
end = _mi_align_down(diff + size, MI_COMMIT_SIZE); end = _mi_align_down(pstart + size, MI_COMMIT_SIZE);
mi_assert_internal(start >= segstart);
mi_assert_internal(end <= segsize);
} }
else { else {
// commit liberal // commit liberal
start = _mi_align_down(diff, MI_COMMIT_SIZE); start = _mi_align_down(pstart, MI_MINIMAL_COMMIT_SIZE);
end = _mi_align_up(diff + size, MI_MINIMAL_COMMIT_SIZE); end = _mi_align_up(pstart + size, MI_MINIMAL_COMMIT_SIZE);
}
if (start < segstart) {
start = segstart;
} }
if (end > segsize) { if (end > segsize) {
end = segsize; end = segsize;
} }
mi_assert_internal(start <= pstart && (pstart + size) <= end);
mi_assert_internal(start % MI_COMMIT_SIZE==0 && end % MI_COMMIT_SIZE == 0); mi_assert_internal(start % MI_COMMIT_SIZE==0 && end % MI_COMMIT_SIZE == 0);
*start_p = (uint8_t*)segment + start; *start_p = (uint8_t*)segment + start;
*full_size = (end > start ? end - start : 0); *full_size = (end > start ? end - start : 0);
@ -504,14 +511,19 @@ static void mi_segment_commit_mask(mi_segment_t* segment, bool conservative, uin
mi_commit_mask_create(bitidx, bitcount, cm); mi_commit_mask_create(bitidx, bitcount, cm);
} }
#define MI_COMMIT_SIZE_BATCH MiB
static bool mi_segment_commitx(mi_segment_t* segment, bool commit, uint8_t* p, size_t size, mi_stats_t* stats) { static bool mi_segment_commitx(mi_segment_t* segment, bool commit, uint8_t* p, size_t size, mi_stats_t* stats) {
mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->decommit_mask)); mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->decommit_mask));
//if (commit && size < MI_COMMIT_SIZE_BATCH && p + MI_COMMIT_SIZE_BATCH <= mi_segment_end(segment)) { // try to commit in at least MI_MINIMAL_COMMIT_SIZE sizes.
// size = MI_COMMIT_SIZE_BATCH; /*
// } if (commit && size > 0) {
const size_t csize = _mi_align_up(size, MI_MINIMAL_COMMIT_SIZE);
if (p + csize <= mi_segment_end(segment)) {
size = csize;
}
}
*/
// commit liberal, but decommit conservative // commit liberal, but decommit conservative
uint8_t* start = NULL; uint8_t* start = NULL;
size_t full_size = 0; size_t full_size = 0;
@ -569,13 +581,13 @@ static void mi_segment_perhaps_decommit(mi_segment_t* segment, uint8_t* p, size_
if (mi_commit_mask_is_empty(&mask) || full_size==0) return; if (mi_commit_mask_is_empty(&mask) || full_size==0) return;
// update delayed commit // update delayed commit
mi_assert_internal(segment->decommit_expire > 0 || mi_commit_mask_is_empty(&segment->decommit_mask));
mi_commit_mask_t cmask; mi_commit_mask_t cmask;
mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); // only decommit what is committed; span_free may try to decommit more mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); // only decommit what is committed; span_free may try to decommit more
mi_commit_mask_set(&segment->decommit_mask, &cmask); mi_commit_mask_set(&segment->decommit_mask, &cmask);
mi_msecs_t now = _mi_clock_now(); mi_msecs_t now = _mi_clock_now();
if (segment->decommit_expire == 0) { if (segment->decommit_expire == 0) {
// no previous decommits, initialize now // no previous decommits, initialize now
mi_assert_internal(mi_commit_mask_is_empty(&segment->decommit_mask));
segment->decommit_expire = now + mi_option_get(mi_option_decommit_delay); segment->decommit_expire = now + mi_option_get(mi_option_decommit_delay);
} }
else if (segment->decommit_expire <= now) { else if (segment->decommit_expire <= now) {
@ -610,6 +622,7 @@ static void mi_segment_delayed_decommit(mi_segment_t* segment, bool force, mi_st
} }
} }
mi_commit_mask_foreach_end() mi_commit_mask_foreach_end()
mi_assert_internal(mi_commit_mask_is_empty(&segment->decommit_mask));
} }
@ -893,6 +906,7 @@ static mi_segment_t* mi_segment_init(mi_segment_t* segment, size_t required, mi_
mi_assert_internal(mi_commit_mask_is_empty(&decommit_mask)); mi_assert_internal(mi_commit_mask_is_empty(&decommit_mask));
segment->decommit_expire = 0; segment->decommit_expire = 0;
mi_commit_mask_create_empty( &segment->decommit_mask ); mi_commit_mask_create_empty( &segment->decommit_mask );
mi_assert_internal(mi_commit_mask_is_empty(&segment->decommit_mask));
} }
} }