Expose GC.config[:implementation], to query the currently active GC

And a default and readonly key to the GC.config hash that names the
current GC implementation.

This is provided by each implementation by the API function
rb_gc_impl_active_gc_name
This commit is contained in:
Matt Valentine-House 2024-10-08 12:16:14 +01:00
Родитель 8a4ce4e9a9
Коммит fa10441981
3 изменённых файлов: 37 добавлений и 3 удалений

19
gc.c
Просмотреть файл

@ -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;
@ -785,6 +787,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
@ -864,6 +868,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;
@ -2761,6 +2767,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)
@ -3489,7 +3501,10 @@ gc_stat_heap(rb_execution_context_t *ec, VALUE self, VALUE heap_name, VALUE arg)
static VALUE
gc_config_get(rb_execution_context_t *ec, VALUE self)
{
return rb_gc_impl_config_get(rb_gc_get_objspace());
VALUE cfg_hash = rb_gc_impl_config_get(rb_gc_get_objspace());
rb_hash_aset(cfg_hash, sym("implementation"), rb_fstring_cstr(rb_gc_impl_active_gc_name()));
return cfg_hash;
}
static VALUE
@ -3582,8 +3597,6 @@ gc_disable(rb_execution_context_t *ec, VALUE _)
return rb_gc_disable();
}
// TODO: think about moving ruby_gc_set_params into Init_heap or Init_gc
void
ruby_gc_set_params(void)

Просмотреть файл

@ -6156,6 +6156,12 @@ rb_gc_impl_copy_attributes(void *objspace_ptr, VALUE dest, VALUE obj)
rb_gc_impl_copy_finalizer(objspace, dest, obj);
}
const char *
rb_gc_impl_active_gc_name(void)
{
return "default";
}
void
rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj)
{

Просмотреть файл

@ -117,6 +117,21 @@ class TestGc < Test::Unit::TestCase
GC.start
end
def test_gc_config_implementation
omit unless /darwin|linux/.match(RUBY_PLATFORM)
gc_name = (ENV['RUBY_GC_LIBRARY'] || "default")
assert_equal gc_name, GC.config[:implementation]
end
def test_gc_config_implementation_is_readonly
omit unless /darwin|linux/.match(RUBY_PLATFORM)
impl = GC.config[:implementation]
GC.config(implementation: "somethingelse")
assert_equal(impl, GC.config[:implementation])
end
def test_start_full_mark
return unless use_rgengc?
omit 'stress' if GC.stress