Qemu.js nrog JIT kev them nyiaj yug: koj tseem tuaj yeem tig lub mince rov qab

Ob peb xyoos dhau los Fabrice Bellard sau los ntawm jslinux yog PC emulator sau hauv JavaScript. Tom qab ntawd muaj tsawg kawg yog ntau dua Virtual x86. Tab sis txhua tus ntawm lawv, raws li kuv paub, yog cov neeg txhais lus, thaum Qemu, sau ntau dhau los ntawm tib lub Fabrice Bellard, thiab, tej zaum, txhua tus neeg hwm tus kheej niaj hnub emulator, siv JIT tso ua ke ntawm cov qhua tuaj rau hauv tus tswv system code. Nws zoo nkaus li rau kuv tias nws yog lub sijhawm los siv cov haujlwm tsis sib xws hauv kev cuam tshuam nrog ib qho uas browsers daws tau: JIT muab tso ua ke ntawm lub tshuab code rau hauv JavaScript, uas nws zoo li feem ntau cov laj thawj rau chaw nres nkoj Qemu. Nws yuav zoo li, vim li cas Qemu, muaj cov yooj yim thiab cov neeg siv-phooj ywg emulators - tib lub VirtualBox, piv txwv li - ntsia thiab ua haujlwm. Tab sis Qemu muaj ob peb yam nthuav

  • qhib qhov chaw
  • muaj peev xwm ua haujlwm yam tsis muaj kernel tsav tsheb
  • muaj peev xwm ua hauj lwm hauv hom neeg txhais lus
  • kev txhawb nqa rau ntau tus tswv tsev thiab qhua architectures

Hais txog lub ntsiab lus thib peb, tam sim no kuv tuaj yeem piav qhia tias qhov tseeb, hauv TCI hom, nws tsis yog tus qhua cov lus qhia lawv tus kheej uas tau txhais, tab sis cov bytecode tau los ntawm lawv, tab sis qhov no tsis hloov lub ntsiab lus - txhawm rau tsim thiab khiav. Qemu ntawm tus qauv tshiab, yog tias koj muaj hmoo, A C compiler txaus - sau lub tshuab hluav taws xob code tuaj yeem ncua sijhawm.

Thiab tam sim no, tom qab ob xyoos ntawm kev lom zem tinkering nrog Qemu qhov chaws hauv kuv lub sijhawm dawb, tus qauv ua haujlwm tau tshwm sim, uas koj tuaj yeem khiav tau, piv txwv li, Kolibri OS.

Emscripten yog dab tsi

Niaj hnub no, ntau tus sau tau tshwm sim, qhov kawg tshwm sim ntawm uas yog JavaScript. Ib txhia, zoo li Type Script, yog Ameslikas tsim los ua txoj hauv kev zoo tshaj plaws los sau rau lub vev xaib. Tib lub sijhawm, Emscripten yog ib txoj hauv kev los nqa C lossis C ++ code uas twb muaj lawm thiab muab tso ua ke rau hauv daim ntawv browser-nyeem tau. Ntawm nplooj ntawv no Peb tau sau ntau qhov chaw nres nkoj ntawm cov kev pab cuam paub zoo: noPiv txwv li, koj tuaj yeem saib PyPy - los ntawm txoj kev, lawv thov tias twb muaj JIT lawm. Qhov tseeb, tsis yog txhua qhov kev pab cuam tuaj yeem muab tso ua ke thiab khiav hauv browser - muaj tus lej nta, uas koj yuav tsum tau muab tso nrog, txawm li cas los xij, raws li cov ntawv sau ntawm tib nplooj ntawv hais tias "Emscripten tuaj yeem siv los sau yuav luag txhua yam portable C / C ++ code rau JavaScript "Qhov ntawd yog, muaj ntau yam kev ua haujlwm uas tsis tau txhais tus cwj pwm raws li tus qauv, tab sis feem ntau ua haujlwm ntawm x86 - piv txwv li, kev nkag mus rau qhov sib txawv tsis sib xws, uas feem ntau txwv tsis pub ntawm qee cov qauv. , Qemu yog qhov kev pab cuam cross-platform thiab , Kuv xav ntseeg, thiab nws tsis tau muaj ntau tus cwj pwm tsis tau hais tseg - coj nws thiab sau, ces tinker me ntsis nrog JIT - thiab koj ua tiav! Tab sis qhov ntawd tsis yog qhov cas...

Ua ntej sim

Feem ntau hais lus, kuv tsis yog thawj tus neeg tuaj nrog lub tswv yim ntawm kev xa Qemu rau JavaScript. Muaj lus nug nug ntawm ReactOS lub rooj sab laj yog tias qhov no tuaj yeem siv Emscripten. Txawm tias ua ntej, muaj lus xaiv tias Fabrice Bellard tau ua qhov no tus kheej, tab sis peb tau tham txog jslinux, uas, raws li kuv paub, tsuas yog kev sim ua kom tau txais kev ua tiav txaus hauv JS, thiab tau sau los ntawm kos. Tom qab ntawd, Virtual x86 tau sau - unobfuscated qhov chaw tau tshaj tawm rau nws, thiab, raws li tau hais, ntau dua "realism" ntawm emulation ua rau nws siv tau SeaBIOS ua firmware. Tsis tas li ntawd, muaj tsawg kawg yog ib qho kev sim chaw nres nkoj Qemu siv Emscripten - Kuv sim ua qhov no qhov (socketpair)., tab sis kev loj hlob, raws li kuv nkag siab, tau khov.

