/******************************************************************** ** Copyright (c) 2018-2020 Guan Wenliang ** This file is part of the Berry default interpreter. ** skiars@qq.com, https://github.com/Skiars/berry ** See Copyright Notice in the LICENSE file or at ** https://github.com/Skiars/berry/blob/master/LICENSE ********************************************************************/ #ifndef BE_GC_H #define BE_GC_H #include "be_object.h" #define gc_object(o) cast(bgcobject*, o) #define gc_cast(o, t, T) ((o) && (o)->type == (t) ? (T*)(o) : NULL) #define cast_proto(o) gc_cast(o, BE_PROTO, bproto) #define cast_closure(o) gc_cast(o, BE_CLOSURE, bclosure) #define cast_ntvclos(o) gc_cast(o, BE_NTVCLOS, bntvclos) #define cast_str(o) gc_cast(o, BE_STRING, bstring) #define cast_class(o) gc_cast(o, BE_CLASS, bclass) #define cast_instance(o) gc_cast(o, BE_INSTANCE, binstance) #define cast_map(o) gc_cast(o, BE_MAP, bmap) #define cast_list(o) gc_cast(o, BE_LIST, blist) #define cast_module(o) gc_cast(o, BE_MODULE, bmodule) #define gc_ismark(o, m) (((o)->marked & 0x03) == m) #define gc_iswhite(o) gc_ismark((o), GC_WHITE) #define gc_isgray(o) gc_ismark((o), GC_GRAY) #define gc_isdark(o) gc_ismark((o), GC_DARK) #define gc_setmark(o, m) \ if (!gc_isconst(o)) { \ (o)->marked &= ~0x03; \ (o)->marked |= (m) & 0x03; \ } #define gc_setwhite(o) gc_setmark((o), GC_WHITE) #define gc_setgray(o) gc_setmark((o), GC_GRAY) #if BE_USE_PERF_COUNTERS #define gc_setdark(o) { vm->counter_gc_kept++; gc_setmark((o), GC_DARK); } #else #define gc_setdark(o) gc_setmark((o), GC_DARK) #endif #define gc_isfixed(o) (((o)->marked & GC_FIXED) != 0) #define gc_setfixed(o) ((o)->marked |= GC_FIXED) #define gc_clearfixed(o) ((o)->marked &= ~GC_FIXED) #define gc_isconst(o) (((o)->marked & GC_CONST) != 0) #define gc_exmark(o) (((o)->marked >> 4) & 0x0F) #define gc_setexmark(o, k) ((o)->marked |= (k) << 4) #define be_isgcobj(o) (var_primetype(o) >= BE_GCOBJECT && var_primetype(o) < BE_GCOBJECT_MAX) #define be_gcnew(v, t, s) be_newgcobj((v), (t), sizeof(s)) #define set_fixed(s) bbool _was_fixed = be_gc_fix_set(vm, cast(bgcobject*, (s)), 1) #define restore_fixed(s) be_gc_fix_set(vm, cast(bgcobject*, (s)), _was_fixed); /* the GC mark uses bit4:0 of the `object->marked` field, * so other bits can be used for special flags (ex-mark). */ typedef enum { GC_WHITE = 0x00, /* unreachable object */ GC_GRAY = 0x01, /* unscanned object */ GC_DARK = 0x02, /* scanned object */ GC_FIXED = 0x04, /* disable collection mark */ GC_CONST = 0x08 /* constant object mark */ } bgcmark; void be_gc_init(bvm *vm); void be_gc_deleteall(bvm *vm); void be_gc_setsteprate(bvm *vm, int rate); void be_gc_setpause(bvm *vm, int pause); size_t be_gc_memcount(bvm *vm); bgcobject *be_newgcobj(bvm *vm, int type, size_t size); bgcobject* be_gc_newstr(bvm *vm, size_t size, int islong); void be_gc_fix(bvm *vm, bgcobject *obj); void be_gc_unfix(bvm *vm, bgcobject *obj); bbool be_gc_fix_set(bvm *vm, bgcobject *obj, bbool fix); void be_gc_collect(bvm *vm); void be_gc_auto(bvm *vm); #endif