Coverage Report

Created: 2018-07-03 15:31

/home/travis/build/MoarVM/MoarVM/src/gc/roots.h
Line
Count
Source (jump to first uncovered line)
1
/* Set this flag to debug temporary root pushes/pops. */
2
#define MVM_TEMP_ROOT_DEBUG 0
3
4
/* The number of temp roots we start out with per thread (and so can rely on
5
 * always having). */
6
#define MVM_TEMP_ROOT_BASE_ALLOC 16
7
8
/* Temp root push slow-path case. */
9
MVM_PUBLIC void MVM_gc_root_temp_push_slow(MVMThreadContext *tc, MVMCollectable **obj_ref);
10
11
/* Fast-path case of pushing a root onto the per-thread temporary roots. */
12
0
MVM_STATIC_INLINE void MVM_gc_root_temp_push(MVMThreadContext *tc, MVMCollectable **obj_ref) {
13
0
    /* If debugging, ensure the root is not null. */
14
0
#ifdef MVM_TEMP_ROOT_DEBUG
15
0
    if (obj_ref == NULL)
16
0
        MVM_panic(MVM_exitcode_gcroots, "Illegal attempt to add null object address as a temporary root");
17
0
#endif
18
0
19
0
    /* If less than the number of always-allocated roots, just add. */
20
0
    if (tc->num_temproots < MVM_TEMP_ROOT_BASE_ALLOC) {
21
0
        tc->temproots[tc->num_temproots] = obj_ref;
22
0
        tc->num_temproots++;
23
0
    }
24
0
25
0
    /* Otherwise call the slow path. */
26
0
    else {
27
0
        MVM_gc_root_temp_push_slow(tc, obj_ref);
28
0
    }
29
0
}
30
31
/* Pop top root from the per-thread temporary roots stack. */
32
0
MVM_STATIC_INLINE void MVM_gc_root_temp_pop(MVMThreadContext *tc) {
33
0
#if MVM_TEMP_ROOT_DEBUG
34
0
    if (tc->num_temproots <= 0)
35
0
        MVM_panic(1, "Illegal attempt to pop empty temporary root stack");
36
0
#endif
37
0
    tc->num_temproots--;
38
0
}
39
40
/* Pop top n roots from the per-thread temporary roots stack. */
41
0
MVM_STATIC_INLINE void MVM_gc_root_temp_pop_n(MVMThreadContext *tc, MVMuint32 n) {
42
0
#if MVM_TEMP_ROOT_DEBUG
43
0
    if (tc->num_temproots < n)
44
0
        MVM_panic(MVM_exitcode_gcroots, "Illegal attempt to pop insufficiently large temporary root stack");
45
0
#endif
46
0
    tc->num_temproots -= n;
47
0
}
48
49
/* Other functions related to roots. */
50
MVM_PUBLIC void MVM_gc_root_add_permanent(MVMThreadContext *tc, MVMCollectable **obj_ref);
51
MVM_PUBLIC void MVM_gc_root_add_permanent_desc(MVMThreadContext *tc, MVMCollectable **obj_ref, char *description);
52
void MVM_gc_root_add_permanents_to_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist, MVMHeapSnapshotState *snapshot);
53
void MVM_gc_root_add_instance_roots_to_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist, MVMHeapSnapshotState *snapshot);
54
void MVM_gc_root_add_tc_roots_to_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist, MVMHeapSnapshotState *snapshot);
55
MVMuint32 MVM_gc_root_temp_mark(MVMThreadContext *tc);
56
void MVM_gc_root_temp_mark_reset(MVMThreadContext *tc, MVMuint32 mark);
57
void MVM_gc_root_temp_pop_all(MVMThreadContext *tc);
58
void MVM_gc_root_add_temps_to_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist, MVMHeapSnapshotState *snapshot);
59
void MVM_gc_root_gen2_add(MVMThreadContext *tc, MVMCollectable *c);
60
void MVM_gc_root_add_gen2s_to_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist);
61
void MVM_gc_root_add_gen2s_to_snapshot(MVMThreadContext *tc, MVMHeapSnapshotState *snapshot);
62
void MVM_gc_root_gen2_cleanup(MVMThreadContext *tc);
63
void MVM_gc_root_add_frame_roots_to_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist, MVMFrame *start_frame);
64
void MVM_gc_root_add_frame_registers_to_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist, MVMFrame *frame);
65
66
/* Macros related to rooting objects into the temporaries list, and
67
 * unrooting them afterwards. */
68
#define MVMROOT(tc, obj_ref, block) do {\
69
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref)); \
70
    block \
71
    MVM_gc_root_temp_pop(tc); \
72
 } while (0)
73
#define MVMROOT2(tc, obj_ref1, obj_ref2, block) do {\
74
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref1)); \
75
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref2)); \
76
    block \
77
    MVM_gc_root_temp_pop_n(tc, 2); \
78
 } while (0)
79
#define MVMROOT3(tc, obj_ref1, obj_ref2, obj_ref3, block) do {\
80
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref1)); \
81
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref2)); \
82
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref3)); \
83
    block \
84
    MVM_gc_root_temp_pop_n(tc, 3); \
85
 } while (0)
86
#define MVMROOT4(tc, obj_ref1, obj_ref2, obj_ref3, obj_ref4, block) do {\
87
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref1)); \
88
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref2)); \
89
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref3)); \
90
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref4)); \
91
    block \
92
    MVM_gc_root_temp_pop_n(tc, 4); \
93
 } while (0)
94
#define MVMROOT5(tc, obj_ref1, obj_ref2, obj_ref3, obj_ref4, obj_ref5, block) do {\
95
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref1)); \
96
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref2)); \
97
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref3)); \
98
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref4)); \
99
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref5)); \
100
    block \
101
    MVM_gc_root_temp_pop_n(tc, 5); \
102
 } while (0)
103
#define MVMROOT6(tc, obj_ref1, obj_ref2, obj_ref3, obj_ref4, obj_ref5, obj_ref6, block) do {\
104
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref1)); \
105
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref2)); \
106
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref3)); \
107
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref4)); \
108
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref5)); \
109
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&(obj_ref6)); \
110
    block \
111
    MVM_gc_root_temp_pop_n(tc, 6); \
112
 } while (0)