Skip to content

Commit

Permalink
Expose GC.active_gc_name, to query the currently active GC
Browse files Browse the repository at this point in the history
And internal GC API function rb_gc_active_gc_name
  • Loading branch information
eightbitraptor committed Oct 9, 2024
1 parent cb3965a commit 9b243ba
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
23 changes: 22 additions & 1 deletion gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,8 @@ typedef struct gc_function_map {
bool (*garbage_object_p)(void *objspace_ptr, VALUE obj);
void (*set_event_hook)(void *objspace_ptr, const rb_event_flag_t event);
void (*copy_attributes)(void *objspace_ptr, VALUE dest, VALUE obj);
// GC Identification
const char *(*active_gc_name)(void);
} rb_gc_function_map_t;

static rb_gc_function_map_t rb_gc_functions;
Expand Down Expand Up @@ -775,6 +777,8 @@ ruby_external_gc_init(void)
load_external_gc_func(garbage_object_p);
load_external_gc_func(set_event_hook);
load_external_gc_func(copy_attributes);
//GC Identification
load_external_gc_func(active_gc_name);

# undef load_external_gc_func

Expand Down Expand Up @@ -854,6 +858,8 @@ ruby_external_gc_init(void)
# define rb_gc_impl_garbage_object_p rb_gc_functions.garbage_object_p
# define rb_gc_impl_set_event_hook rb_gc_functions.set_event_hook
# define rb_gc_impl_copy_attributes rb_gc_functions.copy_attributes
// GC Identification
# define rb_gc_impl_active_gc_name rb_gc_functions.active_gc_name
#endif

static VALUE initial_stress = Qfalse;
Expand Down Expand Up @@ -2752,6 +2758,12 @@ rb_gc_copy_attributes(VALUE dest, VALUE obj)
rb_gc_impl_copy_attributes(rb_gc_get_objspace(), dest, obj);
}

const char *
rb_gc_active_gc_name(void)
{
return rb_gc_impl_active_gc_name();
}

// TODO: rearchitect this function to work for a generic GC
size_t
rb_obj_gc_flags(VALUE obj, ID* flags, size_t max)
Expand Down Expand Up @@ -3515,7 +3527,16 @@ gc_disable(rb_execution_context_t *ec, VALUE _)
return rb_gc_disable();
}


static VALUE
active_gc_name(rb_execution_context_t *ec, VALUE _) {
if (getenv("RUBY_GC_LIBRARY")) {
const char *name = rb_gc_active_gc_name();
return rb_fstring_new(name, strlen(name));
}
else {
return Qnil;
}
}

// TODO: think about moving ruby_gc_set_params into Init_heap or Init_gc
void
Expand Down
12 changes: 12 additions & 0 deletions gc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,18 @@ def self.total_time
ULL2NUM(rb_gc_impl_get_total_time(rb_gc_get_objspace()))
}
end

# call-seq:
# GC.active_gc_name -> string
#
# Return the configured name for the active GC module
def self.active_gc_name
# shared_gc_dir is mandatory when configuring `with-shared-gc`.
# When shared GC is not enabled it will be blank
if RbConfig::CONFIG['shared_gc_dir'].length > 0
Primitive.active_gc_name
end
end
end

module ObjectSpace
Expand Down
6 changes: 6 additions & 0 deletions gc/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -6162,6 +6162,12 @@ rb_gc_impl_copy_attributes(void *objspace_ptr, VALUE dest, VALUE obj)
rb_gc_copy_finalizer(dest, obj);
}

const char *
rb_gc_impl_active_gc_name(void)
{
return "default";
}

void
rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj)
{
Expand Down
12 changes: 12 additions & 0 deletions test/ruby/test_gc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -872,4 +872,16 @@ def test_old_to_young_reference
assert_include ObjectSpace.dump(young_obj), '"old":true'
end
end

def test_active_gc_name
omit unless /darwin|linux/.match(RUBY_PLATFORM)

gc_name = (ENV['RUBY_GC_LIBRARY'] || "").split('.')[1]

if RbConfig::CONFIG['shared_gc_dir'].length > 0
assert_equal gc_name, GC.active_gc_name
else
assert_nil GC.active_gc_name
end
end
end

0 comments on commit 9b243ba

Please sign in to comment.