зеркало из https://github.com/github/ruby.git
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49932 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
5922c95461
Коммит
0952b43b9b
29
ChangeLog
29
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
28
gc.c
28
gc.c
|
@ -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,12 +1720,19 @@ 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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
35
internal.h
35
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)
|
||||
|
|
5
node.c
5
node.c
|
@ -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);
|
||||
|
|
3
node.h
3
node.h
|
@ -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)
|
||||
|
|
5
vm.c
5
vm.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче