ruby-changes:37851
From: ko1 <ko1@a...>
Date: Wed, 11 Mar 2015 19:36:40 +0900 (JST)
Subject: [ruby-changes:37851] ko1:r49932 (trunk): * include/ruby/ruby.h: introduce new type T_IMEMO.
ko1 2015-03-11 19:36:17 +0900 (Wed, 11 Mar 2015) New Revision: 49932 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=49932 Log: * include/ruby/ruby.h: introduce new type T_IMEMO. T_IMEMO is Internal Memo type, internal use only. T_IMEMO has same purpose of NODE_MEMO. To insert T_IMEMO, type numbers are modified a little. * internal.h: define struct RIMemo. Each RIMemo objects has imemo_type. We can observe it by the imemo_type() function. * gc.c (rb_imemo_new): added. * node.h: remove NODE_CREF and NEW_CREF(). * node.c (rb_gc_mark_node): ditto. * vm.c (vm_cref_new): use rb_imem_new(). * vm_eval.c: ditto. * vm_eval.c (eval_string_with_cref): * vm_eval.c (rb_type_str): * vm_insnhelper.c: use RIMemo objects for CREF. * ext/objspace/objspace.c: support T_IMEMO. Modified files: trunk/ChangeLog trunk/ext/objspace/objspace.c trunk/gc.c trunk/include/ruby/ruby.h trunk/internal.h trunk/node.c trunk/node.h trunk/vm.c trunk/vm_eval.c trunk/vm_insnhelper.c Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 49931) +++ include/ruby/ruby.h (revision 49932) @@ -448,11 +448,12 @@ enum ruby_value_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L448 RUBY_T_FALSE = 0x13, RUBY_T_SYMBOL = 0x14, RUBY_T_FIXNUM = 0x15, + RUBY_T_UNDEF = 0x16, - RUBY_T_UNDEF = 0x1b, - RUBY_T_NODE = 0x1c, - RUBY_T_ICLASS = 0x1d, - RUBY_T_ZOMBIE = 0x1e, + RUBY_T_IMEMO = 0x1a, + RUBY_T_NODE = 0x1b, + RUBY_T_ICLASS = 0x1c, + RUBY_T_ZOMBIE = 0x1d, RUBY_T_MASK = 0x1f }; @@ -479,6 +480,7 @@ enum ruby_value_type { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L480 #define T_SYMBOL RUBY_T_SYMBOL #define T_RATIONAL RUBY_T_RATIONAL #define T_COMPLEX RUBY_T_COMPLEX +#define T_IMEMO RUBY_T_IMEMO #define T_UNDEF RUBY_T_UNDEF #define T_NODE RUBY_T_NODE #define T_ZOMBIE RUBY_T_ZOMBIE Index: ChangeLog =================================================================== --- ChangeLog (revision 49931) +++ ChangeLog (revision 49932) @@ -1,3 +1,32 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Mar 11 19:35:46 2015 Koichi Sasada <ko1@a...> + + * include/ruby/ruby.h: introduce new type T_IMEMO. + T_IMEMO is Internal Memo type, internal use only. + T_IMEMO has same purpose of NODE_MEMO. + + To insert T_IMEMO, type numbers are modified a little. + + * internal.h: define struct RIMemo. Each RIMemo objects + has imemo_type. We can observe it by the imemo_type() function. + + * gc.c (rb_imemo_new): added. + + * node.h: remove NODE_CREF and NEW_CREF(). + + * node.c (rb_gc_mark_node): ditto. + + * vm.c (vm_cref_new): use rb_imem_new(). + + * vm_eval.c: ditto. + + * vm_eval.c (eval_string_with_cref): + + * vm_eval.c (rb_type_str): + + * vm_insnhelper.c: use RIMemo objects for CREF. + + * ext/objspace/objspace.c: support T_IMEMO. + Wed Mar 11 17:03:20 2015 Koichi Sasada <ko1@a...> * gc.c: fix memory leak by prepend method. Index: vm_eval.c =================================================================== --- vm_eval.c (revision 49931) +++ vm_eval.c (revision 49932) @@ -498,6 +498,7 @@ rb_type_str(enum ruby_value_type type) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L498 type_case(T_FALSE) type_case(T_SYMBOL) type_case(T_FIXNUM) + type_case(T_IMEMO) type_case(T_UNDEF) type_case(T_NODE) type_case(T_ICLASS) @@ -1308,7 +1309,7 @@ eval_string_with_cref(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1309 if (!cref && base_block->iseq) { if (NIL_P(scope)) { orig_cref = rb_vm_get_cref(base_block->ep); - cref = (rb_cref_t *)NEW_CREF(Qnil); + cref = vm_cref_new(Qnil, 0, NULL); crefval = (VALUE) cref; COPY_CREF(cref, orig_cref); } Index: gc.c =================================================================== --- gc.c (revision 49931) +++ gc.c (revision 49932) @@ -380,6 +380,9 @@ typedef struct RVALUE { https://github.com/ruby/ruby/blob/trunk/gc.c#L380 struct RMatch match; struct RRational rational; struct RComplex complex; + union { + rb_cref_t cref; + } imemo; struct { struct RBasic basic; VALUE v1; @@ -1717,13 +1720,20 @@ rb_newobj_of(VALUE klass, VALUE flags) https://github.com/ruby/ruby/blob/trunk/gc.c#L1720 NODE* rb_node_newnode(enum node_type type, VALUE a0, VALUE a1, VALUE a2) { - VALUE flags = (RGENGC_WB_PROTECTED_NODE_CREF && type == NODE_CREF ? FL_WB_PROTECTED : 0); + VALUE flags = 0; NODE *n = (NODE *)newobj_of(0, T_NODE | flags, a0, a1, a2); nd_set_type(n, type); return n; } VALUE +rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0) +{ + VALUE flags = T_IMEMO | (type << FL_USHIFT) | FL_WB_PROTECTED; + return newobj_of(v0, flags, v1, v2, v3); +} + +VALUE rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree) { if (klass) Check_Type(klass, T_CLASS); @@ -1971,6 +1981,7 @@ obj_free(rb_objspace_t *objspace, VALUE https://github.com/ruby/ruby/blob/trunk/gc.c#L1981 break; case T_RATIONAL: case T_COMPLEX: + case T_IMEMO: break; case T_ICLASS: /* Basically , T_ICLASS shares table with the module */ @@ -2181,6 +2192,7 @@ internal_object_p(VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L2192 if (p->as.basic.flags) { switch (BUILTIN_TYPE(p)) { case T_NONE: + case T_IMEMO: case T_ICLASS: case T_NODE: case T_ZOMBIE: @@ -2917,6 +2929,7 @@ obj_memsize_of(VALUE obj, int use_all_ty https://github.com/ruby/ruby/blob/trunk/gc.c#L2929 break; case T_RATIONAL: case T_COMPLEX: + case T_IMEMO: break; case T_FLOAT: @@ -3060,6 +3073,7 @@ count_objects(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/gc.c#L3073 COUNT_TYPE(T_FALSE); COUNT_TYPE(T_SYMBOL); COUNT_TYPE(T_FIXNUM); + COUNT_TYPE(T_IMEMO); COUNT_TYPE(T_UNDEF); COUNT_TYPE(T_NODE); COUNT_TYPE(T_ICLASS); @@ -4134,6 +4148,17 @@ gc_mark_children(rb_objspace_t *objspace https://github.com/ruby/ruby/blob/trunk/gc.c#L4148 obj = rb_gc_mark_node(&any->as.node); if (obj) gc_mark(objspace, obj); return; /* no need to mark class. */ + + case T_IMEMO: + switch (imemo_type(obj)) { + case imemo_cref: + gc_mark(objspace, RANY(obj)->as.imemo.cref.klass); + gc_mark(objspace, (VALUE)RANY(obj)->as.imemo.cref.next); + gc_mark(objspace, RANY(obj)->as.imemo.cref.refinements); + return; + default: + rb_bug("unreachable"); + } } gc_mark(objspace, any->as.basic.klass); @@ -8609,6 +8634,7 @@ type_name(int type, VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L8634 TYPE_NAME(T_SYMBOL); TYPE_NAME(T_FIXNUM); TYPE_NAME(T_UNDEF); + TYPE_NAME(T_IMEMO); TYPE_NAME(T_NODE); TYPE_NAME(T_ICLASS); TYPE_NAME(T_ZOMBIE); Index: ext/objspace/objspace.c =================================================================== --- ext/objspace/objspace.c (revision 49931) +++ ext/objspace/objspace.c (revision 49932) @@ -56,6 +56,7 @@ total_i(void *vstart, void *vend, size_t https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L56 if (RBASIC(v)->flags) { switch (BUILTIN_TYPE(v)) { case T_NONE: + case T_IMEMO: case T_ICLASS: case T_NODE: case T_ZOMBIE: @@ -166,6 +167,7 @@ type2sym(enum ruby_value_type i) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L167 CASE_TYPE(T_SYMBOL); CASE_TYPE(T_FIXNUM); CASE_TYPE(T_UNDEF); + CASE_TYPE(T_IMEMO); CASE_TYPE(T_NODE); CASE_TYPE(T_ICLASS); CASE_TYPE(T_ZOMBIE); @@ -390,7 +392,6 @@ count_nodes(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L392 COUNT_NODE(NODE_SCLASS); COUNT_NODE(NODE_COLON2); COUNT_NODE(NODE_COLON3); - COUNT_NODE(NODE_CREF); COUNT_NODE(NODE_DOT2); COUNT_NODE(NODE_DOT3); COUNT_NODE(NODE_FLIP2); Index: internal.h =================================================================== --- internal.h (revision 49931) +++ internal.h (revision 49932) @@ -513,15 +513,44 @@ RCLASS_SET_SUPER(VALUE klass, VALUE supe https://github.com/ruby/ruby/blob/trunk/internal.h#L513 RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super); return super; } +/* IMEMO: Internal memo object */ + +/* FL_USER0, FL_USER1, FL_USER2: type */ +#define FL_IMEMO_MARK_V0 FL_USER6 +#define FL_IMEMO_MARK_V1 FL_USER3 +#define FL_IMEMO_MARK_V2 FL_USER4 +#define FL_IMEMO_MARK_V3 FL_USER5 + +struct RIMemo { + VALUE flags; + VALUE v0; + VALUE v1; + VALUE v2; + VALUE v3; +}; + +enum imemo_type { + imemo_none, + imemo_cref, + imemo_mask = 0x07 +}; + +static inline enum imemo_type +imemo_type(VALUE imemo) +{ + return (RBASIC(imemo)->flags >> FL_USHIFT) & imemo_mask; +} + +VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0); /* CREF */ typedef struct rb_cref_struct { VALUE flags; - VALUE refinements; - VALUE klass; + const VALUE refinements; + const VALUE klass; VALUE visi; - struct rb_cref_struct *next; + struct rb_cref_struct * const next; } rb_cref_t; #define NODE_FL_CREF_PUSHED_BY_EVAL_ (((VALUE)1)<<15) Index: vm.c =================================================================== --- vm.c (revision 49931) +++ vm.c (revision 49932) @@ -82,10 +82,7 @@ rb_vm_control_frame_block_ptr(const rb_c https://github.com/ruby/ruby/blob/trunk/vm.c#L82 static rb_cref_t * vm_cref_new(VALUE klass, long visi, const rb_cref_t *prev_cref) { - rb_cref_t *cref = (rb_cref_t *)NEW_CREF(klass); - CREF_REFINEMENTS_SET(cref, Qnil); - CREF_VISI_SET(cref, visi); - CREF_NEXT_SET(cref, prev_cref); + rb_cref_t *cref = (rb_cref_t *)rb_imemo_new(imemo_cref, klass, visi, (VALUE)prev_cref, Qnil); return cref; } Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 49931) +++ vm_insnhelper.c (revision 49932) @@ -163,7 +163,7 @@ lep_svar_get(rb_thread_t *th, const VALU https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L163 const struct SVAR *const svar = *svar_place; if (NIL_P((VALUE)svar)) return Qnil; - if (nd_type(svar) == NODE_CREF) return Qnil; + if (RB_TYPE_P((VALUE)svar, T_IMEMO) && imemo_type((VALUE)svar) == imemo_cref) return Qnil; switch (key) { case VM_SVAR_LASTLINE: @@ -193,7 +193,7 @@ lep_svar_set(rb_thread_t *th, VALUE *lep https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L193 svar = *svar_place = (struct SVAR *)NEW_IF(Qnil, Qnil, Qnil); svar->cref = NULL; } - else if (nd_type(svar) == NODE_CREF) { + else if (RB_TYPE_P((VALUE)svar, T_IMEMO) && imemo_type((VALUE)svar) == imemo_cref) { const rb_cref_t *cref = (rb_cref_t *)svar; svar = *svar_place = (struct SVAR *)NEW_IF(Qnil, Qnil, Qnil); RB_OBJ_WRITE(svar, &svar->cref, (VALUE)cref); @@ -261,7 +261,7 @@ lep_cref(const VALUE *ep) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L261 if (!svar) { return NULL; } - else if (nd_type(svar) == NODE_CREF) { + else if (RB_TYPE_P((VALUE)svar, T_IMEMO) && imemo_type(svar) == imemo_cref) { return (rb_cref_t *)svar; } else { @@ -300,13 +300,13 @@ rb_vm_rewrite_cref_stack(rb_cref_t *node https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L300 while (node) { if (CREF_CLASS(node) == old_klass) { - new_node = (rb_cref_t *)NEW_CREF(new_klass); + new_node = vm_cref_new(new_klass, 0, NULL); COPY_CREF_OMOD(new_node, node); CREF_NEXT_SET(new_node, CREF_NEXT(node)); *new_cref_ptr = new_node; return; } - new_node = (rb_cref_t *)NEW_CREF(CREF_CLASS(node)); + new_node = vm_cref_new(CREF_CLASS(node), 0, NULL); COPY_CREF_OMOD(new_node, node); node = CREF_NEXT(node); *new_cref_ptr = new_node; Index: node.c =================================================================== --- node.c (revision 49931) +++ node.c (revision 49932) @@ -1069,11 +1069,6 @@ rb_gc_mark_node(NODE *obj) https://github.com/ruby/ruby/blob/trunk/node.c#L1069 rb_gc_mark(RNODE(obj)->u2.value); break; - case NODE_CREF: - rb_gc_mark(CREF_REFINEMENTS((rb_cref_t *)obj)); - rb_gc_mark(CREF_CLASS((rb_cref_t *)obj)); - return (VALUE)CREF_NEXT((rb_cref_t *)obj); - default: /* unlisted NODE */ rb_gc_mark_maybe(RNODE(obj)->u1.value); rb_gc_mark_maybe(RNODE(obj)->u2.value); Index: node.h =================================================================== --- node.h (revision 49931) +++ node.h (revision 49932) @@ -192,8 +192,6 @@ enum node_type { https://github.com/ruby/ruby/blob/trunk/node.h#L192 #define NODE_COLON2 NODE_COLON2 NODE_COLON3, #define NODE_COLON3 NODE_COLON3 - NODE_CREF, -#define NODE_CREF NODE_CREF NODE_DOT2, #define NODE_DOT2 NODE_DOT2 NODE_DOT3, @@ -447,7 +445,6 @@ typedef struct RNode { https://github.com/ruby/ruby/blob/trunk/node.h#L445 #define NEW_MODULE(n,b) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(0,b),0) #define NEW_COLON2(c,i) NEW_NODE(NODE_COLON2,c,i,0) #define NEW_COLON3(i) NEW_NODE(NODE_COLON3,0,i,0) -#define NEW_CREF(a) NEW_NODE(NODE_CREF,a,0,0) #define NEW_DOT2(b,e) NEW_NODE(NODE_DOT2,b,e,0) #define NEW_DOT3(b,e) NEW_NODE(NODE_DOT3,b,e,0) #define NEW_SELF() NEW_NODE(NODE_SELF,0,0,0) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/