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

ruby-changes:55368

From: tenderlove <ko1@a...>
Date: Wed, 17 Apr 2019 12:17:47 +0900 (JST)
Subject: [ruby-changes:55368] tenderlove:r67576 (trunk): Adding `GC.compact` and compacting GC support.

tenderlove	2019-04-17 12:17:25 +0900 (Wed, 17 Apr 2019)

  New Revision: 67576

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=67576

  Log:
    Adding `GC.compact` and compacting GC support.
    
    This commit adds the new method `GC.compact` and compacting GC support.
    Please see this issue for caveats:
    
      https://bugs.ruby-lang.org/issues/15626
    
    [Feature #15626]

  Added files:
    trunk/test/ruby/test_gc_compact.rb
  Modified files:
    trunk/NEWS
    trunk/class.c
    trunk/constant.h
    trunk/ext/json/generator/generator.c
    trunk/ext/json/parser/parser.c
    trunk/gc.c
    trunk/gc.h
    trunk/hash.c
    trunk/id_table.c
    trunk/id_table.h
    trunk/include/ruby/intern.h
    trunk/include/ruby/ruby.h
    trunk/include/ruby/st.h
    trunk/internal.h
    trunk/iseq.c
    trunk/iseq.h
    trunk/method.h
    trunk/st.c
    trunk/symbol.c
    trunk/symbol.h
    trunk/thread.c
    trunk/transient_heap.c
    trunk/transient_heap.h
    trunk/variable.c
    trunk/vm.c
    trunk/vm_core.h
    trunk/vm_eval.c
Index: symbol.c
===================================================================
--- symbol.c	(revision 67575)
+++ symbol.c	(revision 67576)
@@ -60,12 +60,7 @@ enum id_entry_type { https://github.com/ruby/ruby/blob/trunk/symbol.c#L60
     ID_ENTRY_SIZE
 };
 
-static struct symbols {
-    rb_id_serial_t last_id;
-    st_table *str_sym;
-    VALUE ids;
-    VALUE dsymbol_fstr_hash;
-} global_symbols = {tNEXT_ID-1};
+rb_symbols_t global_symbols = {tNEXT_ID-1};
 
 static const struct st_hash_type symhash = {
     rb_str_hash_cmp,
Index: symbol.h
===================================================================
--- symbol.h	(revision 67575)
+++ symbol.h	(revision 67576)
@@ -54,6 +54,13 @@ id_type(ID id) https://github.com/ruby/ruby/blob/trunk/symbol.h#L54
 
 typedef uint32_t rb_id_serial_t;
 
+typedef struct {
+    rb_id_serial_t last_id;
+    st_table *str_sym;
+    VALUE ids;
+    VALUE dsymbol_fstr_hash;
+} rb_symbols_t;
+
 static inline rb_id_serial_t
 rb_id_to_serial(ID id)
 {
Index: method.h
===================================================================
--- method.h	(revision 67575)
+++ method.h	(revision 67576)
@@ -40,9 +40,9 @@ typedef struct rb_scope_visi_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L40
 /*! CREF (Class REFerence) */
 typedef struct rb_cref_struct {
     VALUE flags;
-    const VALUE refinements;
-    const VALUE klass;
-    struct rb_cref_struct * const next;
+    VALUE refinements;
+    VALUE klass;
+    struct rb_cref_struct * next;
     const rb_scope_visibility_t scope_visi;
 } rb_cref_t;
 
@@ -50,10 +50,10 @@ typedef struct rb_cref_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L50
 
 typedef struct rb_method_entry_struct {
     VALUE flags;
-    const VALUE defined_class;
+    VALUE defined_class;
     struct rb_method_definition_struct * const def;
     ID called_id;
-    const VALUE owner;
+    VALUE owner;
 } rb_method_entry_t;
 
 typedef struct rb_callable_method_entry_struct { /* same fields with rb_method_entry_t */
@@ -123,8 +123,8 @@ typedef struct rb_iseq_struct rb_iseq_t; https://github.com/ruby/ruby/blob/trunk/method.h#L123
 #endif
 
 typedef struct rb_method_iseq_struct {
-    const rb_iseq_t * const iseqptr; /*!< iseq pointer, should be separated from iseqval */
-    rb_cref_t * const cref;          /*!< class reference, should be marked */
+    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 */
 
 typedef struct rb_method_cfunc_struct {
@@ -135,20 +135,20 @@ typedef struct rb_method_cfunc_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L135
 
 typedef struct rb_method_attr_struct {
     ID id;
-    const VALUE location; /* should be marked */
+    VALUE location; /* should be marked */
 } rb_method_attr_t;
 
 typedef struct rb_method_alias_struct {
-    const struct rb_method_entry_struct * const original_me; /* original_me->klass is original owner */
+    struct rb_method_entry_struct * original_me; /* original_me->klass is original owner */
 } rb_method_alias_t;
 
 typedef struct rb_method_refined_struct {
-    const struct rb_method_entry_struct * const orig_me;
-    const VALUE owner;
+    struct rb_method_entry_struct * orig_me;
+    VALUE owner;
 } rb_method_refined_t;
 
 typedef struct rb_method_bmethod_struct {
-    const VALUE proc; /* should be marked */
+    VALUE proc; /* should be marked */
     struct rb_hook_list_struct *hooks;
 } rb_method_bmethod_t;
 
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 67575)
+++ include/ruby/intern.h	(revision 67576)
@@ -507,10 +507,15 @@ COLDFUNC NORETURN(void rb_memerror(void) https://github.com/ruby/ruby/blob/trunk/include/ruby/intern.h#L507
 PUREFUNC(int rb_during_gc(void));
 void rb_gc_mark_locations(const VALUE*, const VALUE*);
 void rb_mark_tbl(struct st_table*);
+void rb_mark_tbl_no_pin(struct st_table*);
+void rb_gc_update_tbl_refs(st_table *ptr);
 void rb_mark_set(struct st_table*);
 void rb_mark_hash(struct st_table*);
+void rb_update_st_references(struct st_table *ht);
 void rb_gc_mark_maybe(VALUE);
 void rb_gc_mark(VALUE);
+void rb_gc_mark_no_pin(VALUE);
+VALUE rb_gc_new_location(VALUE);
 void rb_gc_force_recycle(VALUE);
 void rb_gc(void);
 void rb_gc_copy_finalizer(VALUE,VALUE);
@@ -622,6 +627,7 @@ VALUE rb_obj_trust(VALUE); https://github.com/ruby/ruby/blob/trunk/include/ruby/intern.h#L627
 VALUE rb_obj_freeze(VALUE);
 PUREFUNC(VALUE rb_obj_frozen_p(VALUE));
 VALUE rb_obj_id(VALUE);
+VALUE rb_memory_id(VALUE);
 VALUE rb_obj_class(VALUE);
 PUREFUNC(VALUE rb_class_real(VALUE));
 PUREFUNC(VALUE rb_class_inherited_p(VALUE, VALUE));
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 67575)
+++ include/ruby/ruby.h	(revision 67576)
@@ -512,6 +512,7 @@ enum ruby_value_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L512
     RUBY_T_NODE   = 0x1b,
     RUBY_T_ICLASS = 0x1c,
     RUBY_T_ZOMBIE = 0x1d,
+    RUBY_T_MOVED  = 0x1e,
 
     RUBY_T_MASK   = 0x1f
 };
@@ -542,6 +543,7 @@ enum ruby_value_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L543
 #define T_UNDEF  RUBY_T_UNDEF
 #define T_NODE   RUBY_T_NODE
 #define T_ZOMBIE RUBY_T_ZOMBIE
+#define T_MOVED RUBY_T_MOVED
 #define T_MASK   RUBY_T_MASK
 
 #define RB_BUILTIN_TYPE(x) (int)(((struct RBasic*)(x))->flags & RUBY_T_MASK)
@@ -845,6 +847,7 @@ enum ruby_fl_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L847
     RUBY_FL_FINALIZE  = (1<<7),
     RUBY_FL_TAINT     = (1<<8),
     RUBY_FL_UNTRUSTED = RUBY_FL_TAINT,
+    RUBY_FL_SEEN_OBJ_ID = (1<<9),
     RUBY_FL_EXIVAR    = (1<<10),
     RUBY_FL_FREEZE    = (1<<11),
 
@@ -883,7 +886,7 @@ enum ruby_fl_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L886
 
 struct RUBY_ALIGNAS(SIZEOF_VALUE) RBasic {
     VALUE flags;
-    const VALUE klass;
+    VALUE klass;
 };
 
 VALUE rb_obj_hide(VALUE obj);
@@ -1105,7 +1108,7 @@ struct RArray { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1108
 struct RRegexp {
     struct RBasic basic;
     struct re_pattern_buffer *ptr;
-    const VALUE src;
+    VALUE src;
     unsigned long usecnt;
 };
 #define RREGEXP_PTR(r) (RREGEXP(r)->ptr)
@@ -1144,7 +1147,8 @@ struct rb_data_type_struct { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1147
 	void (*dmark)(void*);
 	void (*dfree)(void*);
 	size_t (*dsize)(const void *);
-        void *reserved[2]; /* For future extension.
+        void (*dcompact)(void*);
+        void *reserved[1]; /* For future extension.
 			      This array *must* be filled with ZERO. */
     } function;
     const rb_data_type_t *parent;
@@ -1255,6 +1259,7 @@ int rb_big_sign(VALUE); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1259
 #define RBIGNUM_NEGATIVE_P(b) (RBIGNUM_SIGN(b)==0)
 
 #define R_CAST(st)   (struct st*)
+#define RMOVED(obj)  (R_CAST(RMoved)(obj))
 #define RBASIC(obj)  (R_CAST(RBasic)(obj))
 #define ROBJECT(obj) (R_CAST(RObject)(obj))
 #define RCLASS(obj)  (R_CAST(RClass)(obj))
@@ -1273,6 +1278,7 @@ int rb_big_sign(VALUE); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1278
 #define FL_FINALIZE     ((VALUE)RUBY_FL_FINALIZE)
 #define FL_TAINT        ((VALUE)RUBY_FL_TAINT)
 #define FL_UNTRUSTED    ((VALUE)RUBY_FL_UNTRUSTED)
+#define FL_SEEN_OBJ_ID  ((VALUE)RUBY_FL_SEEN_OBJ_ID)
 #define FL_EXIVAR       ((VALUE)RUBY_FL_EXIVAR)
 #define FL_FREEZE       ((VALUE)RUBY_FL_FREEZE)
 
Index: include/ruby/st.h
===================================================================
--- include/ruby/st.h	(revision 67575)
+++ include/ruby/st.h	(revision 67576)
@@ -96,7 +96,7 @@ struct st_table { https://github.com/ruby/ruby/blob/trunk/include/ruby/st.h#L96
 
 #define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)
 
-enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
+enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK, ST_REPLACE};
 
 st_table *st_init_table(const struct st_hash_type *);
 st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t);
@@ -118,6 +118,7 @@ typedef int st_update_callback_func(st_d https://github.com/ruby/ruby/blob/trunk/include/ruby/st.h#L118
  * results of hash() are same and compare() returns 0, otherwise the
  * behavior is undefined */
 int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
+int st_foreach_with_replace(st_table *tab, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg);
 int st_foreach(st_table *, int (*)(ANYARGS), st_data_t);
 int st_foreach_check(st_table *, int (*)(ANYARGS), st_data_t, st_data_t);
 st_index_t st_keys(st_table *table, st_data_t *keys, st_index_t size);
Index: id_table.c
===================================================================
--- id_table.c	(revision 67575)
+++ id_table.c	(revision 67576)
@@ -267,6 +267,28 @@ rb_id_table_delete(struct rb_id_table *t https://github.com/ruby/ruby/blob/trunk/id_table.c#L267
 }
 
 void
+rb_id_table_foreach_with_replace(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, rb_id_table_update_callback_func_t *replace, void *data)
+{
+    int i, capa = tbl->capa;
+
+    for (i=0; i<capa; i++) {
+        if (ITEM_KEY_ISSET(tbl, i)) {
+            const id_key_t key = ITEM_GET_KEY(tbl, i);
+            enum rb_id_table_iterator_result ret = (*func)(Qundef, tbl->items[i].val, data);
+            assert(key != 0);
+
+            if (ret == ID_TABLE_REPLACE) {
+                VALUE val = tbl->items[i].val;
+                ret = (*replace)(NULL, &val, data, TRUE);
+                tbl->items[i].val = val;
+            }
+            else if (ret == ID_TABLE_STOP)
+                return;
+        }
+    }
+}
+
+void
 rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data)
 {
     int i, capa = tbl->capa;
Index: id_table.h
===================================================================
--- id_table.h	(revision 67575)
+++ id_table.h	(revision 67576)
@@ -9,6 +9,7 @@ enum rb_id_table_iterator_result { https://github.com/ruby/ruby/blob/trunk/id_table.h#L9
     ID_TABLE_CONTINUE = ST_CONTINUE,
     ID_TABLE_STOP     = ST_STOP,
     ID_TABLE_DELETE   = ST_DELETE,
+    ID_TABLE_REPLACE  = ST_REPLACE,
     ID_TABLE_ITERATOR_RESULT_END
 };
 
@@ -23,9 +24,11 @@ int rb_id_table_insert(struct rb_id_tabl https://github.com/ruby/ruby/blob/trunk/id_table.h#L24
 int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp);
 int rb_id_table_delete(struct rb_id_table *tbl, ID id);
 
+typedef enum rb_id_table_iterator_result rb_id_table_update_callback_func_t(ID *id, VALUE *val, void *data, int existing);
 typedef enum rb_id_table_iterator_result rb_id_table_foreach_func_t(ID id, VALUE val, void *data);
 typedef enum rb_id_table_iterator_result rb_id_table_foreach_values_func_t(VALUE val, void *data);
 void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data);
+void rb_id_table_foreach_with_replace(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, rb_id_table_update_callback_func_t *replace, void *data);
 void rb_id_table_foreach_values(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, void *data);
 
 #endif	/* RUBY_ID_TABLE_H */
Index: variable.c
===================================================================
--- variable.c	(revision 67575)
+++ variable.c	(revision 67576)
@@ -1201,6 +1201,16 @@ rb_mark_generic_ivar(VALUE obj) https://github.com/ruby/ruby/blob/trunk/variable.c#L1201
 }
 
 void
+rb_mv_generic_ivar(VALUE rsrc, VALUE dst)
+{
+    st_data_t key = (st_data_t)rsrc;
+    struct gen_ivtbl *ivtbl;
+
+    if (st_delete(generic_iv_tbl, &key, (st_data_t *)&ivtbl))
+        st_insert(generic_iv_tbl, (st_data_t)dst, (st_data_t)ivtbl);
+}
+
+void
 rb_free_generic_ivar(VALUE obj)
 {
     st_data_t key = (st_data_t)obj;
@@ -1950,7 +1960,7 @@ rb_mod_const_missing(VALUE klass, VALUE https://github.com/ruby/ruby/blob/trunk/variable.c#L1960
 static void
 autoload_mark(void *ptr)
 {
-    rb_mark_tbl((st_table *)ptr);
+    rb_mark_tbl_no_pin((st_table *)ptr);
 }
 
 static void
@@ -1966,9 +1976,15 @@ autoload_memsize(const void *ptr) https://github.com/ruby/ruby/blob/trunk/variable.c#L1976
     return st_memsize(tbl);
 }
 
+static void
+autoload_compact(void *ptr)
+{
+    rb_gc_update_tbl_refs((st_table *)ptr);
+}
+
 static const rb_data_type_t autoload_data_type = {
     "autoload",
-    {autoload_mark, autoload_free, autoload_memsize,},
+    {autoload_mark, autoload_free, autoload_memsize, autoload_compact,},
     0, 0, RUBY_TYPED_FREE_IMMEDIATELY
 };
 
@@ -2015,11 +2031,18 @@ struct autoload_data_i { https://github.com/ruby/ruby/blob/trunk/variable.c#L2031
 };
 
 static void
+autoload_i_compact(void *ptr)
+{
+    struct autoload_data_i *p = ptr;
+    p->feature = rb_gc_new_location(p->feature);
+}
+
+static void
 autoload_i_mark(void *ptr)
 {
     struct autoload_data_i *p = ptr;
 
-    rb_gc_mark(p->feature);
+    rb_gc_mark_no_pin(p->feature);
 
     /* allow GC to free us if no modules refer to this via autoload_const.ad */
     if (list_empty(&p->constants)) {
@@ -2046,7 +2069,7 @@ autoload_i_memsize(const void *ptr) https://github.com/ruby/ruby/blob/trunk/variable.c#L2069
 
 static const rb_data_type_t autoload_data_i_type = {
     "autoload_i",
-    {autoload_i_mark, autoload_i_free, autoload_i_memsize,},
+    {autoload_i_mark, autoload_i_free, autoload_i_memsize, autoload_i_compact},
     0, 0, RUBY_TYPED_FREE_IMMEDIATELY
 };
 
@@ -2971,6 +2994,7 @@ rb_define_const(VALUE klass, const char https://github.com/ruby/ruby/blob/trunk/variable.c#L2994
     if (!rb_is_const_id(id)) {
 	rb_warn("rb_define_const: invalid name `%s' for constant", name);
     }
+    rb_gc_register_mark_object(val);
     rb_const_set(klass, id, val);
 }
 
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 67575)
+++ vm_core.h	(revision 67576)
@@ -346,7 +346,7 @@ struct rb_iseq_constant_body { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L346
     } type;              /* instruction sequence type */
 
     unsigned int iseq_size;
-    const VALUE *iseq_encoded; /* encoded iseq (insn addr and operands) */
+    VALUE *iseq_encoded; /* encoded iseq (insn addr and operands) */
 
     /**
      * parameter information
@@ -414,7 +414,7 @@ struct rb_iseq_constant_body { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L414
 	    int bits_start;
 	    int rest_start;
 	    const ID *table;
-            const VALUE *default_values;
+            VALUE *default_values;
 	} *keyword;
     } param;
 
@@ -433,7 +433,7 @@ struct rb_iseq_constant_body { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L433
     const ID *local_table;		/* must free */
 
     /* catch table */
-    const struct iseq_catch_table *catch_table;
+    struct iseq_catch_table *catch_table;
 
     /* for child iseq */
     const struct rb_iseq_struct *parent_iseq;
@@ -1029,7 +1029,7 @@ typedef struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1029
 
 typedef struct {
     VALUE flags; /* imemo header */
-    const rb_iseq_t *iseq;
+    rb_iseq_t *iseq;
     const VALUE *ep;
     const VALUE *env;
     unsigned int env_size;
Index: iseq.c
===================================================================
--- iseq.c	(revision 67575)
+++ iseq.c	(revision 67576)
@@ -137,11 +137,11 @@ rb_vm_insn_null_translator(const void *a https://github.com/ruby/ruby/blob/trunk/iseq.c#L137
     return (VALUE)addr;
 }
 
-typedef void iseq_value_itr_t(void *ctx, VALUE obj);
+typedef VALUE iseq_value_itr_t(void *ctx, VALUE obj);
 typedef VALUE rb_vm_insns_translator_t(const void *addr);
 
 static int
-iseq_extract_values(const VALUE *code, size_t pos, iseq_value_itr_t * func, void *data, rb_vm_insns_translator_t * translator)
+iseq_extract_values(VALUE *code, size_t pos, iseq_value_itr_t * func, void *data, rb_vm_insns_translator_t * translator)
 {
     VALUE insn = translator((void *)code[pos]);
     int len = insn_len(insn);
@@ -157,7 +157,10 @@ iseq_extract_values(const VALUE *code, s https://github.com/ruby/ruby/blob/trunk/iseq.c#L157
 		{
 		    VALUE op = code[pos + op_no + 1];
 		    if (!SPECIAL_CONST_P(op)) {
-                        func(data, op);
+                        VALUE newop = func(data, op);
+                        if (newop != op) {
+                            code[pos + op_no + 1] = newop;
+                        }
 		    }
 		    break;
 		}
@@ -165,7 +168,10 @@ iseq_extract_values(const VALUE *code, s https://github.com/ruby/ruby/blob/trunk/iseq.c#L168
 		{
 		    union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)code[pos + op_no + 1];
 		    if (is->once.value) {
-                        func(data, is->once.value);
+                        VALUE nv = func(data, is->once.value);
+                        if (is->once.value != nv) {
+                            is->once.value = nv;
+                        }
 		    }
 		    break;
 		}
@@ -181,7 +187,7 @@ static void https://github.com/ruby/ruby/blob/trunk/iseq.c#L187
 rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
 {
     unsigned int size;
-    const VALUE *code;
+    VALUE *code;
     size_t n;
     rb_vm_insns_translator_t * translator;
     const struct rb_iseq_constant_body *const body = iseq->body;
@@ -205,10 +211,65 @@ rb_iseq_each_value(const rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/iseq.c#L211
     }
 }
 
-static void
+static VALUE
+update_each_insn_value(void *ctx, VALUE obj)
+{
+    return rb_gc_new_location(obj);
+}
+
+void
+rb_iseq_update_references(rb_iseq_t *iseq)
+{
+    if (iseq->body) {
+        struct rb_iseq_constant_body *body = iseq->body;
+
+        body->variable.coverage = rb_gc_new_location(body->variable.coverage);
+        body->variable.pc2branchindex = rb_gc_new_location(body->variable.pc2branchindex);
+        body->location.label = rb_gc_new_location(body->location.label);
+        body->location.base_label = rb_gc_new_location(body->location.base_label);
+        body->location.pathobj = rb_gc_new_location(body->location.pathobj);
+        if (body->local_iseq) {
+            body->local_iseq = (struct rb_iseq_struct *)rb_gc_new_location((VALUE)body->local_iseq);
+        }
+        if (body->parent_iseq) {
+            body->parent_iseq = (struct rb_iseq_struct *)rb_gc_new_location((VALUE)body->parent_iseq);
+        }
+        if (FL_TEST(iseq, ISEQ_MARKABLE_ISEQ)) {
+            rb_iseq_each_value(iseq, update_each_insn_value, NULL);
+        }
+
+        if (body->param.flags.has_kw && ISEQ_COMPILE_DATA(iseq) == NULL) {
+            int i, j;
+
+            i = body->param.keyword->required_num;
+
+            for (j = 0; i < body->param.keyword->num; i++, j++) {
+                VALUE obj = body->param.keyword->default_values[j];
+                if (obj != Qundef) {
+                    body->param.keyword->default_values[j] = rb_gc_new_location(obj);
+                }
+            }
+        }
+
+        if (body->catch_table) {
+            struct iseq_catch_table *table = body->catch_table;
+            unsigned int i;
+            for(i = 0; i < table->size; i++) {
+                struct iseq_catch_table_entry *entry;
+                entry = &table->entries[i];
+                if (entry->iseq) {
+                    entry->iseq = (rb_iseq_t *)rb_gc_new_location((VALUE)entry->iseq);
+                }
+            }
+        }
+    }
+}
+
+static VALUE
 each_insn_value(void *ctx, VALUE obj)
 {
-    rb_gc_mark(obj);
+    rb_gc_mark_no_pin(obj);
+    return obj;
 }
 
 void
@@ -225,12 +286,12 @@ rb_iseq_mark(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L286
 	    rb_iseq (... truncated)

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

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