summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common.mk1
-rw-r--r--gc.c21
-rw-r--r--internal/gc.h4
-rw-r--r--spec/ruby/command_line/dash_v_spec.rb1
-rw-r--r--spec/ruby/command_line/rubyopt_spec.rb4
-rw-r--r--test/ruby/test_rubyoptions.rb12
-rw-r--r--version.c22
7 files changed, 61 insertions, 4 deletions
diff --git a/common.mk b/common.mk
index dc34b9d190..b49e98abe2 100644
--- a/common.mk
+++ b/common.mk
@@ -19555,6 +19555,7 @@ version.$(OBJEXT): $(CCAN_DIR)/str/str.h
version.$(OBJEXT): $(hdrdir)/ruby.h
version.$(OBJEXT): $(hdrdir)/ruby/ruby.h
version.$(OBJEXT): $(hdrdir)/ruby/version.h
+version.$(OBJEXT): $(top_srcdir)/gc/gc.h
version.$(OBJEXT): $(top_srcdir)/internal/array.h
version.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
version.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h
diff --git a/gc.c b/gc.c
index 2033bdecd4..330c537578 100644
--- a/gc.c
+++ b/gc.c
@@ -562,6 +562,8 @@ rb_gc_guarded_ptr_val(volatile VALUE *ptr, VALUE val)
static const char *obj_type_name(VALUE obj);
#define RB_AMALGAMATED_DEFAULT_GC
#include "gc/default.c"
+static int external_gc_loaded = FALSE;
+
#if USE_SHARED_GC && !defined(HAVE_DLOPEN)
# error "Shared GC requires dlopen"
@@ -696,6 +698,7 @@ ruby_external_gc_init(void)
fprintf(stderr, "ruby_external_gc_init: Shared library %s cannot be opened: %s\n", gc_so_path, dlerror());
exit(1);
}
+ external_gc_loaded = TRUE;
}
rb_gc_function_map_t gc_functions;
@@ -2767,10 +2770,26 @@ rb_gc_copy_attributes(VALUE dest, VALUE obj)
rb_gc_impl_copy_attributes(rb_gc_get_objspace(), dest, obj);
}
+int
+rb_gc_external_gc_loaded_p(void) {
+ return external_gc_loaded;
+}
+
const char *
rb_gc_active_gc_name(void)
{
- return rb_gc_impl_active_gc_name();
+ const char *gc_name = rb_gc_impl_active_gc_name();
+ if (strlen(gc_name) > RB_GC_MAX_NAME_LEN) {
+ char *truncated_gc_name = ruby_xmalloc(RB_GC_MAX_NAME_LEN + 1);
+
+ rb_warn("GC module %s has a name larger than %d chars, it will be truncated\n",
+ gc_name, RB_GC_MAX_NAME_LEN);
+
+ strncpy(truncated_gc_name, gc_name, RB_GC_MAX_NAME_LEN);
+ return (const char *)truncated_gc_name;
+ }
+ return gc_name;
+
}
// TODO: rearchitect this function to work for a generic GC
diff --git a/internal/gc.h b/internal/gc.h
index 0f48916ee8..789a389947 100644
--- a/internal/gc.h
+++ b/internal/gc.h
@@ -234,6 +234,7 @@ size_t rb_gc_obj_slot_size(VALUE obj);
VALUE rb_gc_disable_no_rest(void);
+#define RB_GC_MAX_NAME_LEN 20
/* gc.c (export) */
const char *rb_objspace_data_type_name(VALUE obj);
@@ -248,6 +249,9 @@ void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR
void *ruby_sized_xrealloc2(void *ptr, size_t new_count, size_t element_size, size_t old_count) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2, 3));
void ruby_sized_xfree(void *x, size_t size);
+const char * rb_gc_active_gc_name(void);
+int rb_gc_external_gc_loaded_p(void);
+
#if USE_SHARED_GC
void ruby_load_external_gc_from_argv(int argc, char **argv);
#endif
diff --git a/spec/ruby/command_line/dash_v_spec.rb b/spec/ruby/command_line/dash_v_spec.rb
index 747db7f755..d30efa37d6 100644
--- a/spec/ruby/command_line/dash_v_spec.rb
+++ b/spec/ruby/command_line/dash_v_spec.rb
@@ -9,6 +9,7 @@ describe "The -v command line option" do
ruby_exe(nil, args: '-v').sub("+PRISM ", "").should include(RUBY_DESCRIPTION.sub("+PRISM ", ""))
end unless (defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?) ||
(defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?) ||
+ (ENV['RUBY_GC_LIBRARY'] && ENV['RUBY_GC_LIBRARY'].length > 0) ||
(ENV['RUBY_MN_THREADS'] == '1')
end
end
diff --git a/spec/ruby/command_line/rubyopt_spec.rb b/spec/ruby/command_line/rubyopt_spec.rb
index 38e29c0d21..e940f912af 100644
--- a/spec/ruby/command_line/rubyopt_spec.rb
+++ b/spec/ruby/command_line/rubyopt_spec.rb
@@ -25,12 +25,12 @@ describe "Processing RUBYOPT" do
guard -> { RbConfig::CONFIG["CROSS_COMPILING"] != "yes" } do
it "prints the version number for '-v'" do
ENV["RUBYOPT"] = '-v'
- ruby_exe("").sub("+PRISM ", "")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "")
+ ruby_exe("").sub("+PRISM ", "").sub(/\+GC(\[\w+\]\s|\s)?/, "")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "").sub(/\+GC(\[\w+\]\s|\s)?/, "")
end
it "ignores whitespace around the option" do
ENV["RUBYOPT"] = ' -v '
- ruby_exe("").sub("+PRISM ", "")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "")
+ ruby_exe("").sub("+PRISM ", "").sub(/\+GC(\[\w+\]\s|\s)?/, "")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "").sub(/\+GC(\[\w+\]\s|\s)?/, "")
end
end
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index 89ebe8f21d..fd52255acd 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -176,7 +176,7 @@ class TestRubyOptions < Test::Unit::TestCase
VERSION_PATTERN_WITH_RJIT =
case RUBY_ENGINE
when 'ruby'
- /^ruby #{q[RUBY_VERSION]}(?:[p ]|dev|rc).*? \+RJIT (\+MN )?(\+PRISM )?\[#{q[RUBY_PLATFORM]}\]$/
+ /^ruby #{q[RUBY_VERSION]}(?:[p ]|dev|rc).*? \+RJIT (\+MN )?(\+PRISM )?(\+GC)?(\[\w+\]\s|\s)?\[#{q[RUBY_PLATFORM]}\]$/
else
VERSION_PATTERN
end
@@ -307,6 +307,16 @@ class TestRubyOptions < Test::Unit::TestCase
end
end
+ def test_enabled_gc
+ omit unless /linux|darwin/ =~ RUBY_PLATFORM
+
+ if RbConfig::CONFIG['shared_gc_dir'].length > 0
+ assert_match(/\+GC/, RUBY_DESCRIPTION)
+ else
+ assert_no_match(/\+GC/, RUBY_DESCRIPTION)
+ end
+ end
+
def test_parser_flag
assert_in_out_err(%w(--parser=prism -e) + ["puts :hi"], "", %w(hi), [])
assert_in_out_err(%w(--parser=prism --dump=parsetree -e _=:hi), "", /"hi"/, [])
diff --git a/version.c b/version.c
index 416688644a..ddc093ebb0 100644
--- a/version.c
+++ b/version.c
@@ -11,6 +11,7 @@
#include "internal/cmdlineopt.h"
#include "internal/parse.h"
+#include "internal/gc.h"
#include "ruby/ruby.h"
#include "version.h"
#include "vm_core.h"
@@ -61,6 +62,11 @@ const int ruby_api_version[] = {
#else
#define YJIT_DESCRIPTION " +YJIT"
#endif
+#if USE_SHARED_GC
+#define GC_DESCRIPTION " +GC"
+#else
+#define GC_DESCRIPTION ""
+#endif
const char ruby_version[] = RUBY_VERSION;
const char ruby_revision[] = RUBY_FULL_REVISION;
const char ruby_release_date[] = RUBY_RELEASE_DATE;
@@ -167,6 +173,14 @@ define_ruby_description(const char *const jit_opt)
+ rb_strlen_lit(YJIT_DESCRIPTION)
+ rb_strlen_lit(" +MN")
+ rb_strlen_lit(" +PRISM")
+#if USE_SHARED_GC
+ + rb_strlen_lit(GC_DESCRIPTION)
+ // Assume the active GC name can not be longer than 20 chars
+ // so that we don't have to use strlen and remove the static
+ // qualifier from desc.
+ + RB_GC_MAX_NAME_LEN + 3
+#endif
+
];
int n = ruby_description_opt_point;
@@ -176,6 +190,14 @@ define_ruby_description(const char *const jit_opt)
RUBY_ASSERT(n <= ruby_description_opt_point + (int)rb_strlen_lit(YJIT_DESCRIPTION));
if (ruby_mn_threads_enabled) append(" +MN");
if (rb_ruby_prism_p()) append(" +PRISM");
+#if USE_SHARED_GC
+ append(GC_DESCRIPTION);
+ if (rb_gc_external_gc_loaded_p()) {
+ append("[");
+ append(rb_gc_active_gc_name());
+ append("]");
+ }
+#endif
append(ruby_description + ruby_description_opt_point);
# undef append