summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2021-01-21 03:33:59 +0900
committerKoichi Sasada <ko1@atdot.net>2021-01-29 16:22:12 +0900
commit1ecda213668644d656eb0d60654737482447dd92 (patch)
tree2231cf25d2215ba1358c21c82e823fcae5203e34 /vm_method.c
parent9241211538189a58b477bd55b539357617fd42ed (diff)
global call-cache cache table for rb_funcall*
rb_funcall* (rb_funcall(), rb_funcallv(), ...) functions invokes Ruby's method with given receiver. Ruby 2.7 introduced inline method cache with static memory area. However, Ruby 3.0 reimplemented the method cache data structures and the inline cache was removed. Without inline cache, rb_funcall* searched methods everytime. Most of cases per-Class Method Cache (pCMC) will be helped but pCMC requires VM-wide locking and it hurts performance on multi-Ractor execution, especially all Ractors calls methods with rb_funcall*. This patch introduced Global Call-Cache Cache Table (gccct) for rb_funcall*. Call-Cache was introduced from Ruby 3.0 to manage method cache entry atomically and gccct enables method-caching without VM-wide locking. This table solves the performance issue on multi-ractor execution. [Bug #17497] Ruby-level method invocation does not use gccct because it has inline-method-cache and the table size is limited. Basically rb_funcall* is not used frequently, so 1023 entries can be enough. We will revisit the table size if it is not enough.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4129
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/vm_method.c b/vm_method.c
index dd00e524eb..0064488db7 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -1196,11 +1196,10 @@ rb_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)
+callable_method_entry_refeinements0(VALUE klass, ID id, VALUE *defined_class_ptr, bool with_refinements,
+ const rb_callable_method_entry_t *cme)
{
- 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 || LIKELY(cme->def->type != VM_METHOD_TYPE_REFINED)) {
return cme;
}
else {
@@ -1210,6 +1209,13 @@ callable_method_entry_refeinements(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);
+ return callable_method_entry_refeinements0(klass, id, defined_class_ptr, with_refinements, cme);
+}
+
MJIT_FUNC_EXPORTED const rb_callable_method_entry_t *
rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
{