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
rb_cref_t is data type of CREF. Now, the body is still NODE.
It is easy to understand what is CREF and what is pure NODE.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49897 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Time#succ is a deprecated method and not frequently used, so this wastes
icache in vm_exec_core. Using bloat-o-meter in the Linux kernel source
to shows a small reduction on my x86-64 system:
$ ~/linux/scripts/bloat-o-meter ruby.before ruby.after
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-57 (-57)
function old new delta
vm_exec_core 24216 24159 -57
[Feature #10501]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48415 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
keyword arguments/parameters and a splat argument.
[Feature #10440] (Details are described in this ticket)
Most of complex part is moved to vm_args.c.
Now, ISeq#to_a does not catch up new instruction format.
* vm_core.h: change iseq data structures.
* introduce rb_call_info_kw_arg_t to represent keyword arguments.
* add rb_call_info_t::kw_arg.
* rename rb_iseq_t::arg_post_len to rb_iseq_t::arg_post_num.
* rename rb_iseq_t::arg_keywords to arg_keyword_num.
* rename rb_iseq_t::arg_keyword to rb_iseq_t::arg_keyword_bits.
to represent keyword bitmap parameter index.
This bitmap parameter shows that which keyword parameters are given
or not given (0 for given).
It is refered by `checkkeyword' instruction described bellow.
* rename rb_iseq_t::arg_keyword_check to rb_iseq_t::arg_keyword_rest
to represent keyword rest parameter index.
* add rb_iseq_t::arg_keyword_default_values to represent default
keyword values.
* rename VM_CALL_ARGS_SKIP_SETUP to VM_CALL_ARGS_SIMPLE
to represent
(ci->flag & (SPLAT|BLOCKARG)) &&
ci->blockiseq == NULL &&
ci->kw_arg == NULL.
* vm_insnhelper.c, vm_args.c: rewrite with refactoring.
* rewrite splat argument code.
* rewrite keyword arguments/parameters code.
* merge method and block parameter fitting code into one code base.
* vm.c, vm_eval.c: catch up these changes.
* compile.c (new_callinfo): callinfo requires kw_arg parameter.
* compile.c (compile_array_): check the last argument Hash object or
not. If Hash object and all keys are Symbol literals, they are
compiled to keyword arguments.
* insns.def (checkkeyword): add new instruction.
This instruction check the availability of corresponding keyword.
For example, a method "def foo k1: 'v1'; end" is cimpiled to the
following instructions.
0000 checkkeyword 2, 0 # check k1 is given.
0003 branchif 9 # if given, jump to address #9
0005 putstring "v1"
0007 setlocal_OP__WC__0 3 # k1 = 'v1'
0009 trace 8
0011 putnil
0012 trace 16
0014 leave
* insns.def (opt_send_simple): removed and add new instruction
"opt_send_without_block".
* parse.y (new_args_tail_gen): reorder variables.
Before this patch, a method "def foo(k1: 1, kr1:, k2: 2, **krest, &b)"
has parameter variables "k1, kr1, k2, &b, internal_id, krest",
but this patch reorders to "kr1, k1, k2, internal_id, krest, &b".
(locate a block variable at last)
* parse.y (vtable_pop): added.
This function remove latest `n' variables from vtable.
* iseq.c: catch up iseq data changes.
* proc.c: ditto.
* class.c (keyword_error): export as rb_keyword_error().
* common.mk: depend vm_args.c for vm.o.
* hash.c (rb_hash_has_key): export.
* internal.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48239 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def (getlocal,setlocal): add comment to def/opt_operand.def
I spent some time thinking about the same optimization before
realizing it was already done.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48106 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We may tag the running_thread pointer to avoid making the "once" struct
bigger than "struct iseq_inline_cache_entry".
This only saves a small amount with "valgrind ruby -e exit"
before:
total heap usage: 48,122 allocs, 19,248 frees, 8,110,149 bytes allocated
after:
total heap usage: 48,122 allocs, 19,253 frees, 8,099,197 bytes allocated
* insns.def (once): define and use fake RUNNING_THREAD_ONCE_DONE
pointer to indicate is->once.running_thread is done.
* vm_core.h (iseq_inline_storage_entry): remove done field,
allowing the union to be reduced from 24=>16 bytes on 64-bit
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47542 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def (once), vm_insnhelper.c (vm_once_exec): turn the
parameter into a VALUE to get rid of type-punned pointer cast.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46478 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def (opt_regexpmatch2): respect redefined match op
Thanks to Sam Rawlins for the fix.
* test/ruby/test_string.rb: test based on Tsuyoshi Sawada's report
[Bug #9581]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45318 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def (opt_aref_with): new instruction to optimize Hash#[],
removing any allocation overhead when used with a string literal
key. Patch by normalperson (Eric Wong). [ruby-core:59640] [Bug #9382]
* insns.def (opt_aset_with): new instruction to optimize Hash#[]=
* compile.c (iseq_compile_each): compiler shortcuts for new
instructions
* hash.c (static VALUE rb_hash_compare_by_id_p): fix documentation for
Hash#compare_by_identity to reflect frozen string sharing
* test/ruby/test_hash.rb (class TestHash): test for new behavior
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44551 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
vm_insnhelper.c, vm_insnhelper.h, vm_method.c: Rename method_serial
to global_method_state and constant_serial to global_constant_state
after discussion with ko1.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44097 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
method is called on a static string literal with no arguments.
* defs/id.def (firstline): add freeze so idFreeze is available
* insns.def (opt_str_freeze): add opt_str_freeze instruction which
pushes a frozen string literal without allocating a new object if
String#freeze is not overriden
* string.c (Init_String): define String#freeze
* vm.c (vm_init_redefined_flag): define BOP_FREEZE on String class as
a basic operation
* vm_insnhelper.h: ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43627 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
ic_serial. This is possible because these fields are only ever used
exclusively with each other.
* insns.def: ditto
* vm_core.h: ditto
* vm_insnhelper.c: ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43596 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
ruby_vm_global_state_version into two separate counters - one for the
global method state and one for the global constant state. This means
changes to constants do not affect method caches, and changes to
methods do not affect constant caches. In particular, this means
inclusions of modules containing constants no longer globally
invalidate the method cache.
* class.c, eval.c, include/ruby/intern.h, insns.def, vm.c, vm_method.c:
rename rb_clear_cache_by_class to rb_clear_method_cache_by_class
* class.c, include/ruby/intern.h, variable.c, vm_method.c: add
rb_clear_constant_cache
* compile.c, vm_core.h, vm_insnhelper.c: rename vmstat field in
rb_call_info_struct to method_state
* vm_method.c: rename vmstat field in struct cache_entry to method_state
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43455 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
before calling rb_reg_match().
* test/ruby/test_string.rb: Test for above.
* vm.c (vm_init_redefined_flag): Add BOP flag for String#=~
[ruby-core:57385] [Bug #8953]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43052 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def (opt_regexpmatch2): use CALL_SIMPLE_METHOD to call =~ if
the receiver is not a T_STRING [Bug #8847] [ruby-core:56916]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42742 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def (getinlinecache, once, opt_case_dispatch): refine some
English version comments.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42638 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Stack overflow check should be done *after* pushing a stack frame.
However, some stack overflow checking codes checked *before*
pushing a stack frame with iseq->stack_max.
To solve this problem, add a new parameter `stack_max' to specify
a possible consuming stack size.
* vm_core.h (CHECK_VM_STACK_OVERFLOW0): add to share the stack overflow
checking code.
* insns.def: catch up this change.
* vm.c, vm_eval.c: ditto.
* test/ruby/test_exception.rb: add a stack overflow test.
This code is reported by nobu.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42398 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def (defined): use vm_search_superclass() like as normal super
call. based on a patch <https://gist.github.com/wanabe/5520026> by
wanabe.
* vm_insnhelper.c (vm_search_superclass): return error but not raise
exceptions.
* vm_insnhelper.c (vm_search_super_method): check the result of
vm_search_superclass and raise execptions on error.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40584 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def (defined): get method entry from the method top level
frame, not block frame. [ruby-core:54769] [Bug #8367]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40583 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
a significant performance improvement. Thanks to @samsaffron.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40410 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
by scoped module definitions. The bug was introduced in r38495.
* test/ruby/test_module.rb: related test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38772 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
compile.c (iseq_compile_each), insns.def (defineclass): change the
meaning of the third operand of defineclass as follows:
lower 3bits: the type of the defineclass
0 = class, 1 = singleton class, 2 = module
4th bit: a flag represents whether the defineclass is scoped
0 = not scoped (e.g., class Foo)
1 = scoped (e.g., class Bar::Baz)
5th bit: a flag represents whether the superclass is specified
0 = not specified (e.g., class Foo)
1 = specified (e.g., class Bar < Foo)
If the superclass is specified and is not a class, a TypeError
should be raised. [ruby-dev:46747] [Bug #7572]
* test/ruby/test_class.rb: related test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* compile.c (iseq_compile_each): count flip-flop state in local iseq
not in each iseqs, so that the keys can be other than hidden
strings. [ruby-core:47253] [Bug #6899]
* vm_insnhelper.c (lep_svar_get, lep_svar_set, vm_getspecial): store
flip-flop states in an array instead of a hash.
* iseq.c (set_relation): main iseq also can has local scope.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38292 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
of the receiver in module_eval and instance_eval.
* eval.c (ruby_Init_refinement): undef Class#refine.
* eval.c (ruby_Init_refinement): remove Module#using.
* eval.c (ruby_Init_refinement): main.using should be private.
* eval.c (rb_mod_refine): the argument of Module#refine should not
be a module.
* insns.def (defineclass): do not activate refinements in a class or
module.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38262 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Operand unification technique enable to combine
an instruction and specific operands and make new
instruction.
* defs/opt_operand.def: add several configuration
of operand unifications.
* insns.def: use `int' instead to suppress warning.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38173 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
path without caching the computed path. Some classes are frozen, and
will raise an exception without this.
* probes.d (cmethod-entry, cmethod-return): separate cmethods from
regular methods to match set trace func.
* probes_helper.h: refactor macros. Fix probes to avoid calling
#inspect when profiling.
* insns.def: update for use with new macros.
* vm_eval.c: ditto
* vm_insnhelper.c: ditto
* test/dtrace/test_singleton_function.rb: fix test for new output.
* test/dtrace/test_cmethod.rb: test the cmethod probes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38099 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
(1) TracePoint#return_value which returns return
value on the :return and :c_return event.
(2) TracePoint#raised_exception which returns raised exception
value on the :raise event.
Eeach methods raise RuntimeError if it is called at unsupported
event.
Please review and give us feedback until next preview
release (Dec/2012) of Ruby 2.0.0.
* insns.def, vm.c, vm_eval.c, vm_insnhelper.c, eval.c, thread.c:
ditto.
* vm_trace.c, vm_core.h: move definition of rb_trace_arg_t from
vm_trace.c to vm_core.h.
Caller fills rb_trace_arg_t and pass the pointer of this variable.
* test/ruby/test_settracefunc.rb: fix tests to test this change.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37752 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (empty_ary_alloc, ary_new): added array create DTrace probe.
* compile.c (rb_insns_name): allowing DTrace probes to access
instruction sequence name.
* Makefile.in: translate probes.d file to appropriate header file.
* common.mk: declare dependencies on the DTrace header.
* configure.in: add a test for existence of DTrace.
* eval.c (setup_exception): add a probe for when an exception is
raised.
* gc.c: Add DTrace probes for mark begin and end, and sweep begin and
end.
* hash.c (empty_hash_alloc): Add a probe for hash allocation.
* insns.def: Add probes for function entry and return.
* internal.h: function declaration for compile.c change.
* load.c (rb_f_load): add probes for `load` entry and exit, require
entry and exit, and wrapping search_required for load path search.
* object.c (rb_obj_alloc): added a probe for general object creation.
* parse.y (yycompile0): added a probe around parse and compile phase.
* string.c (empty_str_alloc, str_new): DTrace probes for string
allocation.
* test/dtrace/*: tests for DTrace probes.
* vm.c (vm_invoke_proc): add probes for function return on exception
raise, hash create, and instruction sequence execution.
* vm_core.h: add probe declarations for function entry and exit.
* vm_dump.c: add probes header file.
* vm_eval.c (vm_call0_cfunc, vm_call0_cfunc_with_frame): add probe on
function entry and return.
* vm_exec.c: expose instruction number to instruction name function.
* vm_insnshelper.c: add function entry and exit probes for cfunc
methods.
* vm_insnhelper.h: vm usage information is always collected, so
uncomment the functions.
12 19:14:50 2012 Akinori MUSHA <knu@iDaemons.org>
* configure.in (isinf, isnan): isinf() and isnan() are macros on
DragonFly which cannot be found by AC_REPLACE_FUNCS(). This
workaround enforces the fact that they exist on DragonFly.
12 15:59:38 2012 Shugo Maeda <shugo@ruby-lang.org>
* vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo),
vm_insnhelper.c (vm_search_method): revert r37616 because it's too
slow. [ruby-dev:46477]
* test/ruby/test_refinement.rb (test_inline_method_cache): skip
the test until the bug is fixed efficiently.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
`opt_send_simple' to the place near `send' definition.
(to take care about icache locality).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37260 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This condition will be true after r37258.
* vm_insnhelper.c (vm_caller_setup_args): remove `UNLIKELY' on
checking blockiseq (it seems `LIKELY').
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37259 b2dd03c8-39d4-4d8f-98ff-823fe69b080e