[前][次][番号順一覧][スレッド一覧]

ruby-changes:71380

From: nagachika <ko1@a...>
Date: Sat, 12 Mar 2022 16:54:24 +0900 (JST)
Subject: [ruby-changes:71380] f2d996dcff (ruby_3_0): merge revision(s) d6c5a30cfdf658280338dbb8c8b17fab3190b928,a2d4e1cda68a49980a4f9f353f400efbde7e7884: [Backport #18392]

https://git.ruby-lang.org/ruby.git/commit/?id=f2d996dcff

From f2d996dcff56057b48ae41ab6f23e7654848ea4b Mon Sep 17 00:00:00 2001
From: nagachika <nagachika@r...>
Date: Sat, 12 Mar 2022 16:28:26 +0900
Subject: merge revision(s)
 d6c5a30cfdf658280338dbb8c8b17fab3190b928,a2d4e1cda68a49980a4f9f353f400efbde7e7884:
 [Backport #18392]

	ObjectSpace::WeakMap#inspect: check if living object [Bug #18392]

	---
	 gc.c                      | 29 +++++++++++++++++++++++------
	 test/ruby/test_weakmap.rb |  9 +++++++++
	 2 files changed, 32 insertions(+), 6 deletions(-)

	Fixed the check order in wmap_live_p [Bug #18392]

	Check if the object is a pointer to heap before check the flag in
	that object.
	---
	 gc.c | 35 ++++++++++++++++++++++-------------
	 1 file changed, 22 insertions(+), 13 deletions(-)
---
 gc.c                      | 64 +++++++++++++++++++++++++++++++++--------------
 test/ruby/test_weakmap.rb |  9 +++++++
 version.h                 |  2 +-
 3 files changed, 55 insertions(+), 20 deletions(-)

diff --git a/gc.c b/gc.c
index 4f04c22990..5d0c342206 100644
--- a/gc.c
+++ b/gc.c
@@ -1202,6 +1202,14 @@ tick(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L1202
 #define MEASURE_LINE(expr) expr
 #endif /* USE_TICK_T */
 
+static inline void *
+asan_unpoison_object_temporary(VALUE obj)
+{
+    void *ptr = asan_poisoned_object_p(obj);
+    asan_unpoison_object(obj, false);
+    return ptr;
+}
+
 #define FL_CHECK2(name, x, pred) \
     ((RGENGC_CHECK_MODE && SPECIAL_CONST_P(x)) ? \
      (rb_bug(name": SPECIAL_CONST (%p)", (void *)(x)), 0) : (pred))
@@ -3853,16 +3861,6 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L3861
     ATOMIC_SET(finalizing, 0);
 }
 
-PUREFUNC(static inline int is_id_value(rb_objspace_t *objspace, VALUE ptr));
-static inline int
-is_id_value(rb_objspace_t *objspace, VALUE ptr)
-{
-    if (!is_pointer_to_heap(objspace, (void *)ptr)) return FALSE;
-    if (BUILTIN_TYPE(ptr) > T_FIXNUM) return FALSE;
-    if (BUILTIN_TYPE(ptr) == T_ICLASS) return FALSE;
-    return TRUE;
-}
-
 static inline int
 heap_is_swept_object(rb_objspace_t *objspace, rb_heap_t *heap, VALUE ptr)
 {
@@ -11178,9 +11176,20 @@ wmap_allocate(VALUE klass) https://github.com/ruby/ruby/blob/trunk/gc.c#L11176
 static int
 wmap_live_p(rb_objspace_t *objspace, VALUE obj)
 {
-    if (!FL_ABLE(obj)) return TRUE;
-    if (!is_id_value(objspace, obj)) return FALSE;
-    if (!is_live_object(objspace, obj)) return FALSE;
+    if (SPECIAL_CONST_P(obj)) return TRUE;
+    if (is_pointer_to_heap(objspace, (void *)obj)) {
+        void *poisoned = asan_unpoison_object_temporary(obj);
+
+        enum ruby_value_type t = BUILTIN_TYPE(obj);
+        int ret = (!(t == T_NONE || t >= T_FIXNUM || t == T_ICLASS) &&
+                   is_live_object(objspace, obj));
+
+        if (poisoned) {
+            asan_poison_object(obj);
+        }
+
+        return ret;
+    }
     return TRUE;
 }
 
@@ -11246,10 +11255,26 @@ struct wmap_iter_arg { https://github.com/ruby/ruby/blob/trunk/gc.c#L11255
     VALUE value;
 };
 
+static VALUE
+wmap_inspect_append(rb_objspace_t *objspace, VALUE str, VALUE obj)
+{
+    if (SPECIAL_CONST_P(obj)) {
+        return rb_str_append(str, rb_inspect(obj));
+    }
+    else if (wmap_live_p(objspace, obj)) {
+        return rb_str_append(str, rb_any_to_s(obj));
+    }
+    else {
+        return rb_str_catf(str, "#<collected:%p>", (void*)obj);
+    }
+}
+
 static int
 wmap_inspect_i(st_data_t key, st_data_t val, st_data_t arg)
 {
-    VALUE str = (VALUE)arg;
+    struct wmap_iter_arg *argp = (struct wmap_iter_arg *)arg;
+    rb_objspace_t *objspace = argp->objspace;
+    VALUE str = argp->value;
     VALUE k = (VALUE)key, v = (VALUE)val;
 
     if (RSTRING_PTR(str)[0] == '#') {
@@ -11259,11 +11284,9 @@ wmap_inspect_i(st_data_t key, st_data_t val, st_data_t arg) https://github.com/ruby/ruby/blob/trunk/gc.c#L11284
 	rb_str_cat2(str, ": ");
 	RSTRING_PTR(str)[0] = '#';
     }
-    k = SPECIAL_CONST_P(k) ? rb_inspect(k) : rb_any_to_s(k);
-    rb_str_append(str, k);
+    wmap_inspect_append(objspace, str, k);
     rb_str_cat2(str, " => ");
-    v = SPECIAL_CONST_P(v) ? rb_inspect(v) : rb_any_to_s(v);
-    rb_str_append(str, v);
+    wmap_inspect_append(objspace, str, v);
 
     return ST_CONTINUE;
 }
@@ -11274,11 +11297,14 @@ wmap_inspect(VALUE self) https://github.com/ruby/ruby/blob/trunk/gc.c#L11297
     VALUE str;
     VALUE c = rb_class_name(CLASS_OF(self));
     struct weakmap *w;
+    struct wmap_iter_arg args;
 
     TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
     str = rb_sprintf("-<%"PRIsVALUE":%p", c, (void *)self);
     if (w->wmap2obj) {
-	st_foreach(w->wmap2obj, wmap_inspect_i, str);
+	args.objspace = &rb_objspace;
+	args.value = str;
+	st_foreach(w->wmap2obj, wmap_inspect_i, (st_data_t)&args);
     }
     RSTRING_PTR(str)[0] = '#';
     rb_str_cat2(str, ">");
diff --git a/test/ruby/test_weakmap.rb b/test/ruby/test_weakmap.rb
index 3b9eef770a..46d8b50c03 100644
--- a/test/ruby/test_weakmap.rb
+++ b/test/ruby/test_weakmap.rb
@@ -73,6 +73,15 @@ class TestWeakMap < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_weakmap.rb#L73
                  @wm.inspect)
   end
 
+  def test_inspect_garbage
+    1000.times do |i|
+      @wm[i] = Object.new
+      @wm.inspect
+    end
+    assert_match(/\A\#<#{@wm.class.name}:[^:]++:(?:\s\d+\s=>\s\#<(?:Object|collected):[^:<>]*+>(?:,|>\z))+/,
+                 @wm.inspect)
+  end
+
   def test_each
     m = __callee__[/test_(.*)/, 1]
     x1 = Object.new
diff --git a/version.h b/version.h
index 640459726e..924fe5a599 100644
--- a/version.h
+++ b/version.h
@@ -12,7 +12,7 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L12
 # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
 #define RUBY_VERSION_TEENY 4
 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 185
+#define RUBY_PATCHLEVEL 186
 
 #define RUBY_RELEASE_YEAR 2022
 #define RUBY_RELEASE_MONTH 3
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]