* vm_method.c (rb_attr): preserve encoding of the attribute ID in
error message.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43215 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Type of return value of rb_iseq_first_lineno() is now VALUE.
* vm_insnhelper.c (argument_error): ditto.
* vm_method.c (rb_method_entry_make): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43163 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* VALUE rb_iseq_path(VALUE iseqval);
* VALUE rb_iseq_absolute_path(VALUE iseqval);
* VALUE rb_iseq_label(VALUE iseqval);
* VALUE rb_iseq_base_label(VALUE iseqval);
* VALUE rb_iseq_first_lineno(VALUE iseqval);
And new (temporary) function:
* VALUE rb_iseq_klass(VALUE iseqval);
* iseq.c. vm_core.h (int rb_iseq_first_lineno): remove
function `int rb_iseq_first_lineno(const rb_iseq_t *iseq)'.
Use `VALUE rb_iseq_first_lineno(VALUE iseqval)' instead.
* proc.c. vm_insnhelper.c, vm_method.c: catch up this change.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43162 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
of a refined method is not defined.
* vm_insnhelper.c (rb_method_entry_eq): added NULL check to avoid SEGV.
* test/ruby/test_refinement.rb: related test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43090 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* gc.c (obj_free): ditto
* internal.h (struct rb_classext_struct): ditto
* method.h (rb_method_entry): remove ent param
* vm_method.c: restore the global method cache. Per class cache tables
turned out to be far too slow.
[ruby-core:57289] [Bug #8930]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_add_refined_method_entry): clear cache in the
refined class since refining a method entry is modifying the class.
[ruby-core:57079] [Bug #8880]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42896 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (obj_respond_to_missing): [DOC] respond_to_missing? is
used in the example of BasicObject.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42736 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
make classes/modules (who share method table) shady.
If module `a' and `b' shares method table m_tbl and new method
with iseq is added, then write barrier is applied only `a' or `b'.
To avoid this issue, shade such classes/modules.
* vm_method.c (rb_method_entry_make): add write barriers.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41580 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
parameter `slot'. You don't need to write a cast (VALUE *) any more.
* class.c, compile.c, hash.c, iseq.c, proc.c, re.c, variable.c,
vm.c, vm_method.c: remove cast expressions for OBJ_WRITE().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41548 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (set_visibility): use rb_method_flag_t as well as
set_method_visibility() and rename argument.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41110 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_method_entry_at): return the method entry for id at
klass, without ancestors.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40683 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_mod_public_method): fix visibility on anonymous
module. set visibility of singleton method, not method in base
class. [ruby-core:54404] [Bug #8284]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40346 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_export_method): directly override the flag of method
defined in prepending class too, not adding zsuper entry.
[ruby-core:53106] [Bug #8005]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39743 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c: call method_removed hook on called class, not on
prepending iclass.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39234 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* proc.c (rb_method_entry_location, rb_{mod,obj}_method_location): new
functions to obtain source location of method definition.
* vm_method.c (rb_obj_respond_to): show the location of old style
respond_to? method.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39089 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_obj_respond_to): drop optional include_all flag if
respond_to? method is defined in old style. [Bug #7722]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39069 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (call_cfunc_invoker_func): suppress wrong warnings
"C4550: expression evaluates to a function which is missing an
argument list." by VC6.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38847 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
should be private.
* proc.c (Init_Proc): main.define_method should be private.
* test/ruby/test_module.rb: related test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38732 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This method type is for optimized CFUNC such as Fixnum#+ and so on.
This feature is half-baked and no way to use them.
[Background]
Now, VM has opt_plus instructions to optimize `+' methods for
some Classes (such as Fixnum, Float (flonum)). We call this
type of instructions as `specialized instructions'.
This simple technique improve simple program dramatically.
However, we can make specialized instructions for only several
types (classes) and selectors (method names) because a large
instruction will be slow. In other words, this technique has no
extensibility.
To overcome this problem, VM_METHOD_TYPE_CFUNC_FRAMELESS was
introduced (r37198). This type is a variant of CFUNC, but called
their functiions directly without building a method frame.
Any CFUNC method can be defined as frameless methods if a method
is not needed to make method frame. Frameless methods are faster
as specialized instructions (a bit slower, but no need to care).
No problem described at
http://charlie.bz/blog/why-do-singleton-methods-make-ruby-slow
because this technique doesn't see class, but see method body
itself. Alias is also no problem.
[Problem]
However, we can't set frameless method type for polymorphic methods
such as Array#[]. Necessity for method frame depends on which
parameter type. For example, Fixnum#+ needs method frame if
coerce is needed. Current VM_METHOD_TYPE_CFUNC_FRAMELESS is not
flexible and need more tuning to introduce it.
Expected behavior of frameless method type may be:
result = optimized_cfunc(params); /* call optimized cfunc */
if (result == Qundef) { result = normal_cfunc(); }
This is why I say this feature is half-baked.
We need to learn primitive method in Smalltalk more.
(I heard this name at RubyConf Taiwan this month. Thanks!)
[Conclusion]
Nobody may use this feature and there is no compatibility issue.
This feature goes to next minor (2.1?).
* proc.c (rb_method_entry_arity): ditto.
* vm_eval.c, vm_insnhelper.c, vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_resolve_refined_method() to search superclasses if
me->def->orig_me is 0. This change fixes make test-all
TESTS="json ruby/test_refinement.rb".
* test/ruby/test_refinement.rb: related test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38297 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
refinements.
* proc.c (mnew): Kernel#method, Kernel#public_method,
Module#instance_method, and Module#public_instance_method should
not use refinements.
* vm_method.c (rb_method_boundp): Kernel#respond_to? should not use
refinements.
* test/ruby/test_refinement.rb: related test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38279 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
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_def) 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.
* 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@37993 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
refinement module, and don't override method_added.
* vm_method.c (rb_method_entry_make): check redefinition of
optimized methods when a method is added to a refinement module.
[ruby-core:48970] [Bug #7290]
* test/ruby/test_refinement.rb: related test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37534 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
`rb_add_method_cfunc_frameless()' API.
This API is not mature to become an offical API.
For example, we can not use this API with
`rb_define_private_method()'.
* method.h, vm_method.c (rb_add_method_cfunc_frameless): removed.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37320 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
add a new otpimization and its macro `OPT_CALL_CFUNC_WITHOUT_FRAME'.
This optimization makes all cfunc method calls `frameless', which
is fster than ordinal cfunc method call.
If `frame' is needed (for example, it calls another method with
`rb_funcall()'), then build a frame. In other words, this
optimization delays frame building.
However, to delay the frame building, we need additional overheads:
(1) Store the last call information.
(2) Check the delayed frame buidling before the frame is needed.
(3) Overhead to build a delayed frame.
rb_thread_t::passed_ci is storage of delayed cfunc call information.
(1) is lightweight because it is only 1 assignment to `passed_ci'.
To achieve (2), we modify GET_THREAD() to check `passed_ci' every
time. It causes 10% overhead on my envrionment.
This optimization only works for cfunc methods which do not need
their `frame'.
After evaluation on my environment, this optimization does not
effective every time. Because of this evaluation results, this
optimization is disabled at default.
* vm_insnhelper.c, vm.c: add VM_PROFILE* macros to measure behaviour
of VM internals. I will extend this feature.
* vm_method.c, method.h: change parameters of the `invoker' function.
Receive `func' pointer as the first parameter.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37293 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
`invoker'. `invoker' function invoke cfunc body
(rb_method_cfunc_t::func).
`invoker' is set at method definition timing.
With this change, the big `switch' (branch) in `call_cfunc()'
is no longer needed.
However, the performance benefit is only a bit.
* vm_core.h (rb_call_info_t::aux::func): add a new field to store
cfunc body function pointer.
* vm_method.c (call_cfunc_invoker_func): add a new function which
returns a suitable invoke function.
* vm_method.c (setup_method_cfunc_struct): added.
* vm_method.c (rb_add_method): fix to set `invoker'.
* vm_eval.c (vm_call0_body): catch up above changes.
* vm_insnhelper.c (call_cfunc): removed.
* vm_insnhelper.c (vm_call_cfunc): fix to call cfunc body
with `invoker' function.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37268 b2dd03c8-39d4-4d8f-98ff-823fe69b080e