Qemu.js ndi thandizo la JIT: mutha kutembenuza mince kumbuyo

Zaka zingapo zapitazo Fabrice Bellard yolembedwa ndi jslinux ndi emulator ya PC yolembedwa mu JavaScript. Pambuyo pake panali zinanso Pafupifupi x86. Koma onsewa, monga momwe ndikudziwira, anali otanthauzira, pamene Qemu, yolembedwa kale kwambiri ndi Fabrice Bellard yemweyo, ndipo, mwinamwake, aliyense wodzilemekeza wodzilemekeza wamakono, amagwiritsa ntchito JIT kuphatikiza kachidindo ka alendo kukhala code code system host. Zinkawoneka kwa ine kuti inali nthawi yoti ndigwiritse ntchito ntchito yosiyana ndi yomwe asakatuli amathetsa: JIT kuphatikiza makina amakina mu JavaScript, yomwe inkawoneka yomveka bwino ku doko la Qemu. Zingawonekere, chifukwa chiyani Qemu, pali emulators osavuta komanso osavuta kugwiritsa ntchito - VirtualBox yomweyo, mwachitsanzo - yoyikidwa ndikugwira ntchito. Koma Qemu ili ndi zinthu zingapo zosangalatsa

  • gwero lotseguka
  • kuthekera kugwira ntchito popanda woyendetsa kernel
  • luso logwira ntchito munjira yomasulira
  • kuthandizira pazambiri zomanga zonse zokhala ndi alendo komanso alendo

Ponena za mfundo yachitatu, tsopano nditha kufotokoza kuti kwenikweni, mu TCI mode, si malangizo a makina a alendo omwe amamasuliridwa okha, koma bytecode yomwe imachokera kwa iwo, koma izi sizisintha kwenikweni - kuti amange ndi kuyendetsa. Qemu pa zomangamanga zatsopano, ngati muli ndi mwayi, A C compiler ndi yokwanira - kulemba code generator ikhoza kuimitsidwa.

Ndipo tsopano, patatha zaka ziwiri ndikusewera momasuka ndi Qemu source code mu nthawi yanga yaulere, chithunzi chogwira ntchito chidawonekera, momwe mutha kuthamanga kale, mwachitsanzo, Kolibri OS.

Kodi Emscripten ndi chiyani

Masiku ano, opanga ambiri adawonekera, zomwe pamapeto pake ndi JavaScript. Zina, monga Type Script, zidapangidwa kuti zikhale njira yabwino kwambiri yolembera pa intaneti. Nthawi yomweyo, Emscripten ndi njira yotengera kachidindo ka C kapena C ++ yomwe ilipo ndikuiphatikiza mu mawonekedwe owerengeka osatsegula. Yambani tsamba ili Tasonkhanitsa madoko ambiri a mapulogalamu odziwika bwino: apaMwachitsanzo, mutha kuyang'ana PyPy - mwa njira, amati ali ndi JIT kale. M'malo mwake, si pulogalamu iliyonse yomwe imatha kupangidwa ndikuyendetsedwa mu msakatuli - pali nambala Mawonekedwe, zomwe muyenera kupirira, komabe, monga zolembedwa patsamba lomwelo zimati "Emscripten itha kugwiritsidwa ntchito kuphatikiza pafupifupi chilichonse. kunyamulika C/C++ code to JavaScript". Ndiko kuti, pali ntchito zingapo zomwe sizimazindikirika molingana ndi muyezo, koma nthawi zambiri zimagwira ntchito pa x86 - mwachitsanzo, mwayi wosagwirizana ndi zosintha, zomwe zimaletsedwa pazomanga zina. , Qemu ndi pulogalamu yodutsa nsanja ndipo, ndimafuna kukhulupirira, ndipo ilibe zambiri zamakhalidwe osadziwikiratu - tengerani ndikuphatikiza, kenako lingalirani pang'ono ndi JIT - ndipo mwamaliza! mlandu...

Yesani choyamba

Nthawi zambiri, sindine munthu woyamba kubwera ndi lingaliro la kutumiza Qemu ku JavaScript. Panali funso lomwe linafunsidwa pabwalo la ReactOS ngati izi zinali zotheka pogwiritsa ntchito Emscripten. Ngakhale m'mbuyomu, panali mphekesera kuti Fabrice Bellard anachita izi payekha, koma tinali kulankhula za jslinux, zomwe, monga momwe ndikudziwira, ndikungoyesera kukwaniritsa ntchito zokwanira mu JS, ndipo zinalembedwa kuyambira pachiyambi. Pambuyo pake, Virtual x86 idalembedwa - magwero osadziwika adayikidwa, ndipo, monga tafotokozera, "zenizeni" zazikuluzikulu zotsatsira zidapangitsa kuti agwiritse ntchito SeaBIOS ngati firmware. Kuphatikiza apo, panali kuyesa kamodzi kunyamula Qemu pogwiritsa ntchito Emscripten - ndidayesa kuchita izi socketpair, koma chitukuko, monga momwe ndikumvera, chinali chozizira.

Chifukwa chake, zitha kuwoneka, awa ndi magwero, apa pali Emscripten - tengani ndikuphatikiza. Koma palinso malaibulale omwe Qemu amadalira, ndi malaibulale omwe amadalira malaibulale amenewo, ndi zina zotero, ndipo imodzi mwa izo ndi libfi, zomwe glib zimadalira. Panali mphekesera pa intaneti kuti panali imodzi m'gulu lalikulu la malaibulale a Emscripten, koma zinali zovuta kukhulupirira: choyamba, sichinapangidwe kuti chikhale chojambula chatsopano, chachiwiri, chinali chochepa kwambiri. library kuti mungotenga, ndikuphatikiza ku JS. Ndipo si nkhani yongoyikapo pagulu - mwina, ngati mungaipotoze, pamayitanidwe ena oyitanitsa mutha kupanga mikangano yofunikira pamtengo ndikuyitanitsa ntchitoyi popanda iwo. Koma Emscripten ndichinthu chopusitsa: kuti kachidindo kopangidwa kuti kawoneke kodziwika bwino kwa asakatuli a JS injini optimizer, zidule zina zimagwiritsidwa ntchito. Makamaka, zomwe zimatchedwa relooping - jenereta yogwiritsira ntchito LLVM IR yomwe inalandira ndi malangizo ena osinthika amayesa kukonzanso ngati zomveka, malupu, ndi zina zotero. Chabwino, kodi zotsutsana zimaperekedwa bwanji kuntchito? Mwachilengedwe, monga zotsutsana ndi ntchito za JS, ndiye kuti, ngati n'kotheka, osati kudzera pa stack.

Pachiyambi panali lingaliro longolemba m'malo mwa libffi ndi JS ndikuyesa mayeso okhazikika, koma pamapeto pake ndidasokonezeka momwe ndingapangire mafayilo amutu anga kuti agwire ntchito ndi code yomwe ilipo - ndingachite chiyani, monga akunena, "Kodi ntchitozo ndizovuta kwambiri "Kodi ndife opusa kwambiri?" Ndinayenera kuyika libffi kumalo omanga ena, kunena kwake - mwamwayi, Emscripten ali ndi macros onse amtundu wa inline (mu Javascript, eya - chabwino, kaya ndi zomangamanga, kotero wosonkhanitsa), ndi kuthekera koyendetsa kachidindo kopangidwa pa ntchentche. Nthawi zambiri, nditatha kusewera ndi zidutswa za libffi zodalira pa pulatifomu kwakanthawi, ndidapeza ma code ophatikizika ndikuwayendetsa pamayeso oyamba omwe ndidakumana nawo. Ndinadabwa kuti mayesowo anapambana. Kudabwitsidwa ndi luso langa - palibe nthabwala, idagwira ntchito kuyambira kukhazikitsidwa koyamba - ine, osakhulupirirabe maso anga, ndidapita kukayang'ananso code yomwe idatulukanso, kuti ndiwone komwe ndingakumba. Apa ndinachita mtedza kachiwiri - chinthu chokha chimene ntchito yanga inali ffi_call - izi zinanena kuyimba kopambana. Panalibe kuyitana komweko. Chifukwa chake ndidatumiza pempho langa loyamba kukoka, lomwe lidakonza zolakwika pamayeso zomwe zimamveka kwa wophunzira aliyense wa Olympiad - manambala enieni sayenera kufananizidwa a == b ngakhale bwanji a - b < EPS - muyeneranso kukumbukira gawoli, apo ayi 0 idzakhala yofanana kwambiri ndi 1/3 ... kupangidwa - ndinaganiza kuti zingafunike, ndiziwonjezera mtsogolo. Kuyang'ana m'tsogolo, ndikunena kuti, monga momwe zinakhalira, wolembayo sanaphatikizepo ntchito ya libffi mu code yomaliza.

Koma, monga ndanenera kale, pali zolephera zina, ndipo pakati pa kugwiritsa ntchito kwaulere kwa machitidwe osiyanasiyana osadziwika, chinthu chosasangalatsa chabisika - JavaScript ndi mapangidwe sichigwirizana ndi multithreading ndi kukumbukira nawo. M'malo mwake, izi zimatha kutchedwa lingaliro labwino, koma osati pamakina otengera omwe mapangidwe ake amamangiriridwa ku ulusi wa C. Nthawi zambiri, Firefox ikuyesera kuthandizira ogwira nawo ntchito, ndipo Emscripten ali ndi njira yowathandizira, koma sindinkafuna kudalira. Ndinayenera kuchotsa pang'onopang'ono mawerengedwe ambiri kuchokera ku code ya Qemu - ndiko kuti, kupeza kumene ulusi ukuyenda, kusuntha thupi la lupu lomwe likuyenda mu ulusi uwu kuti likhale losiyana, ndikuyitanira ntchito zoterezi imodzi ndi imodzi kuchokera pamtundu waukulu.

