Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
あなたとJIT, 今すぐアセンブ ル
Search
monochrome
August 09, 2025
Programming
1.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
29
Improving my own Ruby thereafter
sisshiki1969
1
260
Improve my own Ruby
sisshiki1969
1
610
My own Ruby, thereafter
sisshiki1969
0
430
Running Optcarrot (faster) on my own Ruby.
sisshiki1969
1
340
仮想マシンにおけるスタックの管理
sisshiki1969
0
250
Rustでゴミ集め
sisshiki1969
1
390
RustでつくるRubyのFiber
sisshiki1969
0
340
Shinjuku.rs#15 Rustでつくるx86アセンブラ
sisshiki1969
0
1.8k
Other Decks in Programming
See All in Programming
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
420
wkhtmltopdfの次どうするか問題2026
willnet
1
110
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
6
2k
Java 27新機能 / Java 27 new features
kishida
2
140
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
120
Vue Fes Japan 2026 タイムテーブル徹底解説
448jp
1
180
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
240
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
180
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
320
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
7.2k
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
230
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.9k
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1033
470k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
670
Being A Developer After 40
akosma
91
590k
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.1k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
67
58k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
BBQ
matthewcrist
89
10k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
It's Worth the Effort
3n
188
29k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
290
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, 今すぐアセンブ ル