mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
YJIT: Set code mem permissions in bulk
Some GC modules, notably MMTk, support parallel GC, i.e. multiple GC threads work in parallel during a GC. Currently, when two GC threads scan two iseq objects simultaneously when YJIT is enabled, both threads will attempt to borrow `CodeBlock::mem_block`, which will result in panic. This commit makes one part of the change. We now set the YJIT code memory to writable in bulk before the reference-updating phase, and reset it to executable in bulk after the reference-updating phase. Previously, YJIT lazily sets memory pages writable while updating object references embedded in JIT-compiled machine code, and sets the memory back to executable by calling `mark_all_executable`. This approach is inherently unfriendly to parallel GC because (1) it borrows `CodeBlock::mem_block`, and (2) it sets the whole `CodeBlock` as executable which races with other GC threads that are updating other iseq objects. It also has performance overhead due to the frequent invocation of system calls. We now set the permission of all the code memory in bulk before and after the reference updating phase. Multiple GC threads can now perform raw memory writes in parallel. We should also see performance improvement during moving GC because of the reduced number of `mprotect` system calls.
This commit is contained in:
parent
e288a86692
commit
51a3ea5ade
7 changed files with 84 additions and 7 deletions
2
yjit.h
2
yjit.h
|
@ -50,6 +50,8 @@ void rb_yjit_show_usage(int help, int highlight, unsigned int width, int columns
|
|||
void rb_yjit_lazy_push_frame(const VALUE *pc);
|
||||
void rb_yjit_invalidate_no_singleton_class(VALUE klass);
|
||||
void rb_yjit_invalidate_ep_is_bp(const rb_iseq_t *iseq);
|
||||
void rb_yjit_mark_all_writeable(void);
|
||||
void rb_yjit_mark_all_executable(void);
|
||||
|
||||
#else
|
||||
// !USE_YJIT
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue