MCPcopy Create free account
hub / github.com/CppCXY/EmmyLuaCodeStyle / mi_segment_span_allocate

Function mi_segment_span_allocate

3rd/mimalloc-2.0.9/src/segment.c:676–723  ·  view source on GitHub ↗

Note: may still return NULL if committing the memory failed

Source from the content-addressed store, hash-verified

674
675// Note: may still return NULL if committing the memory failed
676static mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_index, size_t slice_count, mi_segments_tld_t* tld) {
677 mi_assert_internal(slice_index < segment->slice_entries);
678 mi_slice_t* const slice = &segment->slices[slice_index];
679 mi_assert_internal(slice->xblock_size==0 || slice->xblock_size==1);
680
681 // commit before changing the slice data
682 if (!mi_segment_ensure_committed(segment, _mi_segment_page_start_from_slice(segment, slice, 0, NULL), slice_count * MI_SEGMENT_SLICE_SIZE, tld->stats)) {
683 return NULL; // commit failed!
684 }
685
686 // convert the slices to a page
687 slice->slice_offset = 0;
688 slice->slice_count = (uint32_t)slice_count;
689 mi_assert_internal(slice->slice_count == slice_count);
690 const size_t bsize = slice_count * MI_SEGMENT_SLICE_SIZE;
691 slice->xblock_size = (uint32_t)(bsize >= MI_HUGE_BLOCK_SIZE ? MI_HUGE_BLOCK_SIZE : bsize);
692 mi_page_t* page = mi_slice_to_page(slice);
693 mi_assert_internal(mi_page_block_size(page) == bsize);
694
695 // set slice back pointers for the first MI_MAX_SLICE_OFFSET entries
696 size_t extra = slice_count-1;
697 if (extra > MI_MAX_SLICE_OFFSET) extra = MI_MAX_SLICE_OFFSET;
698 if (slice_index + extra >= segment->slice_entries) extra = segment->slice_entries - slice_index - 1; // huge objects may have more slices than avaiable entries in the segment->slices
699
700 mi_slice_t* slice_next = slice + 1;
701 for (size_t i = 1; i <= extra; i++, slice_next++) {
702 slice_next->slice_offset = (uint32_t)(sizeof(mi_slice_t)*i);
703 slice_next->slice_count = 0;
704 slice_next->xblock_size = 1;
705 }
706
707 // and also for the last one (if not set already) (the last one is needed for coalescing and for large alignments)
708 // note: the cast is needed for ubsan since the index can be larger than MI_SLICES_PER_SEGMENT for huge allocations (see #543)
709 mi_slice_t* last = slice + slice_count - 1;
710 mi_slice_t* end = (mi_slice_t*)mi_segment_slices_end(segment);
711 if (last > end) last = end;
712 if (last > slice) {
713 last->slice_offset = (uint32_t)(sizeof(mi_slice_t) * (last - slice));
714 last->slice_count = 0;
715 last->xblock_size = 1;
716 }
717
718 // and initialize the page
719 page->is_reset = false;
720 page->is_committed = true;
721 segment->used++;
722 return page;
723}
724
725static void mi_segment_slice_split(mi_segment_t* segment, mi_slice_t* slice, size_t slice_count, mi_segments_tld_t* tld) {
726 mi_assert_internal(_mi_ptr_segment(slice) == segment);

Callers 2

mi_segment_allocFunction · 0.85

Calls 5

mi_slice_to_pageFunction · 0.85
mi_page_block_sizeFunction · 0.85
mi_segment_slices_endFunction · 0.85

Tested by

no test coverage detected