summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-08 05:01:23 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-08 05:01:23 +0000
commit26081169e0a227a6ccf477c7fade17b90f266e23 (patch)
treec27e9109ef640c0de230c50c698df4a1fe1a2608 /vm.c
parent96af6823c1b49a41e873fb4d9ffa16dfce7ffdd9 (diff)
separate Thread type (func or proc) explicitly.
* vm_core.h (rb_thread_struct): introduce new fields `invoke_type` and `invoke_arg`. There are two types threads: invoking proc (normal Ruby thread created by `Thread.new do ... end`) and invoking func, created by C-API. `invoke_type` shows the types. * thread.c (thread_do_start): copy `invoke_arg.proc.args` contents from Array to ALLOCA stack memory if args length is enough small (<8). We don't need to keep Array and don't need to cancel using transient heap. * vm.c (thread_mark): For func invoking threads, they can pass (void *) parameter (rb_thread_t::invoke_arg::func::arg). However, a rubyspec test (thread_spec.c) passes an Array object and it expect to mark it. Clealy it is out of scope (misuse of `rb_thread_create` C-API). However, I'm not sure someone else has such kind of misunderstanding. So now we mark conservatively this (void *) arg with rb_gc_mark_maybe. This misuse is found by this error log. http://ci.rvm.jp/results/trunk-theap-asserts@silicon-docker/1448164 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65622 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/vm.c b/vm.c
index 5f89cacd1c..2844441997 100644
--- a/vm.c
+++ b/vm.c
@@ -2435,8 +2435,17 @@ thread_mark(void *ptr)
rb_fiber_mark_self(th->ec->fiber_ptr);
/* mark ruby objects */
- RUBY_MARK_UNLESS_NULL(th->first_proc);
- if (th->first_proc) RUBY_MARK_UNLESS_NULL(th->first_args);
+ switch (th->invoke_type) {
+ case thread_invoke_type_proc:
+ RUBY_MARK_UNLESS_NULL(th->invoke_arg.proc.proc);
+ RUBY_MARK_UNLESS_NULL(th->invoke_arg.proc.args);
+ break;
+ case thread_invoke_type_func:
+ rb_gc_mark_maybe((VALUE)th->invoke_arg.func.arg);
+ break;
+ default:
+ break;
+ }
RUBY_MARK_UNLESS_NULL(th->thgroup);
RUBY_MARK_UNLESS_NULL(th->value);