80 lines
3.2 KiB
C
80 lines
3.2 KiB
C
/********************************************************************
|
|
** 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
|