mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
use method cache on Object#respond_to?
rb_method_boundp (method_boundp) searches method_entry, but this search did not use pCMC, so change to use it.
This commit is contained in:
parent
0362b4c689
commit
53edb27bac
Notes:
git
2020-12-14 15:28:33 +09:00
2 changed files with 36 additions and 14 deletions
|
@ -389,8 +389,8 @@ check_funcall_failed(VALUE v, VALUE e)
|
|||
struct rescue_funcall_args *args = (void *)v;
|
||||
int ret = args->respond;
|
||||
if (!ret) {
|
||||
switch (rb_method_boundp(args->defined_class, args->mid,
|
||||
BOUND_PRIVATE|BOUND_RESPONDS)) {
|
||||
switch (method_boundp(args->defined_class, args->mid,
|
||||
BOUND_PRIVATE|BOUND_RESPONDS)) {
|
||||
case 2:
|
||||
ret = TRUE;
|
||||
break;
|
||||
|
|
46
vm_method.c
46
vm_method.c
|
@ -1182,20 +1182,33 @@ rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
|
|||
return method_entry_resolve_refinement(klass, id, TRUE, defined_class_ptr);
|
||||
}
|
||||
|
||||
MJIT_FUNC_EXPORTED const rb_callable_method_entry_t *
|
||||
rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
|
||||
static const rb_callable_method_entry_t *
|
||||
callable_method_entry_refeinements(VALUE klass, ID id, VALUE *defined_class_ptr, bool with_refinements)
|
||||
{
|
||||
const rb_callable_method_entry_t *cme = callable_method_entry(klass, id, defined_class_ptr);
|
||||
|
||||
if (cme == NULL || cme->def->type != VM_METHOD_TYPE_REFINED) {
|
||||
return cme;
|
||||
}
|
||||
else {
|
||||
VALUE defined_class, *dcp = defined_class_ptr ? defined_class_ptr : &defined_class;
|
||||
const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, TRUE, dcp);
|
||||
const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, with_refinements, dcp);
|
||||
return prepare_callable_method_entry(*dcp, id, me, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
MJIT_FUNC_EXPORTED const rb_callable_method_entry_t *
|
||||
rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
|
||||
{
|
||||
return callable_method_entry_refeinements(klass, id, defined_class_ptr, true);
|
||||
}
|
||||
|
||||
static const rb_callable_method_entry_t *
|
||||
callable_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
|
||||
{
|
||||
return callable_method_entry_refeinements(klass, id, defined_class_ptr, false);
|
||||
}
|
||||
|
||||
const rb_method_entry_t *
|
||||
rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
|
||||
{
|
||||
|
@ -1377,21 +1390,23 @@ rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
|
|||
#define BOUND_PRIVATE 0x01
|
||||
#define BOUND_RESPONDS 0x02
|
||||
|
||||
int
|
||||
rb_method_boundp(VALUE klass, ID id, int ex)
|
||||
static int
|
||||
method_boundp(VALUE klass, ID id, int ex)
|
||||
{
|
||||
const rb_method_entry_t *me;
|
||||
const rb_callable_method_entry_t *cme;
|
||||
|
||||
VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_ICLASS));
|
||||
|
||||
if (ex & BOUND_RESPONDS) {
|
||||
me = method_entry_resolve_refinement(klass, id, TRUE, NULL);
|
||||
cme = rb_callable_method_entry_with_refinements(klass, id, NULL);
|
||||
}
|
||||
else {
|
||||
me = rb_method_entry_without_refinements(klass, id, NULL);
|
||||
cme = callable_method_entry_without_refinements(klass, id, NULL);
|
||||
}
|
||||
|
||||
if (me != NULL) {
|
||||
if (cme != NULL) {
|
||||
if (ex & ~BOUND_RESPONDS) {
|
||||
switch (METHOD_ENTRY_VISI(me)) {
|
||||
switch (METHOD_ENTRY_VISI(cme)) {
|
||||
case METHOD_VISI_PRIVATE:
|
||||
return 0;
|
||||
case METHOD_VISI_PROTECTED:
|
||||
|
@ -1401,7 +1416,7 @@ rb_method_boundp(VALUE klass, ID id, int ex)
|
|||
}
|
||||
}
|
||||
|
||||
if (me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
|
||||
if (cme->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
|
||||
if (ex & BOUND_RESPONDS) return 2;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1410,6 +1425,13 @@ rb_method_boundp(VALUE klass, ID id, int ex)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// deprecated
|
||||
int
|
||||
rb_method_boundp(VALUE klass, ID id, int ex)
|
||||
{
|
||||
return method_boundp(klass, id, ex);
|
||||
}
|
||||
|
||||
static void
|
||||
vm_cref_set_visibility(rb_method_visibility_t method_visi, int module_func)
|
||||
{
|
||||
|
@ -2384,7 +2406,7 @@ basic_obj_respond_to(rb_execution_context_t *ec, VALUE klass, VALUE obj, ID id,
|
|||
{
|
||||
VALUE ret;
|
||||
|
||||
switch (rb_method_boundp(klass, id, pub|BOUND_RESPONDS)) {
|
||||
switch (method_boundp(klass, id, pub|BOUND_RESPONDS)) {
|
||||
case 2:
|
||||
return FALSE;
|
||||
case 0:
|
||||
|
|
Loading…
Add table
Reference in a new issue