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

ruby-changes:58032

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Mon, 30 Sep 2019 10:27:04 +0900 (JST)
Subject: [ruby-changes:58032] cf33608203 (master): refactor constify most of rb_method_definition_t

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

From cf336082039ae84b5001908f6bb7e04bdda8893e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Fri, 20 Sep 2019 14:12:51 +0900
Subject: refactor constify most of rb_method_definition_t

Most (if not all) of the fields of rb_method_definition_t are never
meant to be modified once after they are stored.  Marking them const
makes it possible for compilers to warn on unintended modifications.

diff --git a/gc.c b/gc.c
index c9f26cc..0caee4c 100644
--- a/gc.c
+++ b/gc.c
@@ -7831,7 +7831,7 @@ void rb_update_st_references(struct st_table *ht) https://github.com/ruby/ruby/blob/trunk/gc.c#L7831
 static void
 gc_ref_update_method_entry(rb_objspace_t *objspace, rb_method_entry_t *me)
 {
-    rb_method_definition_t *def = me->def;
+    const rb_method_definition_t *def = me->def;
 
     UPDATE_IF_MOVED(objspace, me->owner);
     UPDATE_IF_MOVED(objspace, me->defined_class);
diff --git a/method.h b/method.h
index b26f678..1ce5d4c 100644
--- a/method.h
+++ b/method.h
@@ -122,32 +122,32 @@ typedef struct rb_iseq_struct rb_iseq_t; https://github.com/ruby/ruby/blob/trunk/method.h#L122
 #endif
 
 typedef struct rb_method_iseq_struct {
-    rb_iseq_t * iseqptr; /*!< iseq pointer, should be separated from iseqval */
-    rb_cref_t * cref;          /*!< class reference, should be marked */
-} rb_method_iseq_t; /* check rb_add_method_iseq() when modify the fields */
+    const rb_iseq_t *const iseqptr; /*!< iseq pointer, should be separated from iseqval */
+    rb_cref_t *const cref;          /*!< class reference, should be marked */
+} rb_method_iseq_t;
 
 typedef struct rb_method_cfunc_struct {
-    VALUE (*func)(ANYARGS);
-    VALUE (*invoker)(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS));
-    int argc;
+    VALUE (*const func)(ANYARGS);
+    VALUE (*const invoker)(VALUE recv, int argc, const VALUE *argv, VALUE (*func)(ANYARGS));
+    const int argc;
 } rb_method_cfunc_t;
 
 typedef struct rb_method_attr_struct {
-    ID id;
-    VALUE location; /* should be marked */
+    const ID id;
+    const VALUE location; /* should be marked */
 } rb_method_attr_t;
 
 typedef struct rb_method_alias_struct {
-    struct rb_method_entry_struct * original_me; /* original_me->klass is original owner */
+    const struct rb_method_entry_struct *const original_me; /* original_me->klass is original owner */
 } rb_method_alias_t;
 
 typedef struct rb_method_refined_struct {
-    struct rb_method_entry_struct * orig_me;
-    VALUE owner;
+    const struct rb_method_entry_struct *const orig_me;
+    const VALUE owner;
 } rb_method_refined_t;
 
 typedef struct rb_method_bmethod_struct {
-    VALUE proc; /* should be marked */
+    const VALUE proc; /* should be marked */
     struct rb_hook_list_struct *hooks;
 } rb_method_bmethod_t;
 
@@ -159,22 +159,22 @@ enum method_optimized_type { https://github.com/ruby/ruby/blob/trunk/method.h#L159
 };
 
 struct rb_method_definition_struct {
-    BITFIELD(rb_method_type_t, type, VM_METHOD_TYPE_MINIMUM_BITS);
+    BITFIELD(rb_method_type_t, const type, VM_METHOD_TYPE_MINIMUM_BITS);
     int alias_count : 28;
     int complemented_count : 28;
 
     union {
-	rb_method_iseq_t iseq;
-	rb_method_cfunc_t cfunc;
-	rb_method_attr_t attr;
-	rb_method_alias_t alias;
-	rb_method_refined_t refined;
+        const rb_method_iseq_t iseq;
+        const rb_method_cfunc_t cfunc;
+        const rb_method_attr_t attr;
+        const rb_method_alias_t alias;
+        const rb_method_refined_t refined;
         rb_method_bmethod_t bmethod;
 
-        enum method_optimized_type optimize_type;
+        const enum method_optimized_type optimize_type;
     } body;
 
-    ID original_id;
+    const ID original_id;
 };
 
 typedef struct rb_method_definition_struct rb_method_definition_t;
diff --git a/proc.c b/proc.c
index 667b86a..496baa4 100644
--- a/proc.c
+++ b/proc.c
@@ -15,6 +15,8 @@ https://github.com/ruby/ruby/blob/trunk/proc.c#L15
 #include "vm_core.h"
 #include "iseq.h"
 
+extern const rb_method_definition_t *rb_method_definition_create(rb_method_type_t type, ID mid);
+
 /* Proc.new with no block will raise an exception in the future
  * versions */
 #define PROC_NEW_REQUIRES_BLOCK 0
@@ -1475,15 +1477,12 @@ mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass) https://github.com/ruby/ruby/blob/trunk/proc.c#L1477
     struct METHOD *data;
     VALUE method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
     rb_method_entry_t *me;
-    rb_method_definition_t *def;
+    const rb_method_definition_t *def;
 
     RB_OBJ_WRITE(method, &data->recv, obj);
     RB_OBJ_WRITE(method, &data->klass, klass);
 
