-
Notifications
You must be signed in to change notification settings - Fork 610
/
write_barrier.hpp
95 lines (77 loc) · 3.4 KB
/
write_barrier.hpp
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
#ifndef RBX_GC_WRITE_BARRIER_HPP
#define RBX_GC_WRITE_BARRIER_HPP
#include "util/thread.hpp"
namespace rubinius {
class Object;
namespace gc {
/**
* A write barrier keeps track of objects in the mature generation that hold
* references to objects in the young generation.
*
* A write barrier allows the young generation to be garbage collected without
* inspecting every object in the older generations (mature and large object)
* to determine if a young object is still referenced (i.e. alive). As most
* cross-generation references are from young objects to mature ones,
* remembering the rarer instances when a mature object has a reference to a
* young object results in a smaller set of objects to scan when collecting
* the young generation.
*
* The set of locations containing pointers to young generation objects is
* known as the remembered set. At every store, the system must ensure that
* the updated location is added to the remembered set if the store creates
* a reference from an older generation object to a young generation object.
*
* The remembered set is cleared on each collection of the young generation
* (via #swap_remember_set), as scanning objects that were in the remember set
* as part of the young collection will re-remember mature objects that
* continue to hold a reference to (still) young objects.
*
* Additionally, when a full collection is performed, any mature objects
* that die are removed from the remember set (via #unremember_object and
* #unremember_objects), ensuring they do not keep alive young objects they
* reference.
*/
class WriteBarrier {
/// Lock for synchronising multi-threaded updates to the remember set
utilities::thread::SpinLock lock_;
protected:
/// Holds a list of remembered Object instances in the mature generation
/// that contain one or more references to young generation objects.
ObjectArray* remember_set_;
public:
/**
* Returns the current remembered set of mature objects.
* The returned ObjectArray* is const, since it should not be modified other
* than via the remember/unremember methods.
*/
ObjectArray* const remember_set() {
return remember_set_;
}
WriteBarrier();
~WriteBarrier();
/**
* Checks if the store is creating a reference from a mature generation
* object (target) to a young generation object (val). If it is, target
* (i.e. the mature object) is added to the remember set.
*
* @param target The object holding the reference (i.e. the referer).
* @param val The object being referenced (i.e. the referee).
*/
void write_barrier(ObjectHeader* target, ObjectHeader* val) {
if(target->remembered_p()) return;
if(!val->reference_p()) return;
if(target->young_object_p()) return;
if(!val->young_object_p()) return;
remember_object(reinterpret_cast<Object*>(target));
}
// Adds the target object directly to the remembered set.
void remember_object(Object* target);
// Removes the mature Object +target+ from the remembered set.
void unremember_object(Object* target);
// Removes objects from the remember set that do not have the specified mark.
int unremember_objects(unsigned int mark);
// Returns the current remember set, and replaces it with a new, empty one.
ObjectArray* swap_remember_set();
};
}}
#endif