summaryrefslogtreecommitdiff
path: root/src
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
parentd6901558cdfa218ce49471b323d5b617a451ce04 (diff)
PR#66 by kickunderscore to ensure consistent small block alignment
Diffstat (limited to 'src')
-rw-r--r--src/os.c1
-rw-r--r--src/page.c6
-rw-r--r--src/segment.c25
3 files changed, 21 insertions, 11 deletions
diff --git a/src/os.c b/src/os.c
index 386a00e..e2c3c4a 100644
--- a/src/os.c
+++ b/src/os.c
@@ -216,6 +216,7 @@ static void* mi_mmap_aligned(size_t size, size_t alignment, mi_stats_t* stats) {
UNUSED(size);
UNUSED(alignment);
#endif
+ UNUSED(stats);
mi_assert(p == NULL || (uintptr_t)p % alignment == 0);
if (p != NULL) mi_stat_increase(stats->mmap_calls, 1);
return p;
diff --git a/src/page.c b/src/page.c
index 73fc593..b9ab14c 100644
--- a/src/page.c
+++ b/src/page.c
@@ -76,7 +76,7 @@ static bool mi_page_is_valid_init(mi_page_t* page) {
mi_segment_t* segment = _mi_page_segment(page);
uint8_t* start = _mi_page_start(segment,page,NULL);
- mi_assert_internal(start == _mi_segment_page_start(segment,page,NULL));
+ mi_assert_internal(start == _mi_segment_page_start(segment,page,page->block_size,NULL));
//mi_assert_internal(start + page->capacity*page->block_size == page->top);
mi_assert_internal(mi_page_list_is_valid(page,page->free));
@@ -514,11 +514,11 @@ static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t block_size, mi
mi_assert(page != NULL);
mi_segment_t* segment = _mi_page_segment(page);
mi_assert(segment != NULL);
+ mi_assert_internal(block_size > 0);
// set fields
size_t page_size;
- _mi_segment_page_start(segment, page, &page_size);
+ _mi_segment_page_start(segment, page, block_size, &page_size);
page->block_size = block_size;
- mi_assert_internal(block_size>0);
mi_assert_internal(page_size / block_size < (1L<<16));
page->reserved = (uint16_t)(page_size / block_size);
page->cookie = _mi_heap_random(heap) | 1;
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) {