Yog li, nws yuav zoo li, ntawm no yog cov peev txheej, ntawm no yog Emscripten - coj nws thiab sau. Tab sis kuj tseem muaj cov tsev qiv ntawv uas Qemu nyob, thiab cov tsev qiv ntawv uas cov tsev qiv ntawv nyob, thiab lwm yam, thiab ib qho ntawm lawv yog libff, uas glib nyob ntawm. Muaj cov lus xaiv hauv Is Taws Nem tias muaj ib qho ntawm cov chaw khaws ntaub ntawv loj ntawm Emscripten, tab sis nws nyuaj rau ntseeg tias: thawj zaug, nws tsis yog npaj los ua tus sau tshiab, qhov thib ob, nws yog qib qis heev. lub tsev qiv ntawv cia li khaws, thiab sau rau JS. Thiab nws tsis yog ib qho teeb meem ntawm kev sib sau ua ke - tej zaum, yog tias koj ntswj nws, rau qee qhov kev sib tham hu koj tuaj yeem tsim cov lus sib cav tsim nyog ntawm pawg thiab hu rau cov haujlwm yam tsis muaj lawv. Tab sis Emscripten yog ib qho tsis yooj yim: txhawm rau ua kom cov lej tsim tau zoo rau qhov browser JS cav optimizer, qee qhov kev siv dag zog siv. Hauv particular, lub npe hu ua relooping - lub tshuab hluav taws xob code siv qhov tau txais LLVM IR nrog qee cov lus qhia hloov pauv hloov pauv sim ua kom rov tsim dua plausible ifs, loops, thiab lwm yam. Zoo, cov lus sib cav dhau mus ua haujlwm li cas? Lawm, raws li kev sib cav rau JS ua haujlwm, uas yog, yog tias ua tau, tsis yog los ntawm pawg.

Thaum pib muaj ib lub tswv yim los tsuas yog sau ib qho kev hloov rau libffi nrog JS thiab khiav cov qauv xeem, tab sis thaum kawg kuv tau tsis meej pem txog yuav ua li cas ua kuv cov ntaub ntawv header kom lawv ua hauj lwm nrog cov cai uas twb muaj lawm - kuv yuav ua li cas, Raws li lawv hais, "Puas yog cov haujlwm nyuaj heev "Puas yog peb ruam heev?" Kuv yuav tsum tau chaw nres nkoj libffi mus rau lwm lub architecture, yog li hais lus - hmoov zoo, Emscripten muaj ob qho tib si macros rau inline sib dhos (hauv Javascript, yog - zoo, txawm li cas los xij ntawm architecture, yog li lub assembler), thiab muaj peev xwm khiav code generated ntawm ya. Feem ntau, tom qab tinkering nrog platform-dependent libffi fragments rau qee lub sij hawm, kuv tau txais ib co compilable code thiab khiav nws ntawm thawj qhov kev xeem kuv tuaj hla. Ua rau kuv xav tsis thoob, qhov kev xeem tau ua tiav. Stunned los ntawm kuv tus neeg txawj ntse - tsis muaj lus tso dag, nws ua haujlwm los ntawm kev tshaj tawm thawj zaug - Kuv, tseem tsis ntseeg kuv ob lub qhov muag, mus saib cov lej tshwm sim dua, txhawm rau ntsuas qhov twg los khawb tom ntej. Ntawm no kuv tau mus txiv ntseej rau zaum ob - qhov tsuas yog qhov kuv ua haujlwm tau ua ffi_call - qhov no tau tshaj tawm txoj xov zoo. Tsis muaj hu nws tus kheej. Yog li kuv tau xa kuv thawj daim ntawv thov rub tawm, uas tau kho qhov yuam kev hauv qhov kev xeem uas pom tseeb rau txhua tus tub ntxhais kawm Olympiad - tus lej tiag yuav tsum tsis txhob muab piv rau a == b thiab txawm li cas a - b < EPS - koj kuj yuav tsum nco ntsoov lub module, txwv tsis pub 0 yuav tig tawm ntau npaum li cas sib npaug rau 1/3... Feem ntau, kuv tau xaus nrog ib qho chaw nres nkoj ntawm libffi, uas dhau qhov kev sim yooj yim, thiab qhov twg glib yog. compiled - Kuv txiav txim siab nws yuav tsim nyog, kuv mam li ntxiv nws tom qab. Saib ua ntej, kuv yuav hais tias, raws li nws tau muab tawm, lub compiler tsis txawm suav nrog libffi muaj nuj nqi hauv cov lej kawg.

Tab sis, raws li kuv twb tau hais lawm, muaj qee qhov kev txwv, thiab ntawm kev siv dawb ntawm ntau yam kev coj cwj pwm tsis zoo, qhov tsis txaus siab ntau dua tau muab zais - JavaScript los ntawm kev tsim tsis txhawb ntau txoj xov nrog kev nco. Raws li txoj cai, qhov no feem ntau tuaj yeem hu ua lub tswv yim zoo, tab sis tsis yog rau kev xa cov lej uas nws cov architecture tau khi rau C threads. Feem ntau hais lus, Firefox tab tom sim nrog kev txhawb nqa cov neeg ua haujlwm sib koom, thiab Emscripten muaj pthread siv rau lawv, tab sis kuv tsis xav nyob ntawm nws. Kuv yuav tsum maj mam pib tawm ntau txoj xov los ntawm Qemu code - uas yog, nrhiav kom paub qhov twg cov xov tau khiav, txav lub cev ntawm lub voj voog khiav hauv cov xov no rau hauv ib qho kev ua haujlwm sib cais, thiab hu cov haujlwm no los ntawm ib qho los ntawm lub ntsiab voj.

Thib ob sim

Qee lub sij hawm, nws tau pom tseeb tias qhov teeb meem tseem nyob ntawd, thiab qhov uas haphazardly shoving crutches nyob ib ncig ntawm tus lej yuav tsis ua rau muaj qhov zoo. Xaus: peb yuav tsum tau ua qee qhov systematize tus txheej txheem ntawm kev ntxiv crutches. Yog li ntawd, version 2.4.1, uas yog tshiab rau lub sijhawm ntawd, tau coj (tsis yog 2.5.0, vim hais tias, koj yeej tsis paub, yuav muaj kab laum nyob rau hauv lub tshiab version uas tseem tsis tau raug ntes, thiab kuv muaj txaus ntawm kuv tus kheej. kab), thiab thawj qhov uas kuv tau ua yog rov sau nws yam xyuam xim thread-posix.c. Zoo, uas yog, raws li kev nyab xeeb: yog tias ib tug neeg sim ua qhov kev ua haujlwm ua rau kev thaiv, qhov haujlwm tau raug hu tam sim ntawd abort() - tau kawg, qhov no tsis daws tau tag nrho cov teeb meem ib zaug, tab sis tsawg kawg yog qee qhov qab ntxiag dua li ntsiag to tau txais cov ntaub ntawv tsis sib xws.

Feem ntau, Emscripten kev xaiv muaj txiaj ntsig zoo hauv kev xa cov lej rau JS -s ASSERTIONS=1 -s SAFE_HEAP=1 - lawv ntes qee hom kev coj cwj pwm tsis zoo, xws li hu mus rau qhov chaw nyob tsis sib xws (uas tsis yog txhua yam raws li cov cai rau ntaus arrays xws li HEAP32[addr >> 2] = 1) los yog hu rau lub luag haujlwm nrog tus lej tsis raug ntawm kev sib cav.

