| 410 | ----------------------------------------------------------- */ |
| 411 | |
| 412 | static void mi_segment_commit_mask(mi_segment_t* segment, bool conservative, uint8_t* p, size_t size, uint8_t** start_p, size_t* full_size, mi_commit_mask_t* cm) { |
| 413 | mi_assert_internal(_mi_ptr_segment(p + 1) == segment); |
| 414 | mi_assert_internal(segment->kind != MI_SEGMENT_HUGE); |
| 415 | mi_commit_mask_create_empty(cm); |
| 416 | if (size == 0 || size > MI_SEGMENT_SIZE || segment->kind == MI_SEGMENT_HUGE) return; |
| 417 | const size_t segstart = mi_segment_info_size(segment); |
| 418 | const size_t segsize = mi_segment_size(segment); |
| 419 | if (p >= (uint8_t*)segment + segsize) return; |
| 420 | |
| 421 | size_t pstart = (p - (uint8_t*)segment); |
| 422 | mi_assert_internal(pstart + size <= segsize); |
| 423 | |
| 424 | size_t start; |
| 425 | size_t end; |
| 426 | if (conservative) { |
| 427 | // decommit conservative |
| 428 | start = _mi_align_up(pstart, MI_COMMIT_SIZE); |
| 429 | end = _mi_align_down(pstart + size, MI_COMMIT_SIZE); |
| 430 | mi_assert_internal(start >= segstart); |
| 431 | mi_assert_internal(end <= segsize); |
| 432 | } |
| 433 | else { |
| 434 | // commit liberal |
| 435 | start = _mi_align_down(pstart, MI_MINIMAL_COMMIT_SIZE); |
| 436 | end = _mi_align_up(pstart + size, MI_MINIMAL_COMMIT_SIZE); |
| 437 | } |
| 438 | if (pstart >= segstart && start < segstart) { // note: the mask is also calculated for an initial commit of the info area |
| 439 | start = segstart; |
| 440 | } |
| 441 | if (end > segsize) { |
| 442 | end = segsize; |
| 443 | } |
| 444 | |
| 445 | mi_assert_internal(start <= pstart && (pstart + size) <= end); |
| 446 | mi_assert_internal(start % MI_COMMIT_SIZE==0 && end % MI_COMMIT_SIZE == 0); |
| 447 | *start_p = (uint8_t*)segment + start; |
| 448 | *full_size = (end > start ? end - start : 0); |
| 449 | if (*full_size == 0) return; |
| 450 | |
| 451 | size_t bitidx = start / MI_COMMIT_SIZE; |
| 452 | mi_assert_internal(bitidx < MI_COMMIT_MASK_BITS); |
| 453 | |
| 454 | size_t bitcount = *full_size / MI_COMMIT_SIZE; // can be 0 |
| 455 | if (bitidx + bitcount > MI_COMMIT_MASK_BITS) { |
| 456 | _mi_warning_message("commit mask overflow: idx=%zu count=%zu start=%zx end=%zx p=0x%p size=%zu fullsize=%zu\n", bitidx, bitcount, start, end, p, size, *full_size); |
| 457 | } |
| 458 | mi_assert_internal((bitidx + bitcount) <= MI_COMMIT_MASK_BITS); |
| 459 | mi_commit_mask_create(bitidx, bitcount, cm); |
| 460 | } |
| 461 | |
| 462 | |
| 463 | static bool mi_segment_commitx(mi_segment_t* segment, bool commit, uint8_t* p, size_t size, mi_stats_t* stats) { |
no test coverage detected