Patch by @spastorino [Fixes GH-849]
https://github.com/ruby/ruby/pull/849
* test/ruby/test_module.rb: Update test for changes
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50585 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
* CREF_CLASS(cref)
* CREF_NEXT(cref)
* CREF_VISI(cref)
* CREF_VISI_SET(cref, v)
* CREF_REFINEMENTS(cref)
* CREF_PUSHED_BY_EVAL(cref)
* CREF_PUSHED_BY_EVAL_SET(cref)
* CREF_OMOD_SHARED(cref)
* CREF_OMOD_SHARED_SET(cref)
* CREF_OMOD_SHARED_UNSET(cref)
This is process to change CREF data type from NODE.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49894 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
* variable.c (rb_alias_variable): IDs are always immportal now, no
pin down is needed.
* vm_method.c (rb_method_entry_make): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49520 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
method, raise a NameError if the method is not
defined in refined class.
But if the method is defined in refined class,
it should keep refined method and remove original
method.
Patch by Seiei Higa. [ruby-core:67722] [Bug #10765]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49480 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* method.h (UNDEFINED_REFINED_METHOD_P): macro to tell if refined
original method is defined.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49222 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_alias): raise a NameError when creating alias to
a refined method if the original method of the refined method is
not defined. [ruby-core:67523] [Bug #10731]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49221 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_method_entry): if no super class, no original
method entry. [ruby-core:67389] [Bug #10707]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49184 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_mod_remove_method): preserve encodings of method
name and class name in error messages.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48576 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* include/ruby/intern.h (rb_disable_super, rb_enable_super): warn
as deprecated at build time, instead of ignoring silently or
warning at runtime only.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48283 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_method_entry_make): get rid of storing method
cache, so that the added method will be called later.
[ruby-dev:48691] [Bug #10421]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48118 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_method_entry_make): warn redefinition only for
already defined methods, but not for undefined methods.
[ruby-dev:48691] [Bug #10421]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48111 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (GLOBAL_METHOD_CACHE): make a single expression.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47604 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We are not currently avoiding recursion by calling
release_method_definition, so use rb_free_method_entry directly
to make changing code easier in case we change the way
rb_method_entry_t is allocated.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47147 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
exposing IDs from collectable symbols.
[Bug #10014]
Now, rb_check_id() returns 0 if corresponding symbol is
pinned dynamic symbol.
There is remaining intern_cstr_without_pindown(), it can return
IDs from collectable symbols. We must be careful to use it
(only used in parse.y). I think it should be removed if
it does not have impact for performance.
* parse.y:
add:
* STATIC_SYM2ID()
* STATIC_ID2SYM()
rename:
* rb_pin_dynamic_symbol() -> dsymbol_pindown()
* internal.h:
remove:
* rb_check_id_without_pindown()
* rb_sym2id_without_pindown()
add:
* rb_check_symbol()
* rb_check_symbol_cstr()
* load.c: use rb_check_id() or rb_check_id_cstr().
* object.c: ditto.
* struct.c: ditto.
* thread.c: ditto.
* vm_method.c: ditto.
* string.c (sym_find): use only rb_check_symbol().
* sprintf.c (rb_str_format): use rb_check_symbol_cstr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46764 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (basic_obj_respond_to): `priv` is not a VALUE but a
mere flag, so cannot call RTEST() on it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46442 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_method_entry_make): separate selection of IDs to
be private from condition of method to be defined.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46438 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
See this ticket about Symbol GC.
* include/ruby/ruby.h:
Declare few functions.
* rb_sym2id: almost same as old SYM2ID but support dynamic symbols.
* rb_id2sym: almost same as old ID2SYM but support dynamic symbols.
* rb_sym2str: almost same as `rb_id2str(SYM2ID(sym))` but not
pin down a dynamic symbol.
Declare a new struct.
* struct RSymbol: represents a dynamic symbol as object in
Ruby's heaps.
Add few macros.
* STATIC_SYM_P: check a static symbol.
* DYNAMIC_SYM_P: check a dynamic symbol.
* RSYMBOL: cast to RSymbol
* gc.c: declare RSymbol. support T_SYMBOL.
* internal.h: Declare few functions.
* rb_gc_free_dsymbol: free up a dynamic symbol. GC call this
function at a sweep phase.
* rb_str_dynamic_intern: convert a string to a dynamic symbol.
* rb_check_id_without_pindown: not pinning function.
* rb_sym2id_without_pindown: ditto.
* rb_check_id_cstr_without_pindown: ditto.
* string.c (Init_String): String#intern and String#to_sym use
rb_str_dynamic_intern.
* template/id.h.tmpl: use LSB of ID as a flag for determining a
static symbol, so we shift left other ruby_id_types.
* string.c: use rb_sym2str instead `rb_id2str(SYM2ID(sym))` to
avoid pinning.
* load.c: use xx_without_pindown function at creating temporary ID
to avoid pinning.
* object.c: ditto.
* sprintf.c: ditto.
* struct.c: ditto.
* thread.c: ditto.
* variable.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45426 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_method_entry_get_without_cache): me->klass is 0
for a method aliased in a module. [ruby-core:61636] [Bug #9663]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45387 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_method_entry_get_without_cache): get rid of
infinite recursion at aliases in a subclass and a superclass.
return actually defined class for other than singleton class.
[ruby-core:60431] [Bug #9475]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45367 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_add_method, rb_attr): cast between pointer and
ID via VALUE.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45341 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
a refining method in case the method is private.
[ruby-core:60111] [Bug #9452]
* vm_method.c (make_method_entry_refined): set me->flag of a refined
method entry to NOEX_PUBLIC in case the original method is private
and it is refined as a public method. The original flag is stored
in me->def->body.orig_me, so it's OK to make a refined method
entry public. [ruby-core:60111] [Bug #9452]
* test/ruby/test_refinement.rb: related tests.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44931 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (GLOBAL_METHOD_CACHE_MASK): set from
GLOBAL_METHOD_CACHE_SIZE automatically.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44302 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Note that rb_method_entry_t::klass is not constified.
We may constify this field.
* test/ruby/test_alias.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44234 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* proc.c (method_owner): return the class where alias is defined, not
the class original method is defined.
* vm_method.c (rb_method_entry_make, rb_alias): store the originally
defined class in me. [Bug #7993] [Bug #7842] [Bug #9236]
* vm_method.c (rb_method_entry_get_without_cache): cache included
module but not iclass.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44175 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_clear_method_cache_by_class): fire
ruby::method-cache-clear probe on global or klass-level method cache
clear [Bug #9190]
* probes.d (provider ruby): new dtrace probe
* doc/dtrace_probes.rdoc: docs for new probe
* test/dtrace/test_method_cache.rb: test for new probe
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44103 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
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
original method of a refined method is undef to avoid SEGV.
* vm_method.c (rb_method_entry_without_refinements): return 0 when
the original method of a refined method is undef to avoid SEGV.
* test/ruby/test_refinement.rb: related test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43334 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* 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
rb_define_method_fast(). Defined method with this C API
does not make a method frame. It is bit lightweight than
ordinal C functions. Now only 0 or 1 argc are permitted.
* method.h (VM_METHOD_TYPE_CFUNC_FRAMELESS): rename macro name
from VM_METHOD_TYPE_CFUNC_FAST.
* vm_insnhelper.c, vm_method.c: rename related functions.
* proc.c (rb_method_entry_arity): catch up above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37252 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This method is similar to VM_METHOD_TYPE_CFUNC methods, but
called cfunc without building new frame (does not push new control
frame). If error is occured in cfunc, the backtrace only shows
caller frame and upper.
This kind of methods can be added by rb_define_method_fast().
This feature is similar to specialized instructions (opt_plus, etc),
but more flexible (but a bit slower).
* class.c (rb_define_method_fast): added.
Maybe it will be renamed soon.
* vm_insnhelper.c (vm_call_method): support method type
VM_METHOD_TYPE_CFUNC_FAST.
* proc.c (rb_method_entry_arity): catch up new method type.
* vm_method.c (rb_add_method_cfunc_fast): added.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37198 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
enable/disable global method caching. [ruby-dev:46203] [Bug #7111]
* vm_method.c (rb_method_entry_get_with_omod): don't use global
method cache if OPT_GLOBAL_METHOD_CACHE is 0.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37106 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
argument of Module#refine.
* vm_method.c (search_method): if klass is an iclass, lookup the
original module of the iclass in omod in order to allow
refinements of modules.
* test/ruby/test_refinement.rb: add tests for the above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37040 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
vm_insnhelper.c, vm_insnhelper.h, vm_method.c: add klass to
rb_control_frame_t to implement super correctly.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36595 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* string.c, vm_insnhelper.c, vm_method.c: use RB_TYPE_P() and
BUILTIN_TYPE() if possible.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36589 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* class.c (rb_include_module): include modules after the origin.
* class.c (include_modules_at): skip prepended modules.
* class.c (rb_prepend_module): now basic.klass in ICLASS refers the
old original class/module. [ruby-dev:45868][Bug #6662]
* class.c (rb_mod_ancestors): ditto.
* vm_method.c (search_method): search method entry from the origin
iclass.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36266 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (remove_method): remove the method from the original
m_tbl on a prepended module.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36239 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_method_entry_make): use name of klass explicitly.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36233 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c (rb_method_entry_make): use NOEX_NOREDEF itself for the
condition.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36231 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
(1) rename rb_location_t to rb_iseq_location_t.
(2) rename field names of rb_iseq_location_t to adjust
RubyVM::Backtrace::Location methods.
(2-1) filename -> path
(2-2) filepath -> absolute_path
(2-3) basename -> base_label
(2-4) name -> label
(3) rename filed name rb_iseq_location_t#line_no to
rb_iseq_location_t#first_lineno to clear purpose of this field.
(4) The field names rb_binding_t#(filename|line_no) are also renamed
to rb_binding_t#(path|first_lineno).
* compile.c: apply above changes.
* iseq.c: ditto.
* proc.c: ditto.
* vm*.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35899 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
nobu pointed out that rb_method_basic_definition_p() is enough
for last commit.
* error.c, eval_error.c: change for above.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35770 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Backtrace information contains an array consists of location
information for each frames by string.
RubyVM::Backtrace object is lightweight backtrace information,
which contains complete information to generate traditional style
backtrace (an array of strings) with faster generation.
If someone accesses to backtrace information via
Exception#backtrace, then convert a RubyVM::Backtrace object to
traditonal style backtrace.
This change causes incompatibility on marshal dumpped binary
of Exception. If you have any trouble on it, please tell us
before Ruby 2.0 release.
Note that RubyVM::Backtrace object should not expose Ruby level.
* error.c, eval.c, vm_eval.c: ditto.
* internal.h: ditto.
* eval_error.c: fix to skip "set_backtrace" method invocation in
creating an exception object if it call a normal set_backtrace
method (defined by core).
* test/ruby/test_settracefunc.rb: fix for above change.
* vm_method.c (rb_method_defined_by): added. This function
checks that the given object responds with the given method
by the given cfunc.
* benchmark/bm_vm2_raise1.rb, benchmark/bm_vm2_raise2.rb:
add to measure exception creation speed. raise1 create
exception objects from shallow stack frame. raise2 create
exception objects from deep stack frame.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35769 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
information.
rb_location_t#filename, filepath, name and line_no was moved from
rb_iseq_t. rb_location_t#basename is a new field which is
similar to `name' field without any decoration.
`name' field contains some decoration such as `block in foo'.
`basename' only contains `foo'.
rb_iseq_t contains memory object of rb_location_t.
* iseq.c: setup rb_location_t for each rb_iseq_t memory objects.
* compile.c, proc.c, vm.c, vm_dump.c, vm_eval.c, vm_insnhelper.c,
vm_method.c: support about it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35756 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
[Bug #6048]. Isolate hash computation for proc
* internal.h: Declaration for above
* vm_method.c (rb_method_definition_hash): Computation for
hash part of a method definition
* method.h: Declaration for above
* test/ruby/test_method.rb: Test for above
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34715 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
obj.respond_to?(:a_protected_method) should return false because
calling a protected method may cause NoMethodError if called
from outside the class inheritance tree. Kernel#respond_to? is
mostly used to test if it is safe to call a method, so the false
positive should be avoided. [ruby-dev:40461] [ruby-dev:41739]
[ruby-dev:41837]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34582 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
is passwd to Module#private_constant. [ruby-list:48558]
* vm_method.c (set_method_visibility): ditto for
Module#private_class_method.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33936 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Manage a redefinition of special methods for each classes.
A patch from Joel Gouly <joel.gouly@gmail.com>. Thanks!
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33059 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
to solve an issue reported at [ruby-dev:44413] [Ruby 1.9 - Bug #5217].
Before this fix, each instruction has an information including
line number (iseq::iseq_insn_info_table). Instead of this data
structure, recording only line number changing places
(iseq::iseq_line_info_table).
The order of entries in iseq_line_info_table is ascending order of
iseq_line_info_table_entry::position. You can get a line number
by an iseq and a program counter with this data structure.
This fix reduces memory consumption of iseq (bytecode).
On my measurement, a rails application consumes 21.8MB for
iseq with this fix on the 32bit CPU. Without this fix, it
consumes 24.7MB for iseq [ruby-dev:44415].
* proc.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
* vm.c (rb_vm_get_sourceline): change to use rb_iseq_line_no().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33046 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
NameError for undefined method.
* load.c (rb_mod_autoload_p), object.c (rb_mod_const_get),
variable.c (rb_f_untrace_var, set_const_visibility), vm_method.c
(rb_mod_{remove,undef,alias}_method, set_method_visibility):
remove inadvertent symbol creation. based on the first patch by
Jeremy Evans at [ruby-core:38447]. [Feature #5089]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32686 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
case. based on the patch by Jeremy Evans at [ruby-core:38417].
[Feature #5072]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32685 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
based on the second patch by Jeremy Evans at [ruby-core:38447]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32684 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
(rb_gc_mark_unlinked_live_method_entries): fix SEGV bug.
rb_method_entry_t was free'd even when the method is still on the
stack if it is BMETHOD (i.e., Method#call). This is because
rb_method_entry_t is embedded in struct METHOD. This commit
separates them and marks the live method entries.
See [ruby-core:38449] in detail. fix [Bug #5047] [ruby-core:38171]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32669 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
avoid inadvertent symbol creation in reflection methods. based
on a patch by Jeremy Evans at [ruby-core:38367]. [Feature #5072]
* vm_method.c (rb_mod_method_defined)
(rb_mod_{public,private,protected}_method_defined)
(obj_respond_to): ditto.
* parse.y (rb_check_id): new function returns already interned ID
or 0.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32621 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* compile.c, eval.c, iseq.c, object.c, parse.y, proc.c, process.c,
thread.c, vm.c, vm_eval.c, vm_insnhelper.c, vm_method.c: don't
declare internal functions.
Note that rb_method_entry_eq() is defined in vm_method.c but
there was a declaration in proc.c with different const-ness.
Now it is declared in method.h with same const-ness to the
definition.
* object.c (rb_mod_module_exec): don't declare functions declared in
include/ruby/intern.h.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32163 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
ruby_vm_global_state_version and related macros
from vm_core.h to vm_insnhelper.h.
* vm.c (vm_clear_all_cache): added. This function is called
when ruby_vm_global_state_version overflows.
TODO: vm_clear_all_inline_method_cache() is only place holder.
We need to implement it ASAP.
* vm_method.c (vm_clear_global_method_cache): added.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32056 b2dd03c8-39d4-4d8f-98ff-823fe69b080e