のでやってみます。まずビルドだけできる状態にしてみます。
これで実行すると当たり前ですがエラーになります。
# ./miniruby --yjit -e 'p 1'
thread '<unnamed>' panicked at ../yjit/src/codegen.rs:10385:56:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
YJIT: yjit_init() panicked. Aborting.
Aborted
yjit/src/codegen.rs:10385 は gen_leave_exit()
を unwrap しています。
compile_with_regs()
が常に None
を返すようにしているので当然こうなります。
compile_with_regs()
で定型のコードを書き込むようにしてみます。
diff --git a/yjit/src/backend/riscv64/mod.rs b/yjit/src/backend/riscv64/mod.rs
index 763af5d..4c5f01d 100644
--- a/yjit/src/backend/riscv64/mod.rs
+++ b/yjit/src/backend/riscv64/mod.rs
@@ -3,6 +3,8 @@ use crate::asm::riscv64::*;
use crate::codegen::CodePtr;
use crate::backend::ir::*;
+use std::backtrace::Backtrace;
+
// Use the x86 register type for this platform
pub type Reg = Riscv64Reg;
@@ -51,7 +53,17 @@ impl Assembler
}
/// Optimize and compile the stored instructions
- pub fn compile_with_regs(self, _cb: &mut CodeBlock, _ocb: Option<&mut OutlinedCb>, _regs: Vec<Reg>) -> Option<(CodePtr, Vec<u32>)> {
- None
+ pub fn compile_with_regs(self, cb: &mut CodeBlock, _ocb: Option<&mut OutlinedCb>, _regs: Vec<Reg>) -> Option<(CodePtr, Vec<u32>)> {
+ println!("compile_with_regs {}", Backtrace::force_capture());
+ let start_ptr = cb.get_write_ptr();
+ let mut gc_offsets: Vec<u32> = Vec::new();
+ cb.write_bytes(&[
+ 0x93, 0x85, 0x85, 0x03, // addi a1,a1,56
+ 0x0c, 0xe9, // sd a1, 16(a0)
+ // retval = Qnil (a0 is retval, 8 is `nil.object_id`)
+ 0x11, 0x45, // li a0, 8
+ 0x82, 0x80, // ret
+ ]);
+ Some((start_ptr, gc_offsets))
}
}
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 072d96f..9316c4c 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -1324,6 +1324,7 @@ pub fn gen_single_block(
}
// Block compiled successfully
+ println!("Block compiled successfully {:?}", block_start_addr);
Ok(jit.into_block(end_insn_idx, block_start_addr, end_addr, gc_offsets))
}
diff --git a/yjit/src/core.rs b/yjit/src/core.rs
index cd6e649..c914bab 100644
--- a/yjit/src/core.rs
+++ b/yjit/src/core.rs
@@ -28,6 +28,8 @@ use YARVOpnd::*;
use TempMappingKind::*;
use crate::invariants::*;
+use std::backtrace::Backtrace;
+
// Maximum number of temp value types we keep track of
pub const MAX_TEMP_TYPES: usize = 8;
@@ -828,6 +830,7 @@ impl PendingBranch {
// Construct the branch and wire it up in the grpah
fn into_branch(mut self, uninit_block: BlockRef) -> BranchRef {
+ println!("into_branch {:?} {:?} {}", self.start_addr.get(), self.end_addr.get(), Backtrace::force_capture());
// Make the branch
let branch = Branch {
block: uninit_block,
@@ -2703,6 +2706,7 @@ pub type PendingBranchRef = Rc<PendingBranch>;
/// Create a new outgoing branch entry for a block
fn new_pending_branch(jit: &mut JITState, gen_fn: BranchGenFn) -> PendingBranchRef {
+ println!("new_pending_branch {}", Backtrace::force_capture());
let branch = Rc::new(PendingBranch {
uninit_branch: Box::new(MaybeUninit::uninit()),
gen_fn,
diff --git a/yjit/src/virtualmem.rs b/yjit/src/virtualmem.rs
index f3c0cee..46bfaba 100644
--- a/yjit/src/virtualmem.rs
+++ b/yjit/src/virtualmem.rs
@@ -202,6 +202,8 @@ impl<A: Allocator> VirtualMemory<A> {
std::slice::from_raw_parts_mut(mapped_region_end, alloc_size).fill(0x1E);
} else if cfg!(target_arch = "aarch64") {
// In aarch64, all zeros encodes UDF, so it's already what we want.
+ } else if cfg!(target_arch = "riscv64") {
+ // TODO
} else {
unreachable!("unknown arch");
}
ですがうまく行きません。
# ./miniruby --yjit --yjit-call-threshold=2 ../../riscv64.rb
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::codegen::gen_leave_exit
at ./../yjit/src/codegen.rs:922:5
3: yjit::codegen::CodegenGlobals::init
at ./../yjit/src/codegen.rs:10386:31
4: yjit::yjit::yjit_init::{{closure}}
at ./../yjit/src/yjit.rs:51:9
5: std::panicking::try::do_call
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:552:40
6: __rust_try.llvm.13386978148669737369
7: std::panicking::try
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:516:19
8: std::panic::catch_unwind
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panic.rs:142:14
9: yjit::yjit::yjit_init
at ./../yjit/src/yjit.rs:49:18
...
23: _start
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::codegen::gen_leave_exception
at ./../yjit/src/codegen.rs:956:5
3: yjit::codegen::CodegenGlobals::init
at ./../yjit/src/codegen.rs:10387:36
4: yjit::yjit::yjit_init::{{closure}}
at ./../yjit/src/yjit.rs:51:9
5: std::panicking::try::do_call
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:552:40
6: __rust_try.llvm.13386978148669737369
7: std::panicking::try
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:516:19
8: std::panic::catch_unwind
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panic.rs:142:14
9: yjit::yjit::yjit_init
at ./../yjit/src/yjit.rs:49:18
...
23: _start
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::codegen::gen_stub_exit
at ./../yjit/src/codegen.rs:719:5
3: yjit::codegen::CodegenGlobals::init
at ./../yjit/src/codegen.rs:10389:30
4: yjit::yjit::yjit_init::{{closure}}
at ./../yjit/src/yjit.rs:51:9
5: std::panicking::try::do_call
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:552:40
6: __rust_try.llvm.13386978148669737369
7: std::panicking::try
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:516:19
8: std::panic::catch_unwind
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panic.rs:142:14
9: yjit::yjit::yjit_init
at ./../yjit/src/yjit.rs:49:18
...
23: _start
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::core::gen_branch_stub_hit_trampoline
at ./../yjit/src/core.rs:2990:5
3: yjit::codegen::CodegenGlobals::init
at ./../yjit/src/codegen.rs:10391:42
4: yjit::yjit::yjit_init::{{closure}}
at ./../yjit/src/yjit.rs:51:9
5: std::panicking::try::do_call
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:552:40
6: __rust_try.llvm.13386978148669737369
7: std::panicking::try
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:516:19
8: std::panic::catch_unwind
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panic.rs:142:14
9: yjit::yjit::yjit_init
at ./../yjit/src/yjit.rs:49:18
...
23: _start
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::core::gen_entry_stub_hit_trampoline
at ./../yjit/src/core.rs:2642:5
3: yjit::codegen::CodegenGlobals::init
at ./../yjit/src/codegen.rs:10392:41
4: yjit::yjit::yjit_init::{{closure}}
at ./../yjit/src/yjit.rs:51:9
5: std::panicking::try::do_call
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:552:40
6: __rust_try.llvm.13386978148669737369
7: std::panicking::try
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:516:19
8: std::panic::catch_unwind
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panic.rs:142:14
9: yjit::yjit::yjit_init
at ./../yjit/src/yjit.rs:49:18
...
23: _start
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::codegen::gen_full_cfunc_return
at ./../yjit/src/codegen.rs:897:5
3: yjit::codegen::CodegenGlobals::init
at ./../yjit/src/codegen.rs:10395:31
4: yjit::yjit::yjit_init::{{closure}}
at ./../yjit/src/yjit.rs:51:9
5: std::panicking::try::do_call
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:552:40
6: __rust_try.llvm.13386978148669737369
7: std::panicking::try
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:516:19
8: std::panic::catch_unwind
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panic.rs:142:14
9: yjit::yjit::yjit_init
at ./../yjit/src/yjit.rs:49:18
...
23: _start
3
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::codegen::gen_entry_prologue
at ./../yjit/src/codegen.rs:1057:5
3: yjit::core::gen_entry_point
at ./../yjit/src/core.rs:2464:20
4: yjit::yjit::rb_yjit_iseq_gen_entry_point::{{closure}}
at ./../yjit/src/yjit.rs:145:49
5: yjit::stats::with_compile_time
at ./../yjit/src/stats.rs:1014:15
6: rb_yjit_iseq_gen_entry_point
at ./../yjit/src/yjit.rs:145:26
7: rb_yjit_compile_iseq
at ./../yjit.c:1138:25
8: jit_compile
at ./../vm.c:446:17
...
18: _start
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::codegen::gen_outlined_exit
at ./../yjit/src/codegen.rs:801:5
3: yjit::backend::ir::Assembler::get_side_exit
at ./../yjit/src/backend/ir.rs:1144:33
4: yjit::codegen::jit_ensure_block_entry_exit
at ./../yjit/src/codegen.rs:861:26
5: yjit::codegen::JITState::assume_no_ep_escape
at ./../yjit/src/codegen.rs:304:12
6: yjit::codegen::gen_getlocal_generic
at ./../yjit/src/codegen.rs:2296:39
7: yjit::codegen::gen_getlocal_wc0
at ./../yjit/src/codegen.rs:2338:5
8: yjit::codegen::gen_single_block
at ./../yjit/src/codegen.rs:1251:22
9: yjit::core::gen_block_series_body
at ./../yjit/src/core.rs:2349:23
10: yjit::core::gen_block_series
at ./../yjit/src/core.rs:2327:18
11: yjit::core::gen_entry_point
at ./../yjit/src/core.rs:2469:17
12: yjit::yjit::rb_yjit_iseq_gen_entry_point::{{closure}}
at ./../yjit/src/yjit.rs:145:49
13: yjit::stats::with_compile_time
at ./../yjit/src/stats.rs:1014:15
14: rb_yjit_iseq_gen_entry_point
at ./../yjit/src/yjit.rs:145:26
15: rb_yjit_compile_iseq
at ./../yjit.c:1138:25
...
26: _start
new_pending_branch 0: yjit::core::new_pending_branch
at ./../yjit/src/core.rs:2709:39
1: yjit::core::defer_compilation
at ./../yjit/src/core.rs:3142:18
2: yjit::codegen::gen_opt_plus
at ./../yjit/src/codegen.rs:1619:13
3: yjit::codegen::gen_single_block
at ./../yjit/src/codegen.rs:1251:22
4: yjit::core::gen_block_series_body
at ./../yjit/src/core.rs:2349:23
5: yjit::core::gen_block_series
at ./../yjit/src/core.rs:2327:18
6: yjit::core::gen_entry_point
at ./../yjit/src/core.rs:2469:17
7: yjit::yjit::rb_yjit_iseq_gen_entry_point::{{closure}}
at ./../yjit/src/yjit.rs:145:49
8: yjit::stats::with_compile_time
at ./../yjit/src/stats.rs:1014:15
9: rb_yjit_iseq_gen_entry_point
at ./../yjit/src/yjit.rs:145:26
10: rb_yjit_compile_iseq
at ./../yjit.c:1138:25
11: jit_compile
at ./../vm.c:446:17
...
21: _start
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::core::gen_branch_stub
at ./../yjit/src/core.rs:2953:5
3: yjit::core::PendingBranch::set_target
at ./../yjit/src/core.rs:816:25
4: yjit::core::defer_compilation
at ./../yjit/src/core.rs:3150:27
5: yjit::codegen::gen_opt_plus
at ./../yjit/src/codegen.rs:1619:13
6: yjit::codegen::gen_single_block
at ./../yjit/src/codegen.rs:1251:22
7: yjit::core::gen_block_series_body
at ./../yjit/src/core.rs:2349:23
8: yjit::core::gen_block_series
at ./../yjit/src/core.rs:2327:18
9: yjit::core::gen_entry_point
at ./../yjit/src/core.rs:2469:17
10: yjit::yjit::rb_yjit_iseq_gen_entry_point::{{closure}}
at ./../yjit/src/yjit.rs:145:49
11: yjit::stats::with_compile_time
at ./../yjit/src/stats.rs:1014:15
12: rb_yjit_iseq_gen_entry_point
at ./../yjit/src/yjit.rs:145:26
13: rb_yjit_compile_iseq
at ./../yjit.c:1138:25
...
24: _start
compile_with_regs 0: yjit::backend::riscv64::<impl yjit::backend::ir::Assembler>::compile_with_regs
at ./../yjit/src/backend/riscv64/mod.rs:57:42
1: yjit::backend::ir::Assembler::compile
at ./../yjit/src/backend/ir.rs:1572:19
2: yjit::codegen::gen_single_block
at ./../yjit/src/codegen.rs:1313:27
3: yjit::core::gen_block_series_body
at ./../yjit/src/core.rs:2349:23
4: yjit::core::gen_block_series
at ./../yjit/src/core.rs:2327:18
5: yjit::core::gen_entry_point
at ./../yjit/src/core.rs:2469:17
6: yjit::yjit::rb_yjit_iseq_gen_entry_point::{{closure}}
at ./../yjit/src/yjit.rs:145:49
7: yjit::stats::with_compile_time
at ./../yjit/src/stats.rs:1014:15
8: rb_yjit_iseq_gen_entry_point
at ./../yjit/src/yjit.rs:145:26
9: rb_yjit_compile_iseq
at ./../yjit.c:1138:25
...
20: _start
Block compiled successfully CodePtr(10)
into_branch None None 0: yjit::core::PendingBranch::into_branch
at ./../yjit/src/core.rs:833:90
1: yjit::core::<impl yjit::codegen::JITState>::into_block::{{closure}}
at ./../yjit/src/core.rs:1641:17
2: core::iter::adapters::map::map_try_fold::{{closure}}
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/core/src/iter/adapters/map.rs:91:28
...
30: _start
ruby: YJIT has panicked. More info to follow...
thread '<unnamed>' panicked at ../yjit/src/core.rs:837:47:
called `Option::unwrap()` on a `None` value
stack backtrace:
0: rust_begin_unwind
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/std/src/panicking.rs:645:5
1: core::panicking::panic_fmt
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/core/src/panicking.rs:72:14
2: core::panicking::panic
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/core/src/panicking.rs:127:5
3: core::option::Option<T>::unwrap
at /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/core/src/option.rs:931:21
4: yjit::core::PendingBranch::into_branch
5: yjit::core::<impl yjit::codegen::JITState>::into_block::{{closure}}
at ./../yjit/src/core.rs:1641:17
...
34: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
../../riscv64.rb:39: [BUG] YJIT panicked
ruby 3.4.0dev (2024-08-11) +YJIT [riscv64-linux]
-- Control frame information -----------------------------------------------
c:0003 p:0000 s:0014 e:000013 METHOD ../../riscv64.rb:39
c:0002 p:0077 s:0008 E:0004c8 EVAL ../../riscv64.rb:44 [FINISH]
c:0001 p:0000 s:0003 E:000a00 DUMMY [FINISH]
-- Ruby level backtrace information ----------------------------------------
../../riscv64.rb:44:in '<main>'
../../riscv64.rb:39:in 'add'
-- Threading information ---------------------------------------------------
Total ractor count: 1
Ruby thread count for this ractor: 1
-- C level backtrace information -------------------------------------------
...
/work/ruby/build/miniruby(panic+0x2a) [0x400003c5b8] library/core/src/panicking.rs:127
/work/ruby/build/miniruby(0x400035cf66) [0x400035cf66]
/work/ruby/build/miniruby(write<core::ptr::non_null::NonNull<yjit::core::Branch>>+0x0) [0x400037d568] ../yjit/src/core.rs:1641
/work/ruby/build/miniruby({closure#0}<core::ptr::non_null::NonNull<yjit::core::Branch>>) /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/alloc/src/vec/in_place_collect.rs:225
/work/ruby/build/miniruby({closure#0}<alloc::rc::Rc<yjit::core::PendingBranch, alloc::alloc::Global>, core::ptr::non_null::NonNull<yjit::core::Branch>, alloc::vec::in_place_drop::InPlaceDrop<core::ptr::non_null::NonNull<yjit::core::Branch>>, core::result::Result<alloc::vec::in_place_drop::InPlaceDrop<core::ptr::non_null::NonNull<yjit::core::Branch>>, !>, yjit::core::{impl#15}::into_block::{closure_env#0}, alloc::vec::in_place_collect::write_in_place_with_drop::{closure_env#0}<core::ptr::non_null::NonNull<yjit::core::Branch>>>) /build/rustc-Kp6Qwc/rustc-1.75.0+dfsg0ubuntu1/library/core/src/iter/adapters/map.rs:91
...
-- Other runtime information -----------------------------------------------
* Loaded script: ../../riscv64.rb
* Loaded features:
0 enumerator.so
1 thread.rb
2 fiber.so
3 rational.so
4 complex.so
5 ruby2_keywords.rb
* Process memory map:
...
Aborted
#
compile_with_regs()
は複数回呼び出される関数であり想定していた部分と違いそうです。
また、gen_entry_point()
あたりの処理はプラットフォームごとで切り替えるようにはできていないようです。
そのため gen_opt_plus()
などちゃんと用意しないで適当なコードを書き込みする方法がわかりませんでした。
ということで、RJIT のように簡単に処理を上書きするのは難しそうです。 がっつり対応するほどの熱量はないので、このあたりで諦めます。