summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-10-29 11:16:54 (GMT)
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-10-29 11:16:54 (GMT)
commitc5e08b764eb342538884b383f0e6428b6faf214b (patch)
treebdd21aa73442d7492b5edf20ec2d9208727eaa95
parent0c6940b718a5a552c4c15e84a5f0eec81a26ad0f (diff)
* add RUBY_TYPED_FREE_IMMEDIATELY to data types which only use
safe functions during garbage collection such as xfree(). On default, T_DATA objects are freed at same points as fianlizers. This approach protects issues such as reported by [ruby-dev:35578]. However, freeing T_DATA objects immediately helps heap usage. Most of T_DATA (in other words, most of dfree functions) are safe. However, we turned off RUBY_TYPED_FREE_IMMEDIATELY by default for safety. * cont.c: ditto. * dir.c: ditto. * encoding.c: ditto. * enumerator.c: ditto. * error.c: ditto. * file.c: ditto. * gc.c: ditto. * io.c: ditto. * iseq.c: ditto. * marshal.c: ditto. * parse.y: ditto. * proc.c: ditto. * process.c: ditto. * random.c: ditto. * thread.c: ditto. * time.c: ditto. * transcode.c: ditto. * variable.c: ditto. * vm.c: ditto. * vm_backtrace.c: ditto. * vm_trace.c: ditto. * ext/bigdecimal/bigdecimal.c: ditto. * ext/objspace/objspace.c: ditto. * ext/stringio/stringio.c: ditto. * ext/strscan/strscan.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog63
-rw-r--r--cont.c2
-rw-r--r--dir.c1
-rw-r--r--encoding.c1
-rw-r--r--enumerator.c3
-rw-r--r--error.c1
-rw-r--r--ext/bigdecimal/bigdecimal.c1
-rw-r--r--ext/objspace/objspace.c1
-rw-r--r--ext/stringio/stringio.c1
-rw-r--r--ext/strscan/strscan.c3
-rw-r--r--file.c1
-rw-r--r--gc.c5
-rw-r--r--io.c1
-rw-r--r--iseq.c5
-rw-r--r--marshal.c2
-rw-r--r--parse.y1
-rw-r--r--proc.c3
-rw-r--r--process.c1
-rw-r--r--random.c1
-rw-r--r--thread.c3
-rw-r--r--time.c1
-rw-r--r--transcode.c1
-rw-r--r--variable.c2
-rw-r--r--vm.c3
-rw-r--r--vm_backtrace.c2
-rw-r--r--vm_trace.c1
26 files changed, 105 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index d85115a..d514943 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,66 @@
+Tue Oct 29 20:01:58 2013 Koichi Sasada <ko1@atdot.net>
+
+ * add RUBY_TYPED_FREE_IMMEDIATELY to data types which only use
+ safe functions during garbage collection such as xfree().
+
+ On default, T_DATA objects are freed at same points as fianlizers.
+ This approach protects issues such as reported by [ruby-dev:35578].
+ However, freeing T_DATA objects immediately helps heap usage.
+
+ Most of T_DATA (in other words, most of dfree functions) are safe.
+ However, we turned off RUBY_TYPED_FREE_IMMEDIATELY by default
+ for safety.
+
+ * cont.c: ditto.
+
+ * dir.c: ditto.
+
+ * encoding.c: ditto.
+
+ * enumerator.c: ditto.
+
+ * error.c: ditto.
+
+ * file.c: ditto.
+
+ * gc.c: ditto.
+
+ * io.c: ditto.
+
+ * iseq.c: ditto.
+
+ * marshal.c: ditto.
+
+ * parse.y: ditto.
+
+ * proc.c: ditto.
+
+ * process.c: ditto.
+
+ * random.c: ditto.
+
+ * thread.c: ditto.
+
+ * time.c: ditto.
+
+ * transcode.c: ditto.
+
+ * variable.c: ditto.
+
+ * vm.c: ditto.
+
+ * vm_backtrace.c: ditto.
+
+ * vm_trace.c: ditto.
+
+ * ext/bigdecimal/bigdecimal.c: ditto.
+
+ * ext/objspace/objspace.c: ditto.
+
+ * ext/stringio/stringio.c: ditto.
+
+ * ext/strscan/strscan.c: ditto.
+
Tue Oct 29 19:48:33 2013 Koichi Sasada <ko1@atdot.net>
* include/ruby/ruby.h: fix typo (FL_WB_PROTECT -> FL_WB_PROTECTED).
diff --git a/cont.c b/cont.c
index 5c1f10e..b976056 100644
--- a/cont.c
+++ b/cont.c
@@ -417,6 +417,7 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
static const rb_data_type_t cont_data_type = {
"continuation",
{cont_mark, cont_free, cont_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static void
@@ -1032,6 +1033,7 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
static const rb_data_type_t fiber_data_type = {
"fiber",
{fiber_mark, fiber_free, fiber_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
diff --git a/dir.c b/dir.c
index d168190..5e36270 100644
--- a/dir.c
+++ b/dir.c
@@ -381,6 +381,7 @@ dir_memsize(const void *ptr)
static const rb_data_type_t dir_data_type = {
"dir",
{dir_mark, dir_free, dir_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE dir_close(VALUE);
diff --git a/encoding.c b/encoding.c
index b073311..fa6e5af 100644
--- a/encoding.c
+++ b/encoding.c
@@ -71,6 +71,7 @@ enc_memsize(const void *p)
static const rb_data_type_t encoding_data_type = {
"encoding",
{0, 0, enc_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
#define is_data_encoding(obj) (RTYPEDDATA_P(obj) && RTYPEDDATA_TYPE(obj) == &encoding_data_type)
diff --git a/enumerator.c b/enumerator.c
index 012a5b0..1c4d507 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -168,6 +168,7 @@ static const rb_data_type_t enumerator_data_type = {
enumerator_free,
enumerator_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static struct enumerator *
@@ -1076,6 +1077,7 @@ static const rb_data_type_t yielder_data_type = {
yielder_free,
yielder_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static struct yielder *
@@ -1181,6 +1183,7 @@ static const rb_data_type_t generator_data_type = {
generator_free,
generator_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static struct generator *
diff --git a/error.c b/error.c
index ba9c720..424999f 100644
--- a/error.c
+++ b/error.c
@@ -1033,6 +1033,7 @@ static const rb_data_type_t name_err_mesg_data_type = {
name_err_mesg_free,
name_err_mesg_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
/* :nodoc: */
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index 31e9be9..e82ac38 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -146,6 +146,7 @@ BigDecimal_memsize(const void *ptr)
static const rb_data_type_t BigDecimal_data_type = {
"BigDecimal",
{ 0, BigDecimal_delete, BigDecimal_memsize, },
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static inline int
diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c
index 2e7bd07..b0df466 100644
--- a/ext/objspace/objspace.c
+++ b/ext/objspace/objspace.c
@@ -643,6 +643,7 @@ iow_size(const void *ptr)
static const rb_data_type_t iow_data_type = {
"ObjectSpace::InternalObjectWrapper",
{iow_mark, 0, iow_size,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE rb_mInternalObjectWrapper;
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
index ebf678b..3fef619 100644
--- a/ext/stringio/stringio.c
+++ b/ext/stringio/stringio.c
@@ -78,6 +78,7 @@ static const rb_data_type_t strio_data_type = {
strio_free,
strio_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
#define check_strio(self) ((struct StringIO*)rb_check_typeddata((self), &strio_data_type))
diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c
index 65b5ca7..f020ba7 100644
--- a/ext/strscan/strscan.c
+++ b/ext/strscan/strscan.c
@@ -190,7 +190,8 @@ strscan_memsize(const void *ptr)
static const rb_data_type_t strscanner_type = {
"StringScanner",
- {strscan_mark, strscan_free, strscan_memsize}
+ {strscan_mark, strscan_free, strscan_memsize},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
diff --git a/file.c b/file.c
index 3b0cd67..8b74369 100644
--- a/file.c
+++ b/file.c
@@ -362,6 +362,7 @@ stat_memsize(const void *p)
static const rb_data_type_t stat_data_type = {
"stat",
{NULL, RUBY_TYPED_DEFAULT_FREE, stat_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
diff --git a/gc.c b/gc.c
index e01a75b..93b1588 100644
--- a/gc.c
+++ b/gc.c
@@ -1378,6 +1378,8 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
if (RTYPEDDATA_P(obj)) {
free_immediately = RANY(obj)->as.typeddata.type->flags & RUBY_TYPED_FREE_IMMEDIATELY;
RDATA(obj)->dfree = RANY(obj)->as.typeddata.type->function.dfree;
+ if (0 && free_immediately == 0) /* to expose non-free-immediate T_DATA */
+ fprintf(stderr, "not immediate -> %s\n", RANY(obj)->as.typeddata.type->wrap_struct_name);
}
if (RANY(obj)->as.data.dfree == RUBY_DEFAULT_FREE) {
xfree(DATA_PTR(obj));
@@ -5369,7 +5371,8 @@ static const rb_data_type_t weakmap_type = {
wmap_mark,
wmap_free,
wmap_memsize,
- }
+ },
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
diff --git a/io.c b/io.c
index 9ad7bff..d136d88 100644
--- a/io.c
+++ b/io.c
@@ -7583,6 +7583,7 @@ argf_memsize(const void *ptr)
static const rb_data_type_t argf_type = {
"ARGF",
{argf_mark, argf_free, argf_memsize},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static inline void
diff --git a/iseq.c b/iseq.c
index 8545e6c..504e96b 100644
--- a/iseq.c
+++ b/iseq.c
@@ -168,9 +168,8 @@ static const rb_data_type_t iseq_data_type = {
iseq_free,
iseq_memsize,
}, /* functions */
- 0, /* parent */
- 0, /* data */
- FL_WB_PROTECTED /* flags */
+ NULL, NULL,
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
};
static VALUE
diff --git a/marshal.c b/marshal.c
index 4cba05d..c1b6a79 100644
--- a/marshal.c
+++ b/marshal.c
@@ -186,6 +186,7 @@ memsize_dump_arg(const void *ptr)
static const rb_data_type_t dump_arg_data = {
"dump_arg",
{mark_dump_arg, free_dump_arg, memsize_dump_arg,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static const char *
@@ -1021,6 +1022,7 @@ memsize_load_arg(const void *ptr)
static const rb_data_type_t load_arg_data = {
"load_arg",
{mark_load_arg, free_load_arg, memsize_load_arg,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
#define r_entry(v, arg) r_entry0((v), (arg)->data->num_entries, (arg))
diff --git a/parse.y b/parse.y
index a2174ca..d04286f 100644
--- a/parse.y
+++ b/parse.y
@@ -11018,6 +11018,7 @@ rb_data_type_t parser_data_type = {
parser_free,
parser_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
#ifndef RIPPER
diff --git a/proc.c b/proc.c
index 01af8de..f3e38e9 100644
--- a/proc.c
+++ b/proc.c
@@ -78,6 +78,7 @@ static const rb_data_type_t proc_data_type = {
proc_free,
proc_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
VALUE
@@ -276,6 +277,7 @@ const rb_data_type_t ruby_binding_data_type = {
binding_free,
binding_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
@@ -1104,6 +1106,7 @@ static const rb_data_type_t method_data_type = {
bm_free,
bm_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
VALUE
diff --git a/process.c b/process.c
index 4c64576..c12182a 100644
--- a/process.c
+++ b/process.c
@@ -1366,6 +1366,7 @@ memsize_exec_arg(const void *ptr)
static const rb_data_type_t exec_arg_data_type = {
"exec_arg",
{mark_exec_arg, free_exec_arg, memsize_exec_arg},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
#ifdef _WIN32
diff --git a/random.c b/random.c
index 4026614..41c20f3 100644
--- a/random.c
+++ b/random.c
@@ -335,6 +335,7 @@ static const rb_data_type_t random_data_type = {
random_free,
random_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static rb_random_t *
diff --git a/thread.c b/thread.c
index e501f78..ef869c6 100644
--- a/thread.c
+++ b/thread.c
@@ -3957,6 +3957,7 @@ thgroup_memsize(const void *ptr)
static const rb_data_type_t thgroup_data_type = {
"thgroup",
{NULL, RUBY_TYPED_DEFAULT_FREE, thgroup_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
/*
@@ -4195,6 +4196,7 @@ mutex_memsize(const void *ptr)
static const rb_data_type_t mutex_data_type = {
"mutex",
{mutex_mark, mutex_free, mutex_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
VALUE
@@ -4644,6 +4646,7 @@ thread_shield_mark(void *ptr)
static const rb_data_type_t thread_shield_data_type = {
"thread_shield",
{thread_shield_mark, 0, 0,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
diff --git a/time.c b/time.c
index 2c83aa7..c8f15bf 100644
--- a/time.c
+++ b/time.c
@@ -1796,6 +1796,7 @@ time_memsize(const void *tobj)
static const rb_data_type_t time_data_type = {
"time",
{time_mark, time_free, time_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
diff --git a/transcode.c b/transcode.c
index 95ef566..4a86f84 100644
--- a/transcode.c
+++ b/transcode.c
@@ -2921,6 +2921,7 @@ econv_memsize(const void *ptr)
static const rb_data_type_t econv_data_type = {
"econv",
{NULL, econv_free, econv_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
diff --git a/variable.c b/variable.c
index d07f9ff..1c7bfb0 100644
--- a/variable.c
+++ b/variable.c
@@ -1535,6 +1535,7 @@ autoload_memsize(const void *ptr)
static const rb_data_type_t autoload_data_type = {
"autoload",
{autoload_mark, autoload_free, autoload_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
#define check_autoload_table(av) \
@@ -1585,6 +1586,7 @@ autoload_i_memsize(const void *ptr)
static const rb_data_type_t autoload_data_i_type = {
"autoload_i",
{autoload_i_mark, autoload_i_free, autoload_i_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
#define check_autoload_data(av) \
diff --git a/vm.c b/vm.c
index af29665..830e66c 100644
--- a/vm.c
+++ b/vm.c
@@ -305,6 +305,7 @@ env_memsize(const void *ptr)
static const rb_data_type_t env_data_type = {
"VM/env",
{env_mark, env_free, env_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
@@ -1686,6 +1687,7 @@ vm_memsize(const void *ptr)
static const rb_data_type_t vm_data_type = {
"VM",
{rb_vm_mark, vm_free, vm_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -1963,6 +1965,7 @@ const rb_data_type_t ruby_threadptr_data_type = {
thread_free,
thread_memsize,
},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
VALUE
diff --git a/vm_backtrace.c b/vm_backtrace.c
index 541eda3..5b05b04 100644
--- a/vm_backtrace.c
+++ b/vm_backtrace.c
@@ -112,6 +112,7 @@ location_memsize(const void *ptr)
static const rb_data_type_t location_data_type = {
"frame_info",
{location_mark, location_free, location_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static inline rb_backtrace_location_t *
@@ -407,6 +408,7 @@ backtrace_memsize(const void *ptr)
static const rb_data_type_t backtrace_data_type = {
"backtrace",
{backtrace_mark, backtrace_free, backtrace_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
int
diff --git a/vm_trace.c b/vm_trace.c
index 77af93b..ce078ca 100644
--- a/vm_trace.c
+++ b/vm_trace.c
@@ -630,6 +630,7 @@ tp_memsize(const void *ptr)
static const rb_data_type_t tp_data_type = {
"tracepoint",
{tp_mark, RUBY_TYPED_NEVER_FREE, tp_memsize,},
+ NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE