...
browser
Parsing and Compilation in V8
10 min read
Thephasesthatareexecutedinordertorunthejavascriptinthebrowserareasfollows.JustinTimecompilationisapartofthesestages.Scanning,Pre-parsing,parsing,interpreting,baselinecompilingandoptimizedcompiling.ForchromeV8,ignitionisaninterpreter.Turbofanandcrankshaftareoptimizedcompilers.OrinocoisaGCandOilpanisaGClibrarysharedwiththerenderingengine.

Scanningcreatesthetokens.ParsingcreatestheAbstractSyntaxTree.Interpretingcreatesthebytecodeandcompilationcreatesthemachinecode.Havingbytecodebeforecompilinghelpsinreducingthememoryoverhead.It’smoreefficientthandirectinterpretationfromthesourcecode.
Parsingandcompilingisdoneduringthecriticalpath.Parsingeachfunctioninthecodeisnotpreferredbecausethisprocesstakesmemoryandtimeandtherecanbepossibilitieswhereaparticularfunctionwhichwasparsedandcompileddidnotgetinvoked.So,thisiswhybrowsersstartedoptingforlazyparsing.Thereisapreparserwhichdoesthebareminimumsyntaxverificationrequiredtoparsethefunctionitencountersandwhenoneofthesepreparsedfunctionsisinvoked,thatiswhenitisfullyparsedandinterpreted.
Scannerreadsfromthestreamofunicodecharactersdecodedfromutf-16codeunitandcreatestokenswhichareusedbytheparser.Scannergetstheseutf16unicodecharactersfromthejsengine.Scanningidentifiertokensisthemostcomplicatedpart.Thesearethetokensusedfornaming.Eachofthesetokenshasavalidstartingcharacterandvalidremainingcharacters.Inordertoconfirmthevalidityofthenamingconventionofaparticularvariable,alookuptableisusedwhereeachasciicharacterismarkedwhetherit’savalidid_startorid_continue.Parsinglongertokenstakesmoretime.Oneofthereasonstokeepyournamesshorterlikei,j.Forscanningkeywords,it’sabitdifferent.Thereareastaticamountofkeywords.Eitheritcancomparethefirstcharacterandthelengthofthekeywordtonarrowdownthesearchoritcanuseperfecthashing.Auniquehashforeachkeyword.
Variableallocationisabitcomplicatedduringparsing.Callstackmanagesthefunctionactivationrecords.Activationrecordisalowlevelmemoryspace.Consistsofvariables,parameters,variablebindingsandmore.ReturnInstructionPointerisapointerwhichtellswherethecontrolflowshouldreturnto.Ideally,whenaparticularfunctionhasfinishedexecutingandreturned(withthehelpofRIP),itsvariablesanddatastoredinthemarealsopoppedout.Thiscanbeaproblemforclosureswheretheinnerfunctionisreferencingthedataoftheouterfunctionafterithasbeenexecutedandreturned.Forcaseslikethis,aseparatecontextismaintainedintheheapwherethevariablesofthatfunctionarestoredsothatevenifthefunctionisremovedfromthestack,itsdatacanstillbeused.
Parsinghappensduringthecriticalpathonabackgroundthreadforloadingtimeimprovements.Parsingachunkofcodewhiletherestisbeingfetchedoverthenetwork.ItusedtogetcompiledintoJITmachinecodeonthemainthreadforitsexecutionbutwithignitionandturbofan,thispartalsohappensinthebackgroundthreadgivingthemainthreadmoreidletime.

Now,earlierthereusedtobeabaselinecompilerandanoptimizedcompiler.Allthecodewascompiledintobaselinemachinecodequicklyandoptionallysomeofitwhichwasneededduringexecutionwasoptimizedfurther.Crankshaftandturbofanaretwooptimizedcompilers.Thisunoptimizedmachinecodewasconsumingasignificantamountofmemoryandtodealwiththisthebaselinecompilerwasreplacedbyaninterpreter,Ignition.Thisreducesthememoryoverheadandsimplifiestheexecutionpipeline.Itgeneratesbytecodewhichisroughlyonefourththesizeofthemachinecodebeinggeneratedearlier.
Bytecodeflushing.Thebytecodecreatedbytheinterpretertakesmemoryaswell.Removewhat,howmuchandwhen?ThishappensduringGarbageCollection.Everyfunction’sbytecodehasanagewhichis0initiallyandgetsincrementedaftereverycycleofGC.Ifitcrossesthethresholdage,thatbytecodeisremoved.Incasethatfunctionisinvokedlater,itcanbelazilyparsed,interpretedandcompiledagain.Thisisforfunctionsthathavebeenonlyexecutedoncesinceinitializationornotatall.
Twomaincomponentsofcompiling-ASTinternalizationandbytecodefinalization.Accesstov8’sheapmemoryisnotallowedforthiscompilationpipelinefromthebackgroundthread.HeapcanonlybeusedbythemainthreadandGC.IgnitionusesthelowlevelassemblyinstructionsofTurbofan.TurbofanhadreplacedCrankshaftbecauseitwasnotabletosupporttheupcomingfeaturesofthelanguagebecauseitrequiredmakingchangesinarchitecturespecificcode.Turbofanwasbuiltinawaywhereaddingsupportfornewecmafeaturesdidn’thavetogothoughlowlevelchangesthusmakingitmoreextensible.Duetothissharingoffoundationalarchitecture,TurbofancancompilemachinecodedirectlyfromthebytecodegeneratedbyIgnitioninsteadoffromthesourcecode,likeCrankshaft.

Ifjavascriptisparsed/interpreted/compiledduringruntimethenhowcanmyIDEtellsomeofthesyntaxerrors.It’sbecauseIDE’shavetheirownparsersthatcanperformstaticcodecheckingandanalysis.Theycannothighlighttheruntimeerrorslikereferenceerrors.
Also,doestypescripthelpinallofthis?Ifyes,howso?Typescriptforcesthedevelopertoexplicitlyaddtypesforfunctionsandvariables,ifnotinferredimplicitly.Thismakesthecodemonomorphicandconsistent.Afunctionwilldealwithonlyaparticulartypeofdataandreturnacertaintypeofdata.Italsohelpsincatchingmostoftheruntimetypechecksduringdevelopment.Thisinformationhelpsreducethepermutationsoftypechecksorlookupsduringruntime.Since,typescriptistranspiledtojavascriptbeforegettingjit’ed,allthedynamicchecksarestillrunbutit’shelpfulasthevariabilityofthesedynamictypechecksisreducedtoagreatextent.Nonetheless,thedifferenceintheruntimeperformanceisinsignificant.