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
45
Improving my own Ruby thereafter
sisshiki1969
1
270
Improve my own Ruby
sisshiki1969
1
630
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
느린 네트워크와 저사양 디바이스 사용자를 위한 웹뷰 로딩 시간 개선기
kmkim
0
140
Performance Optimization With LLMs
xleitix
0
230
ChromeでローカルLLM
ryu1013
0
190
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.7k
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
2
250
조합이폭발하는디자인시스템이걸눈으로도테스트하라고요
giljongyu
0
700
Materialが消えた日 〜真っ白なFlutterキャンバスにRenderObjectで絵を描く〜
umigishiaoi
0
140
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
130
AI Augmentation Techniques with Liberty
ivargrimstad
0
280
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
550
No More NoSuchMethodError
exoego
1
120
Inertia Rails: The One-Person Framework with React & Friends
skryukov
0
210
Featured
See All Featured
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
870
How STYLIGHT went responsive
nonsquared
100
6.3k
Done Done
chrislema
187
17k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
5.6k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.5k
Rails Girls Zürich Keynote
gr2m
96
14k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
520
Technical Leadership for Architectural Decision Making
baasie
3
620
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
320
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
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, 今すぐアセンブ ル