Kuyesera kwachiwiri

Panthawi ina, zinaonekeratu kuti vutoli likadalipo, ndipo kuti kupondaponda mwachisawawa ndodo pa code sikungathandize. Kutsiliza: tiyenera mwanjira ina dongosolo ndondomeko kuwonjezera ndodo. Chifukwa chake, mtundu wa 2.4.1, womwe unali watsopano panthawiyo, unatengedwa (osati 2.5.0, chifukwa, ndani akudziwa, padzakhala nsikidzi mumtundu watsopano womwe sunagwidwe, ndipo ndili ndi nsikidzi zokwanira zanga. ), ndipo chinthu choyamba chinali kulilembanso bwinobwino thread-posix.c. Chabwino, ndiye kuti, otetezeka: ngati wina ayesa kuchita opareshoni yomwe imatsogolera kutsekereza, ntchitoyi idayitanidwa nthawi yomweyo abort() - ndithudi, izi sizinathetse mavuto onse mwakamodzi, koma zinali mwanjira ina zosangalatsa kuposa kulandira mwakachetechete deta yosagwirizana.

Mwambiri, zosankha za Emscripten ndizothandiza kwambiri potengera ma code ku JS -s ASSERTIONS=1 -s SAFE_HEAP=1 - amapeza mitundu ina ya machitidwe osadziwika, monga kuyimba foni ku adilesi yosagwirizana (yomwe siyikugwirizana konse ndi kachidindo kamitundu yolembedwa ngati HEAP32[addr >> 2] = 1) kapena kuyitanira ntchito yokhala ndi mikangano yolakwika.

