summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--iseq.c2
-rw-r--r--lib/ruby_vm/mjit/hooks.rb4
-rw-r--r--lib/ruby_vm/mjit/invariants.rb35
-rw-r--r--mjit.c34
-rw-r--r--mjit.h2
5 files changed, 55 insertions, 22 deletions
diff --git a/iseq.c b/iseq.c
index 3305edde96..03a7336455 100644
--- a/iseq.c
+++ b/iseq.c
@@ -357,7 +357,7 @@ rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating)
if (reference_updating) {
#if USE_MJIT
- mjit_update_references(iseq);
+ rb_mjit_iseq_update_references(iseq);
#endif
#if USE_YJIT
rb_yjit_iseq_update_references(body->yjit_payload);
diff --git a/lib/ruby_vm/mjit/hooks.rb b/lib/ruby_vm/mjit/hooks.rb
index f3943504fd..477c4e0ae8 100644
--- a/lib/ruby_vm/mjit/hooks.rb
+++ b/lib/ruby_vm/mjit/hooks.rb
@@ -26,5 +26,9 @@ module RubyVM::MJIT
def self.on_tracing_invalidate_all(_new_iseq_events)
Invariants.on_tracing_invalidate_all
end
+
+ def self.on_update_references
+ Invariants.on_update_references
+ end
end
end
diff --git a/lib/ruby_vm/mjit/invariants.rb b/lib/ruby_vm/mjit/invariants.rb
index e68a6e5503..0e8063c0c6 100644
--- a/lib/ruby_vm/mjit/invariants.rb
+++ b/lib/ruby_vm/mjit/invariants.rb
@@ -78,6 +78,28 @@ module RubyVM::MJIT
end
def on_tracing_invalidate_all
+ invalidate_all
+ end
+
+ def on_update_references
+ invalidate_all
+ end
+
+ # @param jit [RubyVM::MJIT::JITState]
+ # @param block [RubyVM::MJIT::Block]
+ def ensure_block_entry_exit(jit, cause:)
+ block = jit.block
+ if block.entry_exit.nil?
+ block.entry_exit = Assembler.new.then do |asm|
+ @exit_compiler.compile_entry_exit(block.pc, block.ctx, asm, cause:)
+ @ocb.write(asm)
+ end
+ end
+ end
+
+ private
+
+ def invalidate_all
# On-Stack Replacement
@patches.each do |address, target|
# TODO: assert patches don't overlap each other
@@ -88,6 +110,7 @@ module RubyVM::MJIT
@cb.write(asm)
end
end
+ @patches.clear
# Avoid reusing past code
Compiler.reset_blocks
@@ -99,18 +122,6 @@ module RubyVM::MJIT
iseq.body.total_calls = 0
end
end
-
- # @param jit [RubyVM::MJIT::JITState]
- # @param block [RubyVM::MJIT::Block]
- def ensure_block_entry_exit(jit, cause:)
- block = jit.block
- if block.entry_exit.nil?
- block.entry_exit = Assembler.new.then do |asm|
- @exit_compiler.compile_entry_exit(block.pc, block.ctx, asm, cause:)
- @ocb.write(asm)
- end
- end
- end
end
end
end
diff --git a/mjit.c b/mjit.c
index de55070c58..c140a5f252 100644
--- a/mjit.c
+++ b/mjit.c
@@ -114,12 +114,6 @@ mjit_cancel_all(const char *reason)
}
void
-mjit_update_references(const rb_iseq_t *iseq)
-{
- // TODO: remove this
-}
-
-void
mjit_free_iseq(const rb_iseq_t *iseq)
{
// TODO: remove this
@@ -348,12 +342,13 @@ mjit_cme_invalidate(void *data)
});
}
+extern int rb_workqueue_register(unsigned flags, rb_postponed_job_func_t func, void *data);
+
void
rb_mjit_cme_invalidate(rb_callable_method_entry_t *cme)
{
if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
// Asynchronously hook the Ruby code since running Ruby in the middle of cme invalidation is dangerous.
- extern int rb_workqueue_register(unsigned flags, rb_postponed_job_func_t func, void *data);
rb_workqueue_register(0, mjit_cme_invalidate, (void *)cme);
}
@@ -389,6 +384,28 @@ rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events)
});
}
+static void
+mjit_iseq_update_references(void *data)
+{
+ if (!mjit_enabled || !mjit_call_p || !rb_mMJITHooks) return;
+ WITH_MJIT_ISOLATED({
+ rb_funcall(rb_mMJITHooks, rb_intern("on_update_references"), 0);
+ });
+}
+
+void
+rb_mjit_iseq_update_references(const rb_iseq_t *iseq)
+{
+ if (!mjit_enabled) return;
+
+ // TODO: update mjit_blocks
+
+ // Asynchronously hook the Ruby code to avoid allocation during GC.compact.
+ // Using _one because it's too slow to invalidate all for each ISEQ. Thus
+ // not giving an ISEQ pointer.
+ rb_postponed_job_register_one(0, mjit_iseq_update_references, NULL);
+}
+
// TODO: Use this in more places
VALUE
rb_mjit_iseq_new(rb_iseq_t *iseq)
@@ -442,10 +459,11 @@ mjit_mark(void)
return;
RUBY_MARK_ENTER("mjit");
- // Mark objects used by the MJIT compiler
+ // Pin object pointers used in this file
rb_gc_mark(rb_MJITCompiler);
rb_gc_mark(rb_cMJITIseqPtr);
rb_gc_mark(rb_cMJITCfpPtr);
+ rb_gc_mark(rb_mMJITHooks);
RUBY_MARK_LEAVE("mjit");
}
diff --git a/mjit.h b/mjit.h
index 3f7719d51d..3b65911009 100644
--- a/mjit.h
+++ b/mjit.h
@@ -106,7 +106,7 @@ extern void mjit_cancel_all(const char *reason);
extern bool mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id);
extern void mjit_init(const struct mjit_options *opts);
extern void mjit_free_iseq(const rb_iseq_t *iseq);
-extern void mjit_update_references(const rb_iseq_t *iseq);
+extern void rb_mjit_iseq_update_references(const rb_iseq_t *iseq);
extern void mjit_mark(void);
extern void mjit_mark_cc_entries(const struct rb_iseq_constant_body *const body);
extern void mjit_notify_waitpid(int exit_code);