mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Clean up GC code
This commit is contained in:
+3
-31
@@ -35,6 +35,7 @@
|
||||
#include "mrbconf.h"
|
||||
#include "mruby/common.h"
|
||||
#include "mruby/value.h"
|
||||
#include "mruby/gc.h"
|
||||
#include "mruby/version.h"
|
||||
|
||||
/**
|
||||
@@ -114,16 +115,11 @@ struct mrb_context {
|
||||
struct RFiber *fib;
|
||||
};
|
||||
|
||||
enum gc_state {
|
||||
GC_STATE_ROOT = 0,
|
||||
GC_STATE_MARK,
|
||||
GC_STATE_SWEEP
|
||||
};
|
||||
|
||||
struct mrb_jmpbuf;
|
||||
|
||||
typedef void (*mrb_atexit_func)(struct mrb_state*);
|
||||
|
||||
|
||||
typedef struct mrb_state {
|
||||
struct mrb_jmpbuf *jmp;
|
||||
|
||||
@@ -153,32 +149,8 @@ typedef struct mrb_state {
|
||||
struct RClass *symbol_class;
|
||||
struct RClass *kernel_module;
|
||||
|
||||
struct heap_page *heaps; /* heaps for GC */
|
||||
struct heap_page *sweeps;
|
||||
struct heap_page *free_heaps;
|
||||
size_t live; /* count of live objects */
|
||||
#ifdef MRB_GC_FIXED_ARENA
|
||||
struct RBasic *arena[MRB_GC_ARENA_SIZE]; /* GC protection array */
|
||||
#else
|
||||
struct RBasic **arena; /* GC protection array */
|
||||
int arena_capa;
|
||||
#endif
|
||||
int arena_idx;
|
||||
|
||||
enum gc_state gc_state; /* state of gc */
|
||||
int current_white_part; /* make white object by white_part */
|
||||
struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */
|
||||
struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */
|
||||
size_t gc_live_after_mark;
|
||||
size_t gc_threshold;
|
||||
int gc_interval_ratio;
|
||||
int gc_step_ratio;
|
||||
mrb_bool gc_disabled:1;
|
||||
mrb_bool gc_full:1;
|
||||
mrb_bool is_generational_gc_mode:1;
|
||||
mrb_bool out_of_memory:1;
|
||||
size_t majorgc_old_threshold;
|
||||
struct alloca_header *mems;
|
||||
mrb_gc gc;
|
||||
|
||||
mrb_sym symidx;
|
||||
struct kh_n2s *name2sym; /* symbol hash */
|
||||
|
||||
+62
-3
@@ -14,9 +14,68 @@
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
typedef void (mrb_each_object_callback)(mrb_state *mrb, struct RBasic *obj, void *data);
|
||||
void mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data);
|
||||
MRB_API void mrb_free_context(mrb_state *mrb, struct mrb_context *c);
|
||||
|
||||
struct mrb_state;
|
||||
|
||||
typedef void (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data);
|
||||
void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data);
|
||||
MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c);
|
||||
|
||||
|
||||
/* white: 011, black: 100, gray: 000 */
|
||||
#define MRB_GC_GRAY 0
|
||||
#define MRB_GC_WHITE_A 1
|
||||
#define MRB_GC_WHITE_B (1 << 1)
|
||||
#define MRB_GC_BLACK (1 << 2)
|
||||
#define MRB_GC_WHITES (MRB_GC_WHITE_A | MRB_GC_WHITE_B)
|
||||
#define MRB_GC_COLOR_MASK 7
|
||||
|
||||
typedef enum {
|
||||
GC_STATE_ROOT = 0,
|
||||
GC_STATE_MARK,
|
||||
GC_STATE_SWEEP
|
||||
} mrb_gc_state;
|
||||
|
||||
typedef struct mrb_heap_page {
|
||||
struct RBasic *freelist;
|
||||
struct mrb_heap_page *prev;
|
||||
struct mrb_heap_page *next;
|
||||
struct mrb_heap_page *free_next;
|
||||
struct mrb_heap_page *free_prev;
|
||||
mrb_bool old:1;
|
||||
void *objects[];
|
||||
} mrb_heap_page;
|
||||
|
||||
typedef struct mrb_gc {
|
||||
mrb_heap_page *heaps; /* heaps for GC */
|
||||
mrb_heap_page *sweeps;
|
||||
mrb_heap_page *free_heaps;
|
||||
size_t live; /* count of live objects */
|
||||
#ifdef MRB_GC_FIXED_ARENA
|
||||
struct RBasic *arena[MRB_GC_ARENA_SIZE]; /* GC protection array */
|
||||
#else
|
||||
struct RBasic **arena; /* GC protection array */
|
||||
int arena_capa;
|
||||
#endif
|
||||
int arena_idx;
|
||||
|
||||
mrb_gc_state gc_state; /* state of gc */
|
||||
int current_white_part; /* make white object by white_part */
|
||||
struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */
|
||||
struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */
|
||||
size_t gc_live_after_mark;
|
||||
size_t gc_threshold;
|
||||
int gc_interval_ratio;
|
||||
int gc_step_ratio;
|
||||
mrb_bool disabled :1;
|
||||
mrb_bool full :1;
|
||||
mrb_bool generational :1;
|
||||
mrb_bool out_of_memory :1;
|
||||
size_t majorgc_old_threshold;
|
||||
} mrb_gc;
|
||||
|
||||
MRB_API mrb_bool
|
||||
mrb_object_dead_p(struct mrb_state *mrb, struct RObject *object);
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
|
||||
@@ -16,24 +16,6 @@
|
||||
|
||||
#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & flag)
|
||||
|
||||
/* white: 011, black: 100, gray: 000 */
|
||||
#define MRB_GC_GRAY 0
|
||||
#define MRB_GC_WHITE_A 1
|
||||
#define MRB_GC_WHITE_B (1 << 1)
|
||||
#define MRB_GC_BLACK (1 << 2)
|
||||
#define MRB_GC_WHITES (MRB_GC_WHITE_A | MRB_GC_WHITE_B)
|
||||
#define MRB_GC_COLOR_MASK 7
|
||||
|
||||
#define paint_gray(o) ((o)->color = MRB_GC_GRAY)
|
||||
#define paint_black(o) ((o)->color = MRB_GC_BLACK)
|
||||
#define paint_white(o) ((o)->color = MRB_GC_WHITES)
|
||||
#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part)
|
||||
#define is_gray(o) ((o)->color == MRB_GC_GRAY)
|
||||
#define is_white(o) ((o)->color & MRB_GC_WHITES)
|
||||
#define is_black(o) ((o)->color & MRB_GC_BLACK)
|
||||
#define is_dead(s, o) (((o)->color & other_white_part(s) & MRB_GC_WHITES) || (o)->tt == MRB_TT_FREE)
|
||||
#define flip_white_part(s) ((s)->current_white_part = other_white_part(s))
|
||||
#define other_white_part(s) ((s)->current_white_part ^ MRB_GC_WHITES)
|
||||
|
||||
struct RBasic {
|
||||
MRB_OBJECT_HEADER;
|
||||
|
||||
@@ -17,7 +17,7 @@ os_count_object_type(mrb_state *mrb, struct RBasic *obj, void *data)
|
||||
|
||||
obj_count->total++;
|
||||
|
||||
if (is_dead(mrb, obj)) {
|
||||
if (mrb_object_dead_p(mrb, obj)) {
|
||||
obj_count->freed++;
|
||||
}
|
||||
else {
|
||||
@@ -115,7 +115,7 @@ os_each_object_cb(mrb_state *mrb, struct RBasic *obj, void *ud)
|
||||
struct os_each_object_data *d = (struct os_each_object_data*)ud;
|
||||
|
||||
/* filter dead objects */
|
||||
if (is_dead(mrb, obj)) {
|
||||
if (mrb_object_dead_p(mrb, obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -206,7 +206,7 @@ MRB_API mrb_noreturn void
|
||||
mrb_exc_raise(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb->exc = mrb_obj_ptr(exc);
|
||||
if (!mrb->out_of_memory) {
|
||||
if (!mrb->gc.out_of_memory) {
|
||||
exc_debug_info(mrb, mrb->exc);
|
||||
}
|
||||
if (!mrb->jmp) {
|
||||
|
||||
+5
-13
@@ -12,10 +12,12 @@
|
||||
#include "mruby/debug.h"
|
||||
#include "mruby/string.h"
|
||||
|
||||
void mrb_init_heap(mrb_state*);
|
||||
void mrb_init_core(mrb_state*);
|
||||
void mrb_init_mrbgems(mrb_state*);
|
||||
|
||||
void mrb_gc_init(mrb_state*, mrb_gc *gc);
|
||||
void mrb_gc_destroy(mrb_state*, mrb_gc *gc);
|
||||
|
||||
static mrb_value
|
||||
inspect_main(mrb_state *mrb, mrb_value mod)
|
||||
{
|
||||
@@ -35,15 +37,9 @@ mrb_open_core(mrb_allocf f, void *ud)
|
||||
*mrb = mrb_state_zero;
|
||||
mrb->allocf_ud = ud;
|
||||
mrb->allocf = f;
|
||||
mrb->current_white_part = MRB_GC_WHITE_A;
|
||||
mrb->atexit_stack_len = 0;
|
||||
|
||||
#ifndef MRB_GC_FIXED_ARENA
|
||||
mrb->arena = (struct RBasic**)mrb_malloc(mrb, sizeof(struct RBasic*)*MRB_GC_ARENA_SIZE);
|
||||
mrb->arena_capa = MRB_GC_ARENA_SIZE;
|
||||
#endif
|
||||
|
||||
mrb_init_heap(mrb);
|
||||
mrb_gc_init(mrb, &mrb->gc);
|
||||
mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
|
||||
*mrb->c = mrb_context_zero;
|
||||
mrb->root_c = mrb->c;
|
||||
@@ -122,7 +118,6 @@ mrb_open_allocf(mrb_allocf f, void *ud)
|
||||
}
|
||||
|
||||
void mrb_free_symtbl(mrb_state *mrb);
|
||||
void mrb_free_heap(mrb_state *mrb);
|
||||
|
||||
void
|
||||
mrb_irep_incref(mrb_state *mrb, mrb_irep *irep)
|
||||
@@ -249,11 +244,8 @@ mrb_close(mrb_state *mrb)
|
||||
mrb_gc_free_gv(mrb);
|
||||
mrb_free_context(mrb, mrb->root_c);
|
||||
mrb_free_symtbl(mrb);
|
||||
mrb_free_heap(mrb);
|
||||
mrb_alloca_free(mrb);
|
||||
#ifndef MRB_GC_FIXED_ARENA
|
||||
mrb_free(mrb, mrb->arena);
|
||||
#endif
|
||||
mrb_gc_destroy(mrb, &mrb->gc);
|
||||
mrb_free(mrb, mrb);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ The value below allows about 60000 recursive calls in the simplest case. */
|
||||
# define DEBUG(x)
|
||||
#endif
|
||||
|
||||
#define ARENA_RESTORE(mrb,ai) (mrb)->arena_idx = (ai)
|
||||
#define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai)
|
||||
|
||||
static inline void
|
||||
stack_clear(mrb_value *from, size_t count)
|
||||
|
||||
Reference in New Issue
Block a user