-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New method cache mechanism for Guild and more #2888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| end | ||
|
|
||
| def test_tracks_objspace_count | ||
| return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vm_insnhelper.c
Outdated
| MJIT_FUNC_EXPORTED void | ||
| vm_check_canary(const rb_execution_context_t *ec, VALUE *sp) | ||
| { | ||
| return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| #define RB_DEBUG_COUNTER_INC_UNLESS(type, cond) (!rb_debug_counter_add(RB_DEBUG_COUNTER_##type, 1, !(cond))) | ||
| #define RB_DEBUG_COUNTER_INC_IF(type, cond) rb_debug_counter_add(RB_DEBUG_COUNTER_##type, 1, (cond)) | ||
| #define RB_DEBUG_COUNTER_ADD(type, num) rb_debug_counter_add(RB_DEBUG_COUNTER_##type, (num), 1) | ||
| #define RB_DEBUG_COUNTER_SETMAX(type, num) rb_debug_counter_max(RB_DEBUG_COUNTER_##type, (unsigned int)(num)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we using this somewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now they are not used, but will be used to add not incremental only counters.
For example, SETMAX is used to find maximum length of ccs.
mjit_worker.c
Outdated
| CRITICAL_SECTION_FINISH(3, "in mjit_copy_cache_from_main_thread"); | ||
|
|
||
| job->cc_entries = cc_entries; | ||
| job->cc_entries = (void *)cc_entries; // TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still inevitable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 points.
(1) we need to copy cc_entries for GC. I'll write it in comment. f480167
(2) type mimatch because of const, so it is needed to solve.
| if (BUILTIN_TYPE(m) == T_ICLASS) m = RBASIC(m)->klass; | ||
| rb_module_add_to_subclasses_list(m, iclass); | ||
| if (BUILTIN_TYPE(m) == T_ICLASS) m = RBASIC(m)->klass; | ||
| rb_module_add_to_subclasses_list(m, iclass); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to delete this kind of noisy indent changes before requesting review? Very difficult to read what is important and what isn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry my editor changed it automatically and i missed it. I don't have an idea how to remove this kind of indentation change. any commit option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: adding ?w=1 to the end of URL like https://github.com/ruby/ruby/pull/2888/files?w=1 will hide such diffs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote a script that reverts whitespace only changes and sent you a pull request using it.
| struct rb_call_data *cd = &iseq->body->call_data[i]; | ||
| const struct rb_callinfo *ci = cd->ci; | ||
| const struct rb_callcache *cc = cd->cc; | ||
| if (cc != NULL && cc != vm_cc_empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I ask you why you have to check vm_cc_empty() again here? Is it because the check at TS_CALLDATA branch above miss something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first this code is for verify data structure and disabled at the normal case.
this check is introduced at debugging time and maybe not important. I think we can remove it, but double check can help in future debug (first check and second check represents what call_data should be in different form).
| for (; i > 0; i--) { | ||
| cc->class_serial[i] = cc->class_serial[i - 1]; | ||
| if (cd_owner) { | ||
| RB_OBJ_WRITE(cd_owner, &cd->cc, cc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple guilds can write this field at once, right? I guess that is what you call the "atomicity", and you think that works. Am I correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a guild can consistent CC so there is no problem.
| void | ||
| rb_clear_method_cache_all(void) | ||
| { | ||
| rb_objspace_each_objects(invalidate_all_cc, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it faster to use rb_objspace_each_objects instead of rb_class_foreach_subclass here? I guess this implementation is slower when there are lots of objetcs. Not tested though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't use subclass data structure because we can remove subclasses data structure in future so I use this implementation.
Now it is inefficient implementation, but we can remove it. This function is only used by using and using can employ smarter invalidation I guess. Also using is rarely used method.
4a98ce3 to
b98a947
Compare
Now, rb_call_info contains how to call the method with tuple of (mid, orig_argc, flags, kwarg). Most of cases, kwarg == NULL and mid+argc+flags only requires 64bits. So this patch packed rb_call_info to VALUE (1 word) on such cases. If we can not represent it in VALUE, then use imemo_callinfo which contains conventional callinfo (rb_callinfo, renamed from rb_call_info). iseq->body->ci_kw_size is removed because all of callinfo is VALUE size (packed ci or a pointer to imemo_callinfo). To access ci information, we need to use these functions: vm_ci_mid(ci), _flag(ci), _argc(ci), _kwarg(ci). struct rb_call_info_kw_arg is renamed to rb_callinfo_kwarg. rb_funcallv_with_cc() and rb_method_basic_definition_p_with_cc() is temporary removed because cd->ci should be marked.
This patch contains several ideas:
(1) Disposable inline method cache (IMC) for race-free inline method cache
* Making call-cache (CC) as a RVALUE (GC target object) and allocate new
CC on cache miss.
* This technique allows race-free access from parallel processing
elements like RCU.
(2) Introduce per-Class method cache (pCMC)
* Instead of fixed-size global method cache (GMC), pCMC allows flexible
cache size.
* Caching CCs reduces CC allocation and allow sharing CC's fast-path
between same call-info (CI) call-sites.
(3) Invalidate an inline method cache by invalidating corresponding method
entries (MEs)
* Instead of using class serials, we set "invalidated" flag for method
entry itself to represent cache invalidation.
* Compare with using class serials, the impact of method modification
(add/overwrite/delete) is small.
* Updating class serials invalidate all method caches of the class and
sub-classes.
* Proposed approach only invalidate the method cache of only one ME.
See [Feature #16614] for more details.
Since #2888 this macro is no longer used in any place.
It doesn't do anything since ruby 3.0.0.preview1. It was removed in ruby/ruby#2888
It doesn't do anything since ruby 3.0.0.preview1. It was removed in ruby/ruby#2888
It doesn't do anything since ruby 3.0.0.preview1. It was removed in ruby/ruby#2888
It doesn't do anything since ruby 3.0.0.preview1. It was removed in ruby/ruby#2888
It doesn't do anything since ruby 3.0.0.preview1. It was removed in ruby/ruby#2888
https://bugs.ruby-lang.org/issues/16614 for details.