add counter-based manual gc trigger for FFIBytearray

This commit is contained in:
MihailRis 2026-07-19 19:41:52 +03:00
parent 9d8d00209c
commit 8164a16db8

View file

@ -12,18 +12,34 @@ FFI.cdef[[
} bytearray_t; } bytearray_t;
]] ]]
local malloc = FFI.C.malloc
local free = FFI.C.free
local FFIBytearray local FFIBytearray
local bytearray_type local bytearray_type
local allocated_bytes = 0
local GC_THRESHOLD = 50 * 1024 * 1024
local function malloc(size)
local raw = FFI.C.malloc(size)
if raw == nil then
return nil
end
allocated_bytes = allocated_bytes + size
if allocated_bytes >= GC_THRESHOLD then
collectgarbage("step", 200)
allocated_bytes = 0
end
return FFI.gc(raw, FFI.C.free)
end
local function grow_buffer(self, elems) local function grow_buffer(self, elems)
local new_capacity = math.ceil(self.capacity / 0.75 + elems) local new_capacity = math.ceil(self.capacity / 0.75 + elems)
local prev = self.bytes local prev = self.bytes
self.bytes = malloc(new_capacity) self.bytes = malloc(new_capacity)
FFI.copy(self.bytes, prev, self.size) FFI.copy(self.bytes, prev, self.size)
self.capacity = new_capacity self.capacity = new_capacity
free(prev)
end end
local function trim_buffer(self) local function trim_buffer(self)
@ -35,7 +51,6 @@ local function trim_buffer(self)
self.bytes = malloc(size) self.bytes = malloc(size)
FFI.copy(self.bytes, prev, self.size) FFI.copy(self.bytes, prev, self.size)
self.capacity = size self.capacity = size
free(prev)
end end
local function count_elements(b) local function count_elements(b)
@ -114,7 +129,6 @@ local function reserve(self, new_capacity)
self.bytes = malloc(new_capacity) self.bytes = malloc(new_capacity)
FFI.copy(self.bytes, prev, self.size) FFI.copy(self.bytes, prev, self.size)
self.capacity = new_capacity self.capacity = new_capacity
free(prev)
end end
local function get_capacity(self) local function get_capacity(self)
@ -173,9 +187,7 @@ local bytearray_mt = {
__len = function(self) __len = function(self)
return tonumber(self.size) return tonumber(self.size)
end, end,
__gc = function(self) __gc = function(self) end,
free(self.bytes)
end,
__ipairs = function(self) __ipairs = function(self)
local i = 0 local i = 0
return function() return function()