summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-06 07:32:45 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-06 07:32:45 +0000
commitc29c44c4544896cf3e9d0788f52597e1f73dce02 (patch)
treedce9ead37291ade1d8b514c4d9096d08fa0bfdfa /vm_method.c
parenta9497d5a842d762ad7e18a7abe9413581ea44804 (diff)
* vm_method.c (search_method): check omod only once for performance.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37105 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/vm_method.c b/vm_method.c
index e44782ce6d..c5b33caa58 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -394,16 +394,24 @@ copy_refinement_iclass(VALUE iclass, VALUE superclass)
return result;
}
-static rb_method_entry_t*
-search_method(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr)
+static inline int
+lookup_method_table(VALUE klass, ID id, st_data_t *body)
+{
+ st_table *m_tbl = RCLASS_M_TBL(klass);
+ if (!m_tbl) {
+ m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(RBASIC(klass)->klass));
+ }
+ return st_lookup(m_tbl, id, body);
+}
+
+static inline rb_method_entry_t*
+search_method_with_omod(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr)
{
st_data_t body;
VALUE iclass, skipped_class = Qnil;
for (body = 0; klass; klass = RCLASS_SUPER(klass)) {
- st_table *m_tbl;
-
- if (!NIL_P(omod) && klass != skipped_class) {
+ if (klass != skipped_class) {
iclass = rb_hash_lookup(omod, klass);
if (NIL_P(iclass) && BUILTIN_TYPE(klass) == T_ICLASS) {
iclass = rb_hash_lookup(omod, RBASIC(klass)->klass);
@@ -415,11 +423,21 @@ search_method(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr)
klass = iclass;
}
}
- m_tbl = RCLASS_M_TBL(klass);
- if (!m_tbl) {
- m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(RBASIC(klass)->klass));
- }
- if (st_lookup(m_tbl, id, &body)) break;
+ if (lookup_method_table(klass, id, &body)) break;
+ }
+
+ if (defined_class_ptr)
+ *defined_class_ptr = klass;
+ return (rb_method_entry_t *)body;
+}
+
+static inline rb_method_entry_t*
+search_method_without_omod(VALUE klass, ID id, VALUE *defined_class_ptr)
+{
+ st_data_t body;
+
+ for (body = 0; klass; klass = RCLASS_SUPER(klass)) {
+ if (lookup_method_table(klass, id, &body)) break;
}
if (defined_class_ptr)
@@ -427,6 +445,17 @@ search_method(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr)
return (rb_method_entry_t *)body;
}
+static rb_method_entry_t*
+search_method(VALUE klass, ID id, VALUE omod, VALUE *defined_class_ptr)
+{
+ if (NIL_P(omod)) {
+ return search_method_without_omod(klass, id, defined_class_ptr);
+ }
+ else {
+ return search_method_with_omod(klass, id, omod, defined_class_ptr);
+ }
+}
+
/*
* search method entry without the method cache.
*