Backport #20157 to Ruby 3.3 (#9428)

* Fix GC.measure_total_time regression

Commit 93ac7405b8 introduced a regression
where measurements would still be taken after setting
GC.measure_total_time = false.

Fixes [Bug #20157]

* Add test case for GC.measure_total_time

---------

Co-authored-by: Rian McGuire <rian@rian.id.au>
This commit is contained in:
KJ Tsanaktsidis 2024-02-01 15:33:30 +11:00 committed by GitHub
parent 2886564279
commit 920c17dc94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 33 additions and 8 deletions

16
gc.c
View file

@ -9749,10 +9749,6 @@ gc_enter_count(enum gc_enter_event event)
} }
} }
#ifndef MEASURE_GC
#define MEASURE_GC (objspace->flags.measure_gc)
#endif
static bool current_process_time(struct timespec *ts); static bool current_process_time(struct timespec *ts);
static void static void
@ -9822,37 +9818,49 @@ gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_l
RB_VM_LOCK_LEAVE_LEV(lock_lev); RB_VM_LOCK_LEAVE_LEV(lock_lev);
} }
#ifndef MEASURE_GC
#define MEASURE_GC (objspace->flags.measure_gc)
#endif
static void static void
gc_marking_enter(rb_objspace_t *objspace) gc_marking_enter(rb_objspace_t *objspace)
{ {
GC_ASSERT(during_gc != 0); GC_ASSERT(during_gc != 0);
if (MEASURE_GC) {
gc_clock_start(&objspace->profile.marking_start_time); gc_clock_start(&objspace->profile.marking_start_time);
} }
}
static void static void
gc_marking_exit(rb_objspace_t *objspace) gc_marking_exit(rb_objspace_t *objspace)
{ {
GC_ASSERT(during_gc != 0); GC_ASSERT(during_gc != 0);
if (MEASURE_GC) {
objspace->profile.marking_time_ns += gc_clock_end(&objspace->profile.marking_start_time); objspace->profile.marking_time_ns += gc_clock_end(&objspace->profile.marking_start_time);
} }
}
static void static void
gc_sweeping_enter(rb_objspace_t *objspace) gc_sweeping_enter(rb_objspace_t *objspace)
{ {
GC_ASSERT(during_gc != 0); GC_ASSERT(during_gc != 0);
if (MEASURE_GC) {
gc_clock_start(&objspace->profile.sweeping_start_time); gc_clock_start(&objspace->profile.sweeping_start_time);
} }
}
static void static void
gc_sweeping_exit(rb_objspace_t *objspace) gc_sweeping_exit(rb_objspace_t *objspace)
{ {
GC_ASSERT(during_gc != 0); GC_ASSERT(during_gc != 0);
if (MEASURE_GC) {
objspace->profile.sweeping_time_ns += gc_clock_end(&objspace->profile.sweeping_start_time); objspace->profile.sweeping_time_ns += gc_clock_end(&objspace->profile.sweeping_start_time);
} }
}
static void * static void *
gc_with_gvl(void *ptr) gc_with_gvl(void *ptr)

View file

@ -231,6 +231,23 @@ class TestGc < Test::Unit::TestCase
assert_equal stat[:total_freed_objects], stat_heap_sum[:total_freed_objects] assert_equal stat[:total_freed_objects], stat_heap_sum[:total_freed_objects]
end end
def test_measure_total_time
assert_separately([], __FILE__, __LINE__, <<~RUBY)
GC.measure_total_time = false
time_before = GC.stat(:time)
# Generate some garbage
Random.new.bytes(100 * 1024 * 1024)
GC.start
time_after = GC.stat(:time)
# If time measurement is disabled, the time stat should not change
assert_equal time_before, time_after
RUBY
end
def test_latest_gc_info def test_latest_gc_info
omit 'stress' if GC.stress omit 'stress' if GC.stress