From f9b65a9e37979ab39fd1283a65ad4e1351ca6058 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Tue, 22 Aug 2017 14:37:31 +0200 Subject: [PATCH] RT 131375: Fix calculation for maximum array size We were off by elem_size - log2(elem_size). As we're calculating the number of bits available for adressing individual array elements, we have to substract the number of bits for addressing individual bytes in an array element rather than the number of bytes. For 64 bit array elements, i.e. 8 bytes, we need 3 bits for addressing individual bytes. So we lose 3 bits when adressing elements in the array. --- src/6model/reprs/VMArray.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/6model/reprs/VMArray.c b/src/6model/reprs/VMArray.c index ee727622fc..5dc48db9c0 100644 --- a/src/6model/reprs/VMArray.c +++ b/src/6model/reprs/VMArray.c @@ -1,4 +1,5 @@ #include "moar.h" +#include "limits.h" /* This representation's function pointer table. */ static const MVMREPROps VMArray_this_repr; @@ -337,10 +338,24 @@ static void set_size_internal(MVMThreadContext *tc, MVMArrayBody *body, MVMuint6 else { ssize = (n + 0x1000) & ~0xfffUL; } - if (ssize > (1UL << (8 * sizeof(size_t) - repr_data->elem_size))) - MVM_exception_throw_adhoc(tc, - "Unable to allocate an array of %"PRIu64" elements", - ssize); + { + /* Our budget is 2^( + * + * - + * ) */ + size_t const elem_addr_size = + repr_data->elem_size == 8 + ? 4 + : repr_data->elem_size == 4 + ? 3 + : repr_data->elem_size == 2 + ? 2 + : 1; + if (ssize > (1UL << (CHAR_BIT * sizeof(size_t) - elem_addr_size))) + MVM_exception_throw_adhoc(tc, + "Unable to allocate an array of %"PRIu64" elements", + ssize); + } /* now allocate the new slot buffer */ slots = (slots)