[sgen] Fix block size computation for allocation size
authorVlad Brezae <brezaevlad@gmail.com>
Tue, 4 Oct 2016 11:47:51 +0000 (14:47 +0300)
committerVlad Brezae <brezaevlad@gmail.com>
Tue, 4 Oct 2016 15:18:49 +0000 (18:18 +0300)
The block size for a slot size is the minimum block size that can fit two slots. Make sure the computation accounts for the fact that even though a slot size might fit twice in the block, it still has to be allocated at aligned addresses, so it can end up using a higher block size.

Fixes 44922.

mono/sgen/sgen-internal.c

index 84ea7d4549a9b72c2179c676fc5d1dccf9a63feb..e8c0d7ab595a74fa63e86d3a8e03e087df4fd542 100644 (file)
@@ -65,12 +65,13 @@ block_size (size_t slot_size)
        static int pagesize = -1;
 
        int size;
+       size_t aligned_slot_size = SGEN_ALIGN_UP_TO (slot_size, SIZEOF_VOID_P);
 
        if (pagesize == -1)
                pagesize = mono_pagesize ();
 
        for (size = pagesize; size < LOCK_FREE_ALLOC_SB_MAX_SIZE; size <<= 1) {
-               if (slot_size * 2 <= LOCK_FREE_ALLOC_SB_USABLE_SIZE (size))
+               if (aligned_slot_size * 2 <= LOCK_FREE_ALLOC_SB_USABLE_SIZE (size))
                        return size;
        }
        return LOCK_FREE_ALLOC_SB_MAX_SIZE;
@@ -292,6 +293,9 @@ sgen_init_internal_allocator (void)
                 * so that we do not get different block sizes for sizes that should go to the same one
                 */
                g_assert (allocator_sizes [index_for_size (max_size)] == max_size);
+               g_assert (block_size (max_size) == size);
+               if (size < LOCK_FREE_ALLOC_SB_MAX_SIZE)
+                       g_assert (block_size (max_size + 1) == size << 1);
        }
 }