Round up allocation size to avoid misalignment (issue #226)
Before this change, requesting a large initial allocation could cause the backing store to grow to an unaligned size. Since memory inside vector_downward is relative to the end of the buffer, this then caused all memory in the buffer to be misaligned and also misaligns any further loads and stores. Misaligned loads and stores are undefined behavior and don't work in environments such as emscripten (a JavaScript to C++ compiler).
This commit is contained in:
parent
185b9f9792
commit
47aab78233
|
@ -416,7 +416,10 @@ class vector_downward {
|
||||||
uint8_t *make_space(size_t len) {
|
uint8_t *make_space(size_t len) {
|
||||||
if (len > static_cast<size_t>(cur_ - buf_)) {
|
if (len > static_cast<size_t>(cur_ - buf_)) {
|
||||||
auto old_size = size();
|
auto old_size = size();
|
||||||
|
auto largest_align = AlignOf<largest_scalar_t>();
|
||||||
reserved_ += std::max(len, growth_policy(reserved_));
|
reserved_ += std::max(len, growth_policy(reserved_));
|
||||||
|
// Round up to avoid undefined behavior from unaligned loads and stores.
|
||||||
|
reserved_ = (reserved_ + (largest_align - 1)) & ~(largest_align - 1);
|
||||||
auto new_buf = allocator_.allocate(reserved_);
|
auto new_buf = allocator_.allocate(reserved_);
|
||||||
auto new_cur = new_buf + reserved_ - old_size;
|
auto new_cur = new_buf + reserved_ - old_size;
|
||||||
memcpy(new_cur, cur_, old_size);
|
memcpy(new_cur, cur_, old_size);
|
||||||
|
|
Loading…
Reference in New Issue