Merge pull request #411 from haberman/align-arena

Align arena initial block to ensure allocations are aligned.
pull/13171/head
Joshua Haberman 3 years ago committed by GitHub
commit 7b960dddfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      tests/test_generated_code.c
  2. 8
      upb/upb.c

@ -532,6 +532,23 @@ void test_arena_decode(void) {
upb_arena_free(tmp);
}
void test_arena_unaligned(void) {
char buf1[1024];
// Force the pointer to be unaligned.
char *unaligned_buf_ptr = (char*)((uintptr_t)buf1 | 7);
upb_arena *arena = upb_arena_init(
unaligned_buf_ptr, &buf1[sizeof(buf1)] - unaligned_buf_ptr, NULL);
char *mem = upb_arena_malloc(arena, 5);
ASSERT(((uintptr_t)mem & 15) == 0);
upb_arena_free(arena);
// Try the same, but with a size so small that aligning up will overflow.
arena = upb_arena_init(unaligned_buf_ptr, 5, &upb_alloc_global);
mem = upb_arena_malloc(arena, 5);
ASSERT(((uintptr_t)mem & 15) == 0);
upb_arena_free(arena);
}
int run_tests(int argc, char *argv[]) {
test_scalars();
test_utf8();
@ -544,5 +561,6 @@ int run_tests(int argc, char *argv[]) {
test_arena_fuse();
test_arena_fuse_with_initial_block();
test_arena_decode();
test_arena_unaligned();
return 0;
}

@ -210,6 +210,14 @@ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) {
upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) {
upb_arena *a;
if (n) {
/* Align initial pointer up so that we return properly-aligned pointers. */
void *aligned = (void*)UPB_ALIGN_UP((uintptr_t)mem, 16);
size_t delta = (uintptr_t)aligned - (uintptr_t)mem;
n = delta <= n ? n - delta : 0;
mem = aligned;
}
/* Round block size down to alignof(*a) since we will allocate the arena
* itself at the end. */
n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_arena));

Loading…
Cancel
Save