/
gc.cpp
64 lines (52 loc) · 1.67 KB
/
gc.cpp
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
/* The GC superclass methods, used by both GCs. */
#include "gc.hpp"
#include "objectmemory.hpp"
namespace rubinius {
ObjectMark::ObjectMark(GarbageCollector* gc) : gc(gc) { }
OBJECT ObjectMark::call(OBJECT obj) {
if(obj->reference_p()) {
return gc->saw_object(obj);
}
return NULL;
}
void ObjectMark::set(OBJECT target, OBJECT* pos, OBJECT val) {
*pos = val;
if(val->reference_p()) {
gc->object_memory->write_barrier(target, val);
}
}
void ObjectMark::just_set(OBJECT target, OBJECT val) {
if(val->reference_p()) {
gc->object_memory->write_barrier(target, val);
}
}
GarbageCollector::GarbageCollector(ObjectMemory *om)
:object_memory(om) { }
/* Understands how to read the inside of an object and find all references
* located within. It copies the objects pointed to, but does not follow into
* those further (ie, not recursive) */
void GarbageCollector::scan_object(OBJECT obj) {
OBJECT slot;
if(obj->klass && obj->klass->reference_p()) {
slot = saw_object(obj->klass);
if(slot) object_memory->set_class(obj, slot);
}
TypeInfo* ti = object_memory->type_info[obj->obj_type];
if(ti) {
ObjectMark mark(this);
ti->mark(obj, mark);
} else if(obj->stores_references_p()) {
for(size_t i = 0; i < obj->field_count; i++) {
slot = obj->field[i];
if(slot->reference_p()) {
slot = saw_object(slot);
if(slot) object_memory->store_object(obj, i, slot);
}
}
}
}
void GarbageCollector::delete_object(OBJECT obj) {
TypeInfo *ti = object_memory->find_type_info(obj);
if(ti) ti->cleanup(obj);
}
}