-    def = ZALLOC(rb_method_definition_t);
-    def->type = VM_METHOD_TYPE_MISSING;
-    def->original_id = id;
-
+    def = rb_method_definition_create(VM_METHOD_TYPE_MISSING, id);
     me = rb_method_entry_create(id, klass, METHOD_VISI_UNDEF, def);
 
     RB_OBJ_WRITE(method, &data->me, me);
diff --git a/vm_core.h b/vm_core.h
index 8eb1555..192165b 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -491,7 +491,7 @@ rb_iseq_check(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/vm_core.h#L491
 }
 
 static inline const rb_iseq_t *
-def_iseq_ptr(rb_method_definition_t *def)
+def_iseq_ptr(const rb_method_definition_t *def)
 {
 #if VM_CHECK_MODE > 0
     if (def->type != VM_METHOD_TYPE_ISEQ) rb_bug("def_iseq_ptr: not iseq (%d)", def->type);
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 54142b8..7db8630 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -19,7 +19,7 @@ https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L19
 #include "ruby/config.h"
 #include "debug_counter.h"
 
-extern rb_method_definition_t *rb_method_definition_create(rb_method_type_t type, ID mid);
+extern const rb_method_definition_t *rb_method_definition_create(rb_method_type_t type, ID mid);
 extern void rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts);
 extern int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2);
 extern VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
@@ -2589,9 +2589,9 @@ aliased_callable_method_entry(const rb_callable_method_entry_t *me) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2589
 	    RB_OBJ_WRITE(me, &me->def->body.alias.original_me, cme);
 	}
 	else {
-	    rb_method_definition_t *def =
+	    const rb_method_definition_t *def =
 		rb_method_definition_create(VM_METHOD_TYPE_ALIAS, me->def->original_id);
-	    rb_method_definition_set((rb_method_entry_t *)me, def, (void *)cme);
+	    rb_method_definition_set((rb_method_entry_t *)me, (void *)def, (void *)cme);
 	}
     }
     else {
diff --git a/vm_method.c b/vm_method.c
index 241bb30..4abefd5 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -132,9 +132,7 @@ rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_me https://github.com/ruby/ruby/blob/trunk/vm_method.c#L132
 {
     if (argc < -2 || 15 < argc) rb_raise(rb_eArgError, "arity out of range: %d for -2..15", argc);
     if (func != rb_f_notimplement) {
-	rb_method_cfunc_t opt;
-	opt.func = func;
-	opt.argc = argc;
+        rb_method_cfunc_t opt = { func, 0, argc, };
 	rb_add_method(klass, mid, VM_METHOD_TYPE_CFUNC, &opt, visi);
     }
     else {
@@ -213,14 +211,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/vm_method.c#L211
     }
 }
 
-static void
-setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE (*func)(), int argc)
-{
-    cfunc->func = func;
-    cfunc->argc = argc;
-    cfunc->invoker = call_cfunc_invoker_func(argc);
-}
-
 MJIT_FUNC_EXPORTED void
 rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts)
 {
@@ -250,8 +240,13 @@ rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *de https://github.com/ruby/ruby/blob/trunk/vm_method.c#L240
 	    }
 	  case VM_METHOD_TYPE_CFUNC:
 	    {
-		rb_method_cfunc_t *cfunc = (rb_method_cfunc_t *)opts;
-		setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), cfunc->func, cfunc->argc);
+                const rb_method_cfunc_t *p = (const rb_method_cfunc_t *)opts;
+                rb_method_cfunc_t c = {
+                    p->func,
+                    call_cfunc_invoker_func(p->argc),
+                    p->argc,
+                };
+                memcpy((void *)&def->body.cfunc, &c, sizeof c);
 		return;
 	    }
 	  case VM_METHOD_TYPE_ATTRSET:
@@ -261,7 +256,7 @@ rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *de https://github.com/ruby/ruby/blob/trunk/vm_method.c#L256
 		rb_control_frame_t *cfp;
 		int line;
 
-		def->body.attr.id = (ID)(VALUE)opts;
+                memcpy((void *)&def->body.attr, &(rb_method_attr_t) { (ID)(VALUE)opts }, sizeof(rb_method_attr_t));
 
 		cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
 
@@ -275,14 +270,21 @@ rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *de https://github.com/ruby/ruby/blob/trunk/vm_method.c#L270
 		return;
 	    }
 	  case VM_METHOD_TYPE_BMETHOD:
-            RB_OBJ_WRITE(me, &def->body.bmethod.proc, (VALUE)opts);
+            memcpy((void *)&def->body.bmethod, &(rb_method_bmethod_t) { (VALUE)opts }, sizeof(rb_method_bmethod_t));
+            RB_OBJ_WRITTEN(me, &def->body.bmethod.proc, (VALUE)opts);
 	    return;
 	  case VM_METHOD_TYPE_NOTIMPLEMENTED:
-	    setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), rb_f_notimplement, -1);
-	    return;
+            {
+                rb_method_cfunc_t f = { rb_f_notimplement, call_cfunc_m1, -1, };
+                memcpy((void *)&def->body.cfunc, &f, sizeof f);
+                return;
+            }
 	  case VM_METHOD_TYPE_OPTIMIZED:
-	    def->body.optimize_type = (enum method_optimized_type)opts;
-	    return;
+            {
+                enum method_optimized_type t = (enum method_optimized_type)opts;
+                memcpy((void *)&def->body (... truncated)

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

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