More arena tests. (#279)

pull/13171/head
Joshua Haberman 5 years ago committed by GitHub
parent 16facab490
commit a1c2caeb25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      tests/bindings/lua/test_upb.lua
  2. 26
      tests/test_cpp.cc
  3. 7
      upb/upb.hpp

@ -468,16 +468,23 @@ function test_foo()
end end
function test_gc() function test_gc()
local m = test_messages_proto3.TestAllTypesProto3() local top = test_messages_proto3.TestAllTypesProto3()
local n = 1000 local n = 100
local m
for i=1,n do for i=1,n do
local tmp = m local inner = test_messages_proto3.TestAllTypesProto3()
m = test_messages_proto3.TestAllTypesProto3() m = inner
-- This will cause the arenas to fuse. But we stop referring to the child, for j=1,n do
-- so the Lua object is eligible for collection (and therefore its original local tmp = m
-- arena can be collected too). Only the fusing will keep the C mem alivd. m = test_messages_proto3.TestAllTypesProto3()
m.recursive_message = tmp -- This will cause the arenas to fuse. But we stop referring to the child,
-- so the Lua object is eligible for collection (and therefore its original
-- arena can be collected too). Only the fusing will keep the C mem alivd.
m.recursive_message = tmp
end
top.recursive_message = m
end end
collectgarbage() collectgarbage()

@ -914,6 +914,31 @@ void TestIteration() {
ASSERT(oneof_count == md.oneof_count()); ASSERT(oneof_count == md.oneof_count());
} }
void TestArena() {
int n = 100000;
struct Decrementer {
Decrementer(int* _p) : p(_p) {}
~Decrementer() { (*p)--; }
int* p;
};
{
upb::Arena 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<int*>(upb_arena_malloc(arena.ptr(), sizeof(int)));
*val = i;
}
// Test a large allocation.
upb_arena_malloc(arena.ptr(), 1000000);
}
ASSERT(n == 0);
}
extern "C" { extern "C" {
int run_tests(int argc, char *argv[]) { int run_tests(int argc, char *argv[]) {
@ -950,6 +975,7 @@ int run_tests(int argc, char *argv[]) {
TestHandlerDataDestruction(); TestHandlerDataDestruction();
TestIteration(); TestIteration();
TestArena();
return 0; return 0;
} }

@ -53,8 +53,11 @@ class Arena {
// Add a cleanup function to run when the arena is destroyed. // Add a cleanup function to run when the arena is destroyed.
// Returns false on out-of-memory. // Returns false on out-of-memory.
bool AddCleanup(void *ud, upb_cleanup_func* func) { template <class T>
return upb_arena_addcleanup(ptr_.get(), ud, func); bool Own(T *obj) {
return upb_arena_addcleanup(ptr_.get(), obj, [](void* obj) {
delete static_cast<T*>(obj);
});
} }
private: private:

Loading…
Cancel
Save