* iseq.c (iseq_load): keep type_map to get rid of memory leak.
  based on a patch by Eric Wong at [ruby-core:59699].  [Bug #9399]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44568 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-01-12 07:41:10 +00:00
Родитель 3963c09aed
Коммит ff00300834
3 изменённых файлов: 18 добавлений и 0 удалений

Просмотреть файл

@ -1,3 +1,8 @@
Sun Jan 12 16:41:10 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* iseq.c (iseq_load): keep type_map to get rid of memory leak.
based on a patch by Eric Wong at [ruby-core:59699]. [Bug #9399]
Sun Jan 12 09:21:35 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> Sun Jan 12 09:21:35 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* include/ruby/util.h (DECIMAL_SIZE_OF_BITS): a preprocessor * include/ruby/util.h (DECIMAL_SIZE_OF_BITS): a preprocessor

8
iseq.c
Просмотреть файл

@ -484,6 +484,7 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
VALUE type, body, locals, args, exception; VALUE type, body, locals, args, exception;
st_data_t iseq_type; st_data_t iseq_type;
static struct st_table *type_map_cache = 0;
struct st_table *type_map = 0; struct st_table *type_map = 0;
rb_iseq_t *iseq; rb_iseq_t *iseq;
rb_compile_option_t option; rb_compile_option_t option;
@ -524,7 +525,9 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
iseq->self = iseqval; iseq->self = iseqval;
iseq->local_iseq = iseq; iseq->local_iseq = iseq;
type_map = type_map_cache;
if (type_map == 0) { if (type_map == 0) {
struct st_table *cached_map;
type_map = st_init_numtable(); type_map = st_init_numtable();
st_insert(type_map, ID2SYM(rb_intern("top")), ISEQ_TYPE_TOP); st_insert(type_map, ID2SYM(rb_intern("top")), ISEQ_TYPE_TOP);
st_insert(type_map, ID2SYM(rb_intern("method")), ISEQ_TYPE_METHOD); st_insert(type_map, ID2SYM(rb_intern("method")), ISEQ_TYPE_METHOD);
@ -535,6 +538,11 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
st_insert(type_map, ID2SYM(rb_intern("eval")), ISEQ_TYPE_EVAL); st_insert(type_map, ID2SYM(rb_intern("eval")), ISEQ_TYPE_EVAL);
st_insert(type_map, ID2SYM(rb_intern("main")), ISEQ_TYPE_MAIN); st_insert(type_map, ID2SYM(rb_intern("main")), ISEQ_TYPE_MAIN);
st_insert(type_map, ID2SYM(rb_intern("defined_guard")), ISEQ_TYPE_DEFINED_GUARD); st_insert(type_map, ID2SYM(rb_intern("defined_guard")), ISEQ_TYPE_DEFINED_GUARD);
cached_map = ATOMIC_PTR_CAS(type_map_cache, (struct st_table *)0, type_map);
if (cached_map) {
st_free_table(type_map);
type_map = cached_map;
}
} }
if (st_lookup(type_map, type, &iseq_type) == 0) { if (st_lookup(type_map, type, &iseq_type) == 0) {

Просмотреть файл

@ -161,5 +161,10 @@ atomic_size_exchange(size_t *ptr, size_t val)
# define ATOMIC_PTR_EXCHANGE(var, val) (void *)ATOMIC_SIZE_EXCHANGE(*(size_t *)&(var), (size_t)(val)) # define ATOMIC_PTR_EXCHANGE(var, val) (void *)ATOMIC_SIZE_EXCHANGE(*(size_t *)&(var), (size_t)(val))
# endif # endif
#endif #endif
#ifndef ATOMIC_PTR_CAS
# if SIZEOF_VOIDP == SIZEOF_SIZE_T
# define ATOMIC_PTR_CAS(var, oldval, val) (void *)ATOMIC_SIZE_CAS(*(size_t *)&(var), (size_t)(oldval), (size_t)(val))
# endif
#endif
#endif /* RUBY_ATOMIC_H */ #endif /* RUBY_ATOMIC_H */