From 5d221fa17630caf8ab4f7237314ba84e998bf793 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Mon, 15 Jun 2026 09:24:14 +1200 Subject: [PATCH] Resize coverage count arrays in one step --- ext/ruby/coverage/tracer.c | 4 ++-- test/ruby/coverage/tracer.rb | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ext/ruby/coverage/tracer.c b/ext/ruby/coverage/tracer.c index 46a29ab..ad39177 100644 --- a/ext/ruby/coverage/tracer.c +++ b/ext/ruby/coverage/tracer.c @@ -273,8 +273,8 @@ static void Ruby_Coverage_Tracer_on_line(rb_event_flag_t event, VALUE data, VALU // Counts are 1-indexed: index 0 is unused (nil), index N is the hit count // for source line N. Grow the array if necessary. - while (RARRAY_LEN(tracer->last_counts) <= line) { - rb_ary_push(tracer->last_counts, Qnil); + if (RARRAY_LEN(tracer->last_counts) <= line) { + rb_ary_resize(tracer->last_counts, line + 1); } VALUE current = rb_ary_entry(tracer->last_counts, line); diff --git a/test/ruby/coverage/tracer.rb b/test/ruby/coverage/tracer.rb index b7228ad..fb4ed72 100644 --- a/test/ruby/coverage/tracer.rb +++ b/test/ruby/coverage/tracer.rb @@ -112,6 +112,23 @@ def around expect(counts[1]).to be == 2 end + it "resizes count arrays for sparse high line numbers" do + files = {} + tracer = Ruby::Coverage::Tracer.new{|path, iseq| files[path] ||= []} + + tracer.start + + path = "/tmp/ruby_coverage_tracer_sparse.rb" + line = 100 + Module.new.module_eval("x = 1", path, line) + + tracer.stop + + counts = files[path] + expect(counts).not.to be_nil + expect(counts[line]).to be == 1 + end + it "returns nil from the callback to skip tracking a file" do files = {} tracer = Ruby::Coverage::Tracer.new{|path, iseq| nil}