-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathobjspace.c
More file actions
110 lines (86 loc) · 2.65 KB
/
objspace.c
File metadata and controls
110 lines (86 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "load_so.h"
#include "st.h"
static VALUE (*rb_gc_start)();
VALUE rb_newobj() {
return rb_class_new_instance(0, NULL, rb_cObject);
}
VALUE rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree) {
NEWOBJ(data, struct RData);
OBJSETUP(data, klass, T_DATA);
data->data = datap;
data->dfree = dfree;
data->dmark = dmark;
return (VALUE)data;
}
void rb_gc_mark(VALUE ptr) {
register struct RBasic *obj;
obj = RBASIC(ptr);
if (SPECIAL_CONST_P(ptr)) return; /* special const not marked */
if (obj->flags == 0) return; /* free cell */
if (obj->flags & FL_MARK) return; /* already marked */
obj->flags |= FL_MARK;
/* TODO: objspace->heap.live_num should be incleased */
/* TODO: check stack_overflow */
/* TODO: mark ivar */
switch (BUILTIN_TYPE(obj)) {
case T_DATA:
if (RTYPEDDATA_P(obj)) {
RUBY_DATA_FUNC mark_func = RTYPEDDATA(obj)->type->function.dmark;
if (mark_func) (*mark_func)(DATA_PTR(obj));
} else {
if (RDATA(obj)->dmark) (*RDATA(obj)->dmark)(DATA_PTR(obj));
}
break;
default:
rb_raise(rb_eNotImpError, "TODO: mark %s is not implemented yet", BUILTIN_TYPE(obj));
}
}
static void gv_mark(void *ptr) {
rb_gc_mark(*(VALUE*)ptr);
}
static void gv_free(void *ptr) {
}
void rb_global_variable(VALUE *var) {
VALUE wrap, global_list = rb_eval_string("$__loadso__global_list");
wrap = rb_data_object_alloc(0, var, gv_mark, gv_free);
rb_ary_push(global_list, wrap);
}
void rb_gc_register_mark_object(VALUE obj) {
VALUE global_list = rb_eval_string("$__loadso__global_list");
rb_ary_push(global_list, obj);
}
void *ruby_xmalloc(size_t size) {
return malloc(size);
}
void *ruby_xmalloc2(size_t n, size_t size) {
return malloc(n * size);
}
void ruby_xfree(void *x) {
return free(x);
}
static int mark_keyvalue(VALUE key, VALUE value, st_data_t data) {
rb_gc_mark(key);
rb_gc_mark(value);
return ST_CONTINUE;
}
void rb_mark_hash(st_table *tbl) {
if (!tbl) return;
st_foreach(tbl, mark_keyvalue, 0);
}
int rb_during_gc(void) {
//rb_raise(rb_eNotImpError, "TODO: rb_during_gc is not implemented yet.");
return 0;
}
VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type) {
NEWOBJ(data, struct RTypedData);
/* if (klass) Check_Type(klass, T_CLASS); */
OBJSETUP(data, klass, T_DATA);
data->data = datap;
data->typed_flag = 1;
data->type = type;
return (VALUE)data;
}
void Init_ObjSpace() {
rb_eval_string("$__loadso__global_list = []");
rb_gc_start = get_method(rb_mGC, "start");
}