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

ruby-changes:38647

From: ko1 <ko1@a...>
Date: Tue, 2 Jun 2015 13:20:42 +0900 (JST)
Subject: [ruby-changes:38647] ko1:r50728 (trunk): * method.h: make rb_method_entry_t a VALUE.

ko1	2015-06-02 13:20:30 +0900 (Tue, 02 Jun 2015)

  New Revision: 50728

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

  Log:
    * method.h: make rb_method_entry_t a VALUE.
      Motivation and new data structure are described in [Bug #11203].
      This patch also solve the following issues.
      * [Bug #11200] Memory leak of method entries
      * [Bug #11046] __callee__ returns incorrect method name in orphan
                     proc
    * test/ruby/test_method.rb: add a test for [Bug #11046].
    * vm_core.h: remvoe rb_control_frame_t::me. me is located at value
      stack.
    * vm_core.h, gc.c, vm_method.c: remove unlinked_method... codes
      because method entries are simple VALUEs.
    * method.h:  Now, all method entries has own independent method
      definititons. Strictly speaking, this change is not essential,
      but for future changes.
      * rb_method_entry_t::flag is move to rb_method_definition_t::flag.
      * rb_method_definition_t::alias_count is now
        rb_method_definition_t::alias_count_ptr, a pointer to the counter.
    * vm_core.h, vm_insnhelper.c (rb_vm_frame_method_entry) added to
      search the current method entry from value stack.
    * vm_insnhelper.c (VM_CHECK_MODE): introduced to enable/disable
      assertions.

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/cont.c
    trunk/eval.c
    trunk/gc.c
    trunk/insns.def
    trunk/internal.h
    trunk/method.h
    trunk/proc.c
    trunk/struct.c
    trunk/test/ruby/test_method.rb
    trunk/thread.c
    trunk/vm.c
    trunk/vm_args.c
    trunk/vm_backtrace.c
    trunk/vm_core.h
    trunk/vm_dump.c
    trunk/vm_eval.c
    trunk/vm_insnhelper.c
    trunk/vm_method.c
Index: method.h
===================================================================
--- method.h	(revision 50727)
+++ method.h	(revision 50728)
@@ -44,6 +44,14 @@ typedef enum { https://github.com/ruby/ruby/blob/trunk/method.h#L44
 
 /* method data type */
 
+typedef struct rb_method_entry_struct {
+    VALUE flags;
+    VALUE reserved;
+    struct rb_method_definition_struct * const def;
+    ID called_id;
+    const VALUE klass;    /* should be marked */
+} rb_method_entry_t;
+
 typedef enum {
     VM_METHOD_TYPE_ISEQ,
     VM_METHOD_TYPE_CFUNC,
@@ -61,6 +69,14 @@ typedef enum { https://github.com/ruby/ruby/blob/trunk/method.h#L69
     END_OF_ENUMERATION(VM_METHOD_TYPE)
 } rb_method_type_t;
 
+typedef struct rb_iseq_struct rb_iseq_t;
+
+typedef struct rb_method_iseq_struct {
+    rb_iseq_t * const iseqptr;                    /* should be separated from iseqval */
+    rb_cref_t * const cref;                       /* shoudl be marked */
+    const VALUE iseqval;                          /* should be marked */
+} rb_method_iseq_t;
+
 typedef struct rb_method_cfunc_struct {
     VALUE (*func)(ANYARGS);
     VALUE (*invoker)(VALUE (*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv);
@@ -69,25 +85,21 @@ typedef struct rb_method_cfunc_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L85
 
 typedef struct rb_method_attr_struct {
     ID id;
-    const VALUE location;
+    const VALUE location; /* sould be marked */
 } rb_method_attr_t;
 
 typedef struct rb_method_alias_struct {
     const struct rb_method_entry_struct *original_me; /* original_me->klass is original owner */
 } rb_method_alias_t;
 
-typedef struct rb_iseq_struct rb_iseq_t;
-
 typedef struct rb_method_definition_struct {
+    rb_method_flag_t flag;
     rb_method_type_t type; /* method type */
-    int alias_count;
+    int *alias_count_ptr;
     ID original_id;
 
     union {
-	struct {
-	    rb_iseq_t *const iseq;            /* should be marked */
-	    rb_cref_t *cref;
-	} iseq_body;
+	rb_method_iseq_t iseq;
 	rb_method_cfunc_t cfunc;
 	rb_method_attr_t attr;
 	rb_method_alias_t alias;
@@ -102,26 +114,13 @@ typedef struct rb_method_definition_stru https://github.com/ruby/ruby/blob/trunk/method.h#L114
     } body;
 } rb_method_definition_t;
 
-typedef struct rb_method_entry_struct {
-    rb_method_flag_t flag;
-    char mark;
-    rb_method_definition_t *def;
-    ID called_id;
-    VALUE klass;                    /* should be marked */
-} rb_method_entry_t;
-
-struct unlinked_method_entry_list_entry {
-    struct unlinked_method_entry_list_entry *next;
-    rb_method_entry_t *me;
-};
-
 #define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
 #define UNDEFINED_REFINED_METHOD_P(def) \
     ((def)->type == VM_METHOD_TYPE_REFINED && \
      UNDEFINED_METHOD_ENTRY_P((def)->body.orig_me))
 
 void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_flag_t noex);
-void rb_add_method_iseq(VALUE klass, ID mid, rb_iseq_t *iseq, rb_cref_t *cref, rb_method_flag_t noex);
+void rb_add_method_iseq(VALUE klass, ID mid, VALUE iseq, rb_cref_t *cref, rb_method_flag_t noex);
 rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex);
 rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr);
 rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id);
@@ -145,8 +144,11 @@ VALUE rb_method_entry_location(const rb_ https://github.com/ruby/ruby/blob/trunk/method.h#L144
 VALUE rb_mod_method_location(VALUE mod, ID id);
 VALUE rb_obj_method_location(VALUE obj, ID id);
 
-void rb_mark_method_entry(const rb_method_entry_t *me);
 void rb_free_method_entry(const rb_method_entry_t *me);
 void rb_sweep_method_entry(void *vm);
 
+rb_method_entry_t *rb_method_entry_create(ID called_id, VALUE klass, rb_method_definition_t *def);
+rb_method_entry_t *rb_method_entry_clone(const rb_method_entry_t *me);
+void rb_method_entry_copy(rb_method_entry_t *dst, rb_method_entry_t *src);
+
 #endif /* METHOD_H */
Index: insns.def
===================================================================
--- insns.def	(revision 50727)
+++ insns.def	(revision 50728)
@@ -760,8 +760,9 @@ defined https://github.com/ruby/ruby/blob/trunk/insns.def#L760
 	const rb_method_entry_t *me = rb_method_entry(klass, SYM2ID(obj), 0);
 
 	if (me) {
-	    if (!(me->flag & NOEX_PRIVATE)) {
-		if (!((me->flag & NOEX_PROTECTED) &&
+	    const rb_method_definition_t *def = me->def;
+	    if (!(def->flag & NOEX_PRIVATE)) {
+		if (!((def->flag & NOEX_PROTECTED) &&
 		      !rb_obj_is_kind_of(GET_SELF(),
 					 rb_class_real(klass)))) {
 		    expr_type = DEFINED_METHOD;
@@ -1015,9 +1016,9 @@ defineclass https://github.com/ruby/ruby/blob/trunk/insns.def#L1016
     vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS,
 		  klass, 0,
 		  VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
-		  vm_cref_push(th, klass, NOEX_PUBLIC, NULL),
+		  (VALUE)vm_cref_push(th, klass, NOEX_PUBLIC, NULL),
 		  class_iseq->iseq_encoded, GET_SP(),
-		  class_iseq->local_size, 0, class_iseq->stack_max);
+		  class_iseq->local_size, class_iseq->stack_max);
 
     RESTORE_REGS();
     NEXT_INSN();
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50727)
+++ ChangeLog	(revision 50728)
@@ -1,3 +1,36 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Jun  2 12:43:46 2015  Koichi Sasada  <ko1@a...>
+
+	* method.h: make rb_method_entry_t a VALUE.
+	  Motivation and new data structure are described in [Bug #11203].
+
+	  This patch also solve the following issues.
+
+	  * [Bug #11200] Memory leak of method entries
+	  * [Bug #11046] __callee__ returns incorrect method name in orphan
+	                 proc
+
+	* test/ruby/test_method.rb: add a test for [Bug #11046].
+
+	* vm_core.h: remvoe rb_control_frame_t::me. me is located at value
+	  stack.
+
+	* vm_core.h, gc.c, vm_method.c: remove unlinked_method... codes
+	  because method entries are simple VALUEs.
+
+	* method.h:  Now, all method entries has own independent method
+	  definititons. Strictly speaking, this change is not essential,
+	  but for future changes.
+
+	  * rb_method_entry_t::flag is move to rb_method_definition_t::flag.
+	  * rb_method_definition_t::alias_count is now
+	    rb_method_definition_t::alias_count_ptr, a pointer to the counter.
+
+	* vm_core.h, vm_insnhelper.c (rb_vm_frame_method_entry) added to
+	  search the current method entry from value stack.
+
+	* vm_insnhelper.c (VM_CHECK_MODE): introduced to enable/disable
+	  assertions.
+
 Tue Jun  2 10:46:36 2015  Eric Wong  <e@8...>
 
 	* test/socket/test_nonblock.rb: new test for sendmsg_nonblock
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 50727)
+++ vm_core.h	(revision 50728)
@@ -440,8 +440,6 @@ typedef struct rb_vm_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L440
     VALUE verbose, debug, orig_progname, progname;
     VALUE coverages;
 
-    struct unlinked_method_entry_list_entry *unlinked_method_entry_list;
-
     VALUE defined_module_hash;
 
 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
@@ -513,10 +511,9 @@ typedef struct rb_control_frame_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L511
     VALUE *ep;			/* cfp[6] / block[2] */
     rb_iseq_t *block_iseq;	/* cfp[7] / block[3] */
     VALUE proc;			/* cfp[8] / block[4] */
-    const rb_method_entry_t *me;/* cfp[9] */
 
 #if VM_DEBUG_BP_CHECK
-    VALUE *bp_check;		/* cfp[10] */
+    VALUE *bp_check;		/* cfp[9] */
 #endif
 } rb_control_frame_t;
 
@@ -954,7 +951,6 @@ void rb_vm_gvl_destroy(rb_vm_t *vm); https://github.com/ruby/ruby/blob/trunk/vm_core.h#L951
 VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc,
 		 const VALUE *argv, const rb_method_entry_t *me,
 		 VALUE defined_class);
-void rb_gc_mark_unlinked_live_method_entries(void *pvm);
 
 void rb_thread_start_timer_thread(void);
 void rb_thread_stop_timer_thread(int);
@@ -1001,6 +997,8 @@ int rb_autoloading_value(VALUE mod, ID i https://github.com/ruby/ruby/blob/trunk/vm_core.h#L997
 
 void rb_vm_rewrite_cref_stack(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr);
 
+const rb_method_entry_t *rb_vm_frame_method_entry(const rb_control_frame_t *cfp);
+
 #define sysstack_error GET_VM()->special_exceptions[ruby_error_sysstack]
 
 #define RUBY_CONST_ASSERT(expr) (1/!!(expr)) /* expr must be a compile-time constant */
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 50727)
+++ vm_eval.c	(revision 50728)
@@ -120,8 +120,8 @@ vm_call0_cfunc_with_frame(rb_thread_t* t https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L120
 	rb_control_frame_t *reg_cfp = th->cfp;
 
 	vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv, defined_class,
-		      VM_ENVVAL_BLOCK_PTR(blockptr), NULL /* cref */,
-		      0, reg_cfp->sp, 1, me, 0);
+		      VM_ENVVAL_BLOCK_PTR(blockptr), (VALUE)me,
+		      0, reg_cfp->sp, 1, 0);
 
 	if (len >= 0) rb_check_arity(argc, len, len);
 
@@ -200,8 +200,7 @@ vm_call0_body(rb_thread_t* th, rb_call_i https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L200
       case VM_METHOD_TYPE_REFINED:
 	{
 	    const rb_method_type_t type = ci->me->def->type;
-	    if (type == VM_METHOD_TYPE_REFINED &&
-		ci->me->def->body.orig_me) {
+	    if (type == VM_METHOD_TYPE_REFINED && ci->me->def->body.orig_me) {
 		ci->me = ci->me->def->body.orig_me;
 		goto again;
 	    }
@@ -283,7 +282,7 @@ vm_call_super(rb_thread_t *th, int argc, https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L282
 
     klass = RCLASS_ORIGIN(cfp->klass);
     klass = RCLASS_SUPER(klass);
-    id = cfp->me->def->original_id;
+    id = rb_vm_frame_method_entry(cfp)->def->original_id;
     me = rb_method_entry(klass, id, &klass);
     if (!me) {
 	return method_missing(recv, id, argc, argv, NOEX_SUPER);
@@ -392,7 +391,7 @@ check_funcall_respond_to(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L391
     VALUE defined_class;
     const rb_method_entry_t *me = rb_method_entry(klass, idRespond_to, &defined_class);
 
-    if (me && !(me->flag & NOEX_BASIC)) {
+    if (me && !(me->def->flag & NOEX_BASIC)) {
 	const rb_block_t *passed_block = th->passed_block;
 	VALUE args[2], result;
 	int arity = rb_method_entry_arity(me);
@@ -575,7 +574,7 @@ rb_method_call_status(rb_thread_t *th, c https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L574
     }
     klass = me->klass;
     oid = me->def->original_id;
-    noex = me->flag;
+    noex = me->def->flag;
 
     if (oid != idMethodMissing) {
 	/* receiver specified form for private method */
Index: proc.c
===================================================================
--- proc.c	(revision 50727)
+++ proc.c	(revision 50728)
@@ -21,8 +21,7 @@ struct METHOD { https://github.com/ruby/ruby/blob/trunk/proc.c#L21
     VALUE rclass;
     VALUE defined_class;
     ID id;
-    rb_method_entry_t *me;
-    struct unlinked_method_entry_list_entry *ume;
+    rb_method_entry_t * const me;
 };
 
 VALUE rb_cUnboundMethod;
@@ -1100,18 +1099,12 @@ bm_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/proc.c#L1099
     rb_gc_mark(data->defined_class);
     rb_gc_mark(data->rclass);
     rb_gc_mark(data->recv);
-    if (data->me) rb_mark_method_entry(data->me);
+    rb_gc_mark((VALUE)data->me);
 }
 
 static void
 bm_free(void *ptr)
 {
-    struct METHOD *data = ptr;
-    struct unlinked_method_entry_list_entry *ume = data->ume;
-    data->me->mark = 0;
-    ume->me = data->me;
-    ume->next = GET_VM()->unlinked_method_entry_list;
-    GET_VM()->unlinked_method_entry_list = ume;
     xfree(ptr);
 }
 
@@ -1167,22 +1160,13 @@ mnew_missing(VALUE rclass, VALUE klass, https://github.com/ruby/ruby/blob/trunk/proc.c#L1160
     data->defined_class = klass;
     data->id = rid;
 
-    me = ALLOC(rb_method_entry_t);
-    data->me = me;
-    me->flag = 0;
-    me->mark = 0;
-    me->called_id = id;
-    me->klass = klass;
-    me->def = 0;
-
-    def = ALLOC(rb_method_definition_t);
-    me->def = def;
+    def = ZALLOC(rb_method_definition_t);
+    def->flag = 0;
     def->type = VM_METHOD_TYPE_MISSING;
     def->original_id = id;
-    def->alias_count = 0;
 
-    data->ume = ALLOC(struct unlinked_method_entry_list_entry);
-    data->me->def->alias_count++;
+    me = rb_method_entry_create(id, klass, def);
+    RB_OBJ_WRITE(method, &data->me, me);
 
     OBJ_INFECT(method, klass);
 
@@ -1210,13 +1194,13 @@ mnew_internal(const rb_method_entry_t *m https://github.com/ruby/ruby/blob/trunk/proc.c#L1194
     }
     def = me->def;
     if (flag == NOEX_UNDEF) {
-	flag = me->flag;
+	flag = def->flag;
 	if (scope && (flag & NOEX_MASK) != NOEX_PUBLIC) {
 	    if (!error) return Qnil;
 	    rb_print_inaccessible(klass, id, flag & NOEX_MASK);
 	}
     }
-    if (def && def->type == VM_METHOD_TYPE_ZSUPER) {
+    if (def->type == VM_METHOD_TYPE_ZSUPER) {
 	klass = RCLASS_SUPER(defined_class);
 	id = def->original_id;
 	me = rb_method_entry_without_refinements(klass, id, &defined_class);
@@ -1236,13 +1220,8 @@ mnew_internal(const rb_method_entry_t *m https://github.com/ruby/ruby/blob/trunk/proc.c#L1220
     data->rclass = rclass;
     data->defined_class = defined_class;
     data->id = rid;
-    data->me = ALLOC(rb_method_entry_t);
-    *data->me = *me;
-    data->ume = ALLOC(struct unlinked_method_entry_list_entry);
-    data->me->def->alias_count++;
-
+    RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(me));
     OBJ_INFECT(method, klass);
-
     return method;
 }
 
@@ -1364,12 +1343,9 @@ method_unbind(VALUE obj) https://github.com/ruby/ruby/blob/trunk/proc.c#L1343
 				   &method_data_type, data);
     data->recv = Qundef;
     data->id = orig->id;
-    data->me = ALLOC(rb_method_entry_t);
-    *data->me = *orig->me;
-    if (orig->me->def) orig->me->def->alias_count++;
+    RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me));
     data->rclass = orig->rclass;
     data->defined_class = orig->defined_class;
-    data->ume = ALLOC(struct unlinked_method_entry_list_entry);
     OBJ_INFECT(method, obj);
 
     return method;
@@ -1832,12 +1808,11 @@ method_clone(VALUE self) https://github.com/ruby/ruby/blob/trunk/proc.c#L1808
     TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig);
     clone = TypedData_Make_Struct(CLASS_OF(self), struct METHOD, &method_data_type, data);
     CLONESETUP(clone, self);
-    *data = *orig;
-    data->me = ALLOC(rb_method_entry_t);
-    *data->me = *orig->me;
-    if (data->me->def) data->me->def->alias_count++;
-    data->ume = ALLOC(struct unlinked_method_entry_list_entry);
-
+    data->recv = orig->recv;
+    data->rclass = orig->rclass;
+    data->defined_class = orig->defined_class;
+    data->id = orig->id;
+    RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
     return clone;
 }
 
@@ -2020,10 +1995,11 @@ umethod_bind(VALUE method, VALUE recv) https://github.com/ruby/ruby/blob/trunk/proc.c#L1995
     }
 
     method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
-    *bound = *data;
-    bound->me = ALLOC(rb_method_entry_t);
-    *bound->me = *data->me;
-    if (bound->me->def) bound->me->def->alias_count++;
+    bound->recv = data->recv;
+    bound->rclass = data->rclass;
+    bound->defined_class = data->defined_class;
+    bound->id = data->id;
+    RB_OBJ_WRITE(method, &bound->me, rb_method_entry_clone(data->me));
     rclass = CLASS_OF(recv);
     if (BUILTIN_TYPE(bound->defined_class) == T_MODULE) {
 	VALUE ic = rb_class_search_ancestor(rclass, bound->defined_class);
@@ -2036,7 +2012,6 @@ umethod_bind(VALUE method, VALUE recv) https://github.com/ruby/ruby/blob/trunk/proc.c#L2012
     }
     bound->recv = recv;
     bound->rclass = rclass;
-    data->ume = ALLOC(struct unlinked_method_entry_list_entry);
 
     return method;
 }
@@ -2071,7 +2046,8 @@ rb_method_entry_min_max_arity(const rb_m https://github.com/ruby/ruby/blob/trunk/proc.c#L2046
       case VM_METHOD_TYPE_BMETHOD:
 	return rb_proc_min_max_arity(def->body.proc, max);
       case VM_METHOD_TYPE_ISEQ: {
-	rb_iseq_t *iseq = def->body.iseq_body.iseq;
+	rb_iseq_t *iseq;
+	GetISeqPtr(def->body.iseq.iseqval, iseq);
 	return rb_iseq_min_max_arity(iseq, max);
       }
       case VM_METHOD_TYPE_UNDEF:
@@ -2207,7 +2183,11 @@ method_def_iseq(const rb_method_definiti https://github.com/ruby/ruby/blob/trunk/proc.c#L2183
 {
     switch (def->type) {
       case VM_METHOD_TYPE_ISEQ:
-	return def->body.iseq_body.iseq;
+	{
+	    rb_iseq_t *iseq;
+	    GetISeqPtr(def->body.iseq.iseqval, iseq);
+	    return iseq;
+	}
       case VM_METHOD_TYPE_BMETHOD:
 	return get_proc_iseq(def->body.proc, 0);
       case VM_METHOD_TYPE_ALIAS:
@@ -2240,7 +2220,7 @@ method_cref(VALUE method) https://github.com/ruby/ruby/blob/trunk/proc.c#L2220
   again:
     switch (def->type) {
       case VM_METHOD_TYPE_ISEQ:
-	return def->body.iseq_body.cref;
+	return def->body.iseq.cref;
       case VM_METHOD_TYPE_ALIAS:
 	def = def->body.alias.original_me->def;
 	goto again;
@@ -2675,6 +2655,7 @@ proc_curry(int argc, const VALUE *argv, https://github.com/ruby/ruby/blob/trunk/proc.c#L2655
     else {
 	sarity = FIX2INT(arity);
 	if (rb_proc_lambda_p(self)) {
+	    bp();
 	    rb_check_arity(sarity, min_arity, max_arity);
 	}
     }
Index: thread.c
===================================================================
--- thread.c	(revision 50727)
+++ thread.c	(revision 50728)
@@ -580,7 +580,7 @@ thread_start_func_2(rb_thread_t *th, VAL https://github.com/ruby/ruby/blob/trunk/thread.c#L580
 		    GetProcPtr(th->first_proc, proc);
 		    th->errinfo = Qnil;
 		    th->root_lep = rb_vm_ep_local_ep(proc->block.ep);
-		    th->root_svar = Qnil;
+		    th->root_svar = Qfalse;
 		    EXEC_EVENT_HOOK(th, RUBY_EVENT_THREAD_BEGIN, th->self, 0, 0, Qundef);
 		    th->value = rb_vm_invoke_proc(th, proc, (int)RARRAY_LEN(args), RARRAY_CONST_PTR(args), 0);
 		    EXEC_EVENT_HOOK(th, RUBY_EVENT_THREAD_END, th->self, 0, 0, Qundef);
Index: vm_backtrace.c
===================================================================
--- vm_backtrace.c	(revision 50727)
+++ vm_backtrace.c	(revision 50728)
@@ -465,7 +465,8 @@ backtrace_each(rb_thread_t *th, https://github.com/ruby/ruby/blob/trunk/vm_backtrace.c#L465
 	    }
 	}
 	else if (RUBYVM_CFUNC_FRAME_P(cfp)) {
-	    ID mid = cfp->me->def ? cfp->me->def->original_id : cfp->me->called_id;
+	    const rb_method_entry_t *me = rb_vm_frame_method_entry(cfp);
+	    ID mid = me->def->original_id;
 
 	    iter_cfunc(arg, cfp, mid);
 	}
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 50727)
+++ vm_method.c	(revision 50728)
@@ -2,6 +2,8 @@ https://github.com/ruby/ruby/blob/trunk/vm_method.c#L2
  * This file is included by vm.c
  */
 
+#define METHOD_DEBUG 0
+
 #if OPT_GLOBAL_METHOD_CACHE
 #ifndef GLOBAL_METHOD_CACHE_SIZE
 #define GLOBAL_METHOD_CACHE_SIZE 0x800
@@ -110,7 +112,7 @@ rb_f_notimplement(int argc, const VALUE https://github.com/ruby/ruby/blob/trunk/vm_method.c#L112
 static void
 rb_define_notimplement_method_id(VALUE mod, ID id, rb_method_flag_t noex)
 {
-    rb_add_method(mod, id, VM_METHOD_TYPE_NOTIMPLEMENTED, 0, noex);
+    rb_add_method(mod, id, VM_METHOD_TYPE_NOTIMPLEMENTED, (void *)1, noex);
 }
 
 void
@@ -129,80 +131,33 @@ rb_add_method_cfunc(VALUE klass, ID mid, https://github.com/ruby/ruby/blob/trunk/vm_method.c#L131
 }
 
 static void
-rb_unlink_method_entry(rb_method_entry_t *me)
-{
-    struct unlinked_method_entry_list_entry *ume = ALLOC(struct unlinked_method_entry_list_entry);
-    ume->me = me;
-    ume->next = GET_VM()->unlinked_method_entry_list;
-    GET_VM()->unlinked_method_entry_list = ume;
-}
-
-void
-rb_gc_mark_unlinked_live_method_entries(void *pvm)
+rb_method_definition_release(rb_method_definition_t *def)
 {
-    rb_vm_t *vm = pvm;
-    struct unlinked_method_entry_li (... truncated)

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

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