refine last slice setting for large alignments
This commit is contained in:
parent
562efed54d
commit
651a99b35d
@ -481,7 +481,7 @@ static inline mi_slice_t* mi_slice_first(const mi_slice_t* slice) {
|
||||
|
||||
// Get the page containing the pointer
|
||||
static inline mi_page_t* _mi_segment_page_of(const mi_segment_t* segment, const void* p) {
|
||||
mi_assert_internal(p > segment);
|
||||
mi_assert_internal(p > (void*)segment);
|
||||
ptrdiff_t diff = (uint8_t*)p - (uint8_t*)segment;
|
||||
mi_assert_internal(diff > 0 && diff <= (ptrdiff_t)MI_SEGMENT_SIZE);
|
||||
size_t idx = (size_t)diff >> MI_SEGMENT_SLICE_SHIFT;
|
||||
|
@ -174,8 +174,7 @@ typedef int32_t mi_ssize_t;
|
||||
#endif
|
||||
|
||||
// Maximum slice offset (15)
|
||||
// #define MI_MAX_SLICE_OFFSET ((MI_ALIGNMENT_MAX / MI_SEGMENT_SLICE_SIZE) - 1)
|
||||
#define MI_MAX_SLICE_OFFSET ((MI_SEGMENT_SIZE / MI_SEGMENT_SLICE_SIZE))
|
||||
#define MI_MAX_SLICE_OFFSET ((MI_ALIGNMENT_MAX / MI_SEGMENT_SLICE_SIZE) - 1)
|
||||
|
||||
// Used as a special value to encode block sizes in 32 bits.
|
||||
#define MI_HUGE_BLOCK_SIZE ((uint32_t)(2*MI_GiB))
|
||||
|
@ -277,7 +277,7 @@ static bool mi_segment_is_valid(mi_segment_t* segment, mi_segments_tld_t* tld) {
|
||||
}
|
||||
// and the last entry as well (for coalescing)
|
||||
const mi_slice_t* last = slice + slice->slice_count - 1;
|
||||
if (last > slice && last <= mi_segment_slices_end(segment)) {
|
||||
if (last > slice && last < mi_segment_slices_end(segment)) {
|
||||
mi_assert_internal(last->slice_offset == (slice->slice_count-1)*sizeof(mi_slice_t));
|
||||
mi_assert_internal(last->slice_count == 0);
|
||||
mi_assert_internal(last->xblock_size == 1);
|
||||
@ -679,7 +679,7 @@ static void mi_segment_slice_split(mi_segment_t* segment, mi_slice_t* slice, siz
|
||||
// Note: may still return NULL if committing the memory failed
|
||||
static mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_index, size_t slice_count, mi_segments_tld_t* tld) {
|
||||
mi_assert_internal(slice_index < segment->slice_entries);
|
||||
mi_slice_t* slice = &segment->slices[slice_index];
|
||||
mi_slice_t* const slice = &segment->slices[slice_index];
|
||||
mi_assert_internal(slice->xblock_size==0 || slice->xblock_size==1);
|
||||
|
||||
// commit before changing the slice data
|
||||
@ -700,22 +700,21 @@ static mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_i
|
||||
size_t extra = slice_count-1;
|
||||
if (extra > MI_MAX_SLICE_OFFSET) extra = MI_MAX_SLICE_OFFSET;
|
||||
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
|
||||
slice++;
|
||||
for (size_t i = 1; i <= extra; i++, slice++) {
|
||||
slice->slice_offset = (uint32_t)(sizeof(mi_slice_t)*i);
|
||||
slice->slice_count = 0;
|
||||
slice->xblock_size = 1;
|
||||
|
||||
mi_slice_t* slice_next = slice + 1;
|
||||
for (size_t i = 1; i <= extra; i++, slice_next++) {
|
||||
slice_next->slice_offset = (uint32_t)(sizeof(mi_slice_t)*i);
|
||||
slice_next->slice_count = 0;
|
||||
slice_next->xblock_size = 1;
|
||||
}
|
||||
|
||||
// and also for the last one (if not set already) (the last one is needed for coalescing)
|
||||
// and also for the last one (if not set already) (the last one is needed for coalescing and for large alignments)
|
||||
// note: the cast is needed for ubsan since the index can be larger than MI_SLICES_PER_SEGMENT for huge allocations (see #543)
|
||||
size_t slice_last_index = slice_index + slice_count - 1;
|
||||
if (slice_last_index >= segment->slice_entries) {
|
||||
slice_last_index = segment->slice_entries;
|
||||
}
|
||||
mi_slice_t* last = &((mi_slice_t*)segment->slices)[slice_last_index];
|
||||
if (last <= mi_segment_slices_end(segment) && last >= slice) {
|
||||
last->slice_offset = (uint32_t)(sizeof(mi_slice_t)*(slice_last_index - slice_index));
|
||||
mi_slice_t* last = slice + slice_count - 1;
|
||||
mi_slice_t* end = (mi_slice_t*)mi_segment_slices_end(segment);
|
||||
if (last > end) last = end;
|
||||
if (last > slice) {
|
||||
last->slice_offset = (uint32_t)(sizeof(mi_slice_t) * (last - slice));
|
||||
last->slice_count = 0;
|
||||
last->xblock_size = 1;
|
||||
}
|
||||
|
@ -177,10 +177,11 @@ int main(void) {
|
||||
};
|
||||
CHECK_BODY("malloc-aligned9") {
|
||||
bool ok = true;
|
||||
for (int i = 0; i < 5 && ok; i++) {
|
||||
for (int i = 0; i < 8 && ok; i++) {
|
||||
int n = (1 << i);
|
||||
void* p = mi_malloc_aligned( 2*n*MI_ALIGNMENT_MAX, n*MI_ALIGNMENT_MAX);
|
||||
ok = ((uintptr_t)p % (n*MI_ALIGNMENT_MAX)) == 0;
|
||||
size_t align = n * (MI_ALIGNMENT_MAX / 8);
|
||||
void* p = mi_malloc_aligned( 2*align, align);
|
||||
ok = ((uintptr_t)p % align) == 0;
|
||||
mi_free(p);
|
||||
}
|
||||
result = ok;
|
||||
|
Loading…
Reference in New Issue
Block a user