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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
34
Improving my own Ruby thereafter
sisshiki1969
1
270
Improve my own Ruby
sisshiki1969
1
620
My own Ruby, thereafter
sisshiki1969
0
430
Running Optcarrot (faster) on my own Ruby.
sisshiki1969
1
350
仮想マシンにおけるスタックの管理
sisshiki1969
0
260
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
Verilogで学ぶCPU自作入門
uyuki234
8
4.1k
SREの越境 / SRE Collaboration
y0hgi
2
300
Java 27新機能 / Java 27 new features
kishida
2
220
Jetpack Compose Mechanisms
skydoves
2
710
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
460
パスワード再設定メールのURLについて知っておこう
uyuki234
0
130
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
200
Kubernetes祭り #2 OP/ED
bells17
0
110
wkhtmltopdfの次どうするか問題2026
willnet
2
1.9k
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
110
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.6k
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
360
Featured
See All Featured
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.3k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
980
Navigating Weather and Climate Data
rabernat
0
550
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
Evolving SEO for Evolving Search Engines
ryanjones
0
320
The Cult of Friendly URLs
andyhume
79
7k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
880
Leo the Paperboy
mayatellez
10
2.4k
The untapped power of vector embeddings
frankvandijk
2
1.9k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
Docker and Python
trallard
47
4.2k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
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, 今すぐアセンブ ル