summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Valentine-House <[email protected]>2024-10-08 12:16:14 +0100
committerMatt Valentine-House <[email protected]>2024-11-14 10:46:36 +0000
commitfa10441981c89deec914ba243360b40c5aede6ed (patch)
tree7ccc18e86359840d8ccac77c92f26f6f2f52f054
parent8a4ce4e9a9245c67f5b2b3c360c1400a16ad2c58 (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.c19
-rw-r--r--gc/default.c6
-rw-r--r--test/ruby/test_gc.rb15
3 files changed, 37 insertions, 3 deletions
diff --git a/gc.c b/gc.c
index 0adef25312..2033bdecd4 100644
--- a/gc.c
+++ b/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)
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