diff options
author | Matt Valentine-House <[email protected]> | 2024-10-08 12:16:14 +0100 |
---|---|---|
committer | Matt Valentine-House <[email protected]> | 2024-11-14 10:46:36 +0000 |
commit | fa10441981c89deec914ba243360b40c5aede6ed (patch) | |
tree | 7ccc18e86359840d8ccac77c92f26f6f2f52f054 | |
parent | 8a4ce4e9a9245c67f5b2b3c360c1400a16ad2c58 (diff) |
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
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/11872
-rw-r--r-- | gc.c | 19 | ||||
-rw-r--r-- | gc/default.c | 6 | ||||
-rw-r--r-- | test/ruby/test_gc.rb | 15 |
3 files changed, 37 insertions, 3 deletions
@@ -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) diff --git a/gc/default.c b/gc/default.c index 910526d5d4..c2620e48bb 100644 --- a/gc/default.c +++ b/gc/default.c @@ -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) { diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index f0ab0b0c1a..1eb5451b3f 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -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 |