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;
|
struct rescue_funcall_args *args = (void *)v;
|
||||||
int ret = args->respond;
|
int ret = args->respond;
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
switch (rb_method_boundp(args->defined_class, args->mid,
|
switch (method_boundp(args->defined_class, args->mid,
|
||||||
BOUND_PRIVATE|BOUND_RESPONDS)) {
|
BOUND_PRIVATE|BOUND_RESPONDS)) {
|
||||||
case 2:
|
case 2:
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
break;
|
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);
|
return method_entry_resolve_refinement(klass, id, TRUE, defined_class_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
MJIT_FUNC_EXPORTED const rb_callable_method_entry_t *
|
static const rb_callable_method_entry_t *
|
||||||
rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
|
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);
|
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) {
|
if (cme == NULL || cme->def->type != VM_METHOD_TYPE_REFINED) {
|
||||||
return cme;
|
return cme;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE defined_class, *dcp = defined_class_ptr ? defined_class_ptr : &defined_class;
|
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);
|
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 *
|
const rb_method_entry_t *
|
||||||
rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
|
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_PRIVATE 0x01
|
||||||
#define BOUND_RESPONDS 0x02
|
#define BOUND_RESPONDS 0x02
|
||||||
|
|
||||||
int
|
static int
|
||||||
rb_method_boundp(VALUE klass, ID id, int ex)
|
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) {
|
if (ex & BOUND_RESPONDS) {
|
||||||
me = method_entry_resolve_refinement(klass, id, TRUE, NULL);
|
cme = rb_callable_method_entry_with_refinements(klass, id, NULL);
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
if (ex & ~BOUND_RESPONDS) {
|
||||||
switch (METHOD_ENTRY_VISI(me)) {
|
switch (METHOD_ENTRY_VISI(cme)) {
|
||||||
case METHOD_VISI_PRIVATE:
|
case METHOD_VISI_PRIVATE:
|
||||||
return 0;
|
return 0;
|
||||||
case METHOD_VISI_PROTECTED:
|
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;
|
if (ex & BOUND_RESPONDS) return 2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1410,6 +1425,13 @@ rb_method_boundp(VALUE klass, ID id, int ex)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deprecated
|
||||||
|
int
|
||||||
|
rb_method_boundp(VALUE klass, ID id, int ex)
|
||||||
|
{
|
||||||
|
return method_boundp(klass, id, ex);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vm_cref_set_visibility(rb_method_visibility_t method_visi, int module_func)
|
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;
|
VALUE ret;
|
||||||
|
|
||||||
switch (rb_method_boundp(klass, id, pub|BOUND_RESPONDS)) {
|
switch (method_boundp(klass, id, pub|BOUND_RESPONDS)) {
|
||||||
case 2:
|
case 2:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
case 0:
|
case 0:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue