Skip to content

Commit dee0d0f

Browse files
author
Thomas Kiley
committed
Clarify the calculation for working out the max allocation size
1 parent 5d210c3 commit dee0d0f

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

src/ansi-c/ansi_c_internal_additions.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,16 @@ static std::string architecture_string(T value, const char *s)
124124

125125
using max_alloc_sizet = uint64_t;
126126
/// The maximum allocation size is determined by the number of bits that
127-
/// are left in the pointer of width \p pointer_width after allowing for the
128-
/// signed bit, and the bits used for the objects ID (determined by
129-
/// \p object_bits).
127+
/// are left in the pointer of width \p pointer_width.
128+
///
129+
/// The allocation size cannot exceed the number represented by the (signed)
130+
/// offset, otherwise it would not be possible to store a pointer into a
131+
/// valid bit of memory. Therefore, the max allocation size is
132+
/// 2^(offset_bits - 1), where the offset bits is the number of bits left in the
133+
/// pointer after the object bits.
134+
///
135+
/// The offset must be signed, as a pointer can point to the end of the memory
136+
/// block, and needs to be able to point back to the start.
130137
/// \param pointer_width: The width of the pointer
131138
/// \param object_bits : The number of bits used to represent the ID
132139
/// \return The size in bytes of the maximum allocation supported.
@@ -136,9 +143,14 @@ max_malloc_size(std::size_t pointer_width, std::size_t object_bits)
136143
PRECONDITION(pointer_width >= 1);
137144
PRECONDITION(object_bits < pointer_width - 1);
138145
PRECONDITION(object_bits >= 1);
139-
const auto bits_for_offset = pointer_width - object_bits - 1;
140-
PRECONDITION(bits_for_offset < std::numeric_limits<max_alloc_sizet>::digits);
141-
return ((max_alloc_sizet)1) << (max_alloc_sizet)bits_for_offset;
146+
const auto offset_bits = pointer_width - object_bits;
147+
// We require the offset to be able to express upto allocation_size - 1,
148+
// but also down to -allocation_size, therefore the size is allowable
149+
// is number of bits, less the signed bit.
150+
const auto bits_for_positive_offset = offset_bits - 1;
151+
PRECONDITION(
152+
bits_for_positive_offset < std::numeric_limits<max_alloc_sizet>::digits);
153+
return ((max_alloc_sizet)1) << (max_alloc_sizet)bits_for_positive_offset;
142154
}
143155

144156
void ansi_c_internal_additions(std::string &code)

0 commit comments

Comments
 (0)