split out the alloc code from the arena code

PiperOrigin-RevId: 456531002
pull/13171/head
Protobuf Team Bot 3 years ago committed by Copybara-Service
parent d2177912c7
commit 7b05f25b98
  1. 3
      BUILD
  2. 47
      upb/alloc.c
  3. 98
      upb/alloc.h
  4. 23
      upb/arena.c
  5. 63
      upb/arena.h
  6. 5
      upb/port_def.inc

@ -102,6 +102,7 @@ cc_library(
cc_library(
name = "upb",
srcs = [
"upb/alloc.c",
"upb/arena.c",
"upb/decode.c",
"upb/encode.c",
@ -115,6 +116,7 @@ cc_library(
"upb/upb.c",
],
hdrs = [
"upb/alloc.h",
"upb/arena.h",
"upb/decode.h",
"upb/encode.h",
@ -707,6 +709,7 @@ sh_test(
cc_library(
name = "table",
hdrs = [
"upb/alloc.h",
"upb/arena.h",
"upb/internal/table.h",
"upb/status.h",

@ -0,0 +1,47 @@
/*
* Copyright (c) 2009-2021, Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "upb/alloc.h"
#include <stdlib.h>
// Must be last.
#include "upb/port_def.inc"
static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize,
size_t size) {
UPB_UNUSED(alloc);
UPB_UNUSED(oldsize);
if (size == 0) {
free(ptr);
return NULL;
} else {
return realloc(ptr, size);
}
}
upb_alloc upb_alloc_global = {&upb_global_allocfunc};

@ -0,0 +1,98 @@
/*
* Copyright (c) 2009-2021, Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UPB_ALLOC_H_
#define UPB_ALLOC_H_
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
struct upb_alloc;
typedef struct upb_alloc upb_alloc;
/* A combined `malloc()`/`free()` function.
* If `size` is 0 then the function acts like `free()`, otherwise it acts like
* `realloc()`. Only `oldsize` bytes from a previous allocation are
* preserved. */
typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize,
size_t size);
/* A upb_alloc is a possibly-stateful allocator object.
*
* It could either be an arena allocator (which doesn't require individual
* `free()` calls) or a regular `malloc()` (which does). The client must
* therefore free memory unless it knows that the allocator is an arena
* allocator. */
struct upb_alloc {
upb_alloc_func* func;
};
UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) {
UPB_ASSERT(alloc);
return alloc->func(alloc, NULL, 0, size);
}
UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize,
size_t size) {
UPB_ASSERT(alloc);
return alloc->func(alloc, ptr, oldsize, size);
}
UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) {
UPB_ASSERT(alloc);
alloc->func(alloc, ptr, 0, 0);
}
/* The global allocator used by upb. Uses the standard malloc()/free(). */
extern upb_alloc upb_alloc_global;
/* Functions that hard-code the global malloc.
*
* We still get benefit because we can put custom logic into our global
* allocator, like injecting out-of-memory faults in debug/testing builds. */
UPB_INLINE void* upb_gmalloc(size_t size) {
return upb_malloc(&upb_alloc_global, size);
}
UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, size_t size) {
return upb_realloc(&upb_alloc_global, ptr, oldsize, size);
}
UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); }
#include "upb/port_undef.inc"
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_ALLOC_H_ */

@ -27,27 +27,12 @@
#include "upb/arena.h"
#include <stdlib.h>
#include "upb/alloc.h"
#include "upb/internal/upb.h"
// Must be last.
#include "upb/port_def.inc"
/* upb_alloc ******************************************************************/
static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize,
size_t size) {
UPB_UNUSED(alloc);
UPB_UNUSED(oldsize);
if (size == 0) {
free(ptr);
return NULL;
} else {
return realloc(ptr, size);
}
}
static uint32_t* upb_cleanup_pointer(uintptr_t cleanup_metadata) {
return (uint32_t*)(cleanup_metadata & ~0x1);
}
@ -61,10 +46,6 @@ static uintptr_t upb_cleanup_metadata(uint32_t* cleanup,
return (uintptr_t)cleanup | has_initial_block;
}
upb_alloc upb_alloc_global = {&upb_global_allocfunc};
/* upb_Arena ******************************************************************/
struct mem_block {
struct mem_block* next;
uint32_t size;
@ -135,7 +116,7 @@ static void* upb_Arena_doalloc(upb_alloc* alloc, void* ptr, size_t oldsize,
/* Public Arena API ***********************************************************/
upb_Arena* arena_initslow(void* mem, size_t n, upb_alloc* alloc) {
static upb_Arena* arena_initslow(void* mem, size_t n, upb_alloc* alloc) {
const size_t first_block_overhead = sizeof(upb_Arena) + memblock_reserve;
upb_Arena* a;

@ -28,75 +28,18 @@
#ifndef UPB_ARENA_H_
#define UPB_ARENA_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "upb/alloc.h"
// Must be last.
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
/** upb_alloc *****************************************************************/
/* A upb_alloc is a possibly-stateful allocator object.
*
* It could either be an arena allocator (which doesn't require individual
* free() calls) or a regular malloc() (which does). The client must therefore
* free memory unless it knows that the allocator is an arena allocator. */
struct upb_alloc;
typedef struct upb_alloc upb_alloc;
/* A malloc()/free() function.
* If "size" is 0 then the function acts like free(), otherwise it acts like
* realloc(). Only "oldsize" bytes from a previous allocation are preserved. */
typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize,
size_t size);
struct upb_alloc {
upb_alloc_func* func;
};
UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) {
UPB_ASSERT(alloc);
return alloc->func(alloc, NULL, 0, size);
}
UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize,
size_t size) {
UPB_ASSERT(alloc);
return alloc->func(alloc, ptr, oldsize, size);
}
UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) {
assert(alloc);
alloc->func(alloc, ptr, 0, 0);
}
/* The global allocator used by upb. Uses the standard malloc()/free(). */
extern upb_alloc upb_alloc_global;
/* Functions that hard-code the global malloc.
*
* We still get benefit because we can put custom logic into our global
* allocator, like injecting out-of-memory faults in debug/testing builds. */
UPB_INLINE void* upb_gmalloc(size_t size) {
return upb_malloc(&upb_alloc_global, size);
}
UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, size_t size) {
return upb_realloc(&upb_alloc_global, ptr, oldsize, size);
}
UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); }
/* upb_Arena ******************************************************************/
/* upb_Arena is a specific allocator implementation that uses arena allocation.
* The user provides an allocator that will be used to allocate the underlying
* arena blocks. Arenas by nature do not require the individual allocations

@ -54,8 +54,11 @@
#error upb requires C99 or C++11 or MSVC >= 2015.
#endif
#include <stdint.h>
#include <assert.h>
#include <setjmp.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#if UINTPTR_MAX == 0xffffffff
#define UPB_SIZE(size32, size64) size32

Loading…
Cancel
Save