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

ruby-changes:63408

From: Koichi <ko1@a...>
Date: Wed, 21 Oct 2020 23:52:35 +0900 (JST)
Subject: [ruby-changes:63408] 89f6644de7 (master): refactoring rb_obj_traverse()

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

From 89f6644de71b7dfbdbdba216a8667b9c3348203b Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Wed, 21 Oct 2020 23:00:36 +0900
Subject: refactoring rb_obj_traverse()

* create rec check hash lazily
* do not pass *data pointer for enter/leave function because
  it is not used.

diff --git a/ractor.c b/ractor.c
index 8c498a8..93a1fc5 100644
--- a/ractor.c
+++ b/ractor.c
@@ -1870,15 +1870,15 @@ rb_ractor_stderr_set(VALUE err) https://github.com/ruby/ruby/blob/trunk/ractor.c#L1870
 // 2: stop search
 // 1: skip child
 // 0: continue
-typedef int (*rb_obj_traverse_enter_func)(VALUE obj, void *data);
-typedef int (*rb_obj_traverse_leave_func)(VALUE obj, void *data);
+typedef int (*rb_obj_traverse_enter_func)(VALUE obj);
+typedef int (*rb_obj_traverse_leave_func)(VALUE obj);
 
 struct obj_traverse_data {
     rb_obj_traverse_enter_func enter_func;
     rb_obj_traverse_leave_func leave_func;
-    void *data;
 
     st_table *rec;
+    VALUE rec_hash;
 };
 
 
@@ -1887,19 +1887,19 @@ struct obj_traverse_callback_data { https://github.com/ruby/ruby/blob/trunk/ractor.c#L1887
     struct obj_traverse_data *data;
 };
 
-static int rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data);
+static int obj_traverse_i(VALUE obj, struct obj_traverse_data *data);
 
 static int
 obj_hash_traverse_i(VALUE key, VALUE val, VALUE ptr)
 {
     struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr;
 
-    if (rb_obj_traverse_i(key, d->data)) {
+    if (obj_traverse_i(key, d->data)) {
         d->stop = true;
         return ST_STOP;
     }
 
-    if (rb_obj_traverse_i(val, d->data)) {
+    if (obj_traverse_i(val, d->data)) {
         d->stop = true;
         return ST_STOP;
     }
@@ -1912,24 +1912,34 @@ obj_tdata_traverse_i(VALUE obj, void *ptr) https://github.com/ruby/ruby/blob/trunk/ractor.c#L1912
 {
     struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr;
 
-    if (rb_obj_traverse_i(obj, d->data)) {
+    if (obj_traverse_i(obj, d->data)) {
         d->stop = true;
     }
 }
 
+static struct st_table *
+obj_traverse_rec(struct obj_traverse_data *data)
+{
+    if (UNLIKELY(!data->rec)) {
+        data->rec_hash = rb_ident_hash_new();
+        data->rec = rb_hash_st_table(data->rec_hash);
+    }
+    return data->rec;
+}
+
 static int
-rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
+obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
 {
     if (RB_SPECIAL_CONST_P(obj)) return 0;
 
-    switch (data->enter_func(obj, data->data)) {
+    switch (data->enter_func(obj)) {
       case 0: break;
       case 1: return 0; // skip children
       case 2: return 1; // stop search
       default: rb_bug("rb_obj_traverse_func should return 0 to 2");
     }
 
-    if (st_insert(data->rec, obj, 1)) {
+    if (st_insert(obj_traverse_rec(data), obj, 1)) {
         // already traversed
         return 0;
     }
@@ -1939,7 +1949,7 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) https://github.com/ruby/ruby/blob/trunk/ractor.c#L1949
         rb_ivar_generic_ivtbl_lookup(obj, &ivtbl);
         for (uint32_t i = 0; i < ivtbl->numiv; i++) {
             VALUE val = ivtbl->ivptr[i];
-            if (val != Qundef && rb_obj_traverse_i(val, data)) return 1;
+            if (val != Qundef && obj_traverse_i(val, data)) return 1;
         }
     }
 
@@ -1961,7 +1971,7 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) https://github.com/ruby/ruby/blob/trunk/ractor.c#L1971
 
             for (uint32_t i=0; i<len; i++) {
                 VALUE val = ptr[i];
-                if (val != Qundef && rb_obj_traverse_i(val, data)) return 1;
+                if (val != Qundef && obj_traverse_i(val, data)) return 1;
             }
         }
         break;
@@ -1970,14 +1980,14 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) https://github.com/ruby/ruby/blob/trunk/ractor.c#L1980
         {
             for (int i = 0; i < RARRAY_LENINT(obj); i++) {
                 VALUE e = rb_ary_entry(obj, i);
-                if (rb_obj_traverse_i(e, data)) return 1;
+                if (obj_traverse_i(e, data)) return 1;
             }
         }
         break;
 
       case T_HASH:
         {
-            if (rb_obj_traverse_i(RHASH_IFNONE(obj), data)) return 1;
+            if (obj_traverse_i(RHASH_IFNONE(obj), data)) return 1;
 
             struct obj_traverse_callback_data d = {
                 .stop = false,
@@ -1994,18 +2004,18 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2004
             const VALUE *ptr = RSTRUCT_CONST_PTR(obj);
 
             for (long i=0; i<len; i++) {
-                if (rb_obj_traverse_i(ptr[i], data)) return 1;
+                if (obj_traverse_i(ptr[i], data)) return 1;
             }
         }
         break;
 
       case T_RATIONAL:
-        if (rb_obj_traverse_i(RRATIONAL(obj)->num, data)) return 1;
-        if (rb_obj_traverse_i(RRATIONAL(obj)->den, data)) return 1;
+        if (obj_traverse_i(RRATIONAL(obj)->num, data)) return 1;
+        if (obj_traverse_i(RRATIONAL(obj)->den, data)) return 1;
         break;
       case T_COMPLEX:
-        if (rb_obj_traverse_i(RCOMPLEX(obj)->real, data)) return 1;
-        if (rb_obj_traverse_i(RCOMPLEX(obj)->imag, data)) return 1;
+        if (obj_traverse_i(RCOMPLEX(obj)->real, data)) return 1;
+        if (obj_traverse_i(RCOMPLEX(obj)->imag, data)) return 1;
         break;
 
       case T_DATA:
@@ -2028,7 +2038,7 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2038
         rb_bug("unreachable");
     }
 
-    switch (data->leave_func(obj, data->data)) {
+    switch (data->leave_func(obj)) {
       case 0:
       case 1: return 0; // terminate
       case 2: return 1; // stop search
@@ -2041,21 +2051,15 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2051
 static int
 rb_obj_traverse(VALUE obj,
                 rb_obj_traverse_enter_func enter_func,
-                rb_obj_traverse_leave_func leave_func,
-                void *passed_data)
+                rb_obj_traverse_leave_func leave_func)
 {
-    VALUE h = rb_ident_hash_new();
-
     struct obj_traverse_data data = {
         .enter_func = enter_func,
         .leave_func = leave_func,
-        .data = passed_data,
-        .rec = rb_hash_st_table(h),
+        .rec = NULL,
     };
 
-    int r = rb_obj_traverse_i(obj, &data);
-    RB_GC_GUARD(h);
-    return r;
+    return obj_traverse_i(obj, &data);
 }
 
 static int
@@ -2076,7 +2080,7 @@ frozen_shareable_p(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2080
 }
 
 static int
-make_shareable_check_shareable(VALUE obj, void *data)
+make_shareable_check_shareable(VALUE obj)
 {
     VM_ASSERT(!SPECIAL_CONST_P(obj));
 
@@ -2091,12 +2095,16 @@ make_shareable_check_shareable(VALUE obj, void *data) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2095
 
     if (!OBJ_FROZEN(obj)) {
         rb_funcall(obj, idFreeze, 0);
+
+        if (UNLIKELY(!OBJ_FROZEN(obj))) {
+            rb_raise(rb_eRactorError, "#freeze does not freeze object correctly");
+        }
     }
     return 0;
 }
 
 static int
-mark_shareable(VALUE obj, void *data)
+mark_shareable(VALUE obj)
 {
     FL_SET_RAW(obj, RUBY_FL_SHAREABLE);
     return 0;
@@ -2107,13 +2115,12 @@ rb_ractor_make_shareable(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2115
 {
     rb_obj_traverse(obj,
                     make_shareable_check_shareable,
-                    mark_shareable,
-                    NULL);
+                    mark_shareable);
     return obj;
 }
 
 static int
-shareable_p_enter(VALUE obj, void *ptr)
+shareable_p_enter(VALUE obj)
 {
     if (RB_OBJ_SHAREABLE_P(obj)) {
         return 1;
@@ -2122,7 +2129,7 @@ shareable_p_enter(VALUE obj, void *ptr) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2129
              RB_TYPE_P(obj, T_MODULE) ||
              RB_TYPE_P(obj, T_ICLASS)) {
         // TODO: remove it
-        mark_shareable(obj, NULL);
+        mark_shareable(obj);
         return 1;
     }
     else if (RB_OBJ_FROZEN_RAW(obj) &&
@@ -2138,8 +2145,7 @@ rb_ractor_shareable_p_continue(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ractor.c#L2145
 {
     if (rb_obj_traverse(obj,
                         shareable_p_enter,
-                        mark_shareable,
-                        NULL)) {
+                        mark_shareable)) {
         return false;
     }
     else {
-- 
cgit v0.10.2


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

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