Los ntawm txoj kev, kev sib raug zoo tsis raug yog ib qho teeb meem cais. Raws li kuv twb tau hais lawm, Qemu muaj qhov "degenerate" txhais lus rov qab rau cov cim cim TCI (tus neeg txhais lus me me), thiab tsim thiab khiav Qemu ntawm cov qauv tshiab, yog tias koj muaj hmoo, C compiler txaus. "yog tias koj muaj hmoo". Kuv tsis muaj hmoo, thiab nws tau muab tawm tias TCI siv qhov tsis sib xws thaum txheeb xyuas nws cov bytecode. Ntawd yog, ntawm txhua yam ntawm ARM thiab lwm yam architectures uas yuav tsum tau nkag mus rau theem, Qemu suav nrog vim tias lawv muaj qhov qub TCG backend uas tsim cov cai haiv neeg, tab sis seb TCI yuav ua haujlwm rau lawv yog lwm lo lus nug. Txawm li cas los xij, raws li nws tau muab tawm, TCI cov ntaub ntawv qhia meej meej qhia qee yam zoo sib xws. Yog li ntawd, kev ua haujlwm hu rau kev nyeem ntawv tsis sib haum tau ntxiv rau cov lej, uas tau pom nyob rau lwm qhov ntawm Qemu.

Kev puas tsuaj loj

Raws li qhov tshwm sim, kev nkag mus tsis raug rau TCI tau raug kho, lub voj tseem ceeb tau tsim uas nyob rau hauv lem hu ua processor, RCU thiab lwm yam me me. Thiab yog li kuv tso Qemu nrog kev xaiv -d exec,in_asm,out_asm, uas txhais tau hais tias koj yuav tsum tau hais tias qhov blocks ntawm code raug tua, thiab tseem thaum lub sijhawm tshaj tawm los sau cov qhua code yog dab tsi, tus tswv code tau los ua (qhov no, bytecode). Nws pib, executes ob peb translation blocks, sau cov lus debugging kuv sab laug tias RCU yuav tam sim no pib thiab ... crashes abort() hauv ib txoj haujlwm free(). Los ntawm tinkering nrog kev ua haujlwm free() Peb tau tswj xyuas kom paub tias nyob rau hauv lub header ntawm lub heap block, uas nyob rau hauv yim bytes ua ntej lub cim xeeb faib, es tsis txhob ntawm lub block loj los yog ib yam dab tsi zoo sib xws, muaj cov khib nyiab.

Kev puas tsuaj ntawm heap - yuav ua li cas ntxim hlub ... Nyob rau hauv cov ntaub ntawv no, muaj ib tug pab tau kev kho mob - los ntawm (yog hais tias ua tau) tib qhov chaw, sib sau ua ke ib haiv neeg binary thiab khiav nws nyob rau hauv Valgrind. Tom qab qee lub sijhawm, binary tau npaj txhij. Kuv tso nws nrog tib cov kev xaiv - nws tsoo txawm tias thaum pib, ua ntej ua tiav. Nws tsis txaus siab, tau kawg - pom meej, cov peev txheej tsis zoo ib yam, uas tsis yog qhov xav tsis thoob, vim tias kev teeb tsa scouted tawm cov kev xaiv sib txawv me ntsis, tab sis kuv muaj Valgrind - ua ntej kuv yuav kho cov kab no, thiab tom qab ntawd, yog tias kuv muaj hmoo. , tus thawj yuav tshwm. Kuv tab tom khiav ib yam nkaus hauv Valgrind... Y-y-y, y-y-y, uh-uh, nws pib, mus los ntawm kev pib ib txwm thiab tsiv mus rau yav dhau los tus kab mob qub yam tsis muaj ib qho lus ceeb toom txog kev nkag tsis raug, tsis hais txog kev poob. Lub neej, raws li lawv hais, tsis tau npaj kuv rau qhov no - qhov kev pab cuam nres nres thaum pib hauv Walgrind. Dab tsi nws yog qhov tsis paub. Kuv qhov kev xav yog tias ib zaug nyob ib puag ncig ntawm cov lus qhia tam sim no tom qab kev sib tsoo thaum pib, gdb tau pom ua haujlwm memset-a nrog tus pointer siv tau los yog mmx, los yog xmm sau npe, ces tej zaum nws yog qee yam kev ua yuam kev, txawm tias nws tseem nyuaj rau ntseeg.

Zoo, Valgrind zoo li tsis pab ntawm no. Thiab ntawm no qhov kev qias neeg tshaj plaws tau pib - txhua yam zoo li txawm pib, tab sis kev sib tsoo rau qhov tsis paub tseeb vim muaj qhov xwm txheej uas tuaj yeem tshwm sim ntau lab cov lus qhia dhau los. Tau ntev, nws tseem tsis tau paub meej tias yuav ua li cas. Thaum kawg, kuv tseem yuav tau zaum thiab debug. Kev luam tawm qhov header tau sau dua tshiab nrog pom tias nws tsis zoo li tus lej, tab sis qee yam ntawm cov ntaub ntawv binary. Thiab, saib seb, txoj hlua binary no tau pom nyob rau hauv cov ntaub ntawv BIOS - uas yog, tam sim no nws muaj peev xwm hais nrog kev ntseeg siab tias nws yog qhov tsis txaus, thiab nws tseem pom tseeb tias nws tau sau rau qhov tsis muaj. Zoo, tom qab ntawd ib yam dab tsi zoo li no - hauv Emscripten, hmoov zoo, tsis muaj qhov sib txawv ntawm qhov chaw nyob, tsis muaj qhov nyob hauv ib qho, yog li koj tuaj yeem sau qhov chaw hauv nruab nrab ntawm cov lej kom tso tawm cov ntaub ntawv los ntawm tus taw tes los ntawm kev tso tawm kawg, saib cov ntaub ntawv, saib tus pointer, thiab , yog tias nws tsis tau hloov, tau txais zaub mov rau kev xav. Muaj tseeb, nws yuav siv li ob peb feeb los txuas tom qab kev hloov pauv, tab sis koj tuaj yeem ua li cas? Raws li qhov tshwm sim, ib txoj kab tshwj xeeb tau pom tias tau theej lub BIOS los ntawm qhov tsis nyob ib ntus rau cov qhua nco - thiab, qhov tseeb, tsis muaj chaw txaus hauv qhov tsis. Nrhiav qhov chaw ntawm qhov chaw nyob txawv txawv ntawd ua rau muaj kev ua haujlwm qemu_anon_ram_alloc hauv cov ntaub ntawv oslib-posix.c - lub logic muaj qhov no: qee zaum nws tuaj yeem muaj txiaj ntsig los kho qhov chaw nyob mus rau nplooj ntawv loj ntawm 2 MB loj, rau qhov no peb yuav nug mmap ua ntej me ntsis ntxiv, thiab tom qab ntawd peb mam li rov qab qhov tshaj nrog kev pab munmap. Thiab yog tias tsis xav tau qhov kev sib tw, ces peb yuav qhia qhov tshwm sim tsis yog 2 MB getpagesize() - mmap nws tseem yuav muab qhov chaw nyob aligned... Yog li hauv Emscripten mmap tsuas hu malloc, tab sis tau kawg nws tsis sib haum rau ntawm nplooj ntawv. Feem ntau, kab laum uas ua rau kuv ntxhov siab rau ob peb lub hlis tau raug kho los ntawm kev hloov pauv hauv nraug kab.

