Berry take into account `bytes()` in gc size

This commit is contained in:
Stephan Hadinger 2021-08-26 19:57:03 +02:00
parent 16fdb064c4
commit 4541438e70
3 changed files with 65 additions and 49 deletions

View File

@ -1,36 +1,37 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_bytes_map) {
{ be_const_key(dot_p, -1), be_const_var(0) },
{ be_const_key(seti, 6), be_const_func(m_set) },
{ be_const_key(get, 7), be_const_func(m_getu) },
{ be_const_key(size, 10), be_const_func(m_size) },
{ be_const_key(resize, 1), be_const_func(m_resize) },
{ be_const_key(opt_add, 22), be_const_func(m_merge) },
{ be_const_key(getbits, -1), be_const_closure(getbits_closure) },
{ be_const_key(geti, 16), be_const_func(m_geti) },
{ be_const_key(setitem, -1), be_const_func(m_setitem) },
{ be_const_key(add, -1), be_const_func(m_add) },
{ be_const_key(fromb64, -1), be_const_func(m_fromb64) },
{ be_const_key(opt_neq, -1), be_const_func(m_nequal) },
{ be_const_key(set, -1), be_const_func(m_set) },
{ be_const_key(asstring, -1), be_const_func(m_asstring) },
{ be_const_key(copy, 3), be_const_func(m_copy) },
{ be_const_key(opt_eq, 2), be_const_func(m_equal) },
{ be_const_key(tob64, -1), be_const_func(m_tob64) },
{ be_const_key(setbits, 12), be_const_closure(setbits_closure) },
{ be_const_key(_buffer, -1), be_const_func(m_buffer) },
{ be_const_key(fromstring, 0), be_const_func(m_fromstring) },
{ be_const_key(tostring, 9), be_const_func(m_tostring) },
{ be_const_key(item, 8), be_const_func(m_item) },
{ be_const_key(init, 23), be_const_func(m_init) },
{ be_const_key(deinit, -1), be_const_func(m_deinit) },
{ be_const_key(opt_connect, -1), be_const_func(m_connect) },
{ be_const_key(item, 3), be_const_func(m_item) },
{ be_const_key(seti, 22), be_const_func(m_set) },
{ be_const_key(asstring, -1), be_const_func(m_asstring) },
{ be_const_key(getbits, -1), be_const_closure(getbits_closure) },
{ be_const_key(copy, -1), be_const_func(m_copy) },
{ be_const_key(get, -1), be_const_func(m_getu) },
{ be_const_key(_buffer, -1), be_const_func(m_buffer) },
{ be_const_key(fromb64, -1), be_const_func(m_fromb64) },
{ be_const_key(add, -1), be_const_func(m_add) },
{ be_const_key(dot_p, -1), be_const_var(0) },
{ be_const_key(size, 0), be_const_func(m_size) },
{ be_const_key(tostring, -1), be_const_func(m_tostring) },
{ be_const_key(opt_add, 10), be_const_func(m_merge) },
{ be_const_key(resize, -1), be_const_func(m_resize) },
{ be_const_key(setitem, -1), be_const_func(m_setitem) },
{ be_const_key(set, -1), be_const_func(m_set) },
{ be_const_key(geti, -1), be_const_func(m_geti) },
{ be_const_key(init, -1), be_const_func(m_init) },
{ be_const_key(clear, -1), be_const_func(m_clear) },
{ be_const_key(opt_neq, 23), be_const_func(m_nequal) },
{ be_const_key(tob64, 24), be_const_func(m_tob64) },
{ be_const_key(opt_eq, -1), be_const_func(m_equal) },
{ be_const_key(fromstring, -1), be_const_func(m_fromstring) },
{ be_const_key(setbits, -1), be_const_closure(setbits_closure) },
};
static be_define_const_map(
be_class_bytes_map,
25
26
);
BE_EXPORT_VARIABLE be_define_const_class(

View File

@ -419,26 +419,17 @@ static void buf_add_hex(buf_impl* buf, const char *hex, size_t len)
/********************************************************************
** Wrapping into lib
********************************************************************/
// typedef int (*bntvfunc)(bvm*); /* native function pointer */
int free_bytes_buf(bvm* vm)
{
int argc = be_top(vm);
if (argc > 0) {
buf_impl * buf = (buf_impl*) be_tocomptr(vm, 1);
if (buf != NULL) {
be_os_free(buf);
}
}
be_return_nil(vm);
}
buf_impl * bytes_alloc(int32_t size)
buf_impl * bytes_realloc(bvm *vm, buf_impl *oldbuf, int32_t size)
{
if (size < 4) { size = 4; }
if (size > BYTES_MAX_SIZE) { size = BYTES_MAX_SIZE; }
buf_impl * next = (buf_impl*) be_os_malloc(size + BYTES_OVERHEAD);
size_t oldsize = oldbuf ? oldbuf->size + BYTES_OVERHEAD : 0;
buf_impl * next = (buf_impl*) be_realloc(vm, oldbuf, oldsize, size + BYTES_OVERHEAD); /* malloc */
next->size = size;
next->len = 0;
if (!oldbuf) {
next->len = 0; /* allocate a new buffer */
}
return next;
}
@ -467,10 +458,10 @@ static int m_init(bvm *vm)
} else if (argc > 1 && be_isstring(vm, 2)) {
hex_in = be_tostring(vm, 2);
if (hex_in) {
size = strlen(hex_in) / 2 + BYTES_HEADROOM; // allocate headroom
size = strlen(hex_in) / 2 + BYTES_HEADROOM; /* allocate headroom */
}
}
buf_impl * buf = bytes_alloc(size);
buf_impl * buf = bytes_realloc(vm, NULL, size); /* allocate new buffer */
if (!buf) {
be_throw(vm, BE_MALLOC_FAIL);
}
@ -478,22 +469,35 @@ static int m_init(bvm *vm)
if (hex_in) {
buf_add_hex(buf, hex_in, strlen(hex_in));
}
be_newcomobj(vm, buf, &free_bytes_buf);
be_pushcomptr(vm, buf);
be_setmember(vm, 1, ".p");
be_return_nil(vm);
}
/* deallocate buffer */
static int m_deinit(bvm *vm) {
{
be_getmember(vm, 1, ".p");
buf_impl * buf = be_tocomptr(vm, -1);
be_pop(vm, 1);
if (buf != NULL) {
be_realloc(vm, buf, buf->size + BYTES_OVERHEAD, 0);
}
be_pushcomptr(vm, NULL); /* push NULL pointer instead, just in case */
be_setmember(vm, 1, ".p");
be_return_nil(vm);
}
}
/* grow or shrink to the exact value */
/* stack item 1 must contain the instance */
static buf_impl * _bytes_resize(bvm *vm, buf_impl * buf, size_t new_size) {
buf_impl * new_buf = bytes_alloc(new_size);
buf_impl *new_buf = bytes_realloc(vm, buf, new_size);
if (!new_buf) {
be_throw(vm, BE_MALLOC_FAIL);
}
memmove(buf_get_buf(new_buf), buf_get_buf(buf), buf->len);
new_buf->len = buf->len;
/* replace the .p attribute */
be_newcomobj(vm, new_buf, &free_bytes_buf);
/* replace the .p attribute since address may have changed */
be_pushcomptr(vm, new_buf);
be_setmember(vm, 1, ".p");
be_pop(vm, 1); /* remove comobj from stack */
/* the old buffer will be garbage collected later */
@ -504,7 +508,13 @@ static buf_impl * _bytes_resize(bvm *vm, buf_impl * buf, size_t new_size) {
/* if grow, then add some headroom */
/* stack item 1 must contain the instance */
static buf_impl * bytes_resize(bvm *vm, buf_impl * buf, size_t new_size) {
if (buf->size >= new_size) { return buf; } /* no resize needed */
/* when resized to smaller, we introduce a new heurstic */
/* If the buffer is 64 bytes or smaller, don't shrink */
/* Shrink buffer only if target size is smaller than half the original size */
if (buf->size >= new_size) { /* enough room, consider if need to shrink */
if (buf->size <= 64) { return buf; } /* don't shrink if below 64 bytes */
if (buf->size < new_size * 2) { return buf; }
}
return _bytes_resize(vm, buf, new_size + BYTES_HEADROOM);
}
@ -1226,6 +1236,7 @@ void be_load_byteslib(bvm *vm)
{ ".p", NULL },
{ "_buffer", m_buffer },
{ "init", m_init },
{ "deinit", m_deinit },
{ "tostring", m_tostring },
{ "asstring", m_asstring },
{ "fromstring", m_fromstring },
@ -1261,6 +1272,7 @@ class be_class_bytes (scope: global, name: bytes) {
.p, var
_buffer, func(m_buffer)
init, func(m_init)
deinit, func(m_deinit)
tostring, func(m_tostring)
asstring, func(m_asstring)
fromstring, func(m_fromstring)

View File

@ -461,7 +461,10 @@ static void destruct_object(bvm *vm, bgcobject *obj)
type = be_instance_member(vm, ins, str_literal(vm, "deinit"), vm->top);
be_incrtop(vm);
if (basetype(type) == BE_FUNCTION) {
be_dofunc(vm, vm->top - 1, 1);
var_setinstance(vm->top, ins); /* push instance on stack as arg 1 */
be_incrtop(vm);
be_dofunc(vm, vm->top - 2, 1); /* warning, there shoudln't be any exception raised here, or the gc stops */
be_stackpop(vm, 1);
}
be_stackpop(vm, 1);
}