/home/travis/build/MoarVM/MoarVM/src/spesh/stats.h
Line | Count | Source |
1 | | /* Statistics are stored per static frame. This data structure is only ever |
2 | | * read/written by the specializer thread. */ |
3 | | struct MVMSpeshStats { |
4 | | /* Statistics on a per-callsite basis. */ |
5 | | MVMSpeshStatsByCallsite *by_callsite; |
6 | | |
7 | | /* Map of MVM_SPESH_LOG_STATIC entries for this routine. Held at the top |
8 | | * level as they represent static resolutions, so no need to duplicate |
9 | | * this information across callsites. */ |
10 | | MVMSpeshStatsStatic *static_values; |
11 | | |
12 | | /* The number of entries in by_callsite. */ |
13 | | MVMuint32 num_by_callsite; |
14 | | |
15 | | /* The number of entries in static_values. */ |
16 | | MVMuint32 num_static_values; |
17 | | |
18 | | /* Total calls across all callsites. */ |
19 | | MVMuint32 hits; |
20 | | |
21 | | /* Total OSR hits across all callsites. */ |
22 | | MVMuint32 osr_hits; |
23 | | |
24 | | /* The latest version of the statistics when this was updated. Used to |
25 | | * help decide when to throw out data that is no longer evolving, to |
26 | | * reduce memory use. */ |
27 | | MVMuint32 last_update; |
28 | | }; |
29 | | |
30 | | /* Statistics by callsite. */ |
31 | | struct MVMSpeshStatsByCallsite { |
32 | | /* The callsite, or NULL for the case of no interned callsite. */ |
33 | | MVMCallsite *cs; |
34 | | |
35 | | /* Statistics aggregated by parameter type information. */ |
36 | | MVMSpeshStatsByType *by_type; |
37 | | |
38 | | /* The number of entries in by_type. Zero if cs == NULL. */ |
39 | | MVMuint32 num_by_type; |
40 | | |
41 | | /* Total calls to this callsite. */ |
42 | | MVMuint32 hits; |
43 | | |
44 | | /* Total OSR hits for this callsite. */ |
45 | | MVMuint32 osr_hits; |
46 | | |
47 | | /* The maximum callstack depth we observed this at. */ |
48 | | MVMuint32 max_depth; |
49 | | }; |
50 | | |
51 | | /* Statistics by type. */ |
52 | | struct MVMSpeshStatsByType { |
53 | | /* Argument type information. Length of this is determined by the callsite |
54 | | * of the specialization. */ |
55 | | MVMSpeshStatsType *arg_types; |
56 | | |
57 | | /* Total calls with this callsite/type combination. */ |
58 | | MVMuint32 hits; |
59 | | |
60 | | /* Total OSR hits for this callsite/type combination. */ |
61 | | MVMuint32 osr_hits; |
62 | | |
63 | | /* Logged type and logged value counts, by bytecode offset. */ |
64 | | MVMSpeshStatsByOffset *by_offset; |
65 | | |
66 | | /* Number of stats by offset we have. */ |
67 | | MVMuint32 num_by_offset; |
68 | | |
69 | | /* The maximum callstack depth we observed this at. */ |
70 | | MVMuint32 max_depth; |
71 | | }; |
72 | | |
73 | | /* Type statistics. */ |
74 | | struct MVMSpeshStatsType { |
75 | | /* The type logged. */ |
76 | | MVMObject *type; |
77 | | |
78 | | /* If applicable, and if the type is a container type, the type of the |
79 | | * value logged inside of it. */ |
80 | | MVMObject *decont_type; |
81 | | |
82 | | /* Whether the type and decont type were concrete. */ |
83 | | MVMuint8 type_concrete; |
84 | | MVMuint8 decont_type_concrete; |
85 | | |
86 | | /* If there is a container type, whether it must be rw. */ |
87 | | MVMuint8 rw_cont; |
88 | | }; |
89 | | |
90 | | /* Statistics by bytecode offset. */ |
91 | | struct MVMSpeshStatsByOffset { |
92 | | /* The bytecode offset these types/values were recorded at. */ |
93 | | MVMuint32 bytecode_offset; |
94 | | |
95 | | /* Number of types recorded, with counts. */ |
96 | | MVMuint32 num_types; |
97 | | MVMSpeshStatsTypeCount *types; |
98 | | |
99 | | /* Number of invocation targets recorded, with counts. */ |
100 | | MVMSpeshStatsInvokeCount *invokes; |
101 | | MVMuint32 num_invokes; |
102 | | |
103 | | /* Number of type tuples recorded, with counts. (Type tuples are actually |
104 | | * recorded by the callee, and then also accumulated at the callsite of |
105 | | * the caller.) */ |
106 | | MVMuint32 num_type_tuples; |
107 | | MVMSpeshStatsTypeTupleCount *type_tuples; |
108 | | |
109 | | /* Number of times spesh plugin guard indexes were recorded. */ |
110 | | MVMSpeshStatsPluginGuardCount *plugin_guards; |
111 | | MVMuint32 num_plugin_guards; |
112 | | }; |
113 | | |
114 | | /* Counts of a given type that has shown up at a bytecode offset. */ |
115 | | struct MVMSpeshStatsTypeCount { |
116 | | /* The type and its concreteness. */ |
117 | | MVMObject *type; |
118 | | MVMuint8 type_concrete; |
119 | | |
120 | | /* The number of times we've seen it. */ |
121 | | MVMuint32 count; |
122 | | }; |
123 | | |
124 | | /* Counts of a given static frame that was invoked at a bytecode offset. */ |
125 | | struct MVMSpeshStatsInvokeCount { |
126 | | /* The static frame. */ |
127 | | MVMStaticFrame *sf; |
128 | | |
129 | | /* The number of times the caller frame was also the outer frame. */ |
130 | | MVMuint32 caller_is_outer_count; |
131 | | |
132 | | /* The number of times it was resolved from a multi-dispatch. */ |
133 | | MVMuint32 was_multi_count; |
134 | | |
135 | | /* The number of times we've seen it. */ |
136 | | MVMuint32 count; |
137 | | }; |
138 | | |
139 | | /* Counts of a given type tuple has shown up at the callsite at a bytecode |
140 | | * offset. */ |
141 | | struct MVMSpeshStatsTypeTupleCount { |
142 | | /* The callsite. */ |
143 | | MVMCallsite *cs; |
144 | | |
145 | | /* The type tuple. */ |
146 | | MVMSpeshStatsType *arg_types; |
147 | | |
148 | | /* The number of times we've seen it. */ |
149 | | MVMuint32 count; |
150 | | }; |
151 | | |
152 | | /* Counts of a given spesh plugin guard index. */ |
153 | | struct MVMSpeshStatsPluginGuardCount { |
154 | | /* The guard index that the plugin resolved to. */ |
155 | | MVMuint32 guard_index; |
156 | | |
157 | | /* The number of times we've seen it. */ |
158 | | MVMuint32 count; |
159 | | }; |
160 | | |
161 | | /* Static values table entry. */ |
162 | | struct MVMSpeshStatsStatic { |
163 | | /* The value. */ |
164 | | MVMObject *value; |
165 | | |
166 | | /* The bytecode offset it was recorded at. */ |
167 | | MVMint32 bytecode_offset; |
168 | | }; |
169 | | |
170 | | /* The maximum number of spesh stats updates before we consider a frame's |
171 | | * stats out of date and throw them out. */ |
172 | 1.75M | #define MVM_SPESH_STATS_MAX_AGE 10 |
173 | | |
174 | | /* Logs are linear recordings marked with frame correlation IDs. We need to |
175 | | * simulate the call stack as part of the analysis. This is the model for the |
176 | | * stack simulation. */ |
177 | | struct MVMSpeshSimStack { |
178 | | /* Array of frames. */ |
179 | | MVMSpeshSimStackFrame *frames; |
180 | | |
181 | | /* Current frame index and allocated space. */ |
182 | | MVMuint32 used; |
183 | | MVMuint32 limit; |
184 | | |
185 | | /* Current stack depth. */ |
186 | | MVMuint32 depth; |
187 | | }; |
188 | | |
189 | | /* This is the model of a frame on the simulated stack. */ |
190 | | struct MVMSpeshSimStackFrame { |
191 | | /* The static frame. */ |
192 | | MVMStaticFrame *sf; |
193 | | |
194 | | /* Spesh stats for the stack frame. */ |
195 | | MVMSpeshStats *ss; |
196 | | |
197 | | /* Correlation ID. */ |
198 | | MVMuint32 cid; |
199 | | |
200 | | /* Callsite stats index (not pointer in case of realloc). */ |
201 | | MVMuint32 callsite_idx; |
202 | | |
203 | | /* Type stats index (not pointer in case of realloc); -1 if not yet set. |
204 | | * This is resolved once using arg_types, and then remembered, so we can |
205 | | * correlate the statistics across spesh log buffers. */ |
206 | | MVMint32 type_idx; |
207 | | |
208 | | /* Argument types logged. Sized by number of callsite flags. */ |
209 | | MVMSpeshStatsType *arg_types; |
210 | | |
211 | | /* Spesh log entries for types and values, for later processing. */ |
212 | | MVMSpeshLogEntry **offset_logs; |
213 | | MVMuint32 offset_logs_used; |
214 | | MVMuint32 offset_logs_limit; |
215 | | |
216 | | /* Type tuples observed at a given callsite offset, for later |
217 | | * processing. */ |
218 | | MVMSpeshSimCallType *call_type_info; |
219 | | MVMuint32 call_type_info_used; |
220 | | MVMuint32 call_type_info_limit; |
221 | | |
222 | | /* Number of times we crossed an OSR point. */ |
223 | | MVMuint32 osr_hits; |
224 | | |
225 | | /* The last bytecode offset and static frame seen in an invoke recording; |
226 | | * used for producing callsite type stats based on callee type tuples. */ |
227 | | MVMuint32 last_invoke_offset; |
228 | | MVMStaticFrame *last_invoke_sf; |
229 | | }; |
230 | | |
231 | | /* We associate recoded type tuples in callees with their caller's callsites. |
232 | | * This is kept as a flat view, and then folded in when the caller's sim |
233 | | * frame (see next) is popped. */ |
234 | | struct MVMSpeshSimCallType { |
235 | | MVMuint32 bytecode_offset; |
236 | | MVMCallsite *cs; |
237 | | MVMSpeshStatsType *arg_types; |
238 | | }; |
239 | | |
240 | | void MVM_spesh_stats_update(MVMThreadContext *tc, MVMSpeshLog *sl, MVMObject *sf_updated); |
241 | | void MVM_spesh_stats_cleanup(MVMThreadContext *tc, MVMObject *check_frames); |
242 | | void MVM_spesh_stats_gc_mark(MVMThreadContext *tc, MVMSpeshStats *ss, MVMGCWorklist *worklist); |
243 | | void MVM_spesh_stats_gc_describe(MVMThreadContext *tc, MVMHeapSnapshotState *snapshot, MVMSpeshStats *ss); |
244 | | void MVM_spesh_stats_destroy(MVMThreadContext *tc, MVMSpeshStats *ss); |
245 | | void MVM_spesh_sim_stack_gc_mark(MVMThreadContext *tc, MVMSpeshSimStack *sims, |
246 | | MVMGCWorklist *worklist); |
247 | | void MVM_spesh_sim_stack_gc_describe(MVMThreadContext *tc, MVMHeapSnapshotState *ss, MVMSpeshSimStack *sims); |
248 | | void MVM_spesh_sim_stack_destroy(MVMThreadContext *tc, MVMSpeshSimStack *sims); |