Nta ntawm kev hu ua haujlwm

Thiab tam sim no tus processor yog suav ib yam dab tsi, Qemu tsis poob, tab sis lub vijtsam tsis tig, thiab tus processor sai sai mus rau hauv loops, txiav txim los ntawm cov zis. -d exec,in_asm,out_asm. Ib qho kev xav tau tshwm sim: timer cuam tshuam (lossis, feem ntau, txhua qhov cuam tshuam) tsis tuaj txog. Thiab qhov tseeb, yog tias koj unscrew qhov cuam tshuam los ntawm cov neeg tuaj koom, uas yog vim li cas ua haujlwm, koj tau txais daim duab zoo sib xws. Tab sis qhov no tsis yog lo lus teb tag nrho: kev sib piv ntawm cov cim qhia tawm nrog cov kev xaiv saum toj no qhia tau hais tias kev ua tiav txoj kev sib txawv thaum ntxov. Ntawm no nws yuav tsum tau hais tias kev sib piv ntawm dab tsi tau sau tseg siv lub launcher emrun debugging tso zis nrog cov zis ntawm cov haiv neeg los ua ke tsis yog ib tug tag nrho mechanical txheej txheem. Kuv tsis paub raws nraim li cas qhov kev zov me nyuam khiav hauv qhov browser txuas rau emrun, tab sis qee cov kab nyob rau hauv cov zis tig tawm kom rov kho dua, yog li qhov sib txawv ntawm qhov sib txawv tseem tsis tau muaj qhov laj thawj xav tias cov trajectories tau diverged. Feem ntau, nws tau pom meej tias raws li cov lus qhia ljmpl muaj kev hloov pauv mus rau qhov chaw sib txawv, thiab cov bytecode generated yog qhov sib txawv: ib qho muaj cov lus qhia hu rau tus pab cuam ua haujlwm, lwm qhov tsis yog. Tom qab googling cov lus qhia thiab kawm cov cai uas txhais cov lus qhia no, nws tau pom tseeb tias, ua ntej, tam sim ntawd ua ntej nws nyob rau hauv lub register. cr0 ib qho kev kaw cia - kuj siv tus pab cuam - uas hloov lub processor mus rau hom kev tiv thaiv, thiab qhov thib ob, tias js version yeej tsis hloov mus rau hom kev tiv thaiv. Tab sis qhov tseeb yog tias lwm qhov tshwj xeeb ntawm Emscripten yog nws tsis kam zam cov cai xws li kev siv cov lus qhia. call nyob rau hauv TCI, uas tej function pointer ua rau hom long long f(int arg0, .. int arg9) - kev ua haujlwm yuav tsum raug hu nrog tus lej ntawm cov lus sib cav. Yog tias txoj cai no raug ua txhaum cai, nyob ntawm qhov chaw debugging, qhov kev zov me nyuam yuav poob (uas yog qhov zoo) lossis hu rau qhov ua tsis ncaj ncees lawm (uas yuav tu siab rau kev debug). Kuj tseem muaj qhov kev xaiv thib peb - ​​pab cov tiam ntawm wrappers uas ntxiv / tshem tawm cov lus sib cav, tab sis tag nrho cov wrappers siv ntau qhov chaw, txawm tias qhov tseeb kuv tsuas xav tau me ntsis ntau tshaj li ib puas wrappers. Qhov no ib leeg yog tu siab heev, tab sis muaj dhau los ua ib qho teeb meem loj dua: nyob rau hauv lub generated code ntawm lub wrapper functions, cov kev sib cav tau hloov dua siab tshiab thiab hloov dua siab tshiab, tab sis qee zaus cov hauj lwm nrog cov generated sib cav tsis tau hu ua - zoo, ib yam li nyob rau hauv. kuv libffi siv. Ntawd yog, qee tus neeg pab tsuas tsis raug tua.

Hmoov zoo, Qemu muaj lub tshuab nyeem tau cov npe ntawm cov neeg pab hauv daim ntawv ntawm cov ntaub ntawv header zoo li

DEF_HELPER_0(lock, void)
DEF_HELPER_0(unlock, void)
DEF_HELPER_3(write_eflags, void, env, tl, i32)

Lawv yog siv heev funny: ua ntej, macros raug redefined nyob rau hauv txoj kev txawv tshaj plaw DEF_HELPER_n, thiab ces tig rau helper.h. Raws li qhov uas cov macro tau nthuav dav rau hauv cov qauv pib thiab lub cim cim, thiab tom qab ntawd ib qho array raug txhais, thiab hloov cov ntsiab lus - #include <helper.h> Raws li qhov tshwm sim, thaum kawg kuv tau muaj sijhawm sim ua lub tsev qiv ntawv tom haujlwm pyparsing, thiab ib tsab ntawv tau sau uas tsim cov ntaub ntawv raws nraim rau cov haujlwm uas lawv xav tau.

