/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) |