* vm.c (rb_vm_jump_tag_but_local_jump): no longer used since
r51292.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60025 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_vm_make_jump_tag_but_local_jump): get rid of fetching
retval when it is not used. it is necessary for local jump
state only.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60024 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
when raising exception in bmethod call event
* vm.c (invoke_bmethod): set FINISH flag just before calling vm_exec.
[ruby-dev:50162] [Bug #13705]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59956 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (rb_context_t): introduce saved_ec instaad of saved_thread.
We only need to transfer ec data (not all of thread data).
Introduce `thread_value` field to point creation thread.
To acccess this field, `cont_thread_value()` is introduced.
* vm.c (rb_execution_context_mark): remove `static` and use it
from cont.c (use this function instead of `rb_thread_mark`).
* vm_insnhelper.c (rb_vm_push_frame): accept ec instead of th.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59831 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c: VM_EP_IN_HEAP_P() and vm_ep_in_heap_p_() only requires ec
pointed from th.
* vm.c (rb_execution_context_mark): GET_THREAD() returns current
running thread and we need to use marking thread here. Pass marking
thread's ec instead of current thread.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59756 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_execution_context_mark): separate from thread_mark().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59752 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Sometimes, size of a hash can be calcluated a priori. By providing
such info to the constructor we can avoid unnecessary internal re-
allocations. This can boost for instance creation of hash literals.
[Bug #13861]
Signed-off-by: Urabe, Shyouhei <shyouhei@ruby-lang.org>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59744 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_insnhelper.c (threadptr_stack_overflow): set stack overflow
flag until handling execptions, to get rid of cfp consistency
error when exec tag was rewound. [ruby-core:80618] [Bug #13412]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59606 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* 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 (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
* vm_core.h (rb_vm_struct): separate trap_list cmd and safe to
each arrays, to shrink the size.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59434 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
These caused numerous CI failures I haven't been able to
reproduce [ruby-core:82102]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59364 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The same hash keys may be loaded from tainted data sources
frequently (e.g. parsing headers from socket or loading
YAML data from a file). If a non-tainted fstring already
exists (because the application expects the hash key),
cache and deduplicate the tainted version in the new
tainted_frozen_strings table.
For non-embedded strings, this also allows sharing with the
underlying malloc-ed data.
* vm_core.h (rb_vm_struct): add tainted_frozen_strings
* vm.c (ruby_vm_destruct): free tainted_frozen_strings
(Init_vm_objects): initialize tainted_frozen_strings
(rb_vm_tfstring_table): accessor for tainted_frozen_strings
* internal.h: declare rb_fstring_existing, rb_vm_tfstring_table
* hash.c (fstring_existing_str): remove (moved to string.c)
(hash_aset_str): use rb_fstring_existing
* string.c (rb_fstring_existing): new, based on fstring_existing_str
(tainted_fstr_update): new
(rb_fstring_existing0): new, based on fstring_existing_str
(rb_tainted_fstring_existing): new, special case for tainted strings
(rb_str_free): delete from tainted_frozen_strings table
* test/ruby/test_optimization.rb (test_hash_reuse_fstring): new test
[ruby-core:82012] [Bug #13737]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59354 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (vm_init_redefined_flag): set redefinition flag for Symbol#==.
The bug was introduced in r58895.
* test/ruby/test_symbol.rb: test for above.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59250 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
* 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
* vm_core.h (vm_block_handler_verify): this function only checks
the given block handler with VM_ASSERT(). No need to return any value.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59045 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_eval.c (yield_under): do not inform Proc is lambda or not.
After that invoke_block_from_c_bh() checks it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59017 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* internal.h (rb_yield_lambda): rename to rb_yield_force_blockarg()
because this function prohibt lambda arg setup (strict setup).
* vm.c (invoke_iseq_block_from_c): remove splattable argument because
it is not used.
* vm.c (invoke_block_from_c_splattable): rename to invoke_block_from_c_bh()
because `splattable` doesn't make sense on current this function.
Also accept `force_blockarg' parameter instead of `splattable` parameter.
It is more clear.
* vm.c (invoke_block_from_c_unsplattable): rename to
invoke_block_from_c_proc() and accept `proc` instead of `block'.
This function is used only by proc block invocation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59016 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_args.c (enum arg_setup_type): remove arg_setup_lambda because it is
same as arg_setup_method.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59014 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
VM_FRAME_FLAG_LAMBDA. So that lambda block frame is
VM_FRAME_MAGIC_BLOCK | VM_FRAME_FLAG_LAMBDA.
* vm_core.h: remvoe VM_FRAME_MAGIC_PROC because nobody uses it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59006 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* proc.c (ruby_binding_data_type): set RUBY_TYPED_WB_PROTECTED.
Insert write barriers (WBs) to all of writes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58988 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h: rename absolute_path to realpath because it is expected name.
external APIs (#absolute_path methods) are remained.
* vm_core.h: remove rb_iseq_location_struct::path and
rb_iseq_location_struct::absolute_path and introduce pathobj.
if given path equals to given absolute_path (and most of case
it is true), pathobj is simply given path String. If it is not same,
pathobj is Array and pathobj[0] is path and pathobj[1] is realpath.
This size optimization reduce 8 bytes and
sizeof(struct rb_iseq_constant_body) is 200 bytes -> 192 bytes
on 64bit CPU.
To support this change, the following functions are introduced:
* pathobj_path() (defined in vm_core.h)
* pathobj_realpath() (ditto)
* rb_iseq_path() (decl. in vm_core.h)
* rb_iseq_realpath() (ditto)
* rb_iseq_pathobj_new() (ditto)
* rb_iseq_pathobj_set() (ditto)
* vm_core.h (rb_binding_t): use pathobj instead of path. If binding
is given at eval methods, realpath (absolute_path) was caller's
realpath. However, they should use binding's realpath.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
To convert the object implicitly, it has had two parts in convert_type() which are
1. lookink up the method's id
2. calling the method
Seems that strncmp() and strcmp() in convert_type() are slightly heavy to look up
the method's id for type conversion.
This patch will add and use internal APIs (rb_convert_type_with_id, rb_check_convert_type_with_id)
to call the method without looking up the method's id when convert the object.
Array#flatten -> 19 % up
Array#+ -> 3 % up
[ruby-dev:50024] [Bug #13341] [Fix GH-1537]
### Before
Array#flatten 104.119k (± 1.1%) i/s - 525.690k in 5.049517s
Array#+ 1.993M (± 1.8%) i/s - 10.010M in 5.024258s
### After
Array#flatten 124.005k (± 1.0%) i/s - 624.240k in 5.034477s
Array#+ 2.058M (± 4.8%) i/s - 10.302M in 5.019328s
### Test Code
require 'benchmark/ips'
class Foo
def to_ary
[1,2,3]
end
end
Benchmark.ips do |x|
ary = []
100.times { |i| ary << i }
array = [ary]
x.report "Array#flatten" do |i|
i.times { array.flatten }
end
x.report "Array#+" do |i|
obj = Foo.new
i.times { array + obj }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58978 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Today, it increases IO#close performance with many threads:
Execution time (sec)
name trunk after
vm_thread_close 4.276 3.018
Speedup ratio: compare with the result of `trunk' (greater is better)
name after
vm_thread_close 1.417
This speedup comes because rb_notify_fd_close only scans threads
inside rb_thread_io_blocking_region, not all threads in the VM.
In the future, this type data structure may allow us to notify
waiters of multiple FDs on a single thread (when using
Fibers).
* thread.c (struct waiting_fd): declare
(rb_thread_io_blocking_region): use on-stack list waiter
(rb_notify_fd_close): walk vm->waiting_fds instead
(call_without_gvl): remove old field setting
(th_init): ditto
* vm_core.h (typedef struct rb_vm_struct): add waiting_fds list
* (typedef struct rb_thread_struct): remove waiting_fd field
(rb_vm_living_threads_init): initialize waiting_fds list
I am now kicking myself for not thinking about this 3 years ago
when I introduced ccan/list in [Feature #9632] to optimize this
same function :<
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58812 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (ruby_vm_run_at_exit_hooks): should free by `ruby_xfree`
memories allocated by `ALLOC`.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58670 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
* st.c (rb_hash_bulk_insert): new API to bulk insert entries
into a hash. Given arguments are first inserted into the
table at once, then reindexed. This is faster than inserting
things using rb_hash_aset() one by one.
This arrangement (rb_ prefixed function placed in st.c) is
unavoidable because it both touches table internal and write
barrier at once.
* internal.h: delcare the new function.
* hash.c (rb_hash_s_create): use the new function.
* vm.c (core_hash_merge): ditto.
* insns.def (newhash): ditto.
* test/ruby/test_hash.rb: more coverage on hash creation.
* test/ruby/test_literal.rb: ditto.
-----------------------------------------------------------
benchmark results:
minimum results in each 7 measurements.
Execution time (sec)
name before after
loop_whileloop2 0.136 0.137
vm2_bighash* 1.249 0.623
Speedup ratio: compare with the result of `before' (greater is better)
name after
loop_whileloop2 0.996
vm2_bighash* 2.004
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58492 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We need to fix GC bug before merging this. Revert revisions
58452, 58435, 58434, 58428, 58427 in this order.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58463 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Same as rb_ary_tmp_new_from_values(), it reduces vm_exec_core binary
size from 26,176 bytes to 26,080 bytes. But this time, also with a
bit of optimizations:
- Because we are allocating a new hash and no back references are
introduced at all, we can safely skip write barriers.
- Also, the iteration never recurs. We can avoid complicated
function callbacks by using st_insert instead of st_update.
----
* hash.c (rb_hash_new_from_values): refactor
extract the bulk insert into a function.
* hash.c (rb_hash_new_from_object): also refactor.
* hash.c (rb_hash_s_create): use the new functions.
* insns.def (newhash): ditto.
* vm.c (core_hash_from_ary): ditto.
* iternal.h: export the new function.
-----------------------------------------------------------
benchmark results:
minimum results in each 7 measurements.
Execution time (sec)
name before after
loop_whileloop2 0.135 0.134
vm2_bighash* 1.236 0.687
Speedup ratio: compare with the result of `before' (greater is better)
name after
loop_whileloop2 1.008
vm2_bighash* 1.798
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58427 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (hook_before_rewind): skip rewind hooks if err is SystemStackError
because rewind hooks can cause stack overflow again and again.
* thread.c (ruby_thread_stack_overflow): do not disable all hooks.
Additionally, clearing ruby_vm_event_flags is not suitable way
to disable hooks.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58349 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_vm_register_special_exception): make the contents
of special exception messages static.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58285 b2dd03c8-39d4-4d8f-98ff-823fe69b080e