Thiab yog li ntawd, tom qab ntawd lub processor zoo li ua haujlwm. Nws zoo nkaus li yog vim qhov kev tshuaj ntsuam tsis tau pib, txawm tias memtest86+ tuaj yeem khiav hauv lub rooj sib txoos ib txwm muaj. Ntawm no nws yog qhov tsim nyog los qhia meej tias Qemu thaiv I / O code yog sau rau hauv coroutines. Emscripten muaj nws tus kheej qhov kev siv dag zog heev, tab sis nws tseem xav tau kev txhawb nqa hauv Qemu code, thiab koj tuaj yeem debug tus processor tam sim no: Qemu txhawb kev xaiv -kernel, -initrd, -append, uas koj tuaj yeem khau raj Linux lossis, piv txwv li, memtest86+, tsis tas siv cov khoom siv thaiv txhua. Tab sis ntawm no yog qhov teeb meem: nyob rau hauv haiv neeg sib sau ua ke ib tug tuaj yeem pom Linux ntsiav tso tawm rau lub console nrog kev xaiv -nographic, thiab tsis muaj qhov tso tawm los ntawm browser mus rau lub davhlau ya nyob twg los ntawm qhov chaw nws tau pib emrun, tsis tuaj. Ntawd yog, nws tsis meej: lub processor tsis ua haujlwm lossis cov duab tso tawm tsis ua haujlwm. Thiab ces nws tshwm sim rau kuv tos me ntsis. Nws tau pom tias "tus processor tsis tsaug zog, tab sis tsuas yog blinking qeeb," thiab tom qab li tsib feeb cov ntsiav tau cuam tshuam ntau cov lus mus rau lub console thiab txuas ntxiv mus dai. Nws tau pom tseeb tias tus processor, feem ntau, ua haujlwm, thiab peb yuav tsum tau khawb rau hauv cov cai rau kev ua haujlwm nrog SDL2. Hmoov tsis zoo, kuv tsis paub siv lub tsev qiv ntawv no li cas, yog li hauv qee qhov chaw kuv yuav tsum tau ua ntawm random. Qee lub sij hawm, cov kab sib npaug 0 flashed ntawm qhov screen ntawm xiav keeb kwm yav dhau, uas qhia qee qhov kev xav. Thaum kawg, nws tau pom tias qhov teeb meem yog tias Qemu qhib ntau lub qhov rais virtual hauv ib lub qhov rais lub cev, ntawm qhov koj tuaj yeem hloov siv Ctrl-Alt-n: nws ua haujlwm hauv haiv neeg tsim, tab sis tsis nyob hauv Emscripten. Tom qab tshem tawm cov qhov rais tsis tsim nyog siv cov kev xaiv -monitor none -parallel none -serial none thiab cov lus qhia kom yuam rov qab tag nrho lub vijtsam ntawm txhua tus ncej, txhua yam ua haujlwm sai sai.

Coroutines

Yog li, emulation hauv browser ua haujlwm, tab sis koj tsis tuaj yeem khiav dab tsi nthuav ib leeg-floppy hauv nws, vim tias tsis muaj qhov thaiv I / O - koj yuav tsum siv kev txhawb nqa rau coroutines. Qemu twb muaj ob peb coroutine backends, tab sis vim yog qhov xwm ntawm JavaScript thiab Emscripten code generator, koj tsis tuaj yeem pib juggling pawg. Nws yuav zoo li tias "txhua yam ploj mus, lub plaster raug tshem tawm," tab sis Emscripten developers twb tau saib xyuas txhua yam. Qhov no yog siv tau funny heev: cia peb hu ua haujlwm hu zoo li qhov tsis txaus ntseeg emscripten_sleep thiab ob peb lwm tus siv lub Asyncify mechanism, nrog rau cov pointer hu thiab hu rau txhua qhov haujlwm uas ib qho ntawm ob qho dhau los yuav tshwm sim ntxiv rau hauv pawg. Thiab tam sim no, ua ntej txhua qhov tsis txaus ntseeg hu, peb yuav xaiv cov ntsiab lus async, thiab tam sim ntawd tom qab hu, peb yuav xyuas seb puas muaj kev hu xov tooj asynchronous tshwm sim, thiab yog tias nws muaj, peb yuav txuag txhua qhov hloov pauv hauv zos hauv cov ntsiab lus async no, qhia tias qhov haujlwm twg. hloov kev tswj mus rau thaum peb xav tau kev ua kom tiav, thiab tawm ntawm txoj haujlwm tam sim no. Qhov no yog qhov uas muaj Scope rau kev kawm cov nyhuv kev sib cais - rau qhov xav tau ntawm kev ua lej txuas ntxiv tom qab rov qab los ntawm kev hu xov tooj asynchronous, lub compiler tsim "stubs" ntawm lub luag haujlwm pib tom qab hu xov tooj tsis txaus ntseeg - zoo li qhov no: yog tias muaj n tsis txaus ntseeg hu, tom qab ntawd txoj haujlwm yuav nthuav dav qhov chaw n / 2 lub sij hawm - qhov no tseem yog, yog tias tsis Nco ntsoov tias tom qab txhua qhov muaj peev xwm asynchronous hu, koj yuav tsum tau ntxiv txuag qee qhov hloov pauv hauv zos rau thawj qhov haujlwm. Tom qab ntawd, kuv txawm yuav tsum tau sau ib tsab ntawv yooj yim hauv Python, uas, raws li cov txheej txheem tshwj xeeb uas siv ntau dhau uas xav tias "tsis tso cai rau asynchrony dhau los ntawm lawv tus kheej" (uas yog, pawg nce qib thiab txhua yam uas kuv nyuam qhuav piav qhia tsis yog. ua hauj lwm nyob rau hauv lawv), qhia hu xov tooj los ntawm pointers nyob rau hauv uas functions yuav tsum tau ignored los ntawm lub compiler thiaj li hais tias cov functions no tsis xam asynchronous. Thiab tom qab ntawd JS cov ntaub ntawv qis dua 60 MB yog qhov tseeb ntau dhau - cia peb hais tsawg kawg 30. Txawm hais tias, ib zaug kuv tau teeb tsa cov ntawv sau ua ke, thiab yuam kev cuam tshuam cov kev xaiv sib txuas, cov uas yog -O3. Kuv khiav cov code generated, thiab Chromium noj nco thiab poob. Kuv ces cia li saib nws tab tom sim rub tawm ... Zoo, kuv tuaj yeem hais li cas, Kuv yuav tau khov ib yam nkaus yog tias kuv tau raug nug kom xav txog kev kawm thiab txhim kho 500+ MB Javascript.

