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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9baa4046b7324aa14d7df67a9c32668c9e1c1a0c564abf495908eea750e5c356
4
- data.tar.gz: 44c02aa89d8e75e75870b3bb2d38358e23c6fc020e556f47e04ef1552336126b
3
+ metadata.gz: 176a12a8f629c5fb15d2144517c36e947264e3685d4540efe4bf38e9f2f00a96
4
+ data.tar.gz: 1c4353f4bf6e204bb9cb2b0d2739936165475e2431c42d638c0890265ce772e3
5
5
  SHA512:
6
- metadata.gz: 8401924f89670cfce2ead2b2fa8acdb19c1b19c9a24fe58011cce61ad91aa1c4abbb6b145641bd4d85bb3f88dcb970c58ce17ac6b037ba2974752f5965a20f22
7
- data.tar.gz: 0c9abea17244e949fcb1aba1f694b830efce64ed3ed99e8f04ddd875e638afa32f98e90bc955a5a2a96d9c3618aa9e4d6c01114455d67453bc1cd3a862e42b20
6
+ metadata.gz: 809a55eda78a8aa6c5b019df4b29c1dab823634185354ed16c56d177c3ac38d140a886aeaf9837db901f2071fd76dbb3f0706a579621ce021af2afacbeb810a4
7
+ data.tar.gz: a1309ca0c777b427769821a05f3451652776fee93f8667f11492af70562b728e1509d9c5edf6a8c0e9457835d442cf13055cd3fb5d909c1abb3900b2b0829e0a
checksums.yaml.gz.sig CHANGED
Binary file
@@ -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 rb_add_event_hook. Fires on every new source line.
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 rb_sourcefile() pointer comparison as an O(1) same-file sentinel.
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(rb_event_flag_t event, VALUE data, VALUE self, ID method_id, VALUE klass)
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
- uintptr_t current_path_pointer = (uintptr_t)rb_sourcefile();
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
- if (path_cstr) {
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
- 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();
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
- if (!NIL_P(iseq)) {
258
- counts = Ruby_Coverage_Tracer_invoke_callback(tracer, path, iseq);
257
+ if (!NIL_P(iseq)) {
258
+ counts = Ruby_Coverage_Tracer_invoke_callback(tracer, path, iseq);
259
259
 
260
- if (!NIL_P(counts)) {
261
- rb_hash_aset(tracer->counts, path, counts);
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 = rb_sourceline();
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
- while (RARRAY_LEN(tracer->last_counts) <= line) {
277
- rb_ary_push(tracer->last_counts, Qnil);
275
+ if (RARRAY_LEN(tracer->last_counts) <= line) {
276
+ rb_ary_resize(tracer->last_counts, line + 1);
278
277
  }
279
278
 
280
- VALUE current = rb_ary_entry(tracer->last_counts, line);
281
- rb_ary_store(tracer->last_counts, line,
282
- NIL_P(current) ? INT2FIX(1) : INT2FIX(FIX2INT(current) + 1));
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
- rb_add_event_hook(Ruby_Coverage_Tracer_on_line, RUBY_EVENT_LINE, self);
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);
@@ -7,6 +7,6 @@
7
7
  module Ruby
8
8
  # @namespace
9
9
  module Coverage
10
- VERSION = "0.0.2"
10
+ VERSION = "0.1.0"
11
11
  end
12
12
  end
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 do |path, iseq|
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 do |path, iseq|
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
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-coverage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
metadata.gz.sig CHANGED
Binary file