• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #ifndef UPB_MEM_ALLOC_H_
9 #define UPB_MEM_ALLOC_H_
10 
11 // Must be last.
12 #include "upb/port/def.inc"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 typedef struct upb_alloc upb_alloc;
19 
20 /* A combined `malloc()`/`free()` function.
21  * If `size` is 0 then the function acts like `free()`, otherwise it acts like
22  * `realloc()`.  Only `oldsize` bytes from a previous allocation are
23  * preserved. */
24 typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize,
25                              size_t size);
26 
27 /* A upb_alloc is a possibly-stateful allocator object.
28  *
29  * It could either be an arena allocator (which doesn't require individual
30  * `free()` calls) or a regular `malloc()` (which does).  The client must
31  * therefore free memory unless it knows that the allocator is an arena
32  * allocator. */
33 struct upb_alloc {
34   upb_alloc_func* func;
35 };
36 
upb_malloc(upb_alloc * alloc,size_t size)37 UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) {
38   UPB_ASSERT(alloc);
39   return alloc->func(alloc, NULL, 0, size);
40 }
41 
upb_realloc(upb_alloc * alloc,void * ptr,size_t oldsize,size_t size)42 UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize,
43                              size_t size) {
44   UPB_ASSERT(alloc);
45   return alloc->func(alloc, ptr, oldsize, size);
46 }
47 
upb_free(upb_alloc * alloc,void * ptr)48 UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) {
49   UPB_ASSERT(alloc);
50   alloc->func(alloc, ptr, 0, 0);
51 }
52 
53 // The global allocator used by upb. Uses the standard malloc()/free().
54 
55 extern upb_alloc upb_alloc_global;
56 
57 /* Functions that hard-code the global malloc.
58  *
59  * We still get benefit because we can put custom logic into our global
60  * allocator, like injecting out-of-memory faults in debug/testing builds. */
61 
upb_gmalloc(size_t size)62 UPB_INLINE void* upb_gmalloc(size_t size) {
63   return upb_malloc(&upb_alloc_global, size);
64 }
65 
upb_grealloc(void * ptr,size_t oldsize,size_t size)66 UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, size_t size) {
67   return upb_realloc(&upb_alloc_global, ptr, oldsize, size);
68 }
69 
upb_gfree(void * ptr)70 UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); }
71 
72 #ifdef __cplusplus
73 } /* extern "C" */
74 #endif
75 
76 #include "upb/port/undef.inc"
77 
78 #endif /* UPB_MEM_ALLOC_H_ */
79