/home/travis/build/MoarVM/MoarVM/src/profiler/heapsnapshot.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* A collection of heap snapshots, with common type and static frame names. |
2 | | * Note that we take care to never refer to heap objects themselves in here, |
3 | | * including for types and frames, since to do so would extend their lifetime |
4 | | * for the whole program, which would render the results pretty bogus. */ |
5 | | struct MVMHeapSnapshotCollection { |
6 | | /* List of taken snapshots. */ |
7 | | MVMHeapSnapshot *snapshots; |
8 | | MVMuint64 num_snapshots; |
9 | | MVMuint64 alloc_snapshots; |
10 | | |
11 | | /* Known types/REPRs. Just a list for now, but we might like to look at a |
12 | | * hash or trie if this ends up making taking a snapshot wicked slow. */ |
13 | | MVMHeapSnapshotType *types; |
14 | | MVMuint64 num_types; |
15 | | MVMuint64 alloc_types; |
16 | | |
17 | | /* Known static frames. Same applies to searching this as to the above. */ |
18 | | MVMHeapSnapshotStaticFrame *static_frames; |
19 | | MVMuint64 num_static_frames; |
20 | | MVMuint64 alloc_static_frames; |
21 | | |
22 | | /* Strings, referenced by index from various places. Also a "should we |
23 | | * free it" flag for each one. */ |
24 | | char **strings; |
25 | | MVMuint64 num_strings; |
26 | | MVMuint64 alloc_strings; |
27 | | char *strings_free; |
28 | | MVMuint64 num_strings_free; |
29 | | MVMuint64 alloc_strings_free; |
30 | | }; |
31 | | |
32 | | /* An individual heap snapshot. */ |
33 | | struct MVMHeapSnapshot { |
34 | | /* Array of data about collectables on the heap. */ |
35 | | MVMHeapSnapshotCollectable *collectables; |
36 | | MVMuint64 num_collectables; |
37 | | MVMuint64 alloc_collectables; |
38 | | |
39 | | /* References. */ |
40 | | MVMHeapSnapshotReference *references; |
41 | | MVMuint64 num_references; |
42 | | MVMuint64 alloc_references; |
43 | | }; |
44 | | |
45 | | /* An object/type object/STable type in the snapshot. */ |
46 | | struct MVMHeapSnapshotType { |
47 | | /* String heap index of the REPR name. */ |
48 | | MVMuint64 repr_name; |
49 | | |
50 | | /* String heap index of the type's debug name. */ |
51 | | MVMuint64 type_name; |
52 | | }; |
53 | | |
54 | | /* A static frame in the snapshot. */ |
55 | | struct MVMHeapSnapshotStaticFrame { |
56 | | /* The static frame name; index into the snapshot collection string heap. */ |
57 | | MVMuint64 name; |
58 | | |
59 | | /* The static frame compilation unit ID, for added uniqueness checking. |
60 | | * Also an index into the string heap. */ |
61 | | MVMuint64 cuid; |
62 | | |
63 | | /* The line number where it's declared. */ |
64 | | MVMuint64 line; |
65 | | |
66 | | /* And the filename; also an index into snapshot collection string heap. */ |
67 | | MVMuint64 file; |
68 | | }; |
69 | | |
70 | | /* Kinds of collectable, plus a few "virtual" kinds to cover the various places |
71 | | * we find roots. MVM_SNAPSHOT_COL_KIND_ROOT is the ultimate root of the heap |
72 | | * snapshot and everything hangs off it. */ |
73 | 0 | #define MVM_SNAPSHOT_COL_KIND_OBJECT 1 |
74 | 0 | #define MVM_SNAPSHOT_COL_KIND_TYPE_OBJECT 2 |
75 | 0 | #define MVM_SNAPSHOT_COL_KIND_STABLE 3 |
76 | 0 | #define MVM_SNAPSHOT_COL_KIND_FRAME 4 |
77 | 0 | #define MVM_SNAPSHOT_COL_KIND_PERM_ROOTS 5 |
78 | 0 | #define MVM_SNAPSHOT_COL_KIND_INSTANCE_ROOTS 6 |
79 | 0 | #define MVM_SNAPSHOT_COL_KIND_CSTACK_ROOTS 7 |
80 | 0 | #define MVM_SNAPSHOT_COL_KIND_THREAD_ROOTS 8 |
81 | 0 | #define MVM_SNAPSHOT_COL_KIND_ROOT 9 |
82 | 0 | #define MVM_SNAPSHOT_COL_KIND_INTERGEN_ROOTS 10 |
83 | 0 | #define MVM_SNAPSHOT_COL_KIND_CALLSTACK_ROOTS 11 |
84 | | |
85 | | /* Data about an individual collectable in the heap snapshot. Ordered to avoid |
86 | | * holes. */ |
87 | | struct MVMHeapSnapshotCollectable { |
88 | | /* What kind of collectable is it? */ |
89 | | MVMuint16 kind; |
90 | | |
91 | | /* Self-size (from the collectable header). */ |
92 | | MVMuint16 collectable_size; |
93 | | |
94 | | /* Index into the snapshot collection type name or frame info array, |
95 | | * depending on kind. */ |
96 | | MVMuint32 type_or_frame_index; |
97 | | |
98 | | /* The number of other collectables this one references. */ |
99 | | MVMuint32 num_refs; |
100 | | |
101 | | /* Index into the references info list. */ |
102 | | MVMuint64 refs_start; |
103 | | |
104 | | /* Unmanaged size (memory held but not under the GC's contorl). */ |
105 | | MVMuint64 unmanaged_size; |
106 | | }; |
107 | | |
108 | | /* Reference identifier kinds. */ |
109 | 0 | #define MVM_SNAPSHOT_REF_KIND_UNKNOWN 0 |
110 | 0 | #define MVM_SNAPSHOT_REF_KIND_INDEX 1 |
111 | 0 | #define MVM_SNAPSHOT_REF_KIND_STRING 2 |
112 | | |
113 | | /* Number of bits needed for ref kind. */ |
114 | 0 | #define MVM_SNAPSHOT_REF_KIND_BITS 2 |
115 | | |
116 | | /* A reference from one collectable to another. */ |
117 | | struct MVMHeapSnapshotReference { |
118 | | /* The lower MVM_SNAPSHOT_REF_KIND_BITS bits indicate the type of reference. |
119 | | * After shifting those away, we either have a numeric index (e.g. for |
120 | | * array indexes) or an index into the string heap (for lexicals in frames |
121 | | * and attributes in objects). If kind is MVM_SNAPSHOT_REF_KIND_UNKNOWN the |
122 | | * rest of the bits will be zero; we know nothing of the relationship. */ |
123 | | MVMuint64 description; |
124 | | |
125 | | /* The index of the collectable referenced. */ |
126 | | MVMuint64 collectable_index; |
127 | | }; |
128 | | |
129 | | /* Current state object whlie taking a heap snapshot. */ |
130 | | struct MVMHeapSnapshotState { |
131 | | /* The heap snapshot collection and current working snapshot. */ |
132 | | MVMHeapSnapshotCollection *col; |
133 | | MVMHeapSnapshot *hs; |
134 | | |
135 | | /* Our current collectable worklist. */ |
136 | | MVMHeapSnapshotWorkItem *workitems; |
137 | | MVMuint64 num_workitems; |
138 | | MVMuint64 alloc_workitems; |
139 | | |
140 | | /* The collectable we're currently adding references for. */ |
141 | | MVMuint64 ref_from; |
142 | | |
143 | | /* The seen hash of collectables (including frames). */ |
144 | | MVMHeapSnapshotSeen *seen; |
145 | | |
146 | | /* We sometimes use GC mark functions to find references. Keep a worklist |
147 | | * around for those times (much cheaper than allocating it whenever we |
148 | | * need it). */ |
149 | | MVMGCWorklist *gcwl; |
150 | | }; |
151 | | |
152 | | /* Work item used while taking a heap snapshot. */ |
153 | | struct MVMHeapSnapshotWorkItem { |
154 | | /* The kind of collectable. */ |
155 | | MVMuint16 kind; |
156 | | |
157 | | /* Index in the collectables (assigned upon adding to the worklist). */ |
158 | | MVMuint64 col_idx; |
159 | | |
160 | | /* Target collectable, if any. */ |
161 | | void *target; |
162 | | }; |
163 | | |
164 | | /* Heap seen hash entry used while taking a heap snapshot. */ |
165 | | struct MVMHeapSnapshotSeen { |
166 | | /* The seen address. */ |
167 | | void *address; |
168 | | |
169 | | /* The collectables index it has. */ |
170 | | MVMuint64 idx; |
171 | | |
172 | | /* Hash handle. */ |
173 | | UT_hash_handle hash_handle; |
174 | | }; |
175 | | |
176 | | MVMint32 MVM_profile_heap_profiling(MVMThreadContext *tc); |
177 | | void MVM_profile_heap_start(MVMThreadContext *tc, MVMObject *config); |
178 | | void MVM_profile_heap_take_snapshot(MVMThreadContext *tc); |
179 | | MVMObject * MVM_profile_heap_end(MVMThreadContext *tc); |
180 | | |
181 | | /* API for things that want to contribute more detailed data to the heap |
182 | | * profile. */ |
183 | | MVM_PUBLIC void MVM_profile_heap_add_collectable_rel_const_cstr(MVMThreadContext *tc, |
184 | | MVMHeapSnapshotState *ss, MVMCollectable *collectable, char *desc); |
185 | | MVM_PUBLIC void MVM_profile_heap_add_collectable_rel_vm_str(MVMThreadContext *tc, |
186 | | MVMHeapSnapshotState *ss, MVMCollectable *collectable, MVMString *desc); |
187 | | MVM_PUBLIC void MVM_profile_heap_add_collectable_rel_idx(MVMThreadContext *tc, |
188 | | MVMHeapSnapshotState *ss, MVMCollectable *collectable, MVMuint64 idx); |