diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc index 802b7008f9..9d3f64acb3 100644 --- a/tests/test_cpp.cc +++ b/tests/test_cpp.cc @@ -952,6 +952,31 @@ void TestArena() { } } +void TestInlinedArena() { + int n = 100000; + + struct Decrementer { + Decrementer(int* _p) : p(_p) {} + ~Decrementer() { (*p)--; } + int* p; + }; + + { + upb::InlinedArena<1024> arena; + for (int i = 0; i < n; i++) { + arena.Own(new Decrementer(&n)); + + // Intersperse allocation and ensure we can write to it. + int* val = static_cast(upb_arena_malloc(arena.ptr(), sizeof(int))); + *val = i; + } + + // Test a large allocation. + upb_arena_malloc(arena.ptr(), 1000000); + } + ASSERT(n == 0); +} + extern "C" { int run_tests() { diff --git a/upb/upb.hpp b/upb/upb.hpp index a3ec5faff8..b7b99761fb 100644 --- a/upb/upb.hpp +++ b/upb/upb.hpp @@ -41,6 +41,9 @@ class Arena { public: // A simple arena with no initial memory block and the default allocator. Arena() : ptr_(upb_arena_new(), upb_arena_free) {} + Arena(char *initial_block, size_t size) + : ptr_(upb_arena_init(initial_block, size, &upb_alloc_global), + upb_arena_free) {} upb_arena* ptr() { return ptr_.get(); } @@ -71,15 +74,12 @@ class Arena { template class InlinedArena : public Arena { public: - InlinedArena() : ptr_(upb_arena_new(&initial_block_, N, &upb_alloc_global)) {} - - upb_arena* ptr() { return ptr_.get(); } + InlinedArena() : Arena(initial_block_, N) {} private: InlinedArena(const InlinedArena*) = delete; InlinedArena& operator=(const InlinedArena*) = delete; - std::unique_ptr ptr_; char initial_block_[N]; };