ãã€ãŠãç§ã¯æ¥œãã¿ã®ããã«æ±ºããŸãã ããã»ã¹ã®å¯éæ§ã蚌æãã ãããŠããã·ã³ã³ãŒããã JavaScript (ããæ£ç¢ºã«ã¯ Asm.js) ãçæããæ¹æ³ãåŠã³ãŸãã QEMU ãå®éšã«éžã°ãããã°ããã㊠Habr ã«é¢ããèšäºãæžãããŸããã ã³ã¡ã³ãã§ã¯ãWebAssembly ã§ãããžã§ã¯ããäœãçŽãããšãããã«ã¯èªåèªèº«ãèŸããããšããã¢ããã€ã¹ãããŸããã ã»ãšãã©çµãã£ã ç§ã¯ã©ãããããããã®ãããžã§ã¯ããæãã§ããŸããã§ãã...äœæ¥ã¯é²è¡ããŠããŸããããéåžžã«ãã£ãããšããŠããŸããããããŠä»ãæè¿ãã®èšäºã«æ²èŒãããŸãã
ã¿ã¹ã¯
QEMU ã JavaScript ã«ãã©ããããããã移æ€ããæ¹æ³ããã§ã«åŠãã§ãããããä»åã¯ãããè³¢æã«å®è¡ããå€ãééããç¹°ãè¿ããªãããšã«ããŸããã
ãšã©ãŒãã® XNUMX: ãã€ã³ã ãªãªãŒã¹ããã®åå²
ç§ã®æåã®ééãã¯ãã¢ããã¹ããªãŒã ã®ããŒãžã§ã³ 2.4.1 ããèªåã®ããŒãžã§ã³ããã©ãŒã¯ããããšã§ããã ãããããããã¯è¯ãã¢ã€ãã¢ã®ããã«æããŸããããã€ã³ã ãªãªãŒã¹ãååšããå Žåãããã¯ããããåçŽãª 2.4 ãããå®å®ããŠããããã©ã³ãã¯ããã«å®å®ããŠããŸãã master
ã ãŸããããªãã®éã®ç¬èªã®ãã°ãè¿œå ããäºå®ã ã£ãã®ã§ãä»ã®äººã®ãã°ã¯ãŸã£ããå¿
èŠãããŸããã§ããã ãããããã®ããã«ãªã£ãã®ã§ãããã ãããåé¡ã¯ãQEMU ã¯ç«ã¡æ¢ãŸã£ãŠããããããæç¹ã§ãçæãããã³ãŒãã 10% æé©åããããšããçºè¡šããããšã§ãã ããã§äœè«ãå¿
èŠã«ãªããŸããQEMU.js ã®ã·ã³ã°ã«ã¹ã¬ããã®æ§è³ªãšãå
ã® QEMU ããã«ãã¹ã¬ããã®äžåšãæå³ãããã®ã§ã¯ãªããšããäºå® (ã€ãŸããè€æ°ã®ç¡é¢ä¿ãªã³ãŒã ãã¹ãåæã«æäœããæ©èœ) ã®ããã§ãã ããã¹ãŠã®ã«ãŒãã«ã䜿çšãããã ãã§ã¯ãããŸãã) ãéèŠã§ãããã¹ã¬ããã®äž»èŠãªæ©èœãå€éšããåŒã³åºããããã«ããå¿
èŠããããŸããã ãã®ãããå䜵äžã«åœç¶ã®åé¡ãããã€ãçºçããŸããã ãã ãããã©ã³ãããã®å€æŽã®äžéšã¯ã master
ã³ãŒããããŒãžããããšããŸããããããããã€ã³ããªãªãŒã¹ (ãããã£ãŠç§ã®ãã©ã³ã) ã§å³éžããããã®ã§ãããããããå©äŸ¿æ§ã¯åäžããªãã£ãã§ãããã
äžè¬çã«ããããã¿ã€ããç Žæ£ããããŒãããšã«å解ããããæ°ãããã®ã«åºã¥ããŠæ°ããããŒãžã§ã³ããŒãããæ§ç¯ããããšãäŸç¶ãšããŠæå³ããããšå€æããŸããã master
.
ééããã® XNUMX: TLP ææ³
æ¬è³ªçã«ãããã¯ééãã§ã¯ãããŸãããäžè¬çã«ããã©ãã«ã©ã®ããã«ç§»åãããïŒããšäžè¬çã«ãããã«å°çã§ãããïŒãã®äž¡æ¹ã«ã€ããŠå®å šã«èª€è§£ãããç¶æ ã§ãããžã§ã¯ããäœæããããšã®ç¹åŸŽã«ãããŸããã ãã®ãããªç¶æ³ã§ã¯ äžåšçšãªããã°ã©ãã³ã° ããã¯æ£åœãªéžæè¢ã§ããããåœç¶ã®ããšãªãããäžå¿ èŠã«ãããç¹°ãè¿ããããããŸããã§ããã ä»åã¯ããããè³¢æã«å®è¡ãããã£ãã®ã§ããã¢ãããã¯ãªã³ããããæèçãªã³ãŒãå€æŽ (ãŠã£ãã¯ã©ãŒãã«ãããšããªãŒãã¹ã»ããŒãã«ãºããã€ãŠèª°ãã«ã€ããŠèšã£ãããã«ããã³ã³ãã€ã«ããããŸã§ (èŠåä»ãã§) ã©ã³ãã ãªæåã䞊ã¹ããããšã¯ããŸããã§ãã) ãªã©ã§ãã
ééããã®XNUMXïŒæµ ç¬ãç¥ããã«æ°Žã«å ¥ã£ãŠããŸã£ã
ç§ã¯ãŸã ãã®åé¡ãå®å šã«åãé€ããããã§ã¯ãããŸããããä»ã§ã¯æµæã®æãå°ãªãéãæ©ãã®ã§ã¯ãªããã倧人ãšããŠããããè¡ãããšã«æ±ºããŸãããã€ãŸããTCG ããã¯ãšã³ãããŒãããäœæããããšã§ããåŸã§ãã¯ããããã¯ãã¡ãããã£ããã§ããããã¹ãŠãå¶åŸ¡ããããšã¯ã§ããŸãããTCI ã¯ãã®ããã«æžãããŠããŸã...ããšèšããªããã°ãªããŸããã ããã«ãããã¯æåã¯æçœãªè§£æ±ºçã®ããã«æããŸããã ãã€ããªã³ãŒããçæããŸãã 圌ããèšãããã«ããã²ã³ã¯éãŸã£ããÑãã¡ãããã³ãŒãã¯ãã€ããªã§ãããå¶åŸ¡ãåçŽã«æž¡ãããšã¯ã§ããŸãããã³ã³ãã€ã«ã®ããã«ãã©ãŠã¶ã«æ瀺çã«ããã·ã¥ããå¿ èŠããããŸãããã®çµæãJS ã¯ãŒã«ãããç¹å®ã®ãªããžã§ã¯ããçæãããŸãããããã«ã¯ãŸã å¿ èŠããããŸããã©ããã«æãããã ãã ããç§ã®ç解ããéããéåžžã® RISC ã¢ãŒããã¯ãã£ã§ã¯ãåçæãããã³ãŒãã®åœä»€ãã£ãã·ã¥ãæ瀺çã«ãªã»ããããå¿ èŠãããã®ãäžè¬çãªç¶æ³ã§ãããããå¿ èŠã§ãªãå Žåã¯ããããã«ãããããã«è¿ãç¶æ ã§ãã ããã«ãååã®è©Šã¿ãããå¶åŸ¡ã¯å€æãããã¯ã®éäžã«ã¯ç§»ãããªãããã§ããããšãããããŸããããã®ããããªãã»ãããã解éããããã€ãã³ãŒãã¯å®éã«ã¯å¿ èŠãªããåã« TB äžã®é¢æ°ãããã€ãã³ãŒããçæããããšãã§ããŸãã ã
圌ãã¯ãã£ãŠæ¥ãŠè¹Žã£ã
XNUMX æã«ã³ãŒãã®æžãçŽããå§ããŸããããéæ³ã®ãããªããã¯ãæ°ã¥ãã¬ãã¡ã«å¿ã³å¯ã£ãŠããŸãããéåžžãGitHub ããã®æçŽã¯ãIssue ã Pull Request ãžã®å¿çã«é¢ããéç¥ãšããŠå±ããŸãããããã§ã¯ã çªç¶ ã¹ã¬ããå
ã§ã®èšå
ããããããã«ãããŸãã
- ã€ã³ã¹ããŒã«ããŸã£ããè¡ããã«æè²çãªãã®ãèµ·åãã
- åã«ãããšããªã³ã¶ãã©ã€ã§ã³ãŒããçæããæš©å©ãæã€å¯äžã®ã¢ããªã±ãŒã·ã§ã³ã¯ JS ãšã³ãžã³ã§ã (ããã¯æ¬åœã§ãã?)
- ãã OS ã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ - XNUMX æã®ãããããŒãå èµãããããçš®é¡ã®ãã¡ãŒã ãŠã§ã¢ãªã©...
ãã©ãŠã¶ã®ã©ã³ã¿ã€ã æ©èœ
ãã§ã«è¿°ã¹ãããã«ãQEMU ã¯ãã«ãã¹ã¬ããã«é¢é£ä»ããããŠããŸããããã©ãŠã¶ãŒã«ã¯ãã«ãã¹ã¬ããããããŸããã ããã§ãã...æåã¯ãŸã£ããååšããŸããã§ãããããã®åŸ WebWorkers ãç»å ŽããŸãããç§ãç解ããŠããéããããã¯ã¡ãã»ãŒãž ããã·ã³ã°ã«åºã¥ãããã«ãã¹ã¬ããã§ãã å
±æå€æ°ãªãã åœç¶ã®ããšãªãããå
±æã¡ã¢ãª ã¢ãã«ã«åºã¥ããŠæ¢åã®ã³ãŒãã移æ€ããå Žåãããã«ããé倧ãªåé¡ãçºçããŸãã ãã®åŸãäžè«ã®å§åãåããŠãããã¯ãŸã次ã®åã®äžã§å®è¡ãããŸããã SharedArrayBuffers
ã ããã¯åŸã
ã«å°å
¥ãããããŸããŸãªãã©ãŠã¶ã§ã®ãªãªãŒã¹ãç¥ãã次ã«æ°å¹Žãç¥ãããããŠã¡ã«ãããŠã³ãç¥ããŸãã... ãã®åŸã圌ãã¯æéã®æž¬å®ãç²ããããç²ãããããšããçµè«ã«éããŸããããå
±æã¡ã¢ãªãšã«ãŠã³ã¿ãŒãã€ã³ã¯ãªã¡ã³ãããã¹ã¬ããããã¹ãŠåãã§ã
XNUMX çªç®ã®ç¹åŸŽã¯ãã¹ã¿ãã¯ã䜿çšããäœã¬ãã«ã®æäœãäžå¯èœã§ããããšã§ããçŸåšã®ã³ã³ããã¹ããåçŽã«ååŸããŠä¿åããæ°ããã¹ã¿ãã¯ã§æ°ããã³ã³ããã¹ãã«åãæ¿ããããšã¯ã§ããŸããã ã³ãŒã« ã¹ã¿ãã¯ã¯ JS ä»®æ³ãã·ã³ã«ãã£ãŠç®¡çãããŸãã 以åã®ãããŒãå®å
šã«æåã§ç®¡çããããšã«ããã®ã«ãäœãåé¡ãªã®ã§ãããã? å®éãQEMU ã®ããã㯠I/O ã¯ã³ã«ãŒãã³ãéããŠå®è£
ãããŠãããããã§äœã¬ãã«ã®ã¹ã¿ãã¯æäœã圹ã«ç«ã¡ãŸãã 幞ããªããšã«ãEmscipten ã«ã¯éåææäœã®ã¡ã«ããºã ããã§ã« XNUMX ã€å«ãŸããŠããŸãã
çŸæç¹ã§ã¯ãã³ãŒãã WASM ã§ã³ã³ãã€ã«ããEmterpreter ã䜿çšããŠè§£éãããã®ã«ãŸã åå²ã§ããŠããªããããããã㯠ããã€ã¹ã¯ãŸã æ©èœããŸãã (次ã®ã·ãªãŒãºã§èª¬æããŸã...)ã ã€ãŸããæçµçã«ã¯æ¬¡ã®ãããªé¢çœãéå±€æ§é ãåŸãããã¯ãã§ãã
- 解éãããããã㯠I/Oã ããã§ããããã€ãã£ãã®ããã©ãŒãã³ã¹ã§ãšãã¥ã¬ãŒãããã NVMe ãæ¬åœã«æåŸ ããŠããŸããã? ð
- éçã«ã³ã³ãã€ã«ãããã¡ã€ã³ QEMU ã³ãŒã (ãã©ã³ã¹ã¬ãŒã¿ãŒãä»ã®ãšãã¥ã¬ãŒããããããã€ã¹ãªã©)
- ã²ã¹ã ã³ãŒããåçã«ã³ã³ãã€ã«ã㊠WASM ã«è¿œå
QEMUãœãŒã¹ã®ç¹åŸŽ
ãããããã§ã«ãæ³åã®ãšãããQEMU ã§ã¯ãã²ã¹ã ã¢ãŒããã¯ãã£ããšãã¥ã¬ãŒãããã³ãŒããšãã¹ã ãã·ã³åœä»€ãçæããã³ãŒããåé¢ãããŠããŸãã å®éã«ã¯ãããã«å°ãè€éã§ãã
- ã²ã¹ãã¢ãŒããã¯ãã£ããããŸã
- ããã å éåšã€ãŸããLinux äžã®ããŒããŠã§ã¢ä»®æ³åçšã® KVM (çžäºã«äºææ§ã®ããã²ã¹ã ã·ã¹ãã ãšãã¹ã ã·ã¹ãã çš)ãã©ãã§ã JIT ã³ãŒãçæçšã® TCG ã§ãã QEMU 2.9 以éãWindows ã§ã® HAXM ããŒããŠã§ã¢ä»®æ³åæšæºã®ãµããŒããç»å ŽããŸãã (
詳现 ) - ããŒããŠã§ã¢ä»®æ³åã§ã¯ãªã TCG ã䜿çšãããŠããå ŽåããŠãããŒãµã« ã€ã³ã¿ããªã¿ã ãã§ãªãããã¹ã ã¢ãŒããã¯ãã£ããšã«åå¥ã®ã³ãŒãçæãµããŒãããããŸãã
- ...ãããŠããããã¹ãŠ - ãšãã¥ã¬ãŒããããåšèŸºæ©åšããŠãŒã¶ãŒ ã€ã³ã¿ãŒãã§ã€ã¹ã移è¡ãèšé²åçãªã©ã
ãšããã§ã次ã®ããšããåç¥ã§ãã: QEMU ã¯ãã³ã³ãã¥ãŒã¿ãŒå šäœã ãã§ãªãããã¹ã ã«ãŒãã«å ã®åå¥ã®ãŠãŒã¶ãŒ ããã»ã¹ã®ããã»ããµãŒããšãã¥ã¬ãŒãã§ããŸããããã¯ãããšãã°ããã€ã㪠ã€ã³ã¹ãã«ã¡ã³ããŒã·ã§ã³çšã® AFL ãã¡ã¶ãŒã«ãã£ãŠäœ¿çšãããŸãã ãããã誰ãã QEMU ã®ãã®åäœã¢ãŒãã JS ã«ç§»æ€ããããšèããŠããã§ãããã? ð
ã»ãšãã©ã®é·å¹Žã«ãããããªãŒ ãœãããŠã§ã¢ãšåæ§ãQEMU ã¯åŒã³åºããéããŠæ§ç¯ãããŸãã configure
О make
ã TCG ããã¯ãšã³ããã¹ã¬ããå®è£
ããã®ä»äœããè¿œå ããããšã«ãããšããŸãã Autoconf ãšéä¿¡ã§ããå¯èœæ§ãèããŠãæ¥ãã§åãã ãæãã£ããããªãã§ãã ãã (å¿
èŠã«å¿ããŠäžç·ãåŒããŠãã ãã) - å®éã configure
QEMU ã¯æããã«èªå·±èšè¿°ãããŠãããäœãããçæããããã®ã§ã¯ãããŸããã
WebAssembly
ã§ã¯ãWebAssembly (å¥å WASM) ãšåŒã°ãããã®ã¯äœã§ãããã? ãã㯠Asm.js ã®ä»£æ¿åã§ãããæå¹ãª JavaScript ã³ãŒããè£
ãããšã¯ãªããªããŸããã ããã©ããããããã¯çŽç²ã«ãã€ããªã§æé©åãããŠãããåã«æŽæ°ãæžã蟌ãã ãã§ãããã»ã©åçŽã§ã¯ãããŸãããã³ã³ãã¯ãã«ããããã«ã次ã®åœ¢åŒã§ä¿åãããŸãã
Asm.js ã®åã«ãŒã ã¢ã«ãŽãªãºã ã«ã€ããŠèããããšããããããããŸãããããã¯ãJS ãšã³ãžã³ãèšèšãããŠãããé«ã¬ãã«ããããŒå¶åŸ¡åœä»€ (ã€ãŸããif-then-elseãã«ãŒããªã©) ã埩å ãããã®ã§ããããã»ããµã«ãã£ãŠå®è¡ããããã·ã³ã³ãŒãã«è¿ããäœã¬ãã«ã® LLVM IRã åœç¶ã®ããšãªãããQEMU ã®äžéè¡šçŸã¯ XNUMX çªç®ã«è¿ããã®ã«ãªããŸãã ãã€ãã³ãŒããèŠãã¿ã®çµãããããã«ããããã«æããŸã...ãããŠãããã¯ãif-then-elseããããŠã«ãŒãããããŸã!.
ããããBinaryen ã圹ç«ã€ãã XNUMX ã€ã®çç±ã§ããBinaryen ã¯ãWASM ã«ä¿åããããã®ã«è¿ãé«ã¬ãã«ã®ãããã¯ãèªç¶ã«åãå ¥ããããšãã§ããŸãã ãã ããåºæ¬ãããã¯ãšãããã®éã®é·ç§»ã®ã°ã©ãããã³ãŒããçæããããšãã§ããŸãã ããŠã䟿å©ãª C/C++ API ã®èåŸã« WebAssembly ã¹ãã¬ãŒãžåœ¢åŒãé èœãããŠããããšã¯ãã§ã«è¿°ã¹ãŸããã
TCG (ã¿ã€ã㌠ã³ãŒã ãžã§ãã¬ãŒã¿ãŒ)
TCG tcg_qemu_tb_exec
ãããã¯ç§ã«ãšã£ãŠéåžžã«äŸ¿å©ã§ããããšãããããŸããã
æ°ãã TCG ããã¯ãšã³ãã QEMU ã«è¿œå ããã«ã¯ããµããã£ã¬ã¯ããªãäœæããå¿
èŠããããŸã tcg/<ÐžÐŒÑ Ð°ÑÑ
ОÑекÑÑÑÑ>
ïŒãã®å Žåã tcg/binaryen
)ãããã«ã¯ XNUMX ã€ã®ãã¡ã€ã«ãå«ãŸããŠããŸãã tcg-target.h
О tcg-target.inc.c
О configure
ã ä»ã®ãã¡ã€ã«ãããã«çœ®ãããšãã§ããŸãããããã XNUMX ã€ã®ååããæšæž¬ã§ããããã«ãäž¡æ¹ãšãã©ããã«ã€ã³ã¯ã«ãŒããããŸããXNUMX ã€ã¯éåžžã®ããã㌠ãã¡ã€ã«ãšã㊠( tcg/tcg.h
ããããŠãã®ãã¡ã€ã«ã¯ãã§ã«ãã£ã¬ã¯ããªå
ã®ä»ã®ãã¡ã€ã«ã«ãããŸã tcg
, accel
ã ãã§ã¯ãããŸãã)ãããäžæ¹ã¯ã³ãŒãã¹ãããããšããŠã®ã¿ tcg/tcg.c
ã§ãããéçé¢æ°ã«ã¢ã¯ã»ã¹ã§ããŸãã
ä»çµã¿ã®è©³çŽ°ãªèª¿æ»ã«æéããããããããšå€æããããã XNUMX ã€ã®ãã¡ã€ã«ã®ãã¹ã±ã«ãã³ããå¥ã®ããã¯ãšã³ãå®è£ ããã³ããŒãããããã©ã€ã»ã³ã¹ ããããŒã«æ£çŽã«ç€ºããŸããã
ãã¡ã€ã« tcg-target.h
äž»ã«ãã©ãŒã ã®èšå®ãå«ãŸããŠããŸã #define
-s:
- ã¿ãŒã²ãã ã¢ãŒããã¯ãã£ã«ã¬ãžã¹ã¿ã®æ°ãšå¹ ã¯ã©ããããããã®ã (å¿ èŠãªã ããããŸããå¿ èŠãªã ããããŸããåé¡ã¯ããå®å šãªã¿ãŒã²ãããã¢ãŒããã¯ãã£ã§ãã©ãŠã¶ã«ãã£ãŠäœãããå¹ççãªã³ãŒãã«çæãããããšããããšã§ã) ...)
- ãã¹ãåœä»€ã®ã¢ã©ã€ã¡ã³ã: x86 ã§ã¯ãããã«ã¯ TCI ã§ããåœä»€ã¯ãŸã£ããã¢ã©ã€ã¡ã³ããããŠããŸããããã³ãŒã ãããã¡ãŒã«ã¯åœä»€ã§ã¯ãªããBinaryen ã©ã€ãã©ãªæ§é ãžã®ãã€ã³ã¿ãå ¥ããã€ãããªã®ã§ã次ã®ããã«ããŸãããã€ã
- ããã¯ãšã³ããçæã§ãããªãã·ã§ã³ã®åœä»€ - Binaryen ã§èŠã€ãã£ããã¹ãŠã®åœä»€ãå«ããã¢ã¯ã»ã©ã¬ãŒã¿ãæ®ããããåçŽãªãã®ã«åå²ããŸãã
- ããã¯ãšã³ãã«ãã£ãŠèŠæ±ããã TLB ãã£ãã·ã¥ã®ããããã®ãµã€ãºã¯ã©ããããã§ããã å®éã®ãšãããQEMU ã§ã¯ãã¹ãŠãæ·±å»ã§ããã²ã¹ã MMU ãèæ ®ããŠããŒã/ã¹ãã¢ãå®è¡ãããã«ããŒé¢æ°ã¯ãããŸãã (ããããªããšã©ããªãã§ãããã?)ããããã¯å€æãã£ãã·ã¥ãæ§é äœã®åœ¢åŒã§ä¿åããŸãããã®åŠçã¯ãããŒããã£ã¹ã ãããã¯ã«çŽæ¥åã蟌ããšäŸ¿å©ã§ãã åé¡ã¯ããã®æ§é å ã®ã©ã®ãªãã»ããããå°ãããŠé«éãªã³ãã³ã ã·ãŒã±ã³ã¹ã«ãã£ãŠæãå¹ççã«åŠçãããããšããããšã§ãã
- ããã§ã¯ãXNUMX ã€ãŸã㯠XNUMX ã€ã®äºçŽæžã¿ã¬ãžã¹ã¿ã®ç®çã埮調æŽããããé¢æ°ãä»ã㊠TB ã®åŒã³åºããæå¹ã«ãããããªãã·ã§ã³ã§ããã€ãã®å°ããªã¬ãžã¹ã¿ãèšè¿°ãããã§ããŸãã
inline
-次ã®ãããªæ©èœflush_icache_range
(ãã ããããã¯ç§ãã¡ã®ã±ãŒã¹ã§ã¯ãããŸãã)
ãã¡ã€ã« tcg-target.inc.c
ãã¡ãããéåžžã¯ãµã€ãºãã¯ããã«å€§ãããããã€ãã®å¿
é é¢æ°ãå«ãŸããŠããŸãã
- ããã«ã¯ãã©ã®åœä»€ãã©ã®ãªãã©ã³ãã§åäœã§ãããã«é¢ããå¶éãå«ãŸããŸãã ç§ãå¥ã®ããã¯ãšã³ãããé²éªšã«ã³ããŒãããã®
- XNUMX ã€ã®å éšãã€ãã³ãŒãåœä»€ãåãé¢æ°
- ããã«è£å©é¢æ°ã眮ãããšãã§ããŸãããéçé¢æ°ã䜿çšããããšãã§ããŸãã
tcg/tcg.c
ç§èªèº«ã¯ã次ã®æŠç¥ãéžæããŸããã次ã®ç¿»èš³ãããã¯ã®æåã®åèªã«ãXNUMX ã€ã®ãã€ã³ã¿ãŒãæžãçããŸãããéå§ããŒã¯ (ä»è¿ã®ç¹å®ã®å€) 0xFFFFFFFF
TB)ãã³ã³ããã¹ããçæãããã¢ãžã¥ãŒã«ãããã³ãããã°çšã®ããžãã¯ãã³ããŒã®çŸåšã®ç¶æ
ã決å®ããŸãã æåã«ããŒã¯ãä»ããããã®ã¯ã 0xFFFFFFFF - n
ã©ã n
- å°ããªæ£ã®æ°ãã€ã³ã¿ãŒããªã¿ãéããŠå®è¡ããããã³ã« 1 ãã€å¢å ããŸãã 0xFFFFFFFE
ãã³ã³ãã€ã«ãè¡ãããã¢ãžã¥ãŒã«ãé¢æ°ããŒãã«ã«ä¿åãããå°ããªãã©ã³ãã£ãŒãã«ã€ã³ããŒããããããããå®è¡ãè¡ãããŸãã tcg_qemu_tb_exec
ãã¢ãžã¥ãŒã«ã¯ QEMU ã¡ã¢ãªããåé€ãããŸããã
å€å žçãªèšèãèšãæããã°ããã¯ã©ãããããã¬ãŒã®å¿ããã®ãµãŠã³ãã«ã©ãã»ã©å·»ã蟌ãã§ããã...ãã ããããã©ããã§èšæ¶ãæŒããŠããŸããã ãããQEMUã§ç®¡çãããŠããã¡ã¢ãªã ã£ãïŒ æ¬¡ã®åœä»€ïŒã€ãŸããã€ã³ã¿ïŒãæžããšãã«ã以åã«ãã®å Žæã«ãªã³ã¯ããã£ãåœä»€ãåé€ããã³ãŒãããããŸããããããã¯åœ¹ã«ç«ã¡ãŸããã§ããã å®éãæãåçŽãªã±ãŒã¹ã§ã¯ãQEMU ã¯èµ·åæã«ã¡ã¢ãªãå²ãåœãŠãçæãããã³ãŒããããã«æžã蟌ã¿ãŸãã ãããã¡ããªããªããšã³ãŒãã¯ç Žæ£ããã代ããã«æ¬¡ã®ã³ãŒããæžãå§ããããŸãã
ã³ãŒããç 究ããåŸãããžã㯠ãã³ããŒã䜿çšããããªãã¯ã«ãããæåã®ãã¹ã§åæåãããŠããªããããã¡ã«ããåé¡ã解æŸããããšã§ããŒãã®ç Žå£ã«å€±æããªãããšãããããŸããã ããããåŸã§ç§ã®é¢æ°ããã€ãã¹ããããã«ãããã¡ãæžãæããã®ã¯èª°ã§ãããã? Emscripten éçºè
ãã¢ããã€ã¹ããããã«ãåé¡ãçºçãããšãã¯ãçµæã®ã³ãŒãããã€ãã£ã ã¢ããªã±ãŒã·ã§ã³ã«ç§»æ€ããŠæ»ããããã« Mozilla Record-Replay ãèšå®ããŸãã... äžè¬ã«ãæçµçã«ã¯åçŽãªããšã«æ°ä»ããŸããããããã¯ããšã«ããã struct TranslationBlock
ãã®èª¬æä»ãã ã©ãã«ãããæšæž¬ããŠãã ãã...ããã§ãããããã¡å
ã®ãããã¯ã®çŽåã§ãã ããã«æ°ã¥ããŠãç§ã¯æŸèæïŒå°ãªããšãäžéšã¯ïŒã䜿ãã®ããããããšã«æ±ºããéæ³ã®æ°åãæšãŠãŠãæ®ãã®èšèã次ã®ããšã«ç§»ããŸããã struct TranslationBlock
ã翻蚳ãã£ãã·ã¥ããªã»ããããããšãã«ããã«åç
§ã§ããåäžãªã³ã¯ã®ãªã¹ããäœæããã¡ã¢ãªã解æŸããŸãã
ããã€ãã®æŸèæã¯æ®ããŸã: ããšãã°ãã³ãŒããããã¡å
ã®ããŒã¯ããããã€ã³ã¿ - ãããã®ããã€ãã¯åã« BinaryenExpressionRef
ã€ãŸããçæãããåºæ¬ãããã¯ã«ç·åœ¢ã«å
¥ããå¿
èŠãããåŒã調ã¹ãŸããäžéšã¯ BB éã®é·ç§»ã®æ¡ä»¶ã§ãããäžéšã¯ã©ãã«è¡ããã§ãã ããŠããªã«ãŒããŒçšã®ãããã¯ã¯ãããããçšæãããŠãããæ¡ä»¶ã«å¿ããŠæ¥ç¶ããå¿
èŠããããŸãã ããããåºå¥ããã«ã¯ããã¹ãŠã®ããããå°ãªããšã XNUMX ãã€ãã§æŽåããŠãããšããåæã䜿çšããããããã©ãã«ã«ã¯æäžäœ XNUMX ããããå®å
šã«äœ¿çšã§ããŸããå¿
èŠã«å¿ããŠå¿ããã«åé€ããå¿
èŠããããŸãã ã¡ãªã¿ã«ããã®ãããªã©ãã«ã¯ãTCG ã«ãŒããçµäºããçç±ã瀺ãããã« QEMU ã§ãã§ã«äœ¿çšãããŠããŸãã
ãã€ããªãšã³ã®äœ¿çš
WebAssembly ã®ã¢ãžã¥ãŒã«ã«ã¯é¢æ°ãå«ãŸããŠãããåé¢æ°ã«ã¯åŒã§ããæ¬äœãå«ãŸããŠããŸãã åŒã¯åé æŒç®ãšäºé æŒç®ãä»ã®åŒã®ãªã¹ãã§æ§æããããããã¯ãå¶åŸ¡ãããŒãªã©ã§ãã ãã§ã«è¿°ã¹ãããã«ãããã§ã®å¶åŸ¡ãããŒã¯ãé«ã¬ãã«ã®åå²ãã«ãŒããé¢æ°åŒã³åºããªã©ãšããŠæ£ç¢ºã«ç·šæãããŠããŸãã é¢æ°ãžã®åŒæ°ã¯ã¹ã¿ãã¯äžã§ã¯ãªããJS ãšåæ§ã«æ瀺çã«æž¡ãããŸãã ã°ããŒãã«å€æ°ããããŸããã䜿ã£ãããšããªãã®ã§å²æããŸãã
é¢æ°ã«ã¯ã32 ããçªå·ãä»ãããããint64 / intXNUMX / float / double åã®ããŒã«ã«å€æ°ããããŸãã ãã®å Žåãæåã® n åã®ããŒã«ã«å€æ°ãé¢æ°ã«æž¡ãããåŒæ°ã§ãã ããã§ã®ãã¹ãŠãå¶åŸ¡ãããŒã®èŠ³ç¹ããå®å šã«äœã¬ãã«ã§ããããã§ã¯ãããŸããããæŽæ°ã«ã¯ãŸã ã笊å·ä»ã/笊å·ãªããå±æ§ãå«ãŸããŠããªãããšã«æ³šæããŠãã ãããæ°å€ãã©ã®ããã«åäœãããã¯ãªãã¬ãŒã·ã§ã³ ã³ãŒãã«ãã£ãŠç°ãªããŸãã
äžè¬çã«èšãã°ãBinaryen ã¯æ¬¡ã®ããšãæäŸããŸãã
ãã ããã€ã³ã¿ããªã¿ ã€ã³ã¹ã¿ã³ã¹ãäžå¿ èŠã«äœæãããåé€ãããããã«ããã®å Žã§ã³ãŒãã解éãããå Žåã¯ããã®ããžãã¯ã C++ ãã¡ã€ã«ã«é 眮ããããããã©ã€ãã©ãªã® C++ API å šäœãçŽæ¥ç®¡çããready-ã©ãããŒãäœããŸããã
ãããã£ãŠãå¿ èŠãªã³ãŒããçæããã«ã¯
// МаÑÑÑПОÑÑ Ð³Ð»ÐŸÐ±Ð°Ð»ÑÐœÑе паÑаЌеÑÑÑ (ЌПжМП пПЌеМÑÑÑ Ð¿ÐŸÑПЌ)
BinaryenSetAPITracing(0);
BinaryenSetOptimizeLevel(3);
BinaryenSetShrinkLevel(2);
// ÑПзЎаÑÑ ÐŒÐŸÐŽÑлÑ
BinaryenModuleRef MODULE = BinaryenModuleCreate();
// ПпОÑаÑÑ ÑÐžÐ¿Ñ ÑÑМкÑОй (как ÑПзЎаваеЌÑÑ
, Ñак О вÑзÑваеЌÑÑ
)
helper_type BinaryenAddFunctionType(MODULE, "helper-func", BinaryenTypeInt32(), int32_helper_args, ARRAY_SIZE(int32_helper_args));
// (int23_helper_args пÑОПб^WÑПзЎаÑÑÑÑ ÐŸÑЎелÑМП)
// ÑкПМÑÑÑÑОÑПваÑÑ ÑÑпеÑ-Ќега вÑÑажеМОе
// ... ÐœÑ ÑÑÑ Ñж Ð²Ñ ÐºÐ°Ðº-МОбÑÐŽÑ ÑаЌО :)
// пПÑПЌ ÑПзЎаÑÑ ÑÑМкÑОÑ
BinaryenAddFunction(MODULE, "tb_fun", tb_func_type, func_locals, FUNC_LOCALS_COUNT, expr);
BinaryenAddFunctionExport(MODULE, "tb_fun", "tb_fun");
...
BinaryenSetMemory(MODULE, (1 << 15) - 1, -1, NULL, NULL, NULL, NULL, NULL, 0, 0);
BinaryenAddMemoryImport(MODULE, NULL, "env", "memory", 0);
BinaryenAddTableImport(MODULE, NULL, "env", "tb_funcs");
// запÑПÑОÑÑ Ð²Ð°Ð»ÐžÐŽÐ°ÑÐžÑ Ðž ПпÑОЌОзаÑÐžÑ Ð¿ÑО желаМОО
assert (BinaryenModuleValidate(MODULE));
BinaryenModuleOptimize(MODULE);
...äœããå¿ããŠããå Žåã¯ãç³ãèš³ãããŸããããããã¯ã¹ã±ãŒã«ãè¡šãããã®ãã®ã§ããã詳现ã¯ããã¥ã¡ã³ãã«èšèŒãããŠããŸãã
ãããŠä»ã次ã®ãããªã¯ã©ãã¯ãã§ãã¯ã¹ããã¯ã¹ãå§ãŸããŸã:
static char buf[1 << 20];
BinaryenModuleOptimize(MODULE);
BinaryenSetMemory(MODULE, 0, -1, NULL, NULL, NULL, NULL, NULL, 0, 0);
int sz = BinaryenModuleWrite(MODULE, buf, sizeof(buf));
BinaryenModuleDispose(MODULE);
EM_ASM({
var module = new WebAssembly.Module(new Uint8Array(wasmMemory.buffer, $0, $1));
var fptr = $2;
var instance = new WebAssembly.Instance(module, {
'env': {
'memory': wasmMemory,
// ...
}
);
// О Ð²ÐŸÑ Ñже Ñ Ð²Ð°Ñ ÐµÑÑÑ instance!
}, buf, sz);
QEMU ãš JS ã®äžçãäœããã®æ¹æ³ã§æ¥ç¶ããåæã«ã³ã³ãã€ã«ãããé¢æ°ã«ãã°ããã¢ã¯ã»ã¹ããããã«ãé
å (ã©ã³ãã£ãŒã«ã€ã³ããŒãããããã®é¢æ°ã®ããŒãã«) ãäœæãããçæãããé¢æ°ãããã«é
眮ãããŸããã ã€ã³ããã¯ã¹ãè¿
éã«èšç®ããããã«ãæåã¯ãŒãåèªç¿»èš³ãããã¯ã®ã€ã³ããã¯ã¹ãã€ã³ããã¯ã¹ãšããŠäœ¿çšãããŸãããããã®åŸããã®åŒã䜿çšããŠèšç®ãããã€ã³ããã¯ã¹ãåçŽã«ãã£ãŒã«ãã«é©åãå§ããŸããã struct TranslationBlock
.
ãšããã§ã
ããã¯ä»ã®ãšãããã¹ãŠã§ãã èå³ã®ãã人ããããå¥ã®èšäºããããããããŸããã ã€ãŸããå°ãªããšãæ®ããŸãã ãã ãããã¯ããã€ã¹ãåäœãããŸãã ãŸããJS ã®äžçã§ã¯æ £äŸãšãªã£ãŠããããã«ãWebAssembly ã¢ãžã¥ãŒã«ã®ã³ã³ãã€ã«ãéåæã«ããããšãæå³ããããããããŸãããããã¯ããã€ãã£ã ã¢ãžã¥ãŒã«ã®æºåãã§ãããŸã§ããããã¹ãŠãå®è¡ã§ããã€ã³ã¿ããªã¿ãäŸç¶ãšããŠååšããããã§ãã
æåŸã«ãªããªã: 32 ããã ã¢ãŒããã¯ãã£ã§ãã€ããªãã³ã³ãã€ã«ããŸããããã³ãŒãã¯ã¡ã¢ãªæäœãéã㊠Binaryen ããã¹ã¿ãã¯äžã®ã©ããããŸã㯠2 ããã ã¢ãã¬ã¹ç©ºéã®äžäœ 32 GB ã®ã©ããã«ç§»åããŸãã åé¡ã¯ãBinaryen ã®èŠ³ç¹ãããããšãçµæãšããŠåŸãããã¢ãã¬ã¹ã倧ããããããšã«ãªããŸãã ãããåé¿ããã«ã¯ã©ãããã°ããã§ãããã?
管çè ã®ããæ¹ã§
çµå±ããããã¹ãããããšã¯ã§ããŸããã§ããããæåã«èããã®ã¯ã32 ããã Linux ãã€ã³ã¹ããŒã«ãããã©ããªãã ãã?ããšããããšã§ããã ãã®åŸãã¢ãã¬ã¹ç©ºéã®äžéšã¯ã«ãŒãã«ã«ãã£ãŠå æãããŸãã å¯äžã®åé¡ã¯ãã©ã®ãããã®éãå æããããã§ãã1 GB ãŸã㯠2 GB ã§ãã
ããã°ã©ããŒã®ããæ¹ (å®åè åãã®ãªãã·ã§ã³)
ã¢ãã¬ã¹ç©ºéã®äžéšã«æ³¡ãå¹ããŸãããã ç§èªèº«ããªããããæ©èœããã®ãç解ã§ããŸãã - ãã㧠ãã§ã« ã¹ã¿ãã¯ãããã¯ãã§ãã ãããããç§ãã¡ã¯å®è·µè ã§ãããã¹ãŠãããŸããããŸããããã®çç±ã¯èª°ãç¥ããŸãã...ã
// 2gbubble.c
// Usage: LD_PRELOAD=2gbubble.so <program>
#include <sys/mman.h>
#include <assert.h>
void __attribute__((constructor)) constr(void)
{
assert(MAP_FAILED != mmap(1u >> 31, (1u >> 31) - (1u >> 20), PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
}
...Valgrind ãšäºææ§ããªãã®ã¯äºå®ã§ããã幞ããªããšã«ãValgrind èªäœã¯éåžžã«å¹æçã«å šå¡ãããããè¿œãåºããŸã :)
ãããã誰ãããç§ã®ãã®ã³ãŒããã©ã®ããã«æ©èœãããã«ã€ããŠãã£ãšè©³ãã説æããŠãããã§ããã...
åºæïŒ habr.com