Hmoov tsis zoo, cov tshev hauv Asyncify txhawb lub tsev qiv ntawv code tsis yog tus phooj ywg nkaus xwb longjmp-s uas yog siv nyob rau hauv lub virtual processor code, tab sis tom qab ib tug me me thaj uas lov tes taw cov checks thiab quab yuam rov qab cov ntsiab lus raws li yog hais tias txhua yam yog zoo, cov cai ua hauj lwm. Thiab tom qab ntawd ib qho kev coj txawv txawv pib: qee zaum kev txheeb xyuas hauv kev sib koom ua ke tau tshwm sim - tib yam uas cuam tshuam tus lej yog, raws li kev ua tiav logic, nws yuav tsum raug thaiv - ib tug neeg sim mus ntes ib tug twb ntes mutex. Hmoov zoo, qhov no tau ua rau tsis yog qhov teeb meem hauv cov lej cim - Kuv tsuas yog siv cov txheej txheem lub voj tseem ceeb ua haujlwm tau muab los ntawm Emscripten, tab sis qee zaum kev hu asynchronous yuav ua tiav tag nrho cov pawg, thiab lub sijhawm ntawd nws yuav ua tsis tiav. setTimeout los ntawm lub voj tseem ceeb - yog li, cov cai nkag mus rau lub ntsiab voj iteration yam tsis tau tawm hauv qhov kev rov ua dhau los. Rewrote ntawm ib lub voj infinite thiab emscripten_sleep, thiab cov teeb meem nrog mutexes nres. Cov cai tau dhau los ua ntau qhov laj thawj - tom qab tag nrho, qhov tseeb, kuv tsis muaj qee qhov chaws uas npaj cov duab yeeb yaj kiab tom ntej - tus processor tsuas yog xam ib yam dab tsi thiab lub vijtsam hloov kho ib ntus. Txawm li cas los xij, cov teeb meem tsis tau tso tseg: qee zaum Qemu kev tua tsuas yog txiav tawm ntsiag to yam tsis muaj kev zam lossis tsis raug. Lub sijhawm ntawd kuv tau tso tseg rau nws, tab sis, saib ua ntej, kuv yuav hais tias qhov teeb meem yog qhov no: coroutine code, qhov tseeb, tsis siv. setTimeout (los yog tsawg kawg tsis ntau npaum li koj xav): ua haujlwm emscripten_yield tsuas yog teem lub asynchronous hu chij. Tag nrho cov ntsiab lus yog qhov ntawd emscripten_coroutine_next tsis yog ib qho asynchronous muaj nuj nqi: sab hauv nws xyuas tus chij, rov pib dua thiab hloov kev tswj mus rau qhov twg nws xav tau. Ntawd yog, kev nce qib ntawm pawg xaus rau ntawd. Qhov teeb meem yog vim kev siv-tom qab-dawb, uas tshwm sim thaum lub pas dej coroutine tau ua tsis taus vim qhov tseeb tias kuv tsis tau luam ib txoj kab tseem ceeb ntawm cov cai los ntawm cov coroutine backend uas twb muaj lawm, muaj nuj nqi. qemu_in_coroutine rov qab muaj tseeb thaum qhov tseeb nws yuav tsum tau rov qab tsis tseeb. Qhov no coj mus rau hu emscripten_yield, saum toj no uas tsis muaj leej twg nyob hauv pawg emscripten_coroutine_next, pawg unfolded mus rau sab saum toj, tab sis tsis yog setTimeout, raws li kuv twb tau hais lawm, tsis tau nthuav tawm.

JavaScript code tiam

Thiab ntawm no, qhov tseeb, yog cov lus cog tseg "tig cov nqaij minced rov qab." Tsis yog tiag. Tau kawg, yog tias peb khiav Qemu hauv browser, thiab Node.js hauv nws, ces, ib txwm, tom qab tsim cov lej hauv Qemu peb yuav tau txais JavaScript yuam kev. Txawm li cas los xij, qee qhov kev hloov pauv rov qab.

Ua ntej, me ntsis txog yuav ua li cas Qemu ua haujlwm. Thov zam txim rau kuv tam sim no: Kuv tsis yog tus kws tshaj lij Qemu tus tsim tawm thiab kuv cov lus xaus yuav ua yuam kev hauv qee qhov chaw. Raws li lawv hais, "tus tub ntxhais kawm txoj kev xav tsis tas yuav tsum ua raws li tus kws qhia ntawv lub tswv yim, Peano's axiomatics thiab kev nkag siab zoo." Qemu muaj qee qhov kev txhawb nqa qhua architectures thiab rau txhua tus muaj cov npe zoo li target-i386. Thaum lub tsev, koj tuaj yeem hais qhia txog kev txhawb nqa rau ntau tus qhua architectures, tab sis qhov tshwm sim tsuas yog ob peb binaries xwb. Cov cai los txhawb cov qhua architecture, dhau los, tsim qee qhov kev ua haujlwm hauv Qemu, uas TCG (Tiny Code Generator) twb dhau los ua tshuab code rau tus tswv tsev architecture. Raws li tau hais nyob rau hauv cov ntaub ntawv readme nyob rau hauv tcg directory, qhov no yog Ameslikas ib feem ntawm C compiler li niaj zaus, uas tau hloov kho rau JIT. Yog li ntawd, piv txwv li, lub hom phiaj architecture nyob rau hauv cov nqe lus ntawm cov ntaub ntawv no tsis yog ib tug qhua architecture, tab sis ib tug tswv tsev architecture. Qee lub sij hawm, lwm qhov kev tivthaiv tau tshwm sim - Tus Neeg Txhais Lus Me Me (TCI), uas yuav tsum ua tiav cov lej (yuav luag tib yam haujlwm sab hauv) thaum tsis muaj lub tshuab hluav taws xob rau ib tus tswv tsev tshwj xeeb. Qhov tseeb, raws li nws cov ntaub ntawv teev tseg, tus neeg txhais lus no yuav tsis tas ua zoo li JIT code generator, tsis yog tsuas yog qhov ntau ntawm kev ceev, tab sis kuj zoo. Txawm hais tias kuv tsis paub meej tias nws cov lus piav qhia muaj feem cuam tshuam tag nrho.

