summaryrefslogtreecommitdiff
path: root/src/segment.c
diff options
context:
space:
mode:
authordaan <daan@microsoft.com>2019-07-02 08:46:50 -0700
committerdaan <daan@microsoft.com>2019-07-02 08:46:50 -0700
commitd35fc6cdc44d209fcb12d5311a91f76604d5a8b5 (patch)
tree4ba34f573dd9039d5b9f845c871a26885352c8a1 /src/segment.c
parentd6901558cdfa218ce49471b323d5b617a451ce04 (diff)
PR#66 by kickunderscore to ensure consistent small block alignment
Diffstat (limited to 'src/segment.c')
-rw-r--r--src/segment.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/segment.c b/src/segment.c
index e98eee5..27dde01 100644
--- a/src/segment.c
+++ b/src/segment.c
@@ -121,16 +121,25 @@ static void mi_segment_queue_insert_before(mi_segment_queue_t* queue, mi_segment
}
-// Start of the page available memory
-uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size)
+// Start of the page available memory; can be used on uninitialized pages (only `segment_idx` must be set)
+uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t block_size, size_t* page_size)
{
size_t psize = (segment->page_kind == MI_PAGE_HUGE ? segment->segment_size : (size_t)1 << segment->page_shift);
uint8_t* p = (uint8_t*)segment + page->segment_idx*psize;
if (page->segment_idx == 0) {
- // the first page starts after the segment info (and possible guard page)
- p += segment->segment_info_size;
- psize -= segment->segment_info_size;
+ // the first page starts after the segment info (and possible guard page)
+ p += segment->segment_info_size;
+ psize -= segment->segment_info_size;
+ // for small objects, ensure the page start is aligned with the block size (PR#66 by kickunderscore)
+ if (block_size > 0 && segment->page_kind == MI_PAGE_SMALL) {
+ size_t adjust = block_size - ((uintptr_t)p % block_size);
+ if (adjust < block_size) {
+ p += adjust;
+ psize -= adjust;
+ }
+ mi_assert_internal((uintptr_t)p % block_size == 0);
+ }
}
long secure = mi_option_get(mi_option_secure);
if (secure > 1 || (secure == 1 && page->segment_idx == segment->capacity - 1)) {
@@ -138,7 +147,7 @@ uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* pa
// secure > 1: every page has an os guard page
psize -= _mi_os_page_size();
}
-
+
if (page_size != NULL) *page_size = psize;
mi_assert_internal(_mi_ptr_page(p) == page);
mi_assert_internal(_mi_ptr_segment(p) == segment);
@@ -381,7 +390,7 @@ static mi_segment_t* mi_segment_alloc( size_t required, mi_page_kind_t page_kind
// Available memory in a page
static size_t mi_page_size(const mi_page_t* page) {
size_t psize;
- _mi_segment_page_start(_mi_page_segment(page), page, &psize);
+ _mi_page_start(_mi_page_segment(page), page, &psize);
return psize;
}
#endif
@@ -467,7 +476,7 @@ static void mi_segment_page_clear(mi_segment_t* segment, mi_page_t* page, mi_sta
// reset the page memory to reduce memory pressure?
if (!page->is_reset && mi_option_is_enabled(mi_option_page_reset)) {
size_t psize;
- uint8_t* start = _mi_segment_page_start(segment, page, &psize);
+ uint8_t* start = _mi_page_start(segment, page, &psize);
mi_stat_increase( stats->reset, psize); // for stats we assume resetting the full page
page->is_reset = true;
if (inuse > 0) {