ruby-coverage 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/ext/ruby/coverage/tracer.c +41 -27
- data/lib/ruby/coverage/version.rb +1 -1
- data/lib/ruby/coverage.rb +12 -14
- data.tar.gz.sig +0 -0
- metadata +1 -1
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 176a12a8f629c5fb15d2144517c36e947264e3685d4540efe4bf38e9f2f00a96
|
|
4
|
+
data.tar.gz: 1c4353f4bf6e204bb9cb2b0d2739936165475e2431c42d638c0890265ce772e3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 809a55eda78a8aa6c5b019df4b29c1dab823634185354ed16c56d177c3ac38d140a886aeaf9837db901f2071fd76dbb3f0706a579621ce021af2afacbeb810a4
|
|
7
|
+
data.tar.gz: a1309ca0c777b427769821a05f3451652776fee93f8667f11492af70562b728e1509d9c5edf6a8c0e9457835d442cf13055cd3fb5d909c1abb3900b2b0829e0a
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/ext/ruby/coverage/tracer.c
CHANGED
|
@@ -169,8 +169,7 @@ static VALUE Ruby_Coverage_Tracer_initialize(VALUE self)
|
|
|
169
169
|
static void Ruby_Coverage_Tracer_on_script_compiled(VALUE data, const rb_trace_arg_t *trace_arg)
|
|
170
170
|
{
|
|
171
171
|
struct Ruby_Coverage_Tracer *tracer;
|
|
172
|
-
TypedData_Get_Struct(data, struct Ruby_Coverage_Tracer,
|
|
173
|
-
&Ruby_Coverage_Tracer_type, tracer);
|
|
172
|
+
TypedData_Get_Struct(data, struct Ruby_Coverage_Tracer, &Ruby_Coverage_Tracer_type, tracer);
|
|
174
173
|
|
|
175
174
|
tracer->last_path_pointer = 0;
|
|
176
175
|
|
|
@@ -223,43 +222,43 @@ static void Ruby_Coverage_Tracer_on_script_compiled(VALUE tpval, void *data)
|
|
|
223
222
|
}
|
|
224
223
|
#endif
|
|
225
224
|
|
|
226
|
-
// Installed via
|
|
225
|
+
// Installed via rb_add_event_hook2 with RUBY_EVENT_HOOK_FLAG_RAW_ARG. Fires on
|
|
226
|
+
// every new source line.
|
|
227
227
|
//
|
|
228
|
-
// Uses
|
|
228
|
+
// Uses rb_tracearg_path() pointer comparison as an O(1) same-file sentinel.
|
|
229
229
|
// On first entry to a new file, checks if the script_compiled hook already
|
|
230
230
|
// registered a counts array. If not (file was compiled before the tracer
|
|
231
231
|
// started), falls back to rb_profile_frames to get the iseq and invokes the
|
|
232
232
|
// user callback, matching the behaviour of the script_compiled path.
|
|
233
|
-
static void Ruby_Coverage_Tracer_on_line(
|
|
233
|
+
static void Ruby_Coverage_Tracer_on_line(VALUE data, const rb_trace_arg_t *trace_arg)
|
|
234
234
|
{
|
|
235
235
|
struct Ruby_Coverage_Tracer *tracer;
|
|
236
236
|
TypedData_Get_Struct(data, struct Ruby_Coverage_Tracer, &Ruby_Coverage_Tracer_type, tracer);
|
|
237
237
|
|
|
238
238
|
if (tracer->in_callback) return;
|
|
239
239
|
|
|
240
|
-
|
|
240
|
+
VALUE path = rb_tracearg_path((rb_trace_arg_t *)trace_arg);
|
|
241
|
+
if (NIL_P(path)) return;
|
|
242
|
+
|
|
243
|
+
uintptr_t current_path_pointer = (uintptr_t)RSTRING_PTR(path);
|
|
241
244
|
|
|
242
245
|
if (tracer->last_path_pointer != current_path_pointer) {
|
|
243
246
|
tracer->last_path_pointer = current_path_pointer;
|
|
244
247
|
|
|
245
|
-
const char *path_cstr = rb_sourcefile();
|
|
246
248
|
VALUE counts = Qnil;
|
|
247
249
|
|
|
248
|
-
|
|
249
|
-
VALUE path = rb_str_new_cstr(path_cstr);
|
|
250
|
-
counts = rb_hash_lookup(tracer->counts, path);
|
|
250
|
+
counts = rb_hash_lookup(tracer->counts, path);
|
|
251
251
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
252
|
+
if (NIL_P(counts)) {
|
|
253
|
+
// File was compiled before the tracer started; inspect the current
|
|
254
|
+
// frame to recover the active instruction sequence.
|
|
255
|
+
VALUE iseq = Ruby_Coverage_Tracer_current_iseq();
|
|
256
256
|
|
|
257
|
-
|
|
258
|
-
|
|
257
|
+
if (!NIL_P(iseq)) {
|
|
258
|
+
counts = Ruby_Coverage_Tracer_invoke_callback(tracer, path, iseq);
|
|
259
259
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
260
|
+
if (!NIL_P(counts)) {
|
|
261
|
+
rb_hash_aset(tracer->counts, path, counts);
|
|
263
262
|
}
|
|
264
263
|
}
|
|
265
264
|
}
|
|
@@ -269,17 +268,27 @@ static void Ruby_Coverage_Tracer_on_line(rb_event_flag_t event, VALUE data, VALU
|
|
|
269
268
|
|
|
270
269
|
if (NIL_P(tracer->last_counts)) return;
|
|
271
270
|
|
|
272
|
-
int line =
|
|
271
|
+
int line = RB_NUM2INT(rb_tracearg_lineno((rb_trace_arg_t *)trace_arg));
|
|
273
272
|
|
|
274
273
|
// Counts are 1-indexed: index 0 is unused (nil), index N is the hit count
|
|
275
274
|
// for source line N. Grow the array if necessary.
|
|
276
|
-
|
|
277
|
-
|
|
275
|
+
if (RARRAY_LEN(tracer->last_counts) <= line) {
|
|
276
|
+
rb_ary_resize(tracer->last_counts, line + 1);
|
|
278
277
|
}
|
|
279
278
|
|
|
280
|
-
VALUE
|
|
281
|
-
|
|
282
|
-
|
|
279
|
+
VALUE *counts = RARRAY_PTR(tracer->last_counts);
|
|
280
|
+
VALUE current = counts[line];
|
|
281
|
+
|
|
282
|
+
// Store only immediate values through the raw array pointer. This avoids write-barrier issues; counters saturate at FIXNUM_MAX.
|
|
283
|
+
if (NIL_P(current)) {
|
|
284
|
+
counts[line] = RB_INT2FIX(1);
|
|
285
|
+
} else if (RB_FIXNUM_P(current)) {
|
|
286
|
+
long count = RB_FIX2LONG(current);
|
|
287
|
+
|
|
288
|
+
if (count < RUBY_FIXNUM_MAX) {
|
|
289
|
+
counts[line] = RB_LONG2FIX(count + 1);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
283
292
|
}
|
|
284
293
|
|
|
285
294
|
static VALUE Ruby_Coverage_Tracer_start(VALUE self)
|
|
@@ -304,7 +313,12 @@ static VALUE Ruby_Coverage_Tracer_start(VALUE self)
|
|
|
304
313
|
rb_tracepoint_enable(tracer->script_compiled_tracepoint);
|
|
305
314
|
#endif
|
|
306
315
|
|
|
307
|
-
|
|
316
|
+
rb_add_event_hook2(
|
|
317
|
+
(rb_event_hook_func_t)Ruby_Coverage_Tracer_on_line,
|
|
318
|
+
RUBY_EVENT_LINE,
|
|
319
|
+
self,
|
|
320
|
+
RUBY_EVENT_HOOK_FLAG_SAFE | RUBY_EVENT_HOOK_FLAG_RAW_ARG
|
|
321
|
+
);
|
|
308
322
|
|
|
309
323
|
return self;
|
|
310
324
|
}
|
|
@@ -322,7 +336,7 @@ static VALUE Ruby_Coverage_Tracer_stop(VALUE self)
|
|
|
322
336
|
}
|
|
323
337
|
#endif
|
|
324
338
|
|
|
325
|
-
rb_remove_event_hook_with_data(Ruby_Coverage_Tracer_on_line, self);
|
|
339
|
+
rb_remove_event_hook_with_data((rb_event_hook_func_t)Ruby_Coverage_Tracer_on_line, self);
|
|
326
340
|
|
|
327
341
|
tracer->last_path_pointer = 0;
|
|
328
342
|
RB_OBJ_WRITE(self, &tracer->last_counts, Qnil);
|
data/lib/ruby/coverage.rb
CHANGED
|
@@ -67,13 +67,7 @@ module Ruby
|
|
|
67
67
|
return self if @tracer
|
|
68
68
|
|
|
69
69
|
@files = {}
|
|
70
|
-
@tracer = Tracer.new
|
|
71
|
-
@files[path] ||= begin
|
|
72
|
-
counts = []
|
|
73
|
-
executable_lines(iseq).each{|line| counts[line] = 0}
|
|
74
|
-
counts
|
|
75
|
-
end
|
|
76
|
-
end
|
|
70
|
+
@tracer = Tracer.new(&method(:prepare_counts))
|
|
77
71
|
@tracer.start
|
|
78
72
|
|
|
79
73
|
self
|
|
@@ -113,18 +107,22 @@ module Ruby
|
|
|
113
107
|
elsif clear
|
|
114
108
|
@tracer&.stop
|
|
115
109
|
@files = {}
|
|
116
|
-
@tracer = Tracer.new
|
|
117
|
-
@files[path] ||= begin
|
|
118
|
-
counts = []
|
|
119
|
-
executable_lines(iseq).each{|line| counts[line] = 0}
|
|
120
|
-
counts
|
|
121
|
-
end
|
|
122
|
-
end
|
|
110
|
+
@tracer = Tracer.new(&method(:prepare_counts))
|
|
123
111
|
@tracer.start
|
|
124
112
|
end
|
|
125
113
|
|
|
126
114
|
result
|
|
127
115
|
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def prepare_counts(path, iseq)
|
|
120
|
+
@files[path] ||= begin
|
|
121
|
+
counts = []
|
|
122
|
+
executable_lines(iseq).each{|line| counts[line] = 0}
|
|
123
|
+
counts
|
|
124
|
+
end
|
|
125
|
+
end
|
|
128
126
|
end
|
|
129
127
|
end
|
|
130
128
|
end
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
metadata.gz.sig
CHANGED
|
Binary file
|