Mwa njira, zolakwika za kulinganiza ndi nkhani yosiyana. Monga ndanenera kale, Qemu ali ndi "zowonongeka" kutanthauzira kumbuyo kwa code generation TCI (wotanthauzira kakang'ono ka code), ndi kumanga ndi kuyendetsa Qemu pa zomangamanga zatsopano, ngati muli ndi mwayi, C compiler ndi yokwanira. "ngati muli ndi mwayi". Sindinachite mwamwayi, ndipo zidapezeka kuti TCI imagwiritsa ntchito mwayi wolumikizana ndi ma bytecode. Ndiye kuti, pamitundu yonse ya ARM ndi zomanga zina zokhala ndi mwayi wofikira, Qemu amaphatikiza chifukwa ali ndi TCG yokhazikika yomwe imapanga code yachibadwidwe, koma ngati TCI iwagwirira ntchito ndi funso lina. Komabe, monga momwe zidakhalira, zolemba za TCI zidawonetsanso chimodzimodzi. Zotsatira zake, ntchito zoyitanitsa zowerengera zosawerengeka zidawonjezeredwa ku code, zomwe zidapezeka mbali ina ya Qemu.

Kuwononga milu

Zotsatira zake, mwayi wosagwirizana ndi TCI udakonzedwa, kuzungulira kwakukulu kunapangidwa komwe kumatchedwa purosesa, RCU ndi zinthu zina zazing'ono. Ndipo kotero ndikuyambitsa Qemu ndi mwayi -d exec,in_asm,out_asm, zomwe zikutanthauza kuti muyenera kunena kuti ndi ma code ati omwe akuchitidwa, komanso panthawi yofalitsa kuti mulembe code ya alendo, kodi code host inakhala chiyani (panthawiyi, bytecode). Imayamba, imapanga midadada ingapo yomasulira, ndikulemba uthenga wochotsa zomwe ndasiya kuti RCU iyamba ... abort() mkati mwa ntchito free(). Pakukambirana ndi ntchito free() Tinatha kudziwa kuti pamutu wa mulu wa mulu, womwe uli mu ma byte asanu ndi atatu patsogolo pa kukumbukira komwe adapatsidwa, m'malo mwa kukula kwa chipika kapena china chofanana, panali zinyalala.

Kuwonongeka kwa mulu - kokongola bwanji ... Zikatero, pali chithandizo chothandizira - kuchokera (ngati n'kotheka) magwero omwewo, sonkhanitsani binary mbadwa ndikuyendetsa pansi pa Valgrind. Patapita nthawi, binary anali atakonzeka. Ndimayiyambitsa ndi zosankha zomwezo - imawonongeka ngakhale pakuyambitsa, isanafikire kuphedwa. Ndizosasangalatsa, inde - mwachiwonekere, magwero ake sanali ofanana ndendende, zomwe sizodabwitsa, chifukwa sinthani zosankha zosiyana pang'ono, koma ndili ndi Valgrind - choyamba ndikonza cholakwikacho, ndiyeno, ngati ndili ndi mwayi. , choyambiriracho chidzawonekera. Ndikuyendetsa chinthu chomwecho pansi pa Valgrind ... Y-y-y, y-y-y, uh-uh, izo zinayamba, zinadutsa poyambitsa mwachizolowezi ndikusunthira kupyola cholakwika choyambirira popanda chenjezo limodzi lokhudza kukumbukira kolakwika, osatchula za kugwa. Moyo, monga akunena, sunandikonzekere izi - pulogalamu yowonongeka imasiya kugwedezeka pamene idayambitsidwa pansi pa Walgrind. Chimene icho chinali ndi chinsinsi. Lingaliro langa ndiloti kamodzi pafupi ndi malangizo apano pambuyo pa ngozi panthawi yoyambitsa, gdb inawonetsa ntchito. memset-a yokhala ndi cholozera cholondola pogwiritsa ntchito mwina mmx, kapena xmm zolembetsa, ndiye mwina chinali cholakwika chamtundu wina, ngakhale ndizovuta kukhulupirira.

Chabwino, Valgrind sakuwoneka kuti akuthandiza pano. Ndipo apa chonyansa kwambiri chinayamba - chirichonse chikuwoneka ngati chikuyamba, koma kuwonongeka kwa zifukwa zosadziwika chifukwa cha chochitika chomwe chikadachitika mamiliyoni a malangizo apitawo. Kwa nthawi yayitali, sizinali zodziwika bwino momwe mungayandikire. Pamapeto pake, ndinafunikabe kukhala pansi ndikuwongolera. Kusindikiza zomwe mutuwo unalembedwanso kumasonyeza kuti sichikuwoneka ngati nambala, koma mtundu wina wa deta ya binary. Ndipo, tawonani, chingwe ichi cha binary chinapezeka mu fayilo ya BIOS - ndiye kuti, tsopano zinali zotheka kunena ndi chidaliro chomveka kuti chinali chiwombankhanga, ndipo zikuwonekeratu kuti zinalembedwa ku buffer iyi. Chabwino, ndiye chinachake chonga ichi - mu Emscripten, mwamwayi, palibe randomisation ya malo adiresi, palibe mabowo mmenemo, kotero mukhoza kulemba penapake pakati pa code kuti mutulutse deta ndi pointer kuyambira kukhazikitsidwa komaliza, yang'anani pa data, yang'anani pa pointer, ndipo, ngati sichinasinthe, pezani chakudya chamaganizo. Zowona, zimatenga mphindi zingapo kulumikizana pambuyo pakusintha kulikonse, koma mungatani? Zotsatira zake, mzere wina unapezedwa womwe unakopera BIOS kuchokera ku buffer kwakanthawi kupita ku kukumbukira alendo - ndipo, ndithudi, kunalibe malo okwanira mu buffer. Kupeza gwero la adilesi yachilendo ya buffer kudapangitsa ntchito qemu_anon_ram_alloc mu file oslib-posix.c - zomveka zinali izi: nthawi zina zingakhale zothandiza kugwirizanitsa adilesi ndi tsamba lalikulu la 2 MB kukula, chifukwa cha izi tidzafunsa. mmap choyamba chowonjezera pang'ono, ndiyeno tidzabwezera chowonjezeracho ndi chithandizo munmap. Ndipo ngati kuyanjanitsa koteroko sikofunikira, ndiye kuti tidzasonyeza zotsatira m'malo mwa 2 MB getpagesize() - mmap iperekabe adilesi yolumikizidwa... Kotero mu Emscripten mmap kungoyimba malloc, koma ndithudi sichigwirizana pa tsamba. Kawirikawiri, cholakwika chomwe chinandikhumudwitsa kwa miyezi ingapo chinakonzedwa ndi kusintha Π΄Π²ΡƒΡ… mizere.

Makhalidwe a ntchito zoyitana

Ndipo tsopano purosesa ikuwerengera chinachake, Qemu sichikuwonongeka, koma chinsalu sichimayatsa, ndipo purosesa imapita mofulumira mu malupu, kuweruza ndi zotsatira. -d exec,in_asm,out_asm. Lingaliro latulukira: kusokoneza timer (kapena, kawirikawiri, kusokoneza konse) sikufika. Ndipo ndithudi, ngati mutachotsa zosokoneza kuchokera ku msonkhano wamba, zomwe pazifukwa zina zinagwira ntchito, mumapeza chithunzi chomwecho. Koma iyi sinali yankho konse: kuyerekeza kwazomwe zaperekedwa ndi njira yomwe ili pamwambapa zikuwonetsa kuti njira zopha anthu zidasiyana koyambirira kwambiri. Apa ziyenera kunenedwa kuti kuyerekeza zomwe zidalembedwa pogwiritsa ntchito oyambitsa emrun debugging linanena bungwe ndi linanena bungwe la mbadwa msonkhano si kwathunthu mawotchi ndondomeko. Sindikudziwa momwe pulogalamu yomwe ikuyendera mu msakatuli imalumikizana emrun, koma mizere ina muzotulutsa imakhala yokonzedwanso, kotero kusiyana kwa kusiyana sikuli chifukwa choganiza kuti njirazo zapatukana. Ambiri, zinaonekeratu kuti malinga ndi malangizo ljmpl pali kusintha kwa ma adilesi osiyanasiyana, ndipo ma bytecode opangidwa ndi osiyana kwambiri: imodzi ili ndi malangizo oyitanitsa ntchito yothandizira, inayo alibe. Pambuyo poyang'ana malangizowo ndikuphunzira nambala yomwe imamasulira malangizowa, zinaonekeratu kuti, choyamba, nthawi yomweyo isanachitike mu kaundula. cr0 kujambula kunapangidwa - komanso kugwiritsa ntchito wothandizira - zomwe zinasintha purosesa kuti ikhale yotetezedwa, ndipo kachiwiri, kuti js version sichinasinthe kuti ikhale yotetezedwa. Koma chowonadi ndichakuti gawo lina la Emscripten ndikukayika kwake kulolera ma code monga kukhazikitsa malangizo. call mu TCI, yomwe cholozera chilichonse chantchito chimabweretsa mtundu long long f(int arg0, .. int arg9) - ntchito ziyenera kuyitanidwa ndi nambala yolondola ya mikangano. Ngati lamuloli likuphwanyidwa, malingana ndi zosintha zowonongeka, pulogalamuyo idzawonongeka (yomwe ili yabwino) kapena kuyitana ntchito yolakwika konse (zomwe zidzakhala zachisoni kuthetsa). Palinso njira yachitatu - athe m'badwo wa wrappers kuti kuwonjezera / kuchotsa mikangano, koma okwana wrappers awa amatenga malo ambiri, ngakhale kuti kwenikweni ndimangofunika wrappers pang'ono kuposa zana. Izi zokha ndi zachisoni kwambiri, koma panali vuto lalikulu kwambiri: mu code yomwe idapangidwa ya ntchito za wrapper, mikangano idasinthidwa ndikusinthidwa, koma nthawi zina ntchitoyo ndi mikangano yomwe idapangidwayo sinatchulidwe - chabwino, monga mu kukhazikitsidwa kwanga kwa libffi. Ndiko kuti, othandizira ena sanaphedwe.

Mwamwayi, Qemu ili ndi mndandanda wowerengeka wamakina wa othandizira ngati fayilo yamutu ngati

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

Amagwiritsidwa ntchito moseketsa: choyamba, ma macros amafotokozedwanso modabwitsa kwambiri DEF_HELPER_n, ndiyeno kuyatsa helper.h. Kufikira pomwe macro amakulitsidwa kukhala choyambitsa ndi comma, ndiyeno gulu limatanthauzidwa, ndipo m'malo mwa zinthu - #include <helper.h> Zotsatira zake, ndinakhala ndi mwayi woyesa laibulale ya kuntchito pyparsing, ndipo script inalembedwa yomwe imapanga ndendende mapepalawo kuti agwiritse ntchito zomwe akufunikira.

Kenako, pambuyo pake purosesa idawoneka kuti ikugwira ntchito. Zikuwoneka kuti chifukwa chinsalucho sichinayambike, ngakhale memtest86 + adatha kuthamanga pamsonkhano wamba. Apa m'pofunika kufotokozera kuti Qemu block I/O code yalembedwa mu coroutines. Emscripten ili ndi kukhazikitsa kwake kwachinyengo kwambiri, koma idafunikirabe kuthandizidwa mu code ya Qemu, ndipo mutha kuyimitsa purosesa tsopano: Qemu imathandizira zosankha. -kernel, -initrd, -append, yomwe mutha kuyambitsa Linux kapena, mwachitsanzo, memtest86+, osagwiritsa ntchito zida zotchinga konse. Koma nali vuto: mumsonkhano wamba wina amatha kuwona kutulutsa kwa Linux kernel ku console ndi mwayi -nographic, ndipo palibe zotuluka kuchokera pa msakatuli kupita ku terminal komwe zidayambika emrun, sanabwere. Ndiko kuti, sizodziwika bwino: purosesa sikugwira ntchito kapena zojambulazo sizikugwira ntchito. Ndiyeno zinandichitikira kuti ndidikire pang'ono. Zinapezeka kuti "purosesa sikugona, koma kumangothwanima pang'onopang'ono," ndipo patatha pafupifupi mphindi zisanu kernel idaponya mulu wa mauthenga pa console ndikupitiriza kupachika. Zinali zoonekeratu kuti purosesa, kawirikawiri, imagwira ntchito, ndipo tiyenera kukumba mu code yogwira ntchito ndi SDL2. Tsoka ilo, sindikudziwa momwe ndingagwiritsire ntchito laibulaleyi, motero m'malo ena ndimayenera kuchita mwachisawawa. Panthawi ina, mzere wa parallel0 unkawonekera pazenera pamtundu wabuluu, womwe umapereka malingaliro ena. Pamapeto pake, zidapezeka kuti vuto linali loti Qemu amatsegula mawindo angapo pawindo limodzi, pomwe mutha kusinthana ndi Ctrl-Alt-n: imagwira ntchito pakumanga kwawo, koma osati ku Emscripten. Pambuyo pochotsa mawindo osafunikira pogwiritsa ntchito zosankha -monitor none -parallel none -serial none ndi malangizo kuti ajambulenso chophimba chonse mwamphamvu pa chimango chilichonse, zonse zidayenda mwadzidzidzi.

Ma Coroutines

Chifukwa chake, kutsanzira mu msakatuli kumagwira ntchito, koma simungayendetse chilichonse chosangalatsa cha single-floppy mmenemo, chifukwa palibe chipika I/O - muyenera kukhazikitsa chithandizo cha coroutines. Qemu ali kale ndi ma coroutine backends angapo, koma chifukwa cha mtundu wa JavaScript ndi Emscripten code generator, simungangoyamba ma juggling stacks. Zikuwoneka kuti "zonse zapita, pulasitala ikuchotsedwa," koma opanga Emscripten asamalira kale chilichonse. Izi zimakhazikitsidwa moseketsa: tiyeni tiyimbe foni yokayikitsa ngati iyi emscripten_sleep ndi ena angapo omwe amagwiritsa ntchito njira ya Asyncify, komanso kuyimba foni ndi ma pointer ku ntchito iliyonse pomwe imodzi mwazochitika ziwiri zam'mbuyomu zitha kuchitika mopitilira mulu. Ndipo tsopano, tisanayimbe foni iliyonse yokayikitsa, tidzasankha mawu oti async, ndipo titangoyimba foniyo, tiwona ngati kuyimba kwa asynchronous kwachitika, ndipo ngati kwachitika, tidzasunga zosintha zonse zakumaloko munkhani iyi, kuwonetsa ntchito yomwe yachitika. kusamutsa ulamuliro mpaka pamene tiyenera kupitiriza kupha, ndi kutuluka ntchito panopa. Apa ndipamene pali mwayi wowerengera zotsatira zake kuwononga - pazosowa zopitiliza kutsata ma code pambuyo pobwerera kuchokera ku foni yosasinthika, wopangayo amapanga "stubs" za ntchitoyi kuyambira pakuyimba kokayikitsa - monga chonchi: ngati pali mafoni okayikitsa, ndiye kuti ntchitoyo idzakulitsidwa kwinakwake n/2 nthawi - izi zikadalipobe, ngati sichoncho Kumbukirani kuti mutatha kuyimba kulikonse komwe kungafanane, muyenera kuwonjezera kupulumutsa zosintha zina zakumaloko ku ntchito yoyambirira. Pambuyo pake, ndinayenera kulemba zolemba zosavuta ku Python, zomwe, kutengera ntchito zomwe zimagwiritsidwa ntchito mopitirira muyeso zomwe zimati "samalola kuti asynchrony adzidutse okha" (ndiko kuti, kukwezedwa kwa stack ndi zonse zomwe ndangofotokozazi sizimatero. work in them), ikuwonetsa mafoni kudzera m'zolozera momwe ntchito ziyenera kunyalanyazidwa ndi wophatikiza kuti izi zisamawoneke ngati zosasinthika. Ndiyeno mafayilo a JS pansi pa 60 MB ali ochuluka kwambiri - tiyeni tinene kuti osachepera 30. -O3. Ndimayendetsa khodi yopangidwa, ndipo Chromium imadya kukumbukira ndi kuwonongeka. Ine ndiye mwangozi anayang'ana pa zimene iye anali kuyesera download... Chabwino, ndinganene chiyani, ine ndikanazizira kwambiri ngati ine anafunsidwa kuphunzira moganizira ndi kukhathamiritsa 500+ MB Javascript.

Tsoka ilo, macheke mulaibulale yothandizira ya Asyncify sanali ochezeka nawo longjmp-zomwe zimagwiritsidwa ntchito mu code processor code, koma pambuyo pa kachigamba kakang'ono kamene kamalepheretsa machekewa ndikubwezeretsa mwamphamvu zochitika ngati zonse zinali bwino, code inagwira ntchito. Kenako chinthu chodabwitsa chinayamba: nthawi zina macheke mu code yolumikizira adayambika - omwewo omwe amasokoneza codeyo ngati, malinga ndi malingaliro akupha, iyenera kutsekedwa - wina adayesa kugwira mutex yemwe wagwidwa kale. Mwamwayi, izi sizinakhale vuto lomveka pamasinthidwe - ndinali kungogwiritsa ntchito mawonekedwe a loop operekedwa ndi Emscripten, koma nthawi zina kuyimba kwa asynchronous kumatha kumasula stack, ndipo panthawiyo kumalephera. setTimeout kuchokera pachimake chachikulu - chifukwa chake, codeyo idalowa mulupu waukulu popanda kusiya kubwereza koyambirira. Lembaninso pa lupu lopanda malire ndi emscripten_sleep, ndipo mavuto a mutexes anasiya. Khodiyo yakhala yomveka bwino - pambuyo pake, ndilibe code yomwe imakonzekera chimango chotsatira - purosesa imangowerengera china chake ndipo chinsalu chimasinthidwa nthawi ndi nthawi. Komabe, mavuto sanalekere pamenepo: nthawi zina kuphedwa kwa Qemu kumangotha ​​mwakachetechete popanda kuchotserapo kapena zolakwika. Panthawiyo ndidasiya, koma, ndikuyang'ana m'tsogolo, ndikunena kuti vuto linali ili: code coroutine, kwenikweni, sagwiritsa ntchito. setTimeout (kapena osati pafupipafupi momwe mungaganizire): ntchito emscripten_yield amangoyika asynchronous kuitana mbendera. Mfundo yonse ndi imeneyo emscripten_coroutine_next si ntchito ya asynchronous: mkati mwake imayang'ana mbendera, imayikhazikitsanso ndikusamutsira kuwongolera komwe ikufunika. Ndiko kuti, kukwezedwa kwa stack kumathera pamenepo. Vuto linali loti chifukwa chogwiritsa ntchito-pambuyo paulere, chomwe chinawonekera pamene dziwe la coroutine linali lolemala chifukwa chakuti sindinatsatire mzere wofunikira wa code kuchokera ku coroutine backend yomwe ilipo, ntchitoyo. qemu_in_coroutine zinabweza zoona pomwe zikanayenera kubwerera zabodza. Izi zidapangitsa kuyimba foni emscripten_yield, pamwamba pake panalibe aliyense pamtengowo emscripten_coroutine_next, muluwo unafutukuka pamwamba kwambiri, koma ayi setTimeout, monga ndanenera kale, sizinawonetsedwe.

Kupanga JavaScript code

Ndipo apa, kwenikweni, ndi lolonjezedwa "kubweza nyama minced." Osati kwenikweni. Inde, ngati tithamanga Qemu mu msakatuli, ndi Node.js mmenemo, ndiye, mwachibadwa, pambuyo pa m'badwo wa code ku Qemu tidzalakwitsa JavaScript. Komabe, mtundu wina wa kusintha kosinthika.

Choyamba, pang'ono za momwe Qemu amagwirira ntchito. Chonde ndikhululukireni nthawi yomweyo: sindine katswiri wopanga Qemu ndipo malingaliro anga angakhale olakwika m'malo ena. Monga amanenera, "lingaliro la wophunzira siliyenera kugwirizana ndi maganizo a mphunzitsi, maganizo a Peano ndi nzeru zake." Qemu ili ndi chiwerengero chazomangamanga za alendo othandizidwa ndipo pa chilichonse pali chikwatu ngati target-i386. Mukamanga, mutha kufotokoza chithandizo chazomangamanga zingapo za alendo, koma zotsatira zake zingokhala ma binaries angapo. Khodi yothandizira kamangidwe ka alendo, imapanganso ntchito zina zamkati za Qemu, zomwe TCG (Tiny Code Generator) imasandulika kale kukhala makina omanga omwe akuchititsa. Monga tafotokozera mu fayilo ya readme yomwe ili mu tcg directory, iyi poyamba inali gawo la C compiler yokhazikika, yomwe pambuyo pake idasinthidwa kukhala JIT. Chifukwa chake, mwachitsanzo, zomanga zomwe mukufuna malinga ndi chikalatachi sizikhalanso zomanga za alendo, koma zomangamanga. Panthawi ina, chigawo china chinawonekera - Tiny Code Interpreter (TCI), yomwe iyenera kuyika kachidindo (pafupifupi ntchito zamkati zomwezo) pakalibe jenereta ya kamangidwe kake. M'malo mwake, monga momwe zolemba zake zimanenera, womasulira uyu sangachite nthawi zonse komanso jenereta ya JIT code, osati kuchuluka kwa liwiro, komanso mwaluso. Ngakhale sindikutsimikiza kuti kufotokozera kwake kuli koyenera.

Poyamba ndinayesera kupanga TCG yokhazikika kumbuyo, koma mwamsanga ndinasokonezeka mu code source ndi kufotokozera momveka bwino malangizo a bytecode, kotero ndinaganiza zokulunga womasulira TCI. Izi zidapereka maubwino angapo:

  • pokhazikitsa ma code jenereta, simungayang'ane kufotokozera kwa malangizo, koma pa code yomasulira
  • mutha kupanga magwiridwe antchito osati pa chipika chilichonse chomasulira chomwe mwakumana nacho, koma, mwachitsanzo, pokhapokha patatha zana
  • ngati ma code opangidwa asintha (ndipo izi zikuwoneka kuti ndi zotheka, kuweruza ndi ntchito zomwe zili ndi mayina omwe ali ndi chigamba cha mawu), ndiyenera kuletsa kachidindo ka JS, koma ndidzakhala ndi chinachake choti ndikonzenso.

Ponena za mfundo yachitatu, sindikutsimikiza kuti kuyika zigamba kumatheka pambuyo poti kachidindo kachitika koyamba, koma mfundo ziwiri zoyambirira ndi zokwanira.

Poyamba, code inapangidwa mu mawonekedwe a lophimba lalikulu pa adiresi ya malangizo original bytecode, koma ndiye, kukumbukira nkhani ya Emscripten, kukhathamiritsa kwaiye JS ndi relooping, ndinaganiza kupanga kwambiri anthu malamulo, makamaka popeza empirically izo. kunapezeka kuti malo okhawo olowera mu chipika chomasulira ndi Start yake. Posakhalitsa, patapita kanthawi tinali ndi jenereta ya code yomwe inapanga code ndi ifs (ngakhale popanda malupu). Koma tsoka, idagwa, kupereka uthenga woti malangizowo anali autali wolakwika. Komanso, malangizo otsiriza pa mlingo recursion anali brcond. Chabwino, ndiwonjezera cheke chofananira ku mbadwo wa malangizowa isanayambe kapena itatha kuyitana kobwerezabwereza ndipo... Pamapeto pake, nditaphunzira kachidindo kopangidwa, ndinazindikira kuti pambuyo posintha, cholozera ku malangizo omwe alipo chimatsitsidwanso kuchokera pamndandanda ndipo mwina chimalembedwanso ndi code yopangidwa ndi JavaScript. Ndipo kotero izo zinakhala. Kuchulukitsa buffer kuchokera ku megabyte imodzi mpaka khumi sikunatsogolere ku kalikonse, ndipo zidawonekeratu kuti jenereta ya code imayenda mozungulira. Tinayenera kuonetsetsa kuti sitinapitirire malire a TB yamakono, ndipo ngati titatero, perekani adiresi ya TB yotsatira ndi chizindikiro chochepa kuti tipitirize kuphedwa. Kuphatikiza apo, izi zimathetsa vuto "ndi ntchito zotani zomwe ziyenera kukhala zosavomerezeka ngati gawo la bytecode lasintha?" - ntchito yokhayo yomwe ikugwirizana ndi chipika chomasulirachi chiyenera kuthetsedwa. Mwa njira, ngakhale ndidasokoneza chilichonse mu Chromium (popeza ndimagwiritsa ntchito Firefox ndipo ndizosavuta kuti ndigwiritse ntchito msakatuli wosiyana pazoyeserera), Firefox idandithandiza kukonza zosagwirizana ndi muyezo wa asm.js, kenako code idayamba kugwira ntchito mwachangu. Chromium.

Chitsanzo cha code yopangidwa

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"]

Pomaliza

Kotero, ntchitoyi sinamalizidwebe, koma ndatopa ndi kubweretsa mwachinsinsi kumanga kwa nthawi yayitali ku ungwiro. Choncho, ndinaganiza zofalitsa zomwe ndili nazo panopa. Khodiyo ndi yowopsya pang'ono m'malo, chifukwa ichi ndi kuyesa, ndipo sichidziwikiratu zomwe ziyenera kuchitika. Mwina, ndiye kuti ndikoyenera kutulutsa ma atomiki wamba pamwamba pa mtundu wina wamakono wa Qemu. Pakalipano, pali ulusi mu Gita mu mawonekedwe a blog: pa "mlingo" uliwonse umene wadutsa mwanjira ina, ndemanga yowonjezereka mu Chirasha yawonjezeredwa. Kwenikweni, nkhaniyi ikufotokozanso mfundo zomaliza git log.

Mutha kuyesa zonse apa (chenjerani ndi magalimoto).

Zomwe zikugwira ntchito kale:

  • x86 pafupifupi purosesa ikuyenda
  • Pali chitsanzo chogwira ntchito cha jenereta ya JIT kuchokera pamakina kupita ku JavaScript
  • Pali template yosonkhanitsira zomanga zina za 32-bit: pakali pano mutha kusilira Linux pamapangidwe a MIPS akuzizira mu msakatuli potsitsa

Chinanso mungachite chiyani

  • Limbikitsani kutsanzira. Ngakhale mu JIT mode ikuwoneka kuti ikuyenda pang'onopang'ono kuposa Virtual x86 (koma pali Qemu yonse yokhala ndi zida zambiri zotsatiridwa ndi zomanga)
  • Kuti ndipange mawonekedwe abwino - kunena zoona, sindine wopanga mawebusayiti wabwino, kotero pakadali pano ndapanganso chipolopolo chokhazikika cha Emscripten momwe ndingathere.
  • Yesani kuyambitsa ntchito zovuta za Qemu - maukonde, kusamuka kwa VM, ndi zina zambiri.
  • UPD: mufunika kutumiza malipoti anu ochepa omwe akutukukani ndi zolakwika ku Emscripten kumtunda, monga onyamula am'mbuyomu a Qemu ndi mapulojekiti ena adachitira. Zikomo kwa iwo chifukwa chotha kugwiritsa ntchito zomwe apereka ku Emscripten ngati gawo la ntchito yanga.

Source: www.habr.com

Kuwonjezera ndemanga