* vm_core.h: Ruby processes run with two stacks, a machine stack and a
VM stack. To make it clear, this fix renames
rb_execution_context_t::stack(_size) to vm_stack(_size).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59563 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (fiber_to_s): return with block and status information.
* proc.c (proc_to_s_): removed and introduce rb_block_to_s() function
to return block information string.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59558 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c: revisit fiber status.
"FIBER_RUNNING" status represents fiber is resumed or suspended.
This fix separate these two status explicitly.
FIBER_CREATED: Just after Fiber.new. Not resumed yet.
FIBER_RESUMED (new): Fiber#resumed. Now this fiber is running.
FIBER_SUSPENDED (new): Suspended by Fiber.yield. Not running.
FIBER_TERMINATED: Terminated.
Add sevral assertions to check consistency with these status.
* cont.c (fiber_status_set): added to change status.
* cont.c (FIBER_xxx_P): added to check fiber status.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59557 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (root_fiber_alloc): this function is called by fiber_current()
and fiber_store(). fiber_current() should clear VM stack information
in a fiber data because runnning thread knows stack information and has
responsibility to manage it. However fiber_store() requires to remain
VM stack information in a fiber data because the responsibility to manage
VM stack is moved to the Fiber from the Thread (and switch to another
fiber).
* cont.c (root_fiber_alloc): save thread's fiber and root_fiber information.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59474 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c: r55766 change the handling method of Fiber's VM stack.
Resumed Fiber points NULL as VM stack and running Thread has
responsibility to manage it (marking and releasing).
However, thread_start_func_2()@thread.c and thread_free()@vm.c
doesn't free the VM stack if corresponding root Fiber is exist.
This causes memory leak. [Bug #13772]
* cont.c (root_fiber_alloc): fib->cont.saved_thread.ec.stack should be NULL
because running thread has responsibility to manage this stack.
* vm.c (rb_thread_recycle_stack_release): assert given stack is not NULL
(callers should care it).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59462 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (rb_fiber_t): add rb_fiber_t::first_proc and do not use
rb_thread_t::first_proc which should be thread local.
[Bug #13689]
* test/ruby/test_thread.rb: test for [Bug #13689].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59200 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_ptr): added to replace GetThreadPtr() macro.
* thread.c (in some functions: use "target_th" instead of "th" to make clear
that it is not a current thread.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59192 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_t): move several fields which are copied at cont.c
to rb_execution_context_t.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59177 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (cont_restore_thread): on Fiber we only need to copy ec struct.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59176 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (cont_restore_thread): On Fiber switching, thread status shold be
THREAD_RUNNABLE so that we don't need to store/restore this field.
* cont.c (cont_save_thread): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59174 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_t::tag_state): move to "rb_vm_tag::state".
Lifetime of "state" should be same as current tag.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59159 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_t): rename rb_thread_t::state to tag_state
to make it clear.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59158 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Return value of EXEC_TAG() is saved by "int state".
Instead of "int", use "enum ruby_tag_type". First EXEC_TAG()
value should be 0, so that define TAG_NONE (= 0) and use it.
Some code used "status" instead of "state". To make them clear,
rename them to state.
We can change variable name from "state" to "tag_state", but this
ticket doesn't contain it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The goal is to reduce rb_context_t and rb_fiber_t size
by removing the need to store the entire rb_thread_t in
there.
[ruby-core:81045] Work-in-progress: soon, we will move more fields here.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58614 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
gc.c (gc_mark_children, case T_DATA) does not use
the dmark function pointer if DATA_PTR is NULL
* cont.c (cont_mark, fiber_mark): remove branch, ptr is never NULL
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57614 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
It's many years since we had tiny 4KB fiber stacks :<
point to the manpage instead for current, larger sizes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57205 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Without the fix, the following warning is shown:
compiling cont.c
cont.c: In function ‘rb_callcc’:
cont.c:949:39: warning: passing argument 1 of ‘cont_capture’ discards ‘volatile’ qualifier from pointer target type [-Wdiscarded-qualifiers]
volatile VALUE val = cont_capture(&called);
^
cont.c:473:1: note: expected ‘int * volatile’ but argument is of type ‘volatile int *’
cont_capture(int *volatile stat)
^
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57021 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Use volatile instead of optnone to avoid optimization which causes
segmentation faults.
Patch by Dimitry Andric. [ruby-core:78531] [Bug #13014]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57020 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
and VM_FRAME_CFRAME_P().
Most of case, RUBY_VM_NORMAL_ISEQ_P() is no
longer needed.
* vm_core.h: introduce rb_obj_is_iseq().
* cont.c, vm.c: VM_FRAME_MAGIC_DUMMY with
VM_FRAME_FLAG_CFRAME.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55804 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
[Bug #12628]
This patch introduce many changes.
* Introduce concept of "Block Handler (BH)" to represent
passed blocks.
* move rb_control_frame_t::flag to ep[0] (as a special local
variable). This flags represents not only frame type, but also
env flags such as escaped.
* rename `rb_block_t` to `struct rb_block`.
* Make Proc, Binding and RubyVM::Env objects wb-protected.
Check [Bug #12628] for more details.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55766 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (fiber_initialize_machine_stack_context): fix wrong
_MSC_VER check, should be decimal but not hexadecimal.
[ruby-core:74936] [Bug #12279]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54574 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
NULL checking is finished Before call of memsize functions.
See r52979.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52986 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
fiber_switch. We need more discussion about this feature
so that I don't write it on NEWS.
[Feature #11348]
* test/ruby/test_settracefunc.rb: add tests.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This fix does not affect any ordinal execution, but
affects debug prints.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51165 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Motivation and new data structure are described in [Bug #11203].
This patch also solve the following issues.
* [Bug #11200] Memory leak of method entries
* [Bug #11046] __callee__ returns incorrect method name in orphan
proc
* test/ruby/test_method.rb: add a test for [Bug #11046].
* vm_core.h: remvoe rb_control_frame_t::me. me is located at value
stack.
* vm_core.h, gc.c, vm_method.c: remove unlinked_method... codes
because method entries are simple VALUEs.
* method.h: Now, all method entries has own independent method
definititons. Strictly speaking, this change is not essential,
but for future changes.
* rb_method_entry_t::flag is move to rb_method_definition_t::flag.
* rb_method_definition_t::alias_count is now
rb_method_definition_t::alias_count_ptr, a pointer to the counter.
* vm_core.h, vm_insnhelper.c (rb_vm_frame_method_entry) added to
search the current method entry from value stack.
* vm_insnhelper.c (VM_CHECK_MODE): introduced to enable/disable
assertions.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50728 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (cont_free): check if ruby_current_thread is still valid.
[Fix GH-914]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50679 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
during complex parameter setting process (splat, kw, and so on).
[Bug #11027]
* vm_core.h: remove rb_thead_t::mark_stack_len.
With this modification, we don't need to use th->mark_stack_len.
* test/ruby/test_keyword.rb: add a test.
* cont.c (cont_capture): catch up this fix.
* vm.c (rb_thread_mark): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50172 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_thread_t::local_storage_recursive_hash_for_trace to store
recursive hash to avoid creating new recursive (nested) hashes
for each trace events.
[Bug #10511]
* vm_trace.c (rb_threadptr_exec_event_hooks_orig): use it.
* cont.c: catch up this fix.
* vm.c (rb_thread_mark): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48765 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
use 0 for rb_data_type_t::reserved instead of NULL, since its type
may be changed in the future and possibly not a pointer type.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48662 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Remove some unnecessary VALUE/struct conversions and aggressively inline
functions used during fiber_switch. Either of these changes alone does
not yield significant performance increase, but in combination they
improve performance by ~6%.
Arguably, removal of separate VALUE/rb_fiber_t* variables also makes the
code more readable in a few places.
* vm_core.h: declare rb_fiber_t typedef
(rb_thread_t): fiber and root_fiber become rb_fiber_t * (from VALUE)
* vm.c (rb_thread_mark): use rb_fiber_mark_self
* cont.c (rb_fiber_t): prev becomes rb_fiber_t * (from VALUE)
(cont_mark, cont_free): simplify conditions
(rb_fiber_mark_self): new function
(fiber_mark): use rb_fiber_mark_self
(cont_save_thread, cont_restore_thread): inline
(cont_restore_thread): simplify
(fiber_setcontext): simplify conditions
(rb_cont_call): remove dereference
(fiber_t_alloc): update for rb_fiber_t->prev type change
(rb_fiber_start): ditto
(fiber_current): extract from rb_fiber_current
(return_fiber): move, simplify type checks
(rb_fiber_current): use fiber_current
(fiber_store): simplify type checks
(fiber_switch): ditto, simplify call to fiber_setcontext,
use fiber_current
(rb_fiber_transfer): update for type changes
(rb_fiber_terminate): move, use fiber_switch
(rb_fiber_resume): update for type changes
(rb_fiber_reset_root_local_storage): ditto
(rb_fiber_yield): use rb_fiber_switch instead of rb_fiber_transfer
(rb_fiber_m_transfer): ditto
[ruby-core:65518] [Feature #10341]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47964 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Instead of copying the complete rb_thread_t struct (almost a kB),
selectively copy only those fields that will be needed later on.
* cont.c (rb_context_t): comment on saved_thread
(cont_save_thread): sparse copy
(cont_init): copy extra fields
(fiber_init): use current thread VM stack size
[ruby-core:65518] [Feature #10341]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47963 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Remove variable that is used only once, several lines after
initialization.
* cont.c (cont_capture): remove unnecessary variable
[ruby-core:65518] [Feature #10341]
Author: Knut Franke <Knut.Franke@gmx.de>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47962 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Defragment code blocks depending on FIBER_USE_NATIVE in order to make
the control flow (which is already non-trivial due to nonlocal jumps) in
each case more comprehensible.
Remove some unreachable code from fiber_switch (we've already excluded
the case (th->fiber == fibval) at the start of the function).
Remove call to rb_fiber_current which happened a few lines after
accessing GET_THREAD()->fiber directly (so if that's ever 0 we're
already screwed).
Author: Knut Franke <Knut.Franke@gmx.de>
* cont.c (fiber_store, fiber_switch): simplify
[ruby-core:65518] [Feature #10341]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47961 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
They were added in r19890 (8a0d53a), with the explanation that it's a
double linked list of fibers in the same thread, but without any code
using them.
* cont.c (rb_fiber_t): remove prev_fiber/next_fiber
(fiber_link_join, fiber_link_remove): remove functions
(fiber_free, fiber_init, root_fiber_alloc):
remove references to removed fields and functions
[ruby-core:65518] [Feature #10341]
Author: Knut Franke <Knut.Franke@gmx.de>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47959 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_struct): aggregate cpu stuff into a struct,
so that a debugger can show its content at once.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44722 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* internal.h (ruby_register_rollback_func_for_ensure): catch up above change.
Add rollback mechanism API.
* vm_core.h (typedef struct rb_vm_struct): catch up above change.
Introdule ensure-rollback relation table.
* vm_core.h (typedef struct rb_thread_struct): catch up above change.
Introdule ensure stack.
* eval.c (rb_ensure): catch up above change.
Introdule ensure stack.
* hash.c : New function for rollback ensure, and register it to
ensure-rollback relation table. [ruby-dev:47803] [Bug #9105]
Ensure Rollback Mechanism:
A rollback's function is a function to rollback a state before ensure's
function execution.
When the jump of callcc is across the scope of rb_ensure,
ensure's functions and rollback's functions are executed appropriately
for keeping consistency.
Current API is unstable, and only internal use.
ruby_register_rollback_func_for_ensure(ensure_func,rollback_func)
This API create relation ensure's function to rollback's function.
By registered rollback's function, it is executed When jumpping into
corresponding rb_ensure scope.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43688 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This is another approach to solve an issue discussed at r43530.
This feature is diabled as default.
This feature measures an increment of memory consuption by oldgen
objects. It measures memory consumption for each objects when
the object is promoted. However, measurement of memory consumption
is not accurate now. So that this measurement is `estimation'.
To implement this feature, move memsize_of() function from
ext/objspace/objspace.c and expose rb_obj_memsize_of().
Some memsize() functions for T_DATA (T_TYPEDDATA) have problem to
measure memory size, so that we ignores T_DATA objects now.
For example, some functions skip NULL check for pointer.
The macro RGENGC_ESTIMATE_OLDSPACE enables/disables this feature,
and turned off as default.
We need to compare 3gen GC and this feature carefully.
(it is possible to enable both feature)
We need a help to compare them.
* internal.h: expose rb_obj_memsize_of().
* ext/objspace/objspace.c: use rb_obj_memsize_of() function.
* cont.c (fiber_memsize): fix to check NULL.
* variable.c (autoload_memsize): ditto.
* vm.c (vm_memsize): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43532 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
support a combination getcontext() and threads. Patch by
Gabriele Giacone (1o5g4r8o@gmail.com). [Bug #8990][ruby-core:57685]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43193 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (FIBER_USE_NATIVE): supplement comments the reason why it is
disabled.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43192 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
RARRAY_RAWPTR(ary) returns (const VALUE *) type pointer and
usecase of this macro is not acquire raw pointer, but acquire
read-only pointer. So we rename to better name.
RSTRUCT_RAWPTR() is also renamed to RSTRUCT_CONST_PTR()
(I expect that nobody use it).
* array.c, compile.c, cont.c, enumerator.c, gc.c, proc.c, random.c,
string.c, struct.c, thread.c, vm_eval.c, vm_insnhelper.c:
catch up this change.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43043 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
RARRAY_PTR() because there is no new reference.
* proc.c (curry): ditto.
* proc.c (rb_proc_call): remove line break.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42420 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (cont_restore_thread): svar should be separate per fibers.
[ruby-core:51331] [Bug #7678]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38981 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
from Thread.async_interrupt_timing to Thread.handle_interrupt,
from Thread.async_interrupted? to Thread.pending_interrupt?.
Also rename option from `defer' to `never'.
[ruby-core:51074] [ruby-trunk - Feature #6762]
* vm_core.c, thread.c: rename functions and data structure
`async_errinfo' to `pending_interrupt'.
* thread.c: add global variables sym_immediate, sym_on_blocking and
sym_never.
* cont.c, process.c, vm.c, signal.c: ditto.
* lib/sync.rb, lib/thread.rb: catch up this renaming.
* test/ruby/test_thread.rb: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38577 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
enqueue error into async_errinfo_queue, because you cannot call
TH_TAG_JUMP() in this function. [ruby-dev:45218] [Bug #5993]
* thread.c (rb_threadptr_execute_interrupts): now INT2FIX(TAG_FATAL)
can be popped from async_errinfo_queue.
* vm.c (rb_vm_make_jump_tag_but_local_jump): revert r38441.
rb_vm_make_jump_tag_but_local_jump() shouldn't return exception
in case of state == TAG_FATAL.
* test/ruby/test_fiber.rb (test_exit_in_fiber): fix a test to illuminate
Thread.exit should terminate current Thread.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38550 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Move `trace_arg' from rb_tp_t::trace_arg to rb_thread_t::trace_arg.
`trace_arg' may changed by multiple threads.
rb_thread_t::trace_arg can represent rb_thread_t::trace_running
(null or non-null) and rb_thread_t::trace_running is removed.
After that, `rb_tp_t' is not needed to check tracing or not
(A running thread knows tracing or not). This is why I remove
tp_attr_check_active() and make new function get_trace_arg().
And this modification disable to work the following code:
TracePoint.trace{|tp|
Thread.new{p tp.event} # access `tp' from other threads.
}
I believe nobody mix threads at trace procedure.
This is current limitation.
* cont.c (fiber_switch, rb_cont_call): use rb_thread_t::trace_arg
instead of rb_thread_t::trace_running.
* test/ruby/test_settracefunc.rb: add a multi-threading test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38524 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Specified by the following environment variaables:
- RUBY_THREAD_VM_STACK_SIZE: vm stack size used at thread creation.
default: 128KB (32bit CPU) or 256KB (64bit CPU).
- RUBY_THREAD_MACHINE_STACK_SIZE: machine stack size used at thread
creation. default: 512KB or 1024KB.
- RUBY_FIBER_VM_STACK_SIZE: vm stack size used at fiber creation.
default: 64KB or 128KB.
- RUBY_FIBER_MACHINE_STACK_SIZE: machine stack size used at fiber
creation. default: 256KB or 256KB.
This values are specified at launched timing. You can not change
these values at running time.
Environ variables are only *hints* because:
- They are aligned to 4KB.
- They have minimum values (depend on OSs).
- Machine stack settings are ignored by some OSs.
Default values especially fiber stack sizes are increased.
This change affect Fiber's behavior:
(1) You can run more complex program on a Fiber.
(2) You can not make many (thousands) Fibers because of
lack of address space (on 32bit CPU).
If (2) bothers you,
(a) Use 64bit CPU with big memory, or
(b) Specify RUBY_FIBER_(VM|MACHINE)_STACK_SIZE correctly.
You need to choose correct stack size carefully. These values
are completely rely on systems (OS/compiler and so on).
* vm_core.h (rb_vm_t::default_params): add to record above settings.
* vm.c (RubyVM::DEFAULT_PARAMS): add new constant to see
above setting.
* thread_pthread.c: support RUBY_THREAD_MACHINE_STACK_SIZE.
* cont.c: support RUBY_FIBER_(VM|MACHINE)_STACK_SIZE.
* test/ruby/test_fiber.rb: add tests for above.
* test/ruby/test_thread.rb: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38478 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_vm_make_jump_tag_but_local_jump() could return Qnil (ex. when
finished by Thread.exit). [ruby-dev:45218] [Bug #5993]
* test/ruby/test_fiber.rb (test_exit_in_fiber): add test for it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38414 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
entry with VM_METHOD_TYPE_REFINED holds only the original method
definition, so ci->me is set to a method entry allocated in the
stack, and it causes SEGV/ILL. In this commit, a method entry
with VM_METHOD_TYPE_REFINED holds the whole original method entry.
Furthermore, rb_thread_mark() is changed to mark cfp->klass to
avoid GC for iclasses created by copy_refinement_iclass().
* vm_method.c (rb_method_entry_make): add a method entry with
VM_METHOD_TYPE_REFINED to the class refined by the refinement if
the target module is a refinement. When a method entry with
VM_METHOD_TYPE_UNDEF is invoked by vm_call_method(), a method with
the same name is searched in refinements. If such a method is
found, the method is invoked. Otherwise, the original method in
the refined class (rb_method_definition_t::body.orig_me) is
invoked. This change is made to simplify the normal method lookup
and to improve the performance of normal method calls.
* vm_method.c (EXPR1, search_method, rb_method_entry),
vm_eval.c (rb_call0, rb_search_method_entry): do not use
refinements for method lookup.
* vm_insnhelper.c (vm_call_method): search methods in refinements if
ci->me is VM_METHOD_TYPE_REFINED. If the method is called by
super (i.e., ci->call == vm_call_super_method), skip the same
method entry as the current method to avoid infinite call of the
same method.
* class.c (include_modules_at): add a refined method entry for each
method defined in a module included in a refinement.
* class.c (rb_prepend_module): set an empty table to
RCLASS_M_TBL(klass) to add refined method entries, because
refinements should have priority over prepended modules.
* proc.c (mnew): use rb_method_entry_with_refinements() to get
a refined method.
* vm.c (rb_thread_mark): mark cfp->klass for iclasses created by
copy_refinement_iclass().
* vm.c (Init_VM), cont.c (fiber_init): initialize th->cfp->klass.
* test/ruby/test_refinement.rb (test_inline_method_cache): do not skip
the test because it should pass successfully.
* test/ruby/test_refinement.rb (test_redefine_refined_method): new
test for the case a refined method is redefined.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38236 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
`bp' can be calculate by `sp' (stack pointer) of previous frame.
Now, `bp_check' field is remained for debug. You can eliminate
this field by setting VM_DEBUG_BP_CHECK as 0.
* vm_insnhelper.c (vm_base_ptr): add `vm_base_ptr(cfp).
This function calculates base pointer from cfp.
* vm_insnhelper.c (vm_setup_method): push `recv' value on top of
value stack (before method parameters).
This change is for keeping consistency with normal method dispatch.
* insns.def: fix to use vm_base_ptr().
* vm.c (vm_exec): ditto.
* vm_dump.c: remove `bp' related dumps.
* cont.c (fiber_init): fix to check VM_DEBUG_BP_CHECK.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37043 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_insnhelper.c (vm_call_method): follow iclasses as klass in cfp
but not included modules. [ruby-core:47241] [Bug #6891]
* vm_insnhelper.c (vm_call_bmethod): pass defined_class to follow
proper ancestors. [ruby-core:47241] [Bug #6891]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36736 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
(1) add rb_hook_list_t data structure which includes
hooks, events (flag) and `need_clean' flag.
If the last flag is true, then clean the hooks list.
In other words, deleted hooks are contained by `hooks'.
Cleanup process should run before traversing the list.
(2) Change check mechanism
See EXEC_EVENT_HOOK() in vm_core.h.
(3) Add `raw' hooks APIs
Normal hooks are guarded from exception by rb_protect().
However, this protection is overhead for too simple
functions which never cause exceptions. `raw' hooks
are executed without protection and faster.
Now, we only provide registration APIs. All `raw'
hooks are kicked under protection (same as normal hooks).
* include/ruby/ruby.h: remove internal data definition and
macros.
* internal.h (ruby_suppress_tracing), vm_trace.c: rename
ruby_suppress_tracing() to rb_suppress_tracing()
and remove unused function parameter.
* parse.y: fix to use renamed rb_suppress_tracing().
* thread.c (thread_create_core): no need to set RUBY_VM_VM.
* vm.c (mark_event_hooks): move definition to vm_trace.c.
* vm.c (ruby_vm_event_flags): add a global variable.
This global variable represents all of Threads and VM's
event masks (T1#events | T2#events | ... | VM#events).
You can check the possibility kick trace func or not
with ruby_vm_event_flags.
ruby_vm_event_flags is maintained by vm_trace.c.
* cont.c (fiber_switch, rb_cont_call): restore tracing status.
[Feature #4347]
* test/ruby/test_continuation.rb: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36715 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_thread_s_check_interrupt): added for
Thread.control_intgerrupt and Thread.check_interrupt.
See details on rdoc.
I'll make an ticket for this feature.
* test/ruby/test_thread.rb: add a test for Thread.control_intgerrupt.
* thread.c (rb_threadptr_raise): make a new exception object
even if argc is 0.
* thread.c (rb_thread_kill): kill thread immediately if target thread
is current thread.
* vm_core.h (RUBY_VM_CHECK_INTS_BLOCKING): added.
CHECK_INTS while/after blocking operation.
* vm_core.h (RUBY_VM_CHECK_INTS): require rb_thread_t ptr.
* cont.c (fiber_switch): use replaced RUBY_VM_CHECK_INTS().
* eval.c (ruby_cleanup): ditto.
* insns.def: ditto.
* process.c (rb_waitpid): ditto.
* vm_eval.c (vm_call0): ditto.
* vm_insnhelper.c (vm_call_method): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36470 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Async events such as an exception throwed by Thread#raise,
Thread#kill and thread termination (after main thread termination)
will be queued to th->async_errinfo_queue.
- clear: clear the queue.
- enque: enque err object into queue.
- deque: deque err object from queue.
- active_p: return 1 if the queue should be checked.
rb_thread_t#thrown_errinfo was removed.
* vm_core.h: add declarations of rb_threadptr_async_errinfo_*.
remove rb_thread_t#thrown_errinfo field and
add rb_thread_t#async_errinfo_queue (queue body: Array),
rb_thread_t#async_errinfo_queue_checked (flag),
rb_thread_t#async_errinfo_mask_stack(Array, not used yet).
* vm.c (rb_thread_mark): fix a mark function.
* cont.c (rb_fiber_start): enque an error.
* process.c (after_fork): clear async errinfo queue.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36430 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
dfp (dynamic frame pointer) to ep (environment pointer).
This change make VM `normal' (similar to other interpreters).
Before this commit:
Each frame has two env pointers lfp and dfp. lfp points
local environment which is method/class/toplevel frame.
lfp[0] is block pointer.
dfp is block local frame. dfp[0] points previous (parent)
environment pointer.
lfp == dfp when frame is method/class/toplevel.
You can get lfp from dfp by traversing previous environment
pointers.
After this commit:
Each frame has only `ep' to point respective enviornoment.
If there is parent environment, then ep[0] points parent
envioenment (as dfp). If there are no more environment,
then ep[0] points block pointer (as lfp). We call such ep
as `LEP' (local EP). We add some macros to get LEP and to
detect LEP or not.
In short, we replace dfp and lfp with ep and LEP.
rb_block_t and rb_binding_t member `lfp' and `dfp' are removed
and member `ep' is added.
rename rb_thread_t's member `local_lfp' and `local_svar' to
`root_lep' and `root_svar'.
(VM_EP_PREV_EP(ep)): get previous environment pointer. This macro
assume that ep is not LEP.
(VM_EP_BLOCK_PTR(ep)): get block pointer. This macro assume
that ep is LEP.
(VM_EP_LEP_P(ep)): detect ep is LEP or not.
(VM_ENVVAL_BLOCK_PTR(ptr)): make block pointer.
(VM_ENVVAL_BLOCK_PTR_P(v)): detect v is block pointer.
(VM_ENVVAL_PREV_EP_PTR(ptr)): make prev environment pointer.
(VM_ENVVAL_PREV_EP_PTR_P(v)): detect v is prev env pointer.
* vm.c: apply above changes.
(VM_EP_LEP(ep)): get LEP.
(VM_CF_LEP(cfp)): get LEP of cfp->ep.
(VM_CF_PREV_EP(cfp)): utility function VM_EP_PREV_EP(cfp->ep).
(VM_CF_BLOCK_PTR(cfp)): utility function VM_EP_BLOCK_PTR(cfp->ep).
* vm.c, vm_eval.c, vm_insnhelper.c, vm_insnhelper.h, insns.def:
apply above changes.
* cont.c: ditto.
* eval.c, eval_intern.h: ditto.
* proc.c: ditto.
* thread.c: ditto.
* vm_dump.c: ditto.
* vm_exec.h: fix function name (on vm debug mode).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36030 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
documentation. emphasize the difference between transfer and resume.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35521 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
restore rb_thread_t::local_storage.
* cont.c (rb_obj_is_fiber): add a new function to tell finalizer to
prevent fibers from destroy.
* gc.c (rb_objspace_call_finalizer): don't sweep fibers at finalizing
objspace.
* internal.h (rb_fiber_reset_root_local_storage, rb_obj_is_fiber):
add prototypes.
* vm.c (ruby_vm_destruct): reset main thread's local_storage before
free main thread. rb_thread_t::local_storage is replaced by fiber's
local storage when forked from fiber, and it should be already freed
when the fiber was destroyed.
* test/ruby/test_fiber.rb (test_fork_from_fiber): add test for fork
from fiber.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34629 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
reserving a memory space with ALLOCA_N for restoring machine stack
stored in cont->machine_stack, but clang optimized out it (and
maybe #5851 is also caused by this).
This affected TestContinuation#test_check_localvars.
* cont.c (cont_restore_1): revert workaround introduced in r32201.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34278 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because destination fiber is same as current fiber.
With out this, it may segv on FreeBSD 9.
patched by Koichi Sasada.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33804 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
"resume" after "transfer" method are used. You should not mix
"resume" fiber and "transfer" fiber.
[Bug #5526]
* NEWS: add information about this change.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33684 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
be marked by itself. Patch by Koichi Sasada.
[ruby-dev:44567] [Bug #5386]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33371 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
guard page should have PROT_NONE.
* cont.c (fiber_initialize_machine_stack_context):
th->machine_stack_maxsize shouldn't be included guard pages size.
[Bug #4983][ruby-dev:44043]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32421 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Fiber caused SEGV. I haven't follow up the issue deeply, but it
works when disabling the feature.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32408 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
On clang -O, it is needed to avoid the optimization.
With this and llvm/clang's recent fix, clang 3.0 can
build ruby-trunk with -O option.
* cont.c (cont_capture): use for-loop.
* array.c (rb_ary_each): add volatile and use it.
* vm_insnhelper.c (vm_call_cfunc): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32201 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_context_t::saved_thread.machine_stack_start and
machine_stack_end should be cleared immediately after a snapshot of
current thread is stored to saved_thread.
this change aims to get rid of unnecessary GC mark at machine stack.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32083 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
in cont_mark() only RUNNING fiber's machine stack is marked.
root fiber's status should be RUNNING at the beginning regardless of
FIBER_USE_NATIVE.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31954 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
you can suppress use of setcontext for Fiber with compile option
-DFIBER_USE_NATIVE=0
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31944 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
prevent mark machine stack of GC'ed Thread. root Fiber is not initialized by
fiber_init(). based on a patch by Serge Balyuk [ruby-core:35891] fixes#4612
* test/ruby/test_fiber.rb (test_gc_root_fiber): add test for it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31577 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
unnecessary fibers and retry to create. based on a patch from
masaya tarui at [ruby-dev:41230].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27701 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
on Windows because Fiber APIs are supported only such building
(and running) environments.
[ruby-dev:41192]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27646 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Fiber context switching cost using system APIs. Detail comments
are written in cont.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27635 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
added. Unlinked method entries are collected to
vm->unlinked_method_entry_list. On the GC timing, mark all method
entries which are on all living threads. Only non-marked method
entries are collected. This hack prevents releasing living method
entry.
[Performance Consideration] Since this Method Entry GC (MEGC)
doesn't occuer frequently, MEGC will not be a performance bottleneck.
However, to traverse living method entries, every control frame push
needs to clear cfp->me field. This will be a performance issue
(because pushing control frame is occurred frequently).
Bug #2777 [ruby-dev:40457]
* cont.c (fiber_init): init cfp->me.
* gc.c (garbage_collect): kick rb_sweep_method_entry().
* method.h (rb_method_entry_t): add a mark field.
* vm.c (invoke_block_from_c): set passed me.
* vm.c (rb_thread_mark): mark cfp->me.
* vm_core.h (rb_thread_t): add a field passed_me.
* vm_core.h (rb_vm_t): add a field unlinked_method_entry_list.
* vm_insnhelper.c (vm_push_frame): clear cfp->me at all times.
* vm_insnhelper.c (vm_call_bmethod): pass me.
* bootstraptest/test_method.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27634 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
it seems not to make sense. [ruby-dev:40121]
* vm_core.h, eval.c (rb_protect): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26407 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (cont_init): clear local_storage not to use current thread's.
* cont.c (fiber_t_alloc, root_fiber_alloc): link itself always for
a case that fiber_link_remove() is called before fiber_link_join().
* cont.c (fiber_init): clear cont->vm_stack and th->stack before
root_fiber_alloc() in rb_fiber_current().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (cont_init): clear local_storage not to use current thread's.
* cont.c (fiber_t_alloc, root_fiber_alloc): link itself always for
a case that fiber_link_remove() is called before fiber_link_join().
* cont.c (fiber_init): don't join half-baked fiber.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25623 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (fiber_switch): transfers dead fiber error to the previouse
or root fiber if the current fiber is dead. [ruby-core:23651]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23616 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
[ruby-dev:37991]
* test/ruby/test_fiber.rb: add a test for Fiber#alive?
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22274 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
of #elif. a patch from NISHIMATSU Takeshi <t_nissie at yahoo.co.jp>
in [ruby-list:45856].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22081 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
vm_get_ruby_level_next_cfp(), rb_vm_make_env_object(),
vm_stack_to_heap(), vm_make_proc(), vm_invoke_proc(),
vm_get_sourceline(), vm_cref(), vm_localjump_error(),
vm_make_jump_tag_but_local_jump(), vm_jump_tag_but_local_jump().
This changes may affect only core because most of renamed functions
require a pointer of not-exposed struct such as rb_thread_t or NODE.
In short, they are core functions.
* cont.c, eval.c, eval_intern.h, load.c, proc.c, thread.c,
vm_core.h, vm_dump.c, vm_eval.c, vm_exec.c, vm_insnhelper.c:
ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21659 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
vm_insnhelper.h (BOP): ISO C forbids comma at end of enumerator
list.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20591 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_context_t (rb_fiber_t includes rb_context_t).
rb_fiber_t has double linked list of fibers in same threads.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19890 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
RUBY_VM_SET_TIMER_INTERRUPT(), RUBY_VM_INTERRUPTED().
* thread.c, thread_pthread.c, thread_win32.c: fix to ignore time slice
event until sleep.
* bootstraptest/test_thread.rb: add a test for time limited join test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14654 b2dd03c8-39d4-4d8f-98ff-823fe69b080e