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

ruby-changes:74302

From: John <ko1@a...>
Date: Tue, 1 Nov 2022 06:05:59 +0900 (JST)
Subject: [ruby-changes:74302] 02f1554224 (master): Implement object shapes for T_CLASS and T_MODULE (#6637)

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

From 02f15542245222ee392e68fb244b3b8c4a12ad82 Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Mon, 31 Oct 2022 14:05:37 -0700
Subject: Implement object shapes for T_CLASS and T_MODULE (#6637)

* Avoid RCLASS_IV_TBL in marshal.c
* Avoid RCLASS_IV_TBL for class names
* Avoid RCLASS_IV_TBL for autoload
* Avoid RCLASS_IV_TBL for class variables
* Avoid copying RCLASS_IV_TBL onto ICLASSes
* Use object shapes for Class and Module IVs
---
 class.c             |  21 +---
 gc.c                |  23 ++--
 internal/class.h    |   4 +-
 internal/variable.h |   2 +-
 marshal.c           |   2 +-
 object.c            |  18 +--
 shape.c             |   9 +-
 shape.h             |  24 ++++
 variable.c          | 336 +++++++++++++++++++++++++++++-----------------------
 vm_insnhelper.c     |  28 +++--
 10 files changed, 265 insertions(+), 202 deletions(-)

diff --git a/class.c b/class.c
index 3d8e205007..d181fb0b2e 100644
--- a/class.c
+++ b/class.c
@@ -213,7 +213,6 @@ class_alloc(VALUE flags, VALUE klass) https://github.com/ruby/ruby/blob/trunk/class.c#L213
 #endif
 
     /* ZALLOC
-      RCLASS_IV_TBL(obj) = 0;
       RCLASS_CONST_TBL(obj) = 0;
       RCLASS_M_TBL(obj) = 0;
       RCLASS_IV_INDEX_TBL(obj) = 0;
@@ -402,23 +401,19 @@ class_init_copy_check(VALUE clone, VALUE orig) https://github.com/ruby/ruby/blob/trunk/class.c#L401
 static void
 copy_tables(VALUE clone, VALUE orig)
 {
-    if (RCLASS_IV_TBL(clone)) {
-        st_free_table(RCLASS_IV_TBL(clone));
-        RCLASS_IV_TBL(clone) = 0;
-    }
     if (RCLASS_CONST_TBL(clone)) {
         rb_free_const_table(RCLASS_CONST_TBL(clone));
         RCLASS_CONST_TBL(clone) = 0;
     }
     RCLASS_M_TBL(clone) = 0;
-    if (RCLASS_IV_TBL(orig)) {
+    if (!RB_TYPE_P(clone, T_ICLASS)) {
         st_data_t id;
 
         rb_iv_tbl_copy(clone, orig);
         CONST_ID(id, "__tmp_classpath__");
-        st_delete(RCLASS_IV_TBL(clone), &id, 0);
+        rb_attr_delete(clone, id);
         CONST_ID(id, "__classpath__");
-        st_delete(RCLASS_IV_TBL(clone), &id, 0);
+        rb_attr_delete(clone, id);
     }
     if (RCLASS_CONST_TBL(orig)) {
         struct clone_const_arg arg;
@@ -520,7 +515,6 @@ rb_mod_init_copy(VALUE clone, VALUE orig) https://github.com/ruby/ruby/blob/trunk/class.c#L515
             prev_clone_p = clone_p;
             RCLASS_M_TBL(clone_p) = RCLASS_M_TBL(p);
             RCLASS_CONST_TBL(clone_p) = RCLASS_CONST_TBL(p);
-            RCLASS_IV_TBL(clone_p) = RCLASS_IV_TBL(p);
             RCLASS_ALLOCATOR(clone_p) = RCLASS_ALLOCATOR(p);
             if (RB_TYPE_P(clone, T_CLASS)) {
                 RCLASS_SET_INCLUDER(clone_p, clone);
@@ -607,9 +601,7 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach) https://github.com/ruby/ruby/blob/trunk/class.c#L601
 
         RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass));
         RCLASS_ALLOCATOR(clone) = RCLASS_ALLOCATOR(klass);
-        if (RCLASS_IV_TBL(klass)) {
-            rb_iv_tbl_copy(clone, klass);
-        }
+        rb_iv_tbl_copy(clone, klass);
         if (RCLASS_CONST_TBL(klass)) {
             struct clone_const_arg arg;
             arg.tbl = RCLASS_CONST_TBL(clone) = rb_id_table_create(0);
@@ -1062,13 +1054,10 @@ rb_include_class_new(VALUE module, VALUE super) https://github.com/ruby/ruby/blob/trunk/class.c#L1054
         module = METACLASS_OF(module);
     }
     RUBY_ASSERT(!RB_TYPE_P(module, T_ICLASS));
-    if (!RCLASS_IV_TBL(module)) {
-        RCLASS_IV_TBL(module) = st_init_numtable();
-    }
     if (!RCLASS_CONST_TBL(module)) {
         RCLASS_CONST_TBL(module) = rb_id_table_create(0);
     }
-    RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
+
     RCLASS_CVC_TBL(klass) = RCLASS_CVC_TBL(module);
     RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
 
diff --git a/gc.c b/gc.c
index 76a1f0f2de..75b330ede5 100644
--- a/gc.c
+++ b/gc.c
@@ -3447,8 +3447,8 @@ obj_free(rb_objspace_t *objspace, VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L3447
       case T_CLASS:
         rb_id_table_free(RCLASS_M_TBL(obj));
         cc_table_free(objspace, obj, FALSE);
-        if (RCLASS_IV_TBL(obj)) {
-            st_free_table(RCLASS_IV_TBL(obj));
+        if (RCLASS_IVPTR(obj)) {
+            xfree(RCLASS_IVPTR(obj));
         }
         if (RCLASS_CONST_TBL(obj)) {
             rb_free_const_table(RCLASS_CONST_TBL(obj));
@@ -4865,15 +4865,11 @@ obj_memsize_of(VALUE obj, int use_all_types) https://github.com/ruby/ruby/blob/trunk/gc.c#L4865
             if (RCLASS_M_TBL(obj)) {
                 size += rb_id_table_memsize(RCLASS_M_TBL(obj));
             }
-            if (RCLASS_IV_TBL(obj)) {
-                size += st_memsize(RCLASS_IV_TBL(obj));
-            }
+            // class IV sizes are allocated as powers of two
+            size += SIZEOF_VALUE << bit_length(RCLASS_IV_COUNT(obj));
             if (RCLASS_CVC_TBL(obj)) {
                 size += rb_id_table_memsize(RCLASS_CVC_TBL(obj));
             }
-            if (RCLASS_EXT(obj)->iv_tbl) {
-                size += st_memsize(RCLASS_EXT(obj)->iv_tbl);
-            }
             if (RCLASS_EXT(obj)->const_tbl) {
                 size += rb_id_table_memsize(RCLASS_EXT(obj)->const_tbl);
             }
@@ -7212,7 +7208,9 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L7208
 
         mark_m_tbl(objspace, RCLASS_M_TBL(obj));
         cc_table_mark(objspace, obj);
-        mark_tbl_no_pin(objspace, RCLASS_IV_TBL(obj));
+        for (attr_index_t i = 0; i < RCLASS_IV_COUNT(obj); i++) {
+            gc_mark(objspace, RCLASS_IVPTR(obj)[i]);
+        }
         mark_const_tbl(objspace, RCLASS_CONST_TBL(obj));
         break;
 
@@ -10439,7 +10437,9 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L10437
         update_cvc_tbl(objspace, obj);
         update_superclasses(objspace, obj);
 
-        gc_update_tbl_refs(objspace, RCLASS_IV_TBL(obj));
+        for (attr_index_t i = 0; i < RCLASS_IV_COUNT(obj); i++) {
+            UPDATE_IF_MOVED(objspace, RCLASS_IVPTR(obj)[i]);
+        }
 
         update_class_ext(objspace, RCLASS_EXT(obj));
         update_const_tbl(objspace, RCLASS_CONST_TBL(obj));
@@ -10454,9 +10454,6 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L10454
             UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
         }
         if (!RCLASS_EXT(obj)) break;
-        if (RCLASS_IV_TBL(obj)) {
-            gc_update_tbl_refs(objspace, RCLASS_IV_TBL(obj));
-        }
         update_class_ext(objspace, RCLASS_EXT(obj));
         update_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj));
         update_cc_tbl(objspace, obj);
diff --git a/internal/class.h b/internal/class.h
index 63fe84c6ab..784d508e20 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -33,7 +33,7 @@ struct rb_cvar_class_tbl_entry { https://github.com/ruby/ruby/blob/trunk/internal/class.h#L33
 };
 
 struct rb_classext_struct {
-    struct st_table *iv_tbl;
+    VALUE *iv_ptr;
     struct rb_id_table *const_tbl;
     struct rb_id_table *callable_m_tbl;
     struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
@@ -75,9 +75,9 @@ typedef struct rb_classext_struct rb_classext_t; https://github.com/ruby/ruby/blob/trunk/internal/class.h#L75
 #else
 #  define RCLASS_EXT(c) (RCLASS(c)->ptr)
 #endif
-#define RCLASS_IV_TBL(c) (RCLASS_EXT(c)->iv_tbl)
 #define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
 #define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
+#define RCLASS_IVPTR(c) (RCLASS_EXT(c)->iv_ptr)
 #define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
 #define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
 #define RCLASS_CVC_TBL(c) (RCLASS_EXT(c)->cvc_tbl)
diff --git a/internal/variable.h b/internal/variable.h
index bb24f5129f..734884a5f6 100644
--- a/internal/variable.h
+++ b/internal/variable.h
@@ -24,7 +24,6 @@ void rb_gc_update_global_tbl(void); https://github.com/ruby/ruby/blob/trunk/internal/variable.h#L24
 size_t rb_generic_ivar_memsize(VALUE);
 VALUE rb_search_class_path(VALUE);
 VALUE rb_attr_delete(VALUE, ID);
-VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
 void rb_autoload_str(VALUE mod, ID id, VALUE file);
 VALUE rb_autoload_at_p(VALUE, ID, int);
 NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE));
@@ -49,6 +48,7 @@ void rb_iv_tbl_copy(VALUE dst, VALUE src); https://github.com/ruby/ruby/blob/trunk/internal/variable.h#L48
 RUBY_SYMBOL_EXPORT_END
 
 MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
 VALUE rb_gvar_get(ID);
 VALUE rb_gvar_set(ID, VALUE);
 VALUE rb_gvar_defined(ID);
diff --git a/marshal.c b/marshal.c
index 59edbfe53a..d956260d96 100644
--- a/marshal.c
+++ b/marshal.c
@@ -523,7 +523,7 @@ hash_each(VALUE key, VALUE value, VALUE v) https://github.com/ruby/ruby/blob/trunk/marshal.c#L523
 
 #define SINGLETON_DUMP_UNABLE_P(klass) \
     (rb_id_table_size(RCLASS_M_TBL(klass)) > 0 || \
-     (RCLASS_IV_TBL(klass) && RCLASS_IV_TBL(klass)->num_entries > 1))
+     rb_ivar_count(klass) > 1)
 
 static void
 w_extended(VALUE klass, struct dump_arg *arg, int check)
diff --git a/object.c b/object.c
index aae6cc45a4..5f8568e3b4 100644
--- a/object.c
+++ b/object.c
@@ -298,20 +298,22 @@ init_copy(VALUE dest, VALUE obj) https://github.com/ruby/ruby/blob/trunk/object.c#L298
     rb_copy_generic_ivar(dest, obj);
     rb_gc_copy_finalizer(dest, obj);
 
-    rb_shape_t *shape_to_set = rb_shape_get_shape(obj);
+    if (!RB_TYPE_P(obj, T_CLASS) && !RB_TYPE_P(obj, T_MODULE)) {
+        rb_shape_t *shape_to_set = rb_shape_get_shape(obj);
 
-    // If the object is frozen, the "dup"'d object will *not* be frozen,
-    // so we need to copy the frozen shape's parent to the new object.
-    if (rb_shape_frozen_shape_p(shape_to_set)) {
-        shape_to_set = rb_shape_get_shape_by_id(shape_to_set->parent_id);
+        // If the object is frozen, the "dup"'d object will *not* be frozen,
+        // so we need to  (... truncated)

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

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