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