Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
あなたとJIT, 今すぐアセンブ ル
Search
monochrome
August 09, 2025
Programming
1k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
あなたとJIT, 今すぐアセンブ ル
Kernel/VM探検隊@東京No18
monochrome
August 09, 2025
More Decks by monochrome
See All by monochrome
RubyKaigi2026: Invariants in my own Ruby
sisshiki1969
0
15
Improving my own Ruby thereafter
sisshiki1969
1
250
Improve my own Ruby
sisshiki1969
1
580
My own Ruby, thereafter
sisshiki1969
0
410
Running Optcarrot (faster) on my own Ruby.
sisshiki1969
1
320
仮想マシンにおけるスタックの管理
sisshiki1969
0
240
Rustでゴミ集め
sisshiki1969
1
380
RustでつくるRubyのFiber
sisshiki1969
0
320
Shinjuku.rs#15 Rustでつくるx86アセンブラ
sisshiki1969
0
1.8k
Other Decks in Programming
See All in Programming
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
830
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
490
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
240
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
170
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
820
SREの積み重ねがAI駆動開発のガードレールになった ― 7つの実践/SRE Guardrails The 7
tomoyakitaura
7
1.2k
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
640
ローカルLLMでどこまでコードが書けるか -縮小版 / How much code can be written on a local LLM Shortened
kishida
2
170
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
380
symfony/aiとlaravel/boost
77web
0
120
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
160
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
2.9k
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
340
58k
Between Models and Reality
mayunak
4
360
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Designing for Timeless Needs
cassininazir
1
270
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
The SEO Collaboration Effect
kristinabergwall1
1
500
How GitHub (no longer) Works
holman
316
150k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
500
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
310
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Un-Boring Meetings
codingconduct
0
330
Transcript
あなたとJITASM, 今すぐアセンブ ル @s_isshiki1969 sisshiki1969 monochrome JIT
アセンブラ is 何 int main() { return 42; } main:
push rbp mov rbp, rsp mov eax, 42 pop rbp ret 55 48 89 e5 b8 2a 00 00 00 5d c3 0f 1f 00 hoge.c hoge.s hoge.o これ アセンブリのテキストファイルを機械語へ変換
ダイナミックアセンブラ • 「実行時に機械語を吐くプログラム」のためのライブラリ • メモリ上に機械語を格納するバッファを確保し、そこへ機械語を生成して いく • 応用例としてはJITコンパイラなど • 例:Xbyak(C++、テンプレート)
DynASM(C、プリプロセッサ) monoasm(Rust、手続きマクロ)
monoasm • https://github.com/sisshiki1969/monoasm • Rustで書かれたx86-64専用ダイナミック・アセンブラ • ①ランタイム ②マクロ定義 で構成 • Rubyの自作JITコンパイラ(monoruby)のために開発 ◦
RubyKaigi 2024, 2025で発表 • mov・四則演算・論理演算・比較・条件分岐・浮動小数点数演算 • SIMD命令群は未対応
手続きマクロ(proc macro) マクロの中身をRustコードへ変換するRustプログラム #[proc_macro] pub fn monoasm(tokens: TokenStream) -> TokenStream
{ let stmts = parse_macro_input!(tokens as inst::Stmts); let base = stmts.base; let mut ts = quote!(let mut jit = #base;); ts.extend(stmts.contents.into_iter().map(compile)); quote!({ #ts }).into() } monoasm!(&mut jit, movq rax, [rdi + rsi * 8 + 16]; ); jit.enc_rexw_mr( &[0x8b], Reg::from(0), Rm::ind( Reg::from(7), Disp::from_disp(16), Scale::S1(3, Reg::from(6)), ), );
コード生成:インタプリタ monoasm! { &mut self.jit, movq r15, (self.dispatch.as_ptr()); movzxb rax,
[r13 + (OPECODE)]; addq r13, 16; jmp [r15 + rax * 8]; }; r13: PC(現在処理中のバイトコードを指す) self.dispatch: ジャンプテーブルの先頭アドレス
コード生成:JITコンパイラ match kind { BinOpK::Add => { let overflow =
self.jit.label(); match mode { OpMode::RR(_, _) => { monoasm!( &mut self.jit, subq R(lhs_r), 1; addq R(lhs_r), R(rhs_r); jo overflow; ); } OpMode::RI(_, i) | OpMode::IR(i, _) => { monoasm!( &mut self.jit, addq R(lhs_r), ((*i as i64) << 1); jo overflow; ); } } self.jit.select_page(1); monoasm!( &mut self.jit, overflow: movq rdi, (Value::symbol("_arith_overflow").id()); jmp deopt; ); self.jit.select_page(0); 複数のコードページを使い分ける
コード生成 match kind { BinOpK::Add => { let overflow =
self.jit.label(); match mode { OpMode::RR(_, _) => { monoasm!( &mut self.jit, subq R(lhs_r), 1; addq R(lhs_r), R(rhs_r); jo overflow; ); } OpMode::RI(_, i) | OpMode::IR(i, _) => { monoasm!( &mut self.jit, addq R(lhs_r), ((*i as i64) << 1); jo overflow; ); } } self.jit.select_page(1); monoasm!( &mut self.jit, overflow: movq rdi, (Value::symbol("_arith_overflow").id()); jmp deopt; ); self.jit.select_page(0); ラベルを定義 ラベルを使用 ラベルを実アドレスにバインド let mask = 0x8000_0000_0000_0000u64 as i64; let imm = self.jit.const_i64(mask); monoasm!( &mut self.jit, xorps xmm(dst), [rip + imm]; ); データ領域にPC相対アクセス ()内にRustの式を書ける
Array#size fn array_size(bb: &mut BBContext, ir: &mut AsmIr, _: &JitContext,
_: &Store, callsite: &CallSiteInfo, _: ClassId) -> bool { if !callsite.is_simple() { return false; } let dst = callsite.dst; ir.inline(move |gen, _, _| { monoasm! { &mut gen.jit, movq rax, [rdi + (RVALUE_OFFSET_ARY_CAPA)]; cmpq rax, (ARRAY_INLINE_CAPA); cmovgtq rax, [rdi + (RVALUE_OFFSET_HEAP_LEN)]; salq rax, 1; orq rax, 1; } }); bb.reg2acc_fixnum(ir, GP::Rax, dst); true }
Array#size monoasm! { &mut gen.jit, movq rax, [rdi + (RVALUE_OFFSET_ARY_CAPA)];
cmpq rax, (ARRAY_INLINE_CAPA); cmovgtq rax, [rdi + (RVALUE_OFFSET_HEAP_LEN)]; salq rax, 1; orq rax, 1; } [0] [1] [2] [3] [4] Capa <= 5 Capa Ptr Capa > 5 [0] [1] [2] ... [Len-1] Array object Array object Capa Len
Math#sqrt fn math_sqrt(bb: &mut BBContext, ir: &mut AsmIr, _: &JitContext,
_: &Store, callsite: &CallSiteInfo, _: ClassId) -> bool { if !callsite.is_simple() { return false; } let CallSiteInfo { args, dst, .. } = *callsite; let deopt = ir.new_deopt(bb); let fsrc = bb.fetch_float_for_xmm(ir, args, deopt).enc(); if let Some(dst) = dst { let fret = bb.xmm_write_enc(dst); ir.inline(move |gen, _, _| { monoasm!( &mut gen.jit, sqrtsd xmm(fret), xmm(fsrc); ); }); } true }
JavaScript from “Building a baseline JIT for Lua automatically”, Blog
of Haoran Xu Maglev
Python • PEP 659 – Specializing Adaptive Interpreter • PEP
744 – JIT Compilation • Copy-and-patch compilation: a fast compilation algorithm for high-level languages and bytecode adaptive interpreter Baseline JIT tier-up deopt Interpreter specialize
Ruby • YJIT (Lazy Basic Block Versioning) • ZJIT •
monoruby (https://github.com/sisshiki1969/monoruby) Interpreter Optimizing JIT tier-up deopt
Optcarrot benchmark (~3000 frame)
目的:機械語を書く 手段:コンパイラを書く あなたとJITASM, 今すぐアセンブ ル