diff options
-rw-r--r-- | ChangeLog | 29 | ||||
-rw-r--r-- | ext/objspace/objspace.c | 3 | ||||
-rw-r--r-- | gc.c | 28 | ||||
-rw-r--r-- | include/ruby/ruby.h | 10 | ||||
-rw-r--r-- | internal.h | 35 | ||||
-rw-r--r-- | node.c | 5 | ||||
-rw-r--r-- | node.h | 3 | ||||
-rw-r--r-- | vm.c | 5 | ||||
-rw-r--r-- | vm_eval.c | 3 | ||||
-rw-r--r-- | vm_insnhelper.c | 10 |
10 files changed, 104 insertions, 27 deletions
@@ -1,3 +1,32 @@ +Wed Mar 11 19:35:46 2015 Koichi Sasada <ko1@atdot.net> + + * 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@atdot.net> * gc.c: fix memory leak by prepend method. diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c index 038461a394..fe07ca84f3 100644 --- a/ext/objspace/objspace.c +++ b/ext/objspace/objspace.c @@ -56,6 +56,7 @@ total_i(void *vstart, void *vend, size_t stride, void *ptr) 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) 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 os) 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); @@ -380,6 +380,9 @@ typedef struct RVALUE { 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) 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 obj) 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) 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_types) break; case T_RATIONAL: case T_COMPLEX: + case T_IMEMO: break; case T_FLOAT: @@ -3060,6 +3073,7 @@ count_objects(int argc, VALUE *argv, VALUE os) 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, VALUE obj) 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) 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); diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index a35186c949..32a6d23b2e 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -448,11 +448,12 @@ enum ruby_value_type { 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 { #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 diff --git a/internal.h b/internal.h index 372cf5daba..9172fb1892 100644 --- a/internal.h +++ b/internal.h @@ -513,15 +513,44 @@ RCLASS_SET_SUPER(VALUE klass, VALUE super) 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) @@ -1069,11 +1069,6 @@ rb_gc_mark_node(NODE *obj) 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); @@ -192,8 +192,6 @@ enum node_type { #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 { #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) @@ -82,10 +82,7 @@ rb_vm_control_frame_block_ptr(const rb_control_frame_t *cfp) 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; } @@ -498,6 +498,7 @@ rb_type_str(enum ruby_value_type type) 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 src, VALUE scope, rb_cref_t *const cref_ 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); } diff --git a/vm_insnhelper.c b/vm_insnhelper.c index f5f5634d09..b2481834de 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -163,7 +163,7 @@ lep_svar_get(rb_thread_t *th, const VALUE *lep, rb_num_t key) 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, rb_num_t key, VALUE val) 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) 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, VALUE old_klass, VALUE new_klass, rb_c 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; |