Thaum xub thawj kuv sim ua kom tiav TCG backend, tab sis sai sai tau tsis meej pem hauv qhov chaws thiab cov lus piav qhia tsis meej tag nrho ntawm cov lus qhia bytecode, yog li kuv txiav txim siab qhwv tus neeg txhais lus TCI. Qhov no tau muab ntau yam zoo:

  • Thaum siv lub tshuab hluav taws xob code, koj tuaj yeem saib tsis yog ntawm cov lus piav qhia, tab sis ntawm tus neeg txhais lus code
  • koj tuaj yeem tsim cov haujlwm tsis yog rau txhua qhov kev txhais lus thaiv tau ntsib, tab sis, piv txwv li, tsuas yog tom qab kev ua tiav ntau pua
  • Yog hais tias tus generated code hloov (thiab qhov no zoo li yuav ua tau, txiav txim los ntawm lub functions nrog cov npe uas muaj cov lo lus thaj), kuv yuav tsum invalidate lub generated JS code, tab sis tsawg kawg kuv yuav muaj ib yam dab tsi los regenerate nws los ntawm.

Hais txog lub ntsiab lus thib peb, kuv tsis paub meej tias patching tuaj yeem ua tau tom qab tus lej raug tua thawj zaug, tab sis thawj ob lub ntsiab lus txaus.

Thaum pib, cov cai tau tsim nyob rau hauv daim ntawv ntawm kev hloov pauv loj ntawm qhov chaw nyob ntawm tus thawj bytecode cov lus qhia, tab sis tom qab ntawd, nco ntsoov tsab xov xwm hais txog Emscripten, optimization ntawm generated JS thiab relooping, kuv txiav txim siab los tsim ntau tus tib neeg code, tshwj xeeb tshaj yog txij thaum empirically nws. muab tawm tias tsuas yog nkag mus rau hauv qhov thaiv kev txhais lus yog nws Pib. Tsis tau sai dua hais tias ua tiav, tom qab ib ntus peb muaj lub tshuab hluav taws xob uas tsim cov cai nrog ifs (txawm tias tsis muaj lub voj voog). Tab sis hmoov tsis zoo, nws poob, muab cov lus hais tias cov lus qhia muaj qee qhov tsis raug. Ntxiv mus, cov lus qhia kawg ntawm qib recursion no yog brcond. Okay, Kuv mam li ntxiv ib qho kev txheeb xyuas zoo ib yam rau tiam ntawm cov lus qhia no ua ntej thiab tom qab hu rov qab thiab ... tsis yog ib qho ntawm lawv raug tua, tab sis tom qab qhov kev lees paub lawv tseem ua tsis tiav. Thaum kawg, tom qab kawm txog cov cai tsim tawm, kuv pom tau tias tom qab qhov hloov pauv, tus taw tes rau cov lus qhia tam sim no tau rov qab los ntawm pawg thiab tej zaum yuav tau sau los ntawm JavaScript code tsim. Thiab yog li ntawd nws muab tawm. Kev nce qhov tsis sib xws ntawm ib megabyte mus rau kaum tsis ua rau muaj dab tsi, thiab nws tau pom tseeb tias lub tshuab hluav taws xob code tau khiav hauv lub voj voog. Peb yuav tsum tau kuaj xyuas tias peb tsis mus dhau ntawm tus ciam teb ntawm tus kab mob TB tam sim no, thiab yog tias peb ua tau, ces muab qhov chaw nyob ntawm tus kab mob TB tom ntej nrog rau lub cim rho tawm kom peb thiaj li ua tiav. Tsis tas li ntawd, qhov no daws qhov teeb meem "uas tsim cov haujlwm yuav tsum tsis raug cai yog tias daim ntawv ntawm bytecode tau hloov pauv?" - Tsuas yog cov haujlwm uas cuam tshuam rau qhov kev txhais lus no yuav tsum tau ua tsis raug. Los ntawm txoj kev, txawm hais tias kuv debugged txhua yam hauv Chromium (vim kuv siv Firefox thiab nws yooj yim dua rau kuv siv lub browser cais rau kev sim), Firefox tau pab kuv kho qhov tsis sib xws nrog asm.js tus qauv, tom qab ntawd cov cai pib ua haujlwm sai dua hauv Chromium.

Piv txwv ntawm generated code

