Coverage Report

Created: 2018-07-03 15:31

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