nestlevel: Fix user data alignment #3883
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We need to align the user data properly not to trigger undefined behavior, which even apparently crashes on SPARC.
As
NestingLevels::levels
is actually a single allocation for all levels and their user data mapped as[NL0|UD0|NL1|UD1|...]
(where NL is a NestingLevel, and UD a user data), we need to align twice, as we need everyNL*
and everyUD*
to align properly.Here we align everything to
2*sizeof(size_t)
, which is a logic borrowed from GLib, which seems to have borrowed the value from glibc. This is pretty conservative in our case, because actuallyNL*
s only need aligning toint
's requirements currently, which on some architectures is 4, not 16; but it's trickier to implement (and actually impossible with the current API) as we'd need to compute the actual alignment for each level taking into account it's position in the overall memory region to still alignUD*
s to a conservative value.Also, having all NL+UD group at the same size makes things a bit simpler for debugging, I guess.
We make sure to only add alignment padding manually for cases where there's actually some user data, not to waste memory needlessly for the common case where
sizeof(UD)
is 0, and thus where we can merely align tosizeof(NL)
-- which C does for us already.Note that currently only the Ruby parser is affected, as it's the only current consumer of nesting level user data.
Fixes #3881.