Compiling 0x15b46d0:
CompiledTB[0x015b46d0] = function(stdlib, ffi, heap) {
"use asm";
var HEAP8 = new stdlib.Int8Array(heap);
var HEAP16 = new stdlib.Int16Array(heap);
var HEAP32 = new stdlib.Int32Array(heap);
var HEAPU8 = new stdlib.Uint8Array(heap);
var HEAPU16 = new stdlib.Uint16Array(heap);
var HEAPU32 = new stdlib.Uint32Array(heap);

var dynCall_iiiiiiiiiii = ffi.dynCall_iiiiiiiiiii;
var getTempRet0 = ffi.getTempRet0;
var badAlignment = ffi.badAlignment;
var _i64Add = ffi._i64Add;
var _i64Subtract = ffi._i64Subtract;
var Math_imul = ffi.Math_imul;
var _mul_unsigned_long_long = ffi._mul_unsigned_long_long;
var execute_if_compiled = ffi.execute_if_compiled;
var getThrew = ffi.getThrew;
var abort = ffi.abort;
var qemu_ld_ub = ffi.qemu_ld_ub;
var qemu_ld_leuw = ffi.qemu_ld_leuw;
var qemu_ld_leul = ffi.qemu_ld_leul;
var qemu_ld_beuw = ffi.qemu_ld_beuw;
var qemu_ld_beul = ffi.qemu_ld_beul;
var qemu_ld_beq = ffi.qemu_ld_beq;
var qemu_ld_leq = ffi.qemu_ld_leq;
var qemu_st_b = ffi.qemu_st_b;
var qemu_st_lew = ffi.qemu_st_lew;
var qemu_st_lel = ffi.qemu_st_lel;
var qemu_st_bew = ffi.qemu_st_bew;
var qemu_st_bel = ffi.qemu_st_bel;
var qemu_st_leq = ffi.qemu_st_leq;
var qemu_st_beq = ffi.qemu_st_beq;

function tb_fun(tb_ptr, env, sp_value, depth) {
  tb_ptr = tb_ptr|0;
  env = env|0;
  sp_value = sp_value|0;
  depth = depth|0;
  var u0 = 0, u1 = 0, u2 = 0, u3 = 0, result = 0;
  var r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0;
  var r10 = 0, r11 = 0, r12 = 0, r13 = 0, r14 = 0, r15 = 0, r16 = 0, r17 = 0, r18 = 0, r19 = 0;
  var r20 = 0, r21 = 0, r22 = 0, r23 = 0, r24 = 0, r25 = 0, r26 = 0, r27 = 0, r28 = 0, r29 = 0;
  var r30 = 0, r31 = 0, r41 = 0, r42 = 0, r43 = 0, r44 = 0;
    r14 = env|0;
    r15 = sp_value|0;
  START: do {
    r0 = HEAPU32[((r14 + (-4))|0) >> 2] | 0;
    r42 = 0;
    result = ((r0|0) != (r42|0))|0;
    HEAPU32[1445307] = r0;
    HEAPU32[1445321] = r14;
    if(result|0) {
    HEAPU32[1445322] = r15;
    return 0x0345bf93|0;
    }
    r0 = HEAPU32[((r14 + (16))|0) >> 2] | 0;
    r42 = 8;
    r0 = ((r0|0) - (r42|0))|0;
    HEAPU32[(r14 + (16)) >> 2] = r0;
    r1 = 8;
    HEAPU32[(r14 + (44)) >> 2] = r1;
    r1 = r0|0;
    HEAPU32[(r14 + (40)) >> 2] = r1;
    r42 = 4;
    r0 = ((r0|0) + (r42|0))|0;
    r2 = HEAPU32[((r14 + (24))|0) >> 2] | 0;
    HEAPU32[1445307] = r0;
    HEAPU32[1445308] = r1;
    HEAPU32[1445309] = r2;
    HEAPU32[1445321] = r14;
    HEAPU32[1445322] = r15;
    qemu_st_lel(env|0, r0|0, r2|0, 34, 22759218);
if(getThrew() | 0) abort();
    r0 = 3241038392;
    HEAPU32[1445307] = r0;
    r0 = qemu_ld_leul(env|0, r0|0, 34, 22759233)|0;
if(getThrew() | 0) abort();
    HEAPU32[(r14 + (24)) >> 2] = r0;
    r1 = HEAPU32[((r14 + (12))|0) >> 2] | 0;
    r2 = HEAPU32[((r14 + (40))|0) >> 2] | 0;
    HEAPU32[1445307] = r0;
    HEAPU32[1445308] = r1;
    HEAPU32[1445309] = r2;
    qemu_st_lel(env|0, r2|0, r1|0, 34, 22759265);
if(getThrew() | 0) abort();
    r0 = HEAPU32[((r14 + (24))|0) >> 2] | 0;
    HEAPU32[(r14 + (40)) >> 2] = r0;
    r1 = 24;
    HEAPU32[(r14 + (52)) >> 2] = r1;
    r42 = 0;
    result = ((r0|0) == (r42|0))|0;
    if(result|0) {
    HEAPU32[1445307] = r0;
    HEAPU32[1445308] = r1;
    }
    HEAPU32[1445307] = r0;
    HEAPU32[1445308] = r1;
    return execute_if_compiled(22759392|0, env|0, sp_value|0, depth|0) | 0;
    return execute_if_compiled(23164080|0, env|0, sp_value|0, depth|0) | 0;
    break;
  } while(1); abort(); return 0|0;
}
return {tb_fun: tb_fun};
}(window, CompilerFFI, Module.buffer)["tb_fun"]

xaus

Yog li ntawd, kev ua haujlwm tseem tsis tau tiav, tab sis kuv nkees ntawm kev zais qhov kev tsim kho mus sij hawm ntev no kom ua tiav. Yog li ntawd, kuv txiav txim siab tshaj tawm yam kuv muaj rau tam sim no. Cov cai yog qhov txaus ntshai me ntsis hauv qhov chaw, vim qhov no yog qhov kev sim, thiab nws tsis paub meej ua ntej dab tsi yuav tsum tau ua. Tej zaum, tom qab ntawd nws tsim nyog tshaj tawm cov lus cog tseg ib txwm muaj nyob rau sab saum toj ntawm qee qhov niaj hnub version ntawm Qemu. Nyob rau hauv lub meantime, muaj ib tug xov nyob rau hauv lub Gita nyob rau hauv ib tug blog hom: rau txhua "theem" ​​uas tau tsawg kawg yog ib yam dab tsi dhau lawm, cov ncauj lus kom ntxaws lus nyob rau hauv Lavxias teb sab tau ntxiv. Qhov tseeb, tsab xov xwm no yog rau ntau qhov kev rov hais dua ntawm qhov xaus git log.

Koj tuaj yeem sim nws tag nrho no (ceev faj kev tsheb).

Dab tsi yog ua haujlwm:

  • x86 virtual processor khiav
  • Muaj cov qauv ua haujlwm ntawm JIT code generator los ntawm tshuab code rau JavaScript
  • Muaj cov qauv rau kev sib sau ua ke lwm 32-ntsis qhua architectures: tam sim no koj tuaj yeem qhuas Linux rau MIPS architecture khov hauv qhov browser ntawm lub sijhawm thauj khoom

Koj tuaj yeem ua dab tsi ntxiv

  • Ceev emulation. Txawm tias nyob rau hauv JIT hom nws zoo li khiav qeeb dua Virtual x86 (tab sis muaj peev xwm ua tau tag nrho Qemu nrog ntau cov khoom siv kho vajtse thiab cov qauv tsim)
  • Txhawm rau ua qhov kev sib txuas ib txwm - hais ncaj ncees, Kuv tsis yog tus tsim lub vev xaib zoo, yog li tam sim no kuv tau rov ua tus qauv Emscripten plhaub raws li qhov zoo tshaj plaws uas kuv tuaj yeem ua tau
  • Sim tso ntau txoj haujlwm Qemu - kev sib tham, VM tsiv teb tsaws, thiab lwm yam.
  • Hloov tshiab: koj yuav tsum xa koj ob peb qhov kev txhim kho thiab kab laum cov ntaub ntawv rau Emscripten ntws, raws li yav dhau los porters ntawm Qemu thiab lwm yam dej num tau ua. Ua tsaug rau lawv muaj peev xwm siv tau lawv cov nyiaj pab rau Emscripten ua ib feem ntawm kuv txoj haujlwm.

Tau qhov twg los: www.hab.com

Ntxiv ib saib