Skip to content

Commit

Permalink
* method.h, vm_core.h: add rb_method_entry_t. Remove nodes around
Browse files Browse the repository at this point in the history
  method management.  This change affect some VM control stack structure.
* vm.c, vm_insnhelper.c, vm_method.c, vm_eval.c: ditto.  and make some
  refactoring.
* insns.def, class.c, eval.c, proc.c, vm_dump.c : ditto.
* vm_core.h, compile.c (iseq_specialized_instruction): remove
  VM_CALL_SEND_BIT.  use another optimization tech for Kernel#send.
* node.h: remove unused node types.
* ext/objspace/objspace.c (count_nodes): ditto.
* gc.c: add mark/free functions for method entry.
* include/ruby/intern.h: remove decl of
  rb_define_notimplement_method_id().  nobody can use it
  because noex is not opend.
* iseq.c (iseq_mark): fix to check ic_method is available.
* iseq.c (rb_iseq_disasm): fix to use rb_method_get_iseq().



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24128 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
ko1 committed Jul 15, 2009
1 parent d3cbda6 commit c330876
Show file tree
Hide file tree
Showing 19 changed files with 882 additions and 785 deletions.
27 changes: 27 additions & 0 deletions ChangeLog
@@ -1,3 +1,30 @@
Wed Jul 15 23:46:55 2009 Koichi Sasada <ko1@atdot.net>

* method.h, vm_core.h: add rb_method_entry_t. Remove nodes around
method management. This change affect some VM control stack structure.

* vm.c, vm_insnhelper.c, vm_method.c, vm_eval.c: ditto. and make some
refactoring.

* insns.def, class.c, eval.c, proc.c, vm_dump.c : ditto.

* vm_core.h, compile.c (iseq_specialized_instruction): remove
VM_CALL_SEND_BIT. use another optimization tech for Kernel#send.

* node.h: remove unused node types.

* ext/objspace/objspace.c (count_nodes): ditto.

* gc.c: add mark/free functions for method entry.

* include/ruby/intern.h: remove decl of
rb_define_notimplement_method_id(). nobody can use it
because noex is not opend.

* iseq.c (iseq_mark): fix to check ic_method is available.

* iseq.c (rb_iseq_disasm): fix to use rb_method_get_iseq().

Wed Jul 15 23:45:11 2009 Koichi Sasada <ko1@atdot.net>

* dir.c (push_glob): fix GC problem.
Expand Down
65 changes: 23 additions & 42 deletions class.c
Expand Up @@ -25,7 +25,8 @@

#include "ruby/ruby.h"
#include "ruby/st.h"
#include "node.h"
#include "method.h"
#include "vm_core.h"
#include <ctype.h>

extern st_table *rb_class_tbl;
Expand Down Expand Up @@ -123,28 +124,19 @@ struct clone_method_data {
VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase);

static int
clone_method(ID mid, NODE *body, struct clone_method_data *data)
clone_method(ID mid, const rb_method_entry_t *me, struct clone_method_data *data)
{
if (body == 0) {
st_insert(data->tbl, mid, 0);
}
else {
NODE *fbody = body->nd_body->nd_body;

if (nd_type(fbody) == RUBY_VM_METHOD_NODE) {
fbody = NEW_NODE(RUBY_VM_METHOD_NODE, 0,
rb_iseq_clone((VALUE)fbody->nd_body, data->klass),
0);
}
st_insert(data->tbl, mid,
(st_data_t)
NEW_NODE_LONGLIFE(
NODE_FBODY,
0,
NEW_NODE_LONGLIFE(NODE_METHOD,
rb_gc_write_barrier(data->klass), /* TODO */
rb_gc_write_barrier((VALUE)fbody),
body->nd_body->nd_noex), 0));
switch (me->type) {
case VM_METHOD_TYPE_ISEQ: {
VALUE newiseqval = rb_iseq_clone(me->body.iseq->self, data->klass);
rb_iseq_t *iseq;
GetISeqPtr(newiseqval, iseq);
rb_add_method(data->klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
break;
}
default:
rb_add_method_me(data->klass, mid, me, me->flag);
break;
}
return ST_CONTINUE;
}
Expand Down Expand Up @@ -674,7 +666,7 @@ ins_methods_pub_i(ID name, long type, VALUE ary)
}

static int
method_entry(ID key, NODE *body, st_table *list)
method_entry(ID key, const rb_method_entry_t *me, st_table *list)
{
long type;

Expand All @@ -683,11 +675,11 @@ method_entry(ID key, NODE *body, st_table *list)
}

if (!st_lookup(list, key, 0)) {
if (body ==0 || !body->nd_body->nd_body) {
if (!me || me->type == VM_METHOD_TYPE_UNDEF) {
type = -1; /* none */
}
else {
type = VISI(body->nd_body->nd_noex);
type = VISI(me->flag);
}
st_add_direct(list, key, type);
}
Expand Down Expand Up @@ -874,44 +866,33 @@ rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
}

void
rb_define_method_id(VALUE klass, ID name, VALUE (*func)(ANYARGS), int argc)
rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
{
if (func == rb_f_notimplement)
rb_define_notimplement_method_id(klass, name, NOEX_PUBLIC);
else
rb_add_method(klass, name, NEW_NODE_LONGLIFE(NODE_CFUNC, func, argc, 0), NOEX_PUBLIC);
rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC);
}

void
rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
rb_define_method_id(klass, rb_intern(name), func, argc);
rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC);
}

void
rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
ID id = rb_intern(name);
if (func == rb_f_notimplement)
rb_define_notimplement_method_id(klass, id, NOEX_PROTECTED);
else
rb_add_method(klass, id, NEW_NODE_LONGLIFE(NODE_CFUNC, func, argc, 0), NOEX_PROTECTED);
rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED);
}

void
rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
ID id = rb_intern(name);
if (func == rb_f_notimplement)
rb_define_notimplement_method_id(klass, id, NOEX_PRIVATE);
else
rb_add_method(klass, id, NEW_NODE_LONGLIFE(NODE_CFUNC, func, argc, 0), NOEX_PRIVATE);
rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE);
}

void
rb_undef_method(VALUE klass, const char *name)
{
rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF);
}

#define SPECIAL_SINGLETON(x,c) do {\
Expand Down
6 changes: 0 additions & 6 deletions compile.c
Expand Up @@ -1855,12 +1855,6 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
}
}
}

if (argc > 0) {
if (mid == idSend || mid == id__send__ ) {
OPERAND_AT(iobj, 3) |= INT2FIX(VM_CALL_SEND_BIT);
}
}
}
return COMPILE_OK;
}
Expand Down
2 changes: 1 addition & 1 deletion eval.c
Expand Up @@ -684,7 +684,7 @@ frame_func_id(rb_control_frame_t *cfp)
{
rb_iseq_t *iseq = cfp->iseq;
if (!iseq) {
return cfp->method_id;
return cfp->me->original_id;
}
while (iseq) {
if (RUBY_VM_IFUNC_P(iseq)) {
Expand Down
4 changes: 0 additions & 4 deletions ext/objspace/objspace.c
Expand Up @@ -350,9 +350,6 @@ count_nodes(int argc, VALUE *argv, VALUE os)
VALUE node;
switch (i) {
#define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); break;
COUNT_NODE(NODE_METHOD);
COUNT_NODE(NODE_FBODY);
COUNT_NODE(NODE_CFUNC);
COUNT_NODE(NODE_SCOPE);
COUNT_NODE(NODE_BLOCK);
COUNT_NODE(NODE_IF);
Expand Down Expand Up @@ -441,7 +438,6 @@ count_nodes(int argc, VALUE *argv, VALUE os)
COUNT_NODE(NODE_DOT3);
COUNT_NODE(NODE_FLIP2);
COUNT_NODE(NODE_FLIP3);
COUNT_NODE(NODE_ATTRSET);
COUNT_NODE(NODE_SELF);
COUNT_NODE(NODE_NIL);
COUNT_NODE(NODE_TRUE);
Expand Down
72 changes: 60 additions & 12 deletions gc.c
Expand Up @@ -1435,12 +1435,6 @@ mark_tbl(rb_objspace_t *objspace, st_table *tbl, int lev)
st_foreach(tbl, mark_entry, (st_data_t)&arg);
}

void
rb_mark_tbl(st_table *tbl)
{
mark_tbl(&rb_objspace, tbl, 0);
}

static int
mark_key(VALUE key, VALUE value, st_data_t data)
{
Expand Down Expand Up @@ -1490,6 +1484,64 @@ rb_mark_hash(st_table *tbl)
mark_hash(&rb_objspace, tbl, 0);
}

static void
mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me, int lev)
{
gc_mark(objspace, me->klass, lev);
switch (me->type) {
case VM_METHOD_TYPE_ISEQ:
gc_mark(objspace, me->body.iseq->self, lev);
break;
case VM_METHOD_TYPE_BMETHOD:
gc_mark(objspace, me->body.proc, lev);
break;
default:
break; /* ignore */
}
}

void
rb_gc_mark_method_entry(const rb_method_entry_t *me)
{
mark_method_entry(&rb_objspace, me, 0);
}

static int
mark_method_entry_i(ID key, const rb_method_entry_t *me, st_data_t data)
{
struct mark_tbl_arg *arg = (void*)data;
mark_method_entry(arg->objspace, me, arg->lev);
return ST_CONTINUE;
}

static void
mark_m_tbl(rb_objspace_t *objspace, st_table *tbl, int lev) {
struct mark_tbl_arg arg;
if (!tbl) return;
arg.objspace = objspace;
arg.lev = lev;
st_foreach(tbl, mark_method_entry_i, (st_data_t)&arg);
}

static int
free_method_entry_i(ID key, rb_method_entry_t *me, st_data_t data)
{
xfree(me);
return ST_CONTINUE;
}

static void
free_m_table(st_table *tbl)
{
st_foreach(tbl, free_method_entry_i, 0);
}

void
rb_mark_tbl(st_table *tbl)
{
mark_tbl(&rb_objspace, tbl, 0);
}

void
rb_gc_mark_maybe(VALUE obj)
{
Expand Down Expand Up @@ -1591,7 +1643,6 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
ptr = (VALUE)obj->as.node.u3.node;
goto again;

case NODE_METHOD: /* 1,2 */
case NODE_WHILE:
case NODE_UNTIL:
case NODE_AND:
Expand All @@ -1612,7 +1663,6 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
case NODE_ARGSCAT:
gc_mark(objspace, (VALUE)obj->as.node.u1.node, lev);
/* fall through */
case NODE_FBODY: /* 2 */
case NODE_GASGN:
case NODE_LASGN:
case NODE_DASGN:
Expand Down Expand Up @@ -1653,7 +1703,6 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)

case NODE_ZARRAY: /* - */
case NODE_ZSUPER:
case NODE_CFUNC:
case NODE_VCALL:
case NODE_GVAR:
case NODE_LVAR:
Expand All @@ -1669,7 +1718,6 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
case NODE_TRUE:
case NODE_FALSE:
case NODE_ERRINFO:
case NODE_ATTRSET:
case NODE_BLOCK_ARG:
break;
case NODE_ALLOCA:
Expand Down Expand Up @@ -1698,7 +1746,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
case T_ICLASS:
case T_CLASS:
case T_MODULE:
mark_tbl(objspace, RCLASS_M_TBL(obj), lev);
mark_m_tbl(objspace, RCLASS_M_TBL(obj), lev);
mark_tbl(objspace, RCLASS_IV_TBL(obj), lev);
ptr = RCLASS_SUPER(obj);
goto again;
Expand Down Expand Up @@ -2072,7 +2120,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
case T_MODULE:
case T_CLASS:
rb_clear_cache_by_class((VALUE)obj);
st_free_table(RCLASS_M_TBL(obj));
free_m_table(RCLASS_M_TBL(obj));
if (RCLASS_IV_TBL(obj)) {
st_free_table(RCLASS_IV_TBL(obj));
}
Expand Down
1 change: 0 additions & 1 deletion include/ruby/intern.h
Expand Up @@ -275,7 +275,6 @@ int rb_method_basic_definition_p(VALUE, ID);
VALUE rb_eval_cmd(VALUE, VALUE, int);
int rb_obj_respond_to(VALUE, ID, int);
int rb_respond_to(VALUE, ID);
void rb_define_notimplement_method_id(VALUE mod, ID id, int noex);
VALUE rb_f_notimplement(int argc, VALUE *argv, VALUE obj);
void rb_interrupt(void);
VALUE rb_apply(VALUE, ID, VALUE);
Expand Down

0 comments on commit c330876

Please sign in to comment.