summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-06-02 04:20:30 (GMT)
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-06-02 04:20:30 (GMT)
commit57b817f4c550e54ff57642b50723cc7c92bdd2fe (patch)
tree4eb5c4ef7ac97b4da216c22bcc1defa67942388f /proc.c
parentae042f21fb695fc80eb19273fa542e8dad85f19f (diff)
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50728 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c77
1 files changed, 29 insertions, 48 deletions
diff --git a/proc.c b/proc.c
index 1c6291e..faa82e3 100644
--- a/proc.c
+++ b/proc.c
@@ -21,8 +21,7 @@ struct METHOD {
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)
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, VALUE obj, ID id, ID rid, VALUE mclass)
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 *me, VALUE defined_class, VALUE klass,
}
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 *me, VALUE defined_class, VALUE klass,
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)
&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)
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)
}
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)
}
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_method_entry_t *me, int *max)
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_definition_t *def)
{
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)
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, VALUE self)
else {
sarity = FIX2INT(arity);
if (rb_proc_lambda_p(self)) {
+ bp();
rb_check_arity(sarity, min_arity, max_arity);
}
}