jemalloc.c 181 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800
  1. /* -*- Mode: C; tab-width: 8; c-basic-offset: 8; indent-tabs-mode: t -*- */
  2. /* vim:set softtabstop=8 shiftwidth=8 noet: */
  3. /*-
  4. * Copyright (C) 2006-2008 Jason Evans <jasone@FreeBSD.org>.
  5. * Copyright (C) 2015-2019 Mark Straver <moonchild@palemoon.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice(s), this list of conditions and the following disclaimer as
  12. * the first lines of this file unmodified other than the possible
  13. * addition of one or more copyright notices.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice(s), this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
  20. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  26. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  27. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  28. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  29. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. *******************************************************************************
  32. *
  33. * This allocator implementation is designed to provide scalable performance
  34. * for multi-threaded programs on multi-processor systems. The following
  35. * features are included for this purpose:
  36. *
  37. * + Multiple arenas are used if there are multiple CPUs, which reduces lock
  38. * contention and cache sloshing.
  39. *
  40. * + Cache line sharing between arenas is avoided for internal data
  41. * structures.
  42. *
  43. * + Memory is managed in chunks and runs (chunks can be split into runs),
  44. * rather than as individual pages. This provides a constant-time
  45. * mechanism for associating allocations with particular arenas.
  46. *
  47. * Allocation requests are rounded up to the nearest size class, and no record
  48. * of the original request size is maintained. Allocations are broken into
  49. * categories according to size class. Assuming runtime defaults, 4 kB pages
  50. * and a 16 byte quantum on a 32-bit system, the size classes in each category
  51. * are as follows:
  52. *
  53. * |=====================================|
  54. * | Category | Subcategory | Size |
  55. * |=====================================|
  56. * | Small | Tiny | 2 |
  57. * | | | 4 |
  58. * | | | 8 |
  59. * | |----------------+---------|
  60. * | | Quantum-spaced | 16 |
  61. * | | | 32 |
  62. * | | | 48 |
  63. * | | | ... |
  64. * | | | 480 |
  65. * | | | 496 |
  66. * | | | 512 |
  67. * | |----------------+---------|
  68. * | | Sub-page | 1 kB |
  69. * | | | 2 kB |
  70. * |=====================================|
  71. * | Large | 4 kB |
  72. * | | 8 kB |
  73. * | | 12 kB |
  74. * | | ... |
  75. * | | 1012 kB |
  76. * | | 1016 kB |
  77. * | | 1020 kB |
  78. * |=====================================|
  79. * | Huge | 1 MB |
  80. * | | 2 MB |
  81. * | | 3 MB |
  82. * | | ... |
  83. * |=====================================|
  84. *
  85. * NOTE: Due to Mozilla bug 691003, we cannot reserve less than one word for an
  86. * allocation on Linux or Mac. So on 32-bit *nix, the smallest bucket size is
  87. * 4 bytes, and on 64-bit, the smallest bucket size is 8 bytes.
  88. *
  89. * A different mechanism is used for each category:
  90. *
  91. * Small : Each size class is segregated into its own set of runs. Each run
  92. * maintains a bitmap of which regions are free/allocated.
  93. *
  94. * Large : Each allocation is backed by a dedicated run. Metadata are stored
  95. * in the associated arena chunk header maps.
  96. *
  97. * Huge : Each allocation is backed by a dedicated contiguous set of chunks.
  98. * Metadata are stored in a separate red-black tree.
  99. *
  100. *******************************************************************************
  101. */
  102. /*
  103. * On Linux, we use madvise(MADV_DONTNEED) to release memory back to the
  104. * operating system. If we release 1MB of live pages with MADV_DONTNEED, our
  105. * RSS will decrease by 1MB (almost) immediately.
  106. *
  107. * On Mac, we use madvise(MADV_FREE). Unlike MADV_DONTNEED on Linux, MADV_FREE
  108. * on Mac doesn't cause the OS to release the specified pages immediately; the
  109. * OS keeps them in our process until the machine comes under memory pressure.
  110. *
  111. * It's therefore difficult to measure the process's RSS on Mac, since, in the
  112. * absence of memory pressure, the contribution from the heap to RSS will not
  113. * decrease due to our madvise calls.
  114. *
  115. * We therefore define MALLOC_DOUBLE_PURGE on Mac. This causes jemalloc to
  116. * track which pages have been MADV_FREE'd. You can then call
  117. * jemalloc_purge_freed_pages(), which will force the OS to release those
  118. * MADV_FREE'd pages, making the process's RSS reflect its true memory usage.
  119. *
  120. * The jemalloc_purge_freed_pages definition in memory/build/mozmemory.h needs
  121. * to be adjusted if MALLOC_DOUBLE_PURGE is ever enabled on Linux.
  122. */
  123. #ifdef MOZ_MEMORY_DARWIN
  124. #define MALLOC_DOUBLE_PURGE
  125. #endif
  126. /*
  127. * MALLOC_PRODUCTION disables assertions and statistics gathering. It also
  128. * defaults the A and J runtime options to off. These settings are appropriate
  129. * for production systems.
  130. */
  131. #ifndef MOZ_MEMORY_DEBUG
  132. # define MALLOC_PRODUCTION
  133. #endif
  134. /*
  135. * Uncomment this to use only one arena by default.
  136. */
  137. // #define MOZ_MEMORY_NARENAS_DEFAULT_ONE
  138. /*
  139. * Pass this set of options to jemalloc as its default. It does not override
  140. * the options passed via the MALLOC_OPTIONS environment variable but is
  141. * applied in addition to them.
  142. */
  143. # define MOZ_MALLOC_OPTIONS ""
  144. /*
  145. * MALLOC_STATS enables statistics calculation, and is required for
  146. * jemalloc_stats().
  147. */
  148. #define MALLOC_STATS
  149. /* Memory filling (junk/poison/zero). */
  150. #define MALLOC_FILL
  151. #ifndef MALLOC_PRODUCTION
  152. /*
  153. * MALLOC_DEBUG enables assertions and other sanity checks, and disables
  154. * inline functions.
  155. */
  156. # define MALLOC_DEBUG
  157. /* Support optional abort() on OOM. */
  158. # define MALLOC_XMALLOC
  159. /* Support SYSV semantics. */
  160. # define MALLOC_SYSV
  161. #endif
  162. #ifdef MOZ_MEMORY_LINUX
  163. #define _GNU_SOURCE /* For mremap(2). */
  164. #endif
  165. #include <sys/types.h>
  166. #ifdef MOZ_MEMORY_BSD
  167. #include <sys/sysctl.h>
  168. #endif
  169. #include <errno.h>
  170. #include <stdlib.h>
  171. #include <limits.h>
  172. #include <stdarg.h>
  173. #include <stdio.h>
  174. #include <string.h>
  175. #ifdef MOZ_MEMORY_WINDOWS
  176. #include <io.h>
  177. #include <windows.h>
  178. #include <intrin.h>
  179. #pragma warning( disable: 4267 4996 4146 )
  180. #define bool BOOL
  181. #define false FALSE
  182. #define true TRUE
  183. #define inline __inline
  184. #define SIZE_T_MAX SIZE_MAX
  185. #define STDERR_FILENO 2
  186. #define PATH_MAX MAX_PATH
  187. #define vsnprintf _vsnprintf
  188. #ifndef NO_TLS
  189. static unsigned long tlsIndex = 0xffffffff;
  190. #endif
  191. #define __thread
  192. #define _pthread_self() __threadid()
  193. /* use MSVC intrinsics */
  194. #pragma intrinsic(_BitScanForward)
  195. static __forceinline int
  196. ffs(int x)
  197. {
  198. unsigned long i;
  199. if (_BitScanForward(&i, x) != 0)
  200. return (i + 1);
  201. return (0);
  202. }
  203. /* Implement getenv without using malloc */
  204. static char mozillaMallocOptionsBuf[64];
  205. #define getenv xgetenv
  206. static char *
  207. getenv(const char *name)
  208. {
  209. if (GetEnvironmentVariableA(name, (LPSTR)&mozillaMallocOptionsBuf,
  210. sizeof(mozillaMallocOptionsBuf)) > 0)
  211. return (mozillaMallocOptionsBuf);
  212. return (NULL);
  213. }
  214. typedef unsigned char uint8_t;
  215. typedef unsigned uint32_t;
  216. typedef unsigned long long uint64_t;
  217. typedef unsigned long long uintmax_t;
  218. #if defined(_WIN64)
  219. typedef long long ssize_t;
  220. #else
  221. typedef long ssize_t;
  222. #endif
  223. #define MALLOC_DECOMMIT
  224. #endif
  225. /*
  226. * Allow unmapping pages on all platforms. Note that if this is disabled,
  227. * jemalloc will never unmap anything, instead recycling pages for later use.
  228. */
  229. #define JEMALLOC_MUNMAP
  230. /*
  231. * Enable limited chunk recycling on all platforms. Note that when
  232. * JEMALLOC_MUNMAP is not defined, all chunks will be recycled unconditionally.
  233. */
  234. #define JEMALLOC_RECYCLE
  235. #ifndef MOZ_MEMORY_WINDOWS
  236. #ifndef MOZ_MEMORY_SOLARIS
  237. #include <sys/cdefs.h>
  238. #endif
  239. #ifndef __DECONST
  240. # define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
  241. #endif
  242. #include <sys/mman.h>
  243. #ifndef MADV_FREE
  244. # define MADV_FREE MADV_DONTNEED
  245. #endif
  246. #ifndef MAP_NOSYNC
  247. # define MAP_NOSYNC 0
  248. #endif
  249. #include <sys/param.h>
  250. #include <sys/time.h>
  251. #include <sys/types.h>
  252. #include <sys/uio.h>
  253. #include <errno.h>
  254. #include <limits.h>
  255. #ifndef SIZE_T_MAX
  256. # define SIZE_T_MAX SIZE_MAX
  257. #endif
  258. #include <pthread.h>
  259. #include <sched.h>
  260. #include <stdarg.h>
  261. #include <stdio.h>
  262. #include <stdbool.h>
  263. #include <stdint.h>
  264. #include <stdlib.h>
  265. #include <string.h>
  266. #include <strings.h>
  267. #include <unistd.h>
  268. #endif
  269. #include "jemalloc_types.h"
  270. #include "linkedlist.h"
  271. #include "mozmemory_wrap.h"
  272. /* Some tools, such as /dev/dsp wrappers, LD_PRELOAD libraries that
  273. * happen to override mmap() and call dlsym() from their overridden
  274. * mmap(). The problem is that dlsym() calls malloc(), and this ends
  275. * up in a dead lock in jemalloc.
  276. * On these systems, we prefer to directly use the system call.
  277. * We do that for Linux systems and kfreebsd with GNU userland.
  278. * Note sanity checks are not done (alignment of offset, ...) because
  279. * the uses of mmap are pretty limited, in jemalloc.
  280. *
  281. * On Alpha, glibc has a bug that prevents syscall() to work for system
  282. * calls with 6 arguments
  283. */
  284. #if (defined(MOZ_MEMORY_LINUX) && !defined(__alpha__)) || \
  285. (defined(MOZ_MEMORY_BSD) && defined(__GLIBC__))
  286. #include <sys/syscall.h>
  287. #if defined(SYS_mmap) || defined(SYS_mmap2)
  288. static inline
  289. void *_mmap(void *addr, size_t length, int prot, int flags,
  290. int fd, off_t offset)
  291. {
  292. /* S390 only passes one argument to the mmap system call, which is a
  293. * pointer to a structure containing the arguments */
  294. #ifdef __s390__
  295. struct {
  296. void *addr;
  297. size_t length;
  298. long prot;
  299. long flags;
  300. long fd;
  301. off_t offset;
  302. } args = { addr, length, prot, flags, fd, offset };
  303. return (void *) syscall(SYS_mmap, &args);
  304. #else
  305. #ifdef SYS_mmap2
  306. return (void *) syscall(SYS_mmap2, addr, length, prot, flags,
  307. fd, offset >> 12);
  308. #else
  309. return (void *) syscall(SYS_mmap, addr, length, prot, flags,
  310. fd, offset);
  311. #endif
  312. #endif
  313. }
  314. #define mmap _mmap
  315. #define munmap(a, l) syscall(SYS_munmap, a, l)
  316. #endif
  317. #endif
  318. #ifndef __DECONST
  319. #define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
  320. #endif
  321. #include "rb.h"
  322. #ifdef MALLOC_DEBUG
  323. /* Disable inlining to make debugging easier. */
  324. #ifdef inline
  325. #undef inline
  326. #endif
  327. # define inline
  328. #endif
  329. /* Size of stack-allocated buffer passed to strerror_r(). */
  330. #define STRERROR_BUF 64
  331. /* Minimum alignment of non-tiny allocations is 2^QUANTUM_2POW_MIN bytes. */
  332. # define QUANTUM_2POW_MIN 4
  333. #if defined(_WIN64) || defined(__LP64__)
  334. # define SIZEOF_PTR_2POW 3
  335. #else
  336. # define SIZEOF_PTR_2POW 2
  337. #endif
  338. #define PIC
  339. #ifdef MOZ_MEMORY_DARWIN
  340. # define NO_TLS
  341. #endif
  342. #define SIZEOF_PTR (1U << SIZEOF_PTR_2POW)
  343. /* sizeof(int) == (1U << SIZEOF_INT_2POW). */
  344. #ifndef SIZEOF_INT_2POW
  345. # define SIZEOF_INT_2POW 2
  346. #endif
  347. /* We can't use TLS in non-PIC programs, since TLS relies on loader magic. */
  348. #if (!defined(PIC) && !defined(NO_TLS))
  349. # define NO_TLS
  350. #endif
  351. /*
  352. * Size and alignment of memory chunks that are allocated by the OS's virtual
  353. * memory system.
  354. */
  355. #define CHUNK_2POW_DEFAULT 20
  356. /* Maximum number of dirty pages per arena. */
  357. #define DIRTY_MAX_DEFAULT (1U << 8)
  358. /*
  359. * Maximum size of L1 cache line. This is used to avoid cache line aliasing,
  360. * so over-estimates are okay (up to a point), but under-estimates will
  361. * negatively affect performance.
  362. */
  363. #define CACHELINE_2POW 6
  364. #define CACHELINE ((size_t)(1U << CACHELINE_2POW))
  365. /*
  366. * Smallest size class to support. On Windows the smallest allocation size
  367. * must be 8 bytes on 32-bit, 16 bytes on 64-bit. On Linux and Mac, even
  368. * malloc(1) must reserve a word's worth of memory (see Mozilla bug 691003).
  369. */
  370. #ifdef MOZ_MEMORY_WINDOWS
  371. #define TINY_MIN_2POW (sizeof(void*) == 8 ? 4 : 3)
  372. #else
  373. #define TINY_MIN_2POW (sizeof(void*) == 8 ? 3 : 2)
  374. #endif
  375. /*
  376. * Maximum size class that is a multiple of the quantum, but not (necessarily)
  377. * a power of 2. Above this size, allocations are rounded up to the nearest
  378. * power of 2.
  379. */
  380. #define SMALL_MAX_2POW_DEFAULT 9
  381. #define SMALL_MAX_DEFAULT (1U << SMALL_MAX_2POW_DEFAULT)
  382. /*
  383. * RUN_MAX_OVRHD indicates maximum desired run header overhead. Runs are sized
  384. * as small as possible such that this setting is still honored, without
  385. * violating other constraints. The goal is to make runs as small as possible
  386. * without exceeding a per run external fragmentation threshold.
  387. *
  388. * We use binary fixed point math for overhead computations, where the binary
  389. * point is implicitly RUN_BFP bits to the left.
  390. *
  391. * Note that it is possible to set RUN_MAX_OVRHD low enough that it cannot be
  392. * honored for some/all object sizes, since there is one bit of header overhead
  393. * per object (plus a constant). This constraint is relaxed (ignored) for runs
  394. * that are so small that the per-region overhead is greater than:
  395. *
  396. * (RUN_MAX_OVRHD / (reg_size << (3+RUN_BFP))
  397. */
  398. #define RUN_BFP 12
  399. /* \/ Implicit binary fixed point. */
  400. #define RUN_MAX_OVRHD 0x0000003dU
  401. #define RUN_MAX_OVRHD_RELAX 0x00001800U
  402. /******************************************************************************/
  403. /* MALLOC_DECOMMIT and MALLOC_DOUBLE_PURGE are mutually exclusive. */
  404. #if defined(MALLOC_DECOMMIT) && defined(MALLOC_DOUBLE_PURGE)
  405. #error MALLOC_DECOMMIT and MALLOC_DOUBLE_PURGE are mutually exclusive.
  406. #endif
  407. /*
  408. * Mutexes based on spinlocks. We can't use normal pthread spinlocks in all
  409. * places, because they require malloc()ed memory, which causes bootstrapping
  410. * issues in some cases.
  411. */
  412. #if defined(MOZ_MEMORY_WINDOWS)
  413. #define malloc_mutex_t SRWLOCK
  414. #define malloc_spinlock_t SRWLOCK
  415. #elif defined(MOZ_MEMORY_DARWIN)
  416. typedef struct {
  417. OSSpinLock lock;
  418. } malloc_mutex_t;
  419. typedef struct {
  420. OSSpinLock lock;
  421. } malloc_spinlock_t;
  422. #else
  423. typedef pthread_mutex_t malloc_mutex_t;
  424. typedef pthread_mutex_t malloc_spinlock_t;
  425. #endif
  426. /* Set to true once the allocator has been initialized. */
  427. static volatile bool malloc_initialized = false;
  428. #if defined(MOZ_MEMORY_WINDOWS) || defined(__FreeBSD__)
  429. /* No init lock for Windows nor FreeBSD. */
  430. #elif defined(MOZ_MEMORY_DARWIN)
  431. static malloc_mutex_t init_lock = {OS_SPINLOCK_INIT};
  432. #elif defined(MOZ_MEMORY_LINUX)
  433. static malloc_mutex_t init_lock = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP;
  434. #else
  435. static malloc_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;
  436. #endif
  437. /******************************************************************************/
  438. /*
  439. * Statistics data structures.
  440. */
  441. #ifdef MALLOC_STATS
  442. typedef struct malloc_bin_stats_s malloc_bin_stats_t;
  443. struct malloc_bin_stats_s {
  444. /*
  445. * Number of allocation requests that corresponded to the size of this
  446. * bin.
  447. */
  448. uint64_t nrequests;
  449. /* Total number of runs created for this bin's size class. */
  450. uint64_t nruns;
  451. /*
  452. * Total number of runs reused by extracting them from the runs tree for
  453. * this bin's size class.
  454. */
  455. uint64_t reruns;
  456. /* High-water mark for this bin. */
  457. unsigned long highruns;
  458. /* Current number of runs in this bin. */
  459. unsigned long curruns;
  460. };
  461. typedef struct arena_stats_s arena_stats_t;
  462. struct arena_stats_s {
  463. /* Number of bytes currently mapped. */
  464. size_t mapped;
  465. /*
  466. * Total number of purge sweeps, total number of madvise calls made,
  467. * and total pages purged in order to keep dirty unused memory under
  468. * control.
  469. */
  470. uint64_t npurge;
  471. uint64_t nmadvise;
  472. uint64_t purged;
  473. #ifdef MALLOC_DECOMMIT
  474. /*
  475. * Total number of decommit/commit operations, and total number of
  476. * pages decommitted.
  477. */
  478. uint64_t ndecommit;
  479. uint64_t ncommit;
  480. uint64_t decommitted;
  481. #endif
  482. /* Current number of committed pages. */
  483. size_t committed;
  484. /* Per-size-category statistics. */
  485. size_t allocated_small;
  486. uint64_t nmalloc_small;
  487. uint64_t ndalloc_small;
  488. size_t allocated_large;
  489. uint64_t nmalloc_large;
  490. uint64_t ndalloc_large;
  491. };
  492. #endif /* #ifdef MALLOC_STATS */
  493. /******************************************************************************/
  494. /*
  495. * Extent data structures.
  496. */
  497. /* Tree of extents. */
  498. typedef struct extent_node_s extent_node_t;
  499. struct extent_node_s {
  500. /* Linkage for the size/address-ordered tree. */
  501. rb_node(extent_node_t) link_szad;
  502. /* Linkage for the address-ordered tree. */
  503. rb_node(extent_node_t) link_ad;
  504. /* Pointer to the extent that this tree node is responsible for. */
  505. void *addr;
  506. /* Total region size. */
  507. size_t size;
  508. /* True if zero-filled; used by chunk recycling code. */
  509. bool zeroed;
  510. };
  511. typedef rb_tree(extent_node_t) extent_tree_t;
  512. /******************************************************************************/
  513. /*
  514. * Radix tree data structures.
  515. */
  516. /*
  517. * Size of each radix tree node (must be a power of 2). This impacts tree
  518. * depth.
  519. */
  520. #if (SIZEOF_PTR == 4)
  521. #define MALLOC_RTREE_NODESIZE (1U << 14)
  522. #else
  523. #define MALLOC_RTREE_NODESIZE CACHELINE
  524. #endif
  525. typedef struct malloc_rtree_s malloc_rtree_t;
  526. struct malloc_rtree_s {
  527. malloc_spinlock_t lock;
  528. void **root;
  529. unsigned height;
  530. unsigned level2bits[1]; /* Dynamically sized. */
  531. };
  532. /******************************************************************************/
  533. /*
  534. * Arena data structures.
  535. */
  536. typedef struct arena_s arena_t;
  537. typedef struct arena_bin_s arena_bin_t;
  538. /* Each element of the chunk map corresponds to one page within the chunk. */
  539. typedef struct arena_chunk_map_s arena_chunk_map_t;
  540. struct arena_chunk_map_s {
  541. /*
  542. * Linkage for run trees. There are two disjoint uses:
  543. *
  544. * 1) arena_t's runs_avail tree.
  545. * 2) arena_run_t conceptually uses this linkage for in-use non-full
  546. * runs, rather than directly embedding linkage.
  547. */
  548. rb_node(arena_chunk_map_t) link;
  549. /*
  550. * Run address (or size) and various flags are stored together. The bit
  551. * layout looks like (assuming 32-bit system):
  552. *
  553. * ???????? ???????? ????---- -mckdzla
  554. *
  555. * ? : Unallocated: Run address for first/last pages, unset for internal
  556. * pages.
  557. * Small: Run address.
  558. * Large: Run size for first page, unset for trailing pages.
  559. * - : Unused.
  560. * m : MADV_FREE/MADV_DONTNEED'ed?
  561. * c : decommitted?
  562. * k : key?
  563. * d : dirty?
  564. * z : zeroed?
  565. * l : large?
  566. * a : allocated?
  567. *
  568. * Following are example bit patterns for the three types of runs.
  569. *
  570. * r : run address
  571. * s : run size
  572. * x : don't care
  573. * - : 0
  574. * [cdzla] : bit set
  575. *
  576. * Unallocated:
  577. * ssssssss ssssssss ssss---- --c-----
  578. * xxxxxxxx xxxxxxxx xxxx---- ----d---
  579. * ssssssss ssssssss ssss---- -----z--
  580. *
  581. * Small:
  582. * rrrrrrrr rrrrrrrr rrrr---- -------a
  583. * rrrrrrrr rrrrrrrr rrrr---- -------a
  584. * rrrrrrrr rrrrrrrr rrrr---- -------a
  585. *
  586. * Large:
  587. * ssssssss ssssssss ssss---- ------la
  588. * -------- -------- -------- ------la
  589. * -------- -------- -------- ------la
  590. */
  591. size_t bits;
  592. /* Note that CHUNK_MAP_DECOMMITTED's meaning varies depending on whether
  593. * MALLOC_DECOMMIT and MALLOC_DOUBLE_PURGE are defined.
  594. *
  595. * If MALLOC_DECOMMIT is defined, a page which is CHUNK_MAP_DECOMMITTED must be
  596. * re-committed with pages_commit() before it may be touched. If
  597. * MALLOC_DECOMMIT is defined, MALLOC_DOUBLE_PURGE may not be defined.
  598. *
  599. * If neither MALLOC_DECOMMIT nor MALLOC_DOUBLE_PURGE is defined, pages which
  600. * are madvised (with either MADV_DONTNEED or MADV_FREE) are marked with
  601. * CHUNK_MAP_MADVISED.
  602. *
  603. * Otherwise, if MALLOC_DECOMMIT is not defined and MALLOC_DOUBLE_PURGE is
  604. * defined, then a page which is madvised is marked as CHUNK_MAP_MADVISED.
  605. * When it's finally freed with jemalloc_purge_freed_pages, the page is marked
  606. * as CHUNK_MAP_DECOMMITTED.
  607. */
  608. #if defined(MALLOC_DECOMMIT) || defined(MALLOC_STATS) || defined(MALLOC_DOUBLE_PURGE)
  609. #define CHUNK_MAP_MADVISED ((size_t)0x40U)
  610. #define CHUNK_MAP_DECOMMITTED ((size_t)0x20U)
  611. #define CHUNK_MAP_MADVISED_OR_DECOMMITTED (CHUNK_MAP_MADVISED | CHUNK_MAP_DECOMMITTED)
  612. #endif
  613. #define CHUNK_MAP_KEY ((size_t)0x10U)
  614. #define CHUNK_MAP_DIRTY ((size_t)0x08U)
  615. #define CHUNK_MAP_ZEROED ((size_t)0x04U)
  616. #define CHUNK_MAP_LARGE ((size_t)0x02U)
  617. #define CHUNK_MAP_ALLOCATED ((size_t)0x01U)
  618. };
  619. typedef rb_tree(arena_chunk_map_t) arena_avail_tree_t;
  620. typedef rb_tree(arena_chunk_map_t) arena_run_tree_t;
  621. /* Arena chunk header. */
  622. typedef struct arena_chunk_s arena_chunk_t;
  623. struct arena_chunk_s {
  624. /* Arena that owns the chunk. */
  625. arena_t *arena;
  626. /* Linkage for the arena's chunks_dirty tree. */
  627. rb_node(arena_chunk_t) link_dirty;
  628. #ifdef MALLOC_DOUBLE_PURGE
  629. /* If we're double-purging, we maintain a linked list of chunks which
  630. * have pages which have been madvise(MADV_FREE)'d but not explicitly
  631. * purged.
  632. *
  633. * We're currently lazy and don't remove a chunk from this list when
  634. * all its madvised pages are recommitted. */
  635. LinkedList chunks_madvised_elem;
  636. #endif
  637. /* Number of dirty pages. */
  638. size_t ndirty;
  639. /* Map of pages within chunk that keeps track of free/large/small. */
  640. arena_chunk_map_t map[1]; /* Dynamically sized. */
  641. };
  642. typedef rb_tree(arena_chunk_t) arena_chunk_tree_t;
  643. typedef struct arena_run_s arena_run_t;
  644. struct arena_run_s {
  645. #if defined(MALLOC_DEBUG) || defined(MOZ_JEMALLOC_HARD_ASSERTS)
  646. uint32_t magic;
  647. # define ARENA_RUN_MAGIC 0x384adf93
  648. #endif
  649. /* Bin this run is associated with. */
  650. arena_bin_t *bin;
  651. /* Index of first element that might have a free region. */
  652. unsigned regs_minelm;
  653. /* Number of free regions in run. */
  654. unsigned nfree;
  655. /* Bitmask of in-use regions (0: in use, 1: free). */
  656. unsigned regs_mask[1]; /* Dynamically sized. */
  657. };
  658. struct arena_bin_s {
  659. /*
  660. * Current run being used to service allocations of this bin's size
  661. * class.
  662. */
  663. arena_run_t *runcur;
  664. /*
  665. * Tree of non-full runs. This tree is used when looking for an
  666. * existing run when runcur is no longer usable. We choose the
  667. * non-full run that is lowest in memory; this policy tends to keep
  668. * objects packed well, and it can also help reduce the number of
  669. * almost-empty chunks.
  670. */
  671. arena_run_tree_t runs;
  672. /* Size of regions in a run for this bin's size class. */
  673. size_t reg_size;
  674. /* Total size of a run for this bin's size class. */
  675. size_t run_size;
  676. /* Total number of regions in a run for this bin's size class. */
  677. uint32_t nregs;
  678. /* Number of elements in a run's regs_mask for this bin's size class. */
  679. uint32_t regs_mask_nelms;
  680. /* Offset of first region in a run for this bin's size class. */
  681. uint32_t reg0_offset;
  682. #ifdef MALLOC_STATS
  683. /* Bin statistics. */
  684. malloc_bin_stats_t stats;
  685. #endif
  686. };
  687. struct arena_s {
  688. #if defined(MALLOC_DEBUG) || defined(MOZ_JEMALLOC_HARD_ASSERTS)
  689. uint32_t magic;
  690. # define ARENA_MAGIC 0x947d3d24
  691. #endif
  692. /* All operations on this arena require that lock be locked. */
  693. malloc_spinlock_t lock;
  694. #ifdef MALLOC_STATS
  695. arena_stats_t stats;
  696. #endif
  697. /* Tree of dirty-page-containing chunks this arena manages. */
  698. arena_chunk_tree_t chunks_dirty;
  699. #ifdef MALLOC_DOUBLE_PURGE
  700. /* Head of a linked list of MADV_FREE'd-page-containing chunks this
  701. * arena manages. */
  702. LinkedList chunks_madvised;
  703. #endif
  704. /*
  705. * In order to avoid rapid chunk allocation/deallocation when an arena
  706. * oscillates right on the cusp of needing a new chunk, cache the most
  707. * recently freed chunk. The spare is left in the arena's chunk trees
  708. * until it is deleted.
  709. *
  710. * There is one spare chunk per arena, rather than one spare total, in
  711. * order to avoid interactions between multiple threads that could make
  712. * a single spare inadequate.
  713. */
  714. arena_chunk_t *spare;
  715. /*
  716. * Current count of pages within unused runs that are potentially
  717. * dirty, and for which madvise(... MADV_FREE) has not been called. By
  718. * tracking this, we can institute a limit on how much dirty unused
  719. * memory is mapped for each arena.
  720. */
  721. size_t ndirty;
  722. /*
  723. * Size/address-ordered tree of this arena's available runs. This tree
  724. * is used for first-best-fit run allocation.
  725. */
  726. arena_avail_tree_t runs_avail;
  727. /*
  728. * bins is used to store rings of free regions of the following sizes,
  729. * assuming a 16-byte quantum, 4kB pagesize, and default MALLOC_OPTIONS.
  730. *
  731. * bins[i] | size |
  732. * --------+------+
  733. * 0 | 2 |
  734. * 1 | 4 |
  735. * 2 | 8 |
  736. * --------+------+
  737. * 3 | 16 |
  738. * 4 | 32 |
  739. * 5 | 48 |
  740. * 6 | 64 |
  741. * : :
  742. * : :
  743. * 33 | 496 |
  744. * 34 | 512 |
  745. * --------+------+
  746. * 35 | 1024 |
  747. * 36 | 2048 |
  748. * --------+------+
  749. */
  750. arena_bin_t bins[1]; /* Dynamically sized. */
  751. };
  752. /******************************************************************************/
  753. /*
  754. * Data.
  755. */
  756. #ifndef MOZ_MEMORY_NARENAS_DEFAULT_ONE
  757. /* Number of CPUs. */
  758. static unsigned ncpus;
  759. #endif
  760. #ifdef JEMALLOC_MUNMAP
  761. static const bool config_munmap = true;
  762. #else
  763. static const bool config_munmap = false;
  764. #endif
  765. #ifdef JEMALLOC_RECYCLE
  766. static const bool config_recycle = true;
  767. #else
  768. static const bool config_recycle = false;
  769. #endif
  770. /*
  771. * When MALLOC_STATIC_SIZES is defined most of the parameters
  772. * controlling the malloc behavior are defined as compile-time constants
  773. * for best performance and cannot be altered at runtime.
  774. */
  775. #if !defined(__ia64__) && !defined(__sparc__) && !defined(__mips__) && !defined(__aarch64__)
  776. #define MALLOC_STATIC_SIZES 1
  777. #endif
  778. #ifdef MALLOC_STATIC_SIZES
  779. /*
  780. * VM page size. It must divide the runtime CPU page size or the code
  781. * will abort.
  782. * Platform specific page size conditions copied from js/public/HeapAPI.h
  783. */
  784. #if (defined(SOLARIS) || defined(__FreeBSD__)) && \
  785. (defined(__sparc) || defined(__sparcv9) || defined(__ia64))
  786. #define pagesize_2pow ((size_t) 13)
  787. #elif defined(__powerpc64__)
  788. #define pagesize_2pow ((size_t) 16)
  789. #else
  790. #define pagesize_2pow ((size_t) 12)
  791. #endif
  792. #define pagesize ((size_t) 1 << pagesize_2pow)
  793. #define pagesize_mask (pagesize - 1)
  794. /* Various quantum-related settings. */
  795. #define QUANTUM_DEFAULT ((size_t) 1 << QUANTUM_2POW_MIN)
  796. static const size_t quantum = QUANTUM_DEFAULT;
  797. static const size_t quantum_mask = QUANTUM_DEFAULT - 1;
  798. /* Various bin-related settings. */
  799. static const size_t small_min = (QUANTUM_DEFAULT >> 1) + 1;
  800. static const size_t small_max = (size_t) SMALL_MAX_DEFAULT;
  801. /* Max size class for bins. */
  802. static const size_t bin_maxclass = pagesize >> 1;
  803. /* Number of (2^n)-spaced tiny bins. */
  804. static const unsigned ntbins = (unsigned)
  805. (QUANTUM_2POW_MIN - TINY_MIN_2POW);
  806. /* Number of quantum-spaced bins. */
  807. static const unsigned nqbins = (unsigned)
  808. (SMALL_MAX_DEFAULT >> QUANTUM_2POW_MIN);
  809. /* Number of (2^n)-spaced sub-page bins. */
  810. static const unsigned nsbins = (unsigned)
  811. (pagesize_2pow -
  812. SMALL_MAX_2POW_DEFAULT - 1);
  813. #else /* !MALLOC_STATIC_SIZES */
  814. /* VM page size. */
  815. static size_t pagesize;
  816. static size_t pagesize_mask;
  817. static size_t pagesize_2pow;
  818. /* Various bin-related settings. */
  819. static size_t bin_maxclass; /* Max size class for bins. */
  820. static unsigned ntbins; /* Number of (2^n)-spaced tiny bins. */
  821. static unsigned nqbins; /* Number of quantum-spaced bins. */
  822. static unsigned nsbins; /* Number of (2^n)-spaced sub-page bins. */
  823. static size_t small_min;
  824. static size_t small_max;
  825. /* Various quantum-related settings. */
  826. static size_t quantum;
  827. static size_t quantum_mask; /* (quantum - 1). */
  828. #endif
  829. /* Various chunk-related settings. */
  830. /*
  831. * Compute the header size such that it is large enough to contain the page map
  832. * and enough nodes for the worst case: one node per non-header page plus one
  833. * extra for situations where we briefly have one more node allocated than we
  834. * will need.
  835. */
  836. #define calculate_arena_header_size() \
  837. (sizeof(arena_chunk_t) + sizeof(arena_chunk_map_t) * (chunk_npages - 1))
  838. #define calculate_arena_header_pages() \
  839. ((calculate_arena_header_size() >> pagesize_2pow) + \
  840. ((calculate_arena_header_size() & pagesize_mask) ? 1 : 0))
  841. /* Max size class for arenas. */
  842. #define calculate_arena_maxclass() \
  843. (chunksize - (arena_chunk_header_npages << pagesize_2pow))
  844. /*
  845. * Recycle at most 128 chunks. With 1 MiB chunks, this means we retain at most
  846. * 6.25% of the process address space on a 32-bit OS for later use.
  847. */
  848. #define CHUNK_RECYCLE_LIMIT 128
  849. #ifdef MALLOC_STATIC_SIZES
  850. #define CHUNKSIZE_DEFAULT ((size_t) 1 << CHUNK_2POW_DEFAULT)
  851. static const size_t chunksize = CHUNKSIZE_DEFAULT;
  852. static const size_t chunksize_mask =CHUNKSIZE_DEFAULT - 1;
  853. static const size_t chunk_npages = CHUNKSIZE_DEFAULT >> pagesize_2pow;
  854. #define arena_chunk_header_npages calculate_arena_header_pages()
  855. #define arena_maxclass calculate_arena_maxclass()
  856. static const size_t recycle_limit = CHUNK_RECYCLE_LIMIT * CHUNKSIZE_DEFAULT;
  857. #else
  858. static size_t chunksize;
  859. static size_t chunksize_mask; /* (chunksize - 1). */
  860. static size_t chunk_npages;
  861. static size_t arena_chunk_header_npages;
  862. static size_t arena_maxclass; /* Max size class for arenas. */
  863. static size_t recycle_limit;
  864. #endif
  865. /* The current amount of recycled bytes, updated atomically. */
  866. static size_t recycled_size;
  867. /********/
  868. /*
  869. * Chunks.
  870. */
  871. static malloc_rtree_t *chunk_rtree;
  872. /* Protects chunk-related data structures. */
  873. static malloc_mutex_t chunks_mtx;
  874. /*
  875. * Trees of chunks that were previously allocated (trees differ only in node
  876. * ordering). These are used when allocating chunks, in an attempt to re-use
  877. * address space. Depending on function, different tree orderings are needed,
  878. * which is why there are two trees with the same contents.
  879. */
  880. static extent_tree_t chunks_szad_mmap;
  881. static extent_tree_t chunks_ad_mmap;
  882. /* Protects huge allocation-related data structures. */
  883. static malloc_mutex_t huge_mtx;
  884. /* Tree of chunks that are stand-alone huge allocations. */
  885. static extent_tree_t huge;
  886. #ifdef MALLOC_STATS
  887. /* Huge allocation statistics. */
  888. static uint64_t huge_nmalloc;
  889. static uint64_t huge_ndalloc;
  890. static size_t huge_allocated;
  891. static size_t huge_mapped;
  892. #endif
  893. /****************************/
  894. /*
  895. * base (internal allocation).
  896. */
  897. /*
  898. * Current pages that are being used for internal memory allocations. These
  899. * pages are carved up in cacheline-size quanta, so that there is no chance of
  900. * false cache line sharing.
  901. */
  902. static void *base_pages;
  903. static void *base_next_addr;
  904. #if defined(MALLOC_DECOMMIT) || defined(MALLOC_STATS)
  905. static void *base_next_decommitted;
  906. #endif
  907. static void *base_past_addr; /* Addr immediately past base_pages. */
  908. static extent_node_t *base_nodes;
  909. static malloc_mutex_t base_mtx;
  910. #ifdef MALLOC_STATS
  911. static size_t base_mapped;
  912. static size_t base_committed;
  913. #endif
  914. /********/
  915. /*
  916. * Arenas.
  917. */
  918. /*
  919. * Arenas that are used to service external requests. Not all elements of the
  920. * arenas array are necessarily used; arenas are created lazily as needed.
  921. */
  922. static arena_t **arenas;
  923. static unsigned narenas;
  924. #ifndef NO_TLS
  925. static unsigned next_arena;
  926. #endif
  927. static malloc_spinlock_t arenas_lock; /* Protects arenas initialization. */
  928. #ifndef NO_TLS
  929. /*
  930. * Map of pthread_self() --> arenas[???], used for selecting an arena to use
  931. * for allocations.
  932. */
  933. #ifndef MOZ_MEMORY_WINDOWS
  934. static __thread arena_t *arenas_map;
  935. #endif
  936. #endif
  937. /*******************************/
  938. /*
  939. * Runtime configuration options.
  940. */
  941. MOZ_JEMALLOC_API
  942. const char *_malloc_options = MOZ_MALLOC_OPTIONS;
  943. #ifndef MALLOC_PRODUCTION
  944. static bool opt_abort = true;
  945. #ifdef MALLOC_FILL
  946. static bool opt_junk = true;
  947. static bool opt_poison = true;
  948. static bool opt_zero = false;
  949. #endif
  950. #else
  951. static bool opt_abort = false;
  952. #ifdef MALLOC_FILL
  953. static const bool opt_junk = false;
  954. static const bool opt_poison = true;
  955. static const bool opt_zero = false;
  956. #endif
  957. #endif
  958. static size_t opt_dirty_max = DIRTY_MAX_DEFAULT;
  959. static bool opt_print_stats = false;
  960. #ifdef MALLOC_STATIC_SIZES
  961. #define opt_quantum_2pow QUANTUM_2POW_MIN
  962. #define opt_small_max_2pow SMALL_MAX_2POW_DEFAULT
  963. #define opt_chunk_2pow CHUNK_2POW_DEFAULT
  964. #else
  965. static size_t opt_quantum_2pow = QUANTUM_2POW_MIN;
  966. static size_t opt_small_max_2pow = SMALL_MAX_2POW_DEFAULT;
  967. static size_t opt_chunk_2pow = CHUNK_2POW_DEFAULT;
  968. #endif
  969. #ifdef MALLOC_SYSV
  970. static bool opt_sysv = false;
  971. #endif
  972. #ifdef MALLOC_XMALLOC
  973. static bool opt_xmalloc = false;
  974. #endif
  975. static int opt_narenas_lshift = 0;
  976. /******************************************************************************/
  977. /*
  978. * Begin function prototypes for non-inline static functions.
  979. */
  980. static char *umax2s(uintmax_t x, unsigned base, char *s);
  981. static bool malloc_mutex_init(malloc_mutex_t *mutex);
  982. static bool malloc_spin_init(malloc_spinlock_t *lock);
  983. static void wrtmessage(const char *p1, const char *p2, const char *p3,
  984. const char *p4);
  985. #ifdef MALLOC_STATS
  986. #ifdef MOZ_MEMORY_DARWIN
  987. /* Avoid namespace collision with OS X's malloc APIs. */
  988. #define malloc_printf moz_malloc_printf
  989. #endif
  990. static void malloc_printf(const char *format, ...);
  991. #endif
  992. static bool base_pages_alloc(size_t minsize);
  993. static void *base_alloc(size_t size);
  994. static void *base_calloc(size_t number, size_t size);
  995. static extent_node_t *base_node_alloc(void);
  996. static void base_node_dealloc(extent_node_t *node);
  997. #ifdef MALLOC_STATS
  998. static void stats_print(arena_t *arena);
  999. #endif
  1000. static void *pages_map(void *addr, size_t size);
  1001. static void pages_unmap(void *addr, size_t size);
  1002. static void *chunk_alloc_mmap(size_t size, size_t alignment);
  1003. static void *chunk_recycle(extent_tree_t *chunks_szad,
  1004. extent_tree_t *chunks_ad, size_t size,
  1005. size_t alignment, bool base, bool *zero);
  1006. static void *chunk_alloc(size_t size, size_t alignment, bool base, bool zero);
  1007. static void chunk_record(extent_tree_t *chunks_szad,
  1008. extent_tree_t *chunks_ad, void *chunk, size_t size);
  1009. static bool chunk_dalloc_mmap(void *chunk, size_t size);
  1010. static void chunk_dealloc(void *chunk, size_t size);
  1011. #ifndef NO_TLS
  1012. static arena_t *choose_arena_hard(void);
  1013. #endif
  1014. static void arena_run_split(arena_t *arena, arena_run_t *run, size_t size,
  1015. bool large, bool zero);
  1016. static void arena_chunk_init(arena_t *arena, arena_chunk_t *chunk);
  1017. static void arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk);
  1018. static arena_run_t *arena_run_alloc(arena_t *arena, arena_bin_t *bin,
  1019. size_t size, bool large, bool zero);
  1020. static void arena_purge(arena_t *arena, bool all);
  1021. static void arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty);
  1022. static void arena_run_trim_head(arena_t *arena, arena_chunk_t *chunk,
  1023. arena_run_t *run, size_t oldsize, size_t newsize);
  1024. static void arena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk,
  1025. arena_run_t *run, size_t oldsize, size_t newsize, bool dirty);
  1026. static arena_run_t *arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin);
  1027. static void *arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin);
  1028. static size_t arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size);
  1029. static void *arena_malloc_large(arena_t *arena, size_t size, bool zero);
  1030. static void *arena_palloc(arena_t *arena, size_t alignment, size_t size,
  1031. size_t alloc_size);
  1032. static size_t arena_salloc(const void *ptr);
  1033. static void arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk,
  1034. void *ptr);
  1035. static void arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk,
  1036. void *ptr, size_t size, size_t oldsize);
  1037. static bool arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk,
  1038. void *ptr, size_t size, size_t oldsize);
  1039. static bool arena_ralloc_large(void *ptr, size_t size, size_t oldsize);
  1040. static void *arena_ralloc(void *ptr, size_t size, size_t oldsize);
  1041. static bool arena_new(arena_t *arena);
  1042. static arena_t *arenas_extend(unsigned ind);
  1043. static void *huge_malloc(size_t size, bool zero);
  1044. static void *huge_palloc(size_t size, size_t alignment, bool zero);
  1045. static void *huge_ralloc(void *ptr, size_t size, size_t oldsize);
  1046. static void huge_dalloc(void *ptr);
  1047. static void malloc_print_stats(void);
  1048. #ifndef MOZ_MEMORY_WINDOWS
  1049. static
  1050. #endif
  1051. bool malloc_init_hard(void);
  1052. static void _malloc_prefork(void);
  1053. static void _malloc_postfork(void);
  1054. #ifdef MOZ_MEMORY_DARWIN
  1055. /*
  1056. * MALLOC_ZONE_T_NOTE
  1057. *
  1058. * On Darwin, we hook into the memory allocator using a malloc_zone_t struct.
  1059. * We must be very careful around this struct because of different behaviour on
  1060. * different versions of OSX.
  1061. *
  1062. * Each of OSX 10.5, 10.6 and 10.7 use different versions of the struct
  1063. * (with version numbers 3, 6 and 8 respectively). The binary we use on each of
  1064. * these platforms will not necessarily be built using the correct SDK [1].
  1065. * This means we need to statically know the correct struct size to use on all
  1066. * OSX releases, and have a fallback for unknown future versions. The struct
  1067. * sizes defined in osx_zone_types.h.
  1068. *
  1069. * For OSX 10.8 and later, we may expect the malloc_zone_t struct to change
  1070. * again, and need to dynamically account for this. By simply leaving
  1071. * malloc_zone_t alone, we don't quite deal with the problem, because there
  1072. * remain calls to jemalloc through the mozalloc interface. We check this
  1073. * dynamically on each allocation, using the CHECK_DARWIN macro and
  1074. * osx_use_jemalloc.
  1075. *
  1076. *
  1077. * [1] Mozilla is built as a universal binary on Mac, supporting i386 and
  1078. * x86_64. The i386 target is built using the 10.5 SDK, even if it runs on
  1079. * 10.6. The x86_64 target is built using the 10.6 SDK, even if it runs on
  1080. * 10.7 or later, or 10.5.
  1081. *
  1082. * FIXME:
  1083. * When later versions of OSX come out (10.8 and up), we need to check their
  1084. * malloc_zone_t versions. If they're greater than 8, we need a new version
  1085. * of malloc_zone_t adapted into osx_zone_types.h.
  1086. */
  1087. #ifndef MOZ_REPLACE_MALLOC
  1088. #include "osx_zone_types.h"
  1089. #define LEOPARD_MALLOC_ZONE_T_VERSION 3
  1090. #define SNOW_LEOPARD_MALLOC_ZONE_T_VERSION 6
  1091. #define LION_MALLOC_ZONE_T_VERSION 8
  1092. static bool osx_use_jemalloc = false;
  1093. static lion_malloc_zone l_szone;
  1094. static malloc_zone_t * szone = (malloc_zone_t*)(&l_szone);
  1095. static lion_malloc_introspection l_ozone_introspect;
  1096. static malloc_introspection_t * const ozone_introspect =
  1097. (malloc_introspection_t*)(&l_ozone_introspect);
  1098. static void szone2ozone(malloc_zone_t *zone, size_t size);
  1099. static size_t zone_version_size(int version);
  1100. #else
  1101. static const bool osx_use_jemalloc = true;
  1102. #endif
  1103. #endif
  1104. /*
  1105. * End function prototypes.
  1106. */
  1107. /******************************************************************************/
  1108. static inline size_t
  1109. load_acquire_z(size_t *p)
  1110. {
  1111. volatile size_t result = *p;
  1112. # ifdef MOZ_MEMORY_WINDOWS
  1113. /*
  1114. * We use InterlockedExchange with a dummy value to insert a memory
  1115. * barrier. This has been confirmed to generate the right instruction
  1116. * and is also used by MinGW.
  1117. */
  1118. volatile long dummy = 0;
  1119. InterlockedExchange(&dummy, 1);
  1120. # else
  1121. __sync_synchronize();
  1122. # endif
  1123. return result;
  1124. }
  1125. /*
  1126. * umax2s() provides minimal integer printing functionality, which is
  1127. * especially useful for situations where allocation in vsnprintf() calls would
  1128. * potentially cause deadlock.
  1129. */
  1130. #define UMAX2S_BUFSIZE 65
  1131. char *
  1132. umax2s(uintmax_t x, unsigned base, char *s)
  1133. {
  1134. unsigned i;
  1135. i = UMAX2S_BUFSIZE - 1;
  1136. s[i] = '\0';
  1137. switch (base) {
  1138. case 10:
  1139. do {
  1140. i--;
  1141. s[i] = "0123456789"[x % 10];
  1142. x /= 10;
  1143. } while (x > 0);
  1144. break;
  1145. case 16:
  1146. do {
  1147. i--;
  1148. s[i] = "0123456789abcdef"[x & 0xf];
  1149. x >>= 4;
  1150. } while (x > 0);
  1151. break;
  1152. default:
  1153. do {
  1154. i--;
  1155. s[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[x % base];
  1156. x /= base;
  1157. } while (x > 0);
  1158. }
  1159. return (&s[i]);
  1160. }
  1161. static void
  1162. wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4)
  1163. {
  1164. #if !defined(MOZ_MEMORY_WINDOWS)
  1165. #define _write write
  1166. #endif
  1167. // Pretend to check _write() errors to suppress gcc warnings about
  1168. // warn_unused_result annotations in some versions of glibc headers.
  1169. if (_write(STDERR_FILENO, p1, (unsigned int) strlen(p1)) < 0)
  1170. return;
  1171. if (_write(STDERR_FILENO, p2, (unsigned int) strlen(p2)) < 0)
  1172. return;
  1173. if (_write(STDERR_FILENO, p3, (unsigned int) strlen(p3)) < 0)
  1174. return;
  1175. if (_write(STDERR_FILENO, p4, (unsigned int) strlen(p4)) < 0)
  1176. return;
  1177. }
  1178. MOZ_JEMALLOC_API
  1179. void (*_malloc_message)(const char *p1, const char *p2, const char *p3,
  1180. const char *p4) = wrtmessage;
  1181. #include "mozilla/Assertions.h"
  1182. #include "mozilla/Attributes.h"
  1183. #include "mozilla/TaggedAnonymousMemory.h"
  1184. // Note: MozTaggedAnonymousMmap() could call an LD_PRELOADed mmap
  1185. // instead of the one defined here; use only MozTagAnonymousMemory().
  1186. #ifdef MALLOC_DEBUG
  1187. # define assert(e) MOZ_ASSERT(e)
  1188. #else
  1189. # define assert(e)
  1190. #endif
  1191. #if defined(MOZ_JEMALLOC_HARD_ASSERTS)
  1192. # define RELEASE_ASSERT(assertion) do { \
  1193. if (!(assertion)) { \
  1194. MOZ_CRASH_UNSAFE_OOL(#assertion); \
  1195. } \
  1196. } while (0)
  1197. #else
  1198. # define RELEASE_ASSERT(assertion) assert(assertion)
  1199. #endif
  1200. /******************************************************************************/
  1201. /*
  1202. * Begin mutex. We can't use normal pthread mutexes in all places, because
  1203. * they require malloc()ed memory, which causes bootstrapping issues in some
  1204. * cases.
  1205. */
  1206. #ifdef __FreeBSD__
  1207. // If true, memory calls must be diverted to the bootstrap allocator
  1208. static __thread bool in_mutex_init = false;
  1209. #endif
  1210. static bool
  1211. malloc_mutex_init(malloc_mutex_t *mutex)
  1212. {
  1213. #if defined(MOZ_MEMORY_WINDOWS)
  1214. InitializeSRWLock(mutex);
  1215. #elif defined(MOZ_MEMORY_DARWIN)
  1216. mutex->lock = OS_SPINLOCK_INIT;
  1217. #elif defined(MOZ_MEMORY_LINUX)
  1218. pthread_mutexattr_t attr;
  1219. if (pthread_mutexattr_init(&attr) != 0)
  1220. return (true);
  1221. pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
  1222. if (pthread_mutex_init(mutex, &attr) != 0) {
  1223. pthread_mutexattr_destroy(&attr);
  1224. return (true);
  1225. }
  1226. pthread_mutexattr_destroy(&attr);
  1227. #elif defined(__FreeBSD__)
  1228. in_mutex_init = true;
  1229. *mutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP;
  1230. // Make sure necessary mutex memory is allocated right now, with
  1231. // 'in_mutex_init' set to true (allocations to be diverted to the
  1232. // bootstrap allocator). Also force multi-thread initialization in
  1233. // libthr (checked and performed in 'pthread_mutex_lock').
  1234. pthread_mutex_lock(mutex);
  1235. pthread_mutex_unlock(mutex);
  1236. in_mutex_init = false;
  1237. #else
  1238. if (pthread_mutex_init(mutex, NULL) != 0)
  1239. return (true);
  1240. #endif
  1241. return (false);
  1242. }
  1243. static inline void
  1244. malloc_mutex_lock(malloc_mutex_t *mutex)
  1245. {
  1246. #if defined(MOZ_MEMORY_WINDOWS)
  1247. AcquireSRWLockExclusive(mutex);
  1248. #elif defined(MOZ_MEMORY_DARWIN)
  1249. OSSpinLockLock(&mutex->lock);
  1250. #else
  1251. pthread_mutex_lock(mutex);
  1252. #endif
  1253. }
  1254. static inline void
  1255. malloc_mutex_unlock(malloc_mutex_t *mutex)
  1256. {
  1257. #if defined(MOZ_MEMORY_WINDOWS)
  1258. ReleaseSRWLockExclusive(mutex);
  1259. #elif defined(MOZ_MEMORY_DARWIN)
  1260. OSSpinLockUnlock(&mutex->lock);
  1261. #else
  1262. pthread_mutex_unlock(mutex);
  1263. #endif
  1264. }
  1265. #if (defined(__GNUC__))
  1266. __attribute__((unused))
  1267. # endif
  1268. static bool
  1269. malloc_spin_init(malloc_spinlock_t *lock)
  1270. {
  1271. #if defined(MOZ_MEMORY_WINDOWS)
  1272. InitializeSRWLock(lock);
  1273. #elif defined(MOZ_MEMORY_DARWIN)
  1274. lock->lock = OS_SPINLOCK_INIT;
  1275. #elif defined(MOZ_MEMORY_LINUX)
  1276. pthread_mutexattr_t attr;
  1277. if (pthread_mutexattr_init(&attr) != 0)
  1278. return (true);
  1279. pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
  1280. if (pthread_mutex_init(lock, &attr) != 0) {
  1281. pthread_mutexattr_destroy(&attr);
  1282. return (true);
  1283. }
  1284. pthread_mutexattr_destroy(&attr);
  1285. #elif defined(__FreeBSD__)
  1286. malloc_lock_init(lock);
  1287. #else
  1288. if (pthread_mutex_init(lock, NULL) != 0)
  1289. return (true);
  1290. #endif
  1291. return (false);
  1292. }
  1293. static inline void
  1294. malloc_spin_lock(malloc_spinlock_t *lock)
  1295. {
  1296. #if defined(MOZ_MEMORY_WINDOWS)
  1297. AcquireSRWLockExclusive(lock);
  1298. #elif defined(MOZ_MEMORY_DARWIN)
  1299. OSSpinLockLock(&lock->lock);
  1300. #else
  1301. pthread_mutex_lock(lock);
  1302. #endif
  1303. }
  1304. static inline void
  1305. malloc_spin_unlock(malloc_spinlock_t *lock)
  1306. {
  1307. #if defined(MOZ_MEMORY_WINDOWS)
  1308. ReleaseSRWLockExclusive(lock);
  1309. #elif defined(MOZ_MEMORY_DARWIN)
  1310. OSSpinLockUnlock(&lock->lock);
  1311. #else
  1312. pthread_mutex_unlock(lock);
  1313. #endif
  1314. }
  1315. /*
  1316. * End mutex.
  1317. */
  1318. /******************************************************************************/
  1319. /*
  1320. * Begin spin lock. Spin locks here are actually adaptive mutexes that block
  1321. * after a period of spinning, because unbounded spinning would allow for
  1322. * priority inversion.
  1323. */
  1324. #if !defined(MOZ_MEMORY_DARWIN)
  1325. # define malloc_spin_init malloc_mutex_init
  1326. # define malloc_spin_lock malloc_mutex_lock
  1327. # define malloc_spin_unlock malloc_mutex_unlock
  1328. #endif
  1329. /*
  1330. * End spin lock.
  1331. */
  1332. /******************************************************************************/
  1333. /*
  1334. * Begin Utility functions/macros.
  1335. */
  1336. /* Return the chunk address for allocation address a. */
  1337. #define CHUNK_ADDR2BASE(a) \
  1338. ((void *)((uintptr_t)(a) & ~chunksize_mask))
  1339. /* Return the chunk offset of address a. */
  1340. #define CHUNK_ADDR2OFFSET(a) \
  1341. ((size_t)((uintptr_t)(a) & chunksize_mask))
  1342. /* Return the smallest chunk multiple that is >= s. */
  1343. #define CHUNK_CEILING(s) \
  1344. (((s) + chunksize_mask) & ~chunksize_mask)
  1345. /* Return the smallest cacheline multiple that is >= s. */
  1346. #define CACHELINE_CEILING(s) \
  1347. (((s) + (CACHELINE - 1)) & ~(CACHELINE - 1))
  1348. /* Return the smallest quantum multiple that is >= a. */
  1349. #define QUANTUM_CEILING(a) \
  1350. (((a) + quantum_mask) & ~quantum_mask)
  1351. /* Return the smallest pagesize multiple that is >= s. */
  1352. #define PAGE_CEILING(s) \
  1353. (((s) + pagesize_mask) & ~pagesize_mask)
  1354. /* Compute the smallest power of 2 that is >= x. */
  1355. static inline size_t
  1356. pow2_ceil(size_t x)
  1357. {
  1358. x--;
  1359. x |= x >> 1;
  1360. x |= x >> 2;
  1361. x |= x >> 4;
  1362. x |= x >> 8;
  1363. x |= x >> 16;
  1364. #if (SIZEOF_PTR == 8)
  1365. x |= x >> 32;
  1366. #endif
  1367. x++;
  1368. return (x);
  1369. }
  1370. static inline const char *
  1371. _getprogname(void)
  1372. {
  1373. return ("<jemalloc>");
  1374. }
  1375. #ifdef MALLOC_STATS
  1376. /*
  1377. * Print to stderr in such a way as to (hopefully) avoid memory allocation.
  1378. */
  1379. static void
  1380. malloc_printf(const char *format, ...)
  1381. {
  1382. char buf[4096];
  1383. va_list ap;
  1384. va_start(ap, format);
  1385. vsnprintf(buf, sizeof(buf), format, ap);
  1386. va_end(ap);
  1387. _malloc_message(buf, "", "", "");
  1388. }
  1389. #endif
  1390. /******************************************************************************/
  1391. static inline void
  1392. pages_decommit(void *addr, size_t size)
  1393. {
  1394. #ifdef MOZ_MEMORY_WINDOWS
  1395. /*
  1396. * The region starting at addr may have been allocated in multiple calls
  1397. * to VirtualAlloc and recycled, so decommitting the entire region in one
  1398. * go may not be valid. However, since we allocate at least a chunk at a
  1399. * time, we may touch any region in chunksized increments.
  1400. */
  1401. size_t pages_size = min(size, chunksize -
  1402. CHUNK_ADDR2OFFSET((uintptr_t)addr));
  1403. while (size > 0) {
  1404. if (!VirtualFree(addr, pages_size, MEM_DECOMMIT))
  1405. abort();
  1406. addr = (void *)((uintptr_t)addr + pages_size);
  1407. size -= pages_size;
  1408. pages_size = min(size, chunksize);
  1409. }
  1410. #else
  1411. if (mmap(addr, size, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1,
  1412. 0) == MAP_FAILED)
  1413. abort();
  1414. MozTagAnonymousMemory(addr, size, "jemalloc-decommitted");
  1415. #endif
  1416. }
  1417. static inline void
  1418. pages_commit(void *addr, size_t size)
  1419. {
  1420. # ifdef MOZ_MEMORY_WINDOWS
  1421. /*
  1422. * The region starting at addr may have been allocated in multiple calls
  1423. * to VirtualAlloc and recycled, so committing the entire region in one
  1424. * go may not be valid. However, since we allocate at least a chunk at a
  1425. * time, we may touch any region in chunksized increments.
  1426. */
  1427. size_t pages_size = min(size, chunksize -
  1428. CHUNK_ADDR2OFFSET((uintptr_t)addr));
  1429. while (size > 0) {
  1430. if (!VirtualAlloc(addr, pages_size, MEM_COMMIT, PAGE_READWRITE))
  1431. abort();
  1432. addr = (void *)((uintptr_t)addr + pages_size);
  1433. size -= pages_size;
  1434. pages_size = min(size, chunksize);
  1435. }
  1436. # else
  1437. if (mmap(addr, size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE |
  1438. MAP_ANON, -1, 0) == MAP_FAILED)
  1439. abort();
  1440. MozTagAnonymousMemory(addr, size, "jemalloc");
  1441. # endif
  1442. }
  1443. static bool
  1444. base_pages_alloc(size_t minsize)
  1445. {
  1446. size_t csize;
  1447. #if defined(MALLOC_DECOMMIT) || defined(MALLOC_STATS)
  1448. size_t pminsize;
  1449. #endif
  1450. assert(minsize != 0);
  1451. csize = CHUNK_CEILING(minsize);
  1452. base_pages = chunk_alloc(csize, chunksize, true, false);
  1453. if (base_pages == NULL)
  1454. return (true);
  1455. base_next_addr = base_pages;
  1456. base_past_addr = (void *)((uintptr_t)base_pages + csize);
  1457. #if defined(MALLOC_DECOMMIT) || defined(MALLOC_STATS)
  1458. /*
  1459. * Leave enough pages for minsize committed, since otherwise they would
  1460. * have to be immediately recommitted.
  1461. */
  1462. pminsize = PAGE_CEILING(minsize);
  1463. base_next_decommitted = (void *)((uintptr_t)base_pages + pminsize);
  1464. # if defined(MALLOC_DECOMMIT)
  1465. if (pminsize < csize)
  1466. pages_decommit(base_next_decommitted, csize - pminsize);
  1467. # endif
  1468. # ifdef MALLOC_STATS
  1469. base_mapped += csize;
  1470. base_committed += pminsize;
  1471. # endif
  1472. #endif
  1473. return (false);
  1474. }
  1475. static void *
  1476. base_alloc(size_t size)
  1477. {
  1478. void *ret;
  1479. size_t csize;
  1480. /* Round size up to nearest multiple of the cacheline size. */
  1481. csize = CACHELINE_CEILING(size);
  1482. malloc_mutex_lock(&base_mtx);
  1483. /* Make sure there's enough space for the allocation. */
  1484. if ((uintptr_t)base_next_addr + csize > (uintptr_t)base_past_addr) {
  1485. if (base_pages_alloc(csize)) {
  1486. malloc_mutex_unlock(&base_mtx);
  1487. return (NULL);
  1488. }
  1489. }
  1490. /* Allocate. */
  1491. ret = base_next_addr;
  1492. base_next_addr = (void *)((uintptr_t)base_next_addr + csize);
  1493. #if defined(MALLOC_DECOMMIT) || defined(MALLOC_STATS)
  1494. /* Make sure enough pages are committed for the new allocation. */
  1495. if ((uintptr_t)base_next_addr > (uintptr_t)base_next_decommitted) {
  1496. void *pbase_next_addr =
  1497. (void *)(PAGE_CEILING((uintptr_t)base_next_addr));
  1498. # ifdef MALLOC_DECOMMIT
  1499. pages_commit(base_next_decommitted, (uintptr_t)pbase_next_addr -
  1500. (uintptr_t)base_next_decommitted);
  1501. # endif
  1502. base_next_decommitted = pbase_next_addr;
  1503. # ifdef MALLOC_STATS
  1504. base_committed += (uintptr_t)pbase_next_addr -
  1505. (uintptr_t)base_next_decommitted;
  1506. # endif
  1507. }
  1508. #endif
  1509. malloc_mutex_unlock(&base_mtx);
  1510. return (ret);
  1511. }
  1512. static void *
  1513. base_calloc(size_t number, size_t size)
  1514. {
  1515. void *ret;
  1516. ret = base_alloc(number * size);
  1517. memset(ret, 0, number * size);
  1518. return (ret);
  1519. }
  1520. static extent_node_t *
  1521. base_node_alloc(void)
  1522. {
  1523. extent_node_t *ret;
  1524. malloc_mutex_lock(&base_mtx);
  1525. if (base_nodes != NULL) {
  1526. ret = base_nodes;
  1527. base_nodes = *(extent_node_t **)ret;
  1528. malloc_mutex_unlock(&base_mtx);
  1529. } else {
  1530. malloc_mutex_unlock(&base_mtx);
  1531. ret = (extent_node_t *)base_alloc(sizeof(extent_node_t));
  1532. }
  1533. return (ret);
  1534. }
  1535. static void
  1536. base_node_dealloc(extent_node_t *node)
  1537. {
  1538. malloc_mutex_lock(&base_mtx);
  1539. *(extent_node_t **)node = base_nodes;
  1540. base_nodes = node;
  1541. malloc_mutex_unlock(&base_mtx);
  1542. }
  1543. /******************************************************************************/
  1544. #ifdef MALLOC_STATS
  1545. static void
  1546. stats_print(arena_t *arena)
  1547. {
  1548. unsigned i, gap_start;
  1549. #ifdef MOZ_MEMORY_WINDOWS
  1550. malloc_printf("dirty: %Iu page%s dirty, %I64u sweep%s,"
  1551. " %I64u madvise%s, %I64u page%s purged\n",
  1552. arena->ndirty, arena->ndirty == 1 ? "" : "s",
  1553. arena->stats.npurge, arena->stats.npurge == 1 ? "" : "s",
  1554. arena->stats.nmadvise, arena->stats.nmadvise == 1 ? "" : "s",
  1555. arena->stats.purged, arena->stats.purged == 1 ? "" : "s");
  1556. # ifdef MALLOC_DECOMMIT
  1557. malloc_printf("decommit: %I64u decommit%s, %I64u commit%s,"
  1558. " %I64u page%s decommitted\n",
  1559. arena->stats.ndecommit, (arena->stats.ndecommit == 1) ? "" : "s",
  1560. arena->stats.ncommit, (arena->stats.ncommit == 1) ? "" : "s",
  1561. arena->stats.decommitted,
  1562. (arena->stats.decommitted == 1) ? "" : "s");
  1563. # endif
  1564. malloc_printf(" allocated nmalloc ndalloc\n");
  1565. malloc_printf("small: %12Iu %12I64u %12I64u\n",
  1566. arena->stats.allocated_small, arena->stats.nmalloc_small,
  1567. arena->stats.ndalloc_small);
  1568. malloc_printf("large: %12Iu %12I64u %12I64u\n",
  1569. arena->stats.allocated_large, arena->stats.nmalloc_large,
  1570. arena->stats.ndalloc_large);
  1571. malloc_printf("total: %12Iu %12I64u %12I64u\n",
  1572. arena->stats.allocated_small + arena->stats.allocated_large,
  1573. arena->stats.nmalloc_small + arena->stats.nmalloc_large,
  1574. arena->stats.ndalloc_small + arena->stats.ndalloc_large);
  1575. malloc_printf("mapped: %12Iu\n", arena->stats.mapped);
  1576. #else
  1577. malloc_printf("dirty: %zu page%s dirty, %llu sweep%s,"
  1578. " %llu madvise%s, %llu page%s purged\n",
  1579. arena->ndirty, arena->ndirty == 1 ? "" : "s",
  1580. arena->stats.npurge, arena->stats.npurge == 1 ? "" : "s",
  1581. arena->stats.nmadvise, arena->stats.nmadvise == 1 ? "" : "s",
  1582. arena->stats.purged, arena->stats.purged == 1 ? "" : "s");
  1583. # ifdef MALLOC_DECOMMIT
  1584. malloc_printf("decommit: %llu decommit%s, %llu commit%s,"
  1585. " %llu page%s decommitted\n",
  1586. arena->stats.ndecommit, (arena->stats.ndecommit == 1) ? "" : "s",
  1587. arena->stats.ncommit, (arena->stats.ncommit == 1) ? "" : "s",
  1588. arena->stats.decommitted,
  1589. (arena->stats.decommitted == 1) ? "" : "s");
  1590. # endif
  1591. malloc_printf(" allocated nmalloc ndalloc\n");
  1592. malloc_printf("small: %12zu %12llu %12llu\n",
  1593. arena->stats.allocated_small, arena->stats.nmalloc_small,
  1594. arena->stats.ndalloc_small);
  1595. malloc_printf("large: %12zu %12llu %12llu\n",
  1596. arena->stats.allocated_large, arena->stats.nmalloc_large,
  1597. arena->stats.ndalloc_large);
  1598. malloc_printf("total: %12zu %12llu %12llu\n",
  1599. arena->stats.allocated_small + arena->stats.allocated_large,
  1600. arena->stats.nmalloc_small + arena->stats.nmalloc_large,
  1601. arena->stats.ndalloc_small + arena->stats.ndalloc_large);
  1602. malloc_printf("mapped: %12zu\n", arena->stats.mapped);
  1603. #endif
  1604. malloc_printf("bins: bin size regs pgs requests newruns"
  1605. " reruns maxruns curruns\n");
  1606. for (i = 0, gap_start = UINT_MAX; i < ntbins + nqbins + nsbins; i++) {
  1607. if (arena->bins[i].stats.nrequests == 0) {
  1608. if (gap_start == UINT_MAX)
  1609. gap_start = i;
  1610. } else {
  1611. if (gap_start != UINT_MAX) {
  1612. if (i > gap_start + 1) {
  1613. /* Gap of more than one size class. */
  1614. malloc_printf("[%u..%u]\n",
  1615. gap_start, i - 1);
  1616. } else {
  1617. /* Gap of one size class. */
  1618. malloc_printf("[%u]\n", gap_start);
  1619. }
  1620. gap_start = UINT_MAX;
  1621. }
  1622. malloc_printf(
  1623. #if defined(MOZ_MEMORY_WINDOWS)
  1624. "%13u %1s %4u %4u %3u %9I64u %9I64u"
  1625. " %9I64u %7u %7u\n",
  1626. #else
  1627. "%13u %1s %4u %4u %3u %9llu %9llu"
  1628. " %9llu %7lu %7lu\n",
  1629. #endif
  1630. i,
  1631. i < ntbins ? "T" : i < ntbins + nqbins ? "Q" : "S",
  1632. arena->bins[i].reg_size,
  1633. arena->bins[i].nregs,
  1634. arena->bins[i].run_size >> pagesize_2pow,
  1635. arena->bins[i].stats.nrequests,
  1636. arena->bins[i].stats.nruns,
  1637. arena->bins[i].stats.reruns,
  1638. arena->bins[i].stats.highruns,
  1639. arena->bins[i].stats.curruns);
  1640. }
  1641. }
  1642. if (gap_start != UINT_MAX) {
  1643. if (i > gap_start + 1) {
  1644. /* Gap of more than one size class. */
  1645. malloc_printf("[%u..%u]\n", gap_start, i - 1);
  1646. } else {
  1647. /* Gap of one size class. */
  1648. malloc_printf("[%u]\n", gap_start);
  1649. }
  1650. }
  1651. }
  1652. #endif
  1653. /*
  1654. * End Utility functions/macros.
  1655. */
  1656. /******************************************************************************/
  1657. /*
  1658. * Begin extent tree code.
  1659. */
  1660. static inline int
  1661. extent_szad_comp(extent_node_t *a, extent_node_t *b)
  1662. {
  1663. int ret;
  1664. size_t a_size = a->size;
  1665. size_t b_size = b->size;
  1666. ret = (a_size > b_size) - (a_size < b_size);
  1667. if (ret == 0) {
  1668. uintptr_t a_addr = (uintptr_t)a->addr;
  1669. uintptr_t b_addr = (uintptr_t)b->addr;
  1670. ret = (a_addr > b_addr) - (a_addr < b_addr);
  1671. }
  1672. return (ret);
  1673. }
  1674. /* Wrap red-black tree macros in functions. */
  1675. rb_wrap(static, extent_tree_szad_, extent_tree_t, extent_node_t,
  1676. link_szad, extent_szad_comp)
  1677. static inline int
  1678. extent_ad_comp(extent_node_t *a, extent_node_t *b)
  1679. {
  1680. uintptr_t a_addr = (uintptr_t)a->addr;
  1681. uintptr_t b_addr = (uintptr_t)b->addr;
  1682. return ((a_addr > b_addr) - (a_addr < b_addr));
  1683. }
  1684. /* Wrap red-black tree macros in functions. */
  1685. rb_wrap(static, extent_tree_ad_, extent_tree_t, extent_node_t, link_ad,
  1686. extent_ad_comp)
  1687. /*
  1688. * End extent tree code.
  1689. */
  1690. /******************************************************************************/
  1691. /*
  1692. * Begin chunk management functions.
  1693. */
  1694. #ifdef MOZ_MEMORY_WINDOWS
  1695. static void *
  1696. pages_map(void *addr, size_t size)
  1697. {
  1698. void *ret = NULL;
  1699. ret = VirtualAlloc(addr, size, MEM_COMMIT | MEM_RESERVE,
  1700. PAGE_READWRITE);
  1701. return (ret);
  1702. }
  1703. static void
  1704. pages_unmap(void *addr, size_t size)
  1705. {
  1706. if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
  1707. _malloc_message(_getprogname(),
  1708. ": (malloc) Error in VirtualFree()\n", "", "");
  1709. if (opt_abort)
  1710. abort();
  1711. }
  1712. }
  1713. #else
  1714. static void *
  1715. pages_map(void *addr, size_t size)
  1716. {
  1717. void *ret;
  1718. #if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__linux__)) || (defined(__sun) && defined(__x86_64__))
  1719. /*
  1720. * The JS engine assumes that all allocated pointers have their high 17 bits clear,
  1721. * which ia64's mmap doesn't support directly. However, we can emulate it by passing
  1722. * mmap an "addr" parameter with those bits clear. The mmap will return that address,
  1723. * or the nearest available memory above that address, providing a near-guarantee
  1724. * that those bits are clear. If they are not, we return NULL below to indicate
  1725. * out-of-memory.
  1726. *
  1727. * The addr is chosen as 0x0000070000000000, which still allows about 120TB of virtual
  1728. * address space.
  1729. *
  1730. * See Bug 589735 for more information.
  1731. */
  1732. bool check_placement = true;
  1733. if (addr == NULL) {
  1734. addr = (void*)0x0000070000000000;
  1735. check_placement = false;
  1736. }
  1737. #endif
  1738. #if defined(__sparc__) && defined(__arch64__) && defined(__linux__) || (defined(__sun) && defined(__x86_64__))
  1739. const uintptr_t start = 0x0000070000000000ULL;
  1740. const uintptr_t end = 0x0000800000000000ULL;
  1741. /* Copied from js/src/gc/Memory.cpp and adapted for this source */
  1742. uintptr_t hint;
  1743. void* region = MAP_FAILED;
  1744. for (hint = start; region == MAP_FAILED && hint + size <= end; hint += chunksize) {
  1745. region = mmap((void*)hint, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
  1746. if (region != MAP_FAILED) {
  1747. if (((size_t) region + (size - 1)) & 0xffff800000000000) {
  1748. if (munmap(region, size)) {
  1749. MOZ_ASSERT(errno == ENOMEM);
  1750. }
  1751. region = MAP_FAILED;
  1752. }
  1753. }
  1754. }
  1755. ret = region;
  1756. #else
  1757. /*
  1758. * We don't use MAP_FIXED here, because it can cause the *replacement*
  1759. * of existing mappings, and we only want to create new mappings.
  1760. */
  1761. ret = mmap(addr, size, PROT_READ | PROT_WRITE,
  1762. MAP_PRIVATE | MAP_ANON, -1, 0);
  1763. assert(ret != NULL);
  1764. #endif
  1765. if (ret == MAP_FAILED) {
  1766. ret = NULL;
  1767. }
  1768. #if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__linux__)) || (defined(__sun) && defined(__x86_64__))
  1769. /*
  1770. * If the allocated memory doesn't have its upper 17 bits clear, consider it
  1771. * as out of memory.
  1772. */
  1773. else if ((long long)ret & 0xffff800000000000) {
  1774. munmap(ret, size);
  1775. ret = NULL;
  1776. }
  1777. /* If the caller requested a specific memory location, verify that's what mmap returned. */
  1778. else if (check_placement && ret != addr) {
  1779. #else
  1780. else if (addr != NULL && ret != addr) {
  1781. #endif
  1782. /*
  1783. * We succeeded in mapping memory, but not in the right place.
  1784. */
  1785. if (munmap(ret, size) == -1) {
  1786. char buf[STRERROR_BUF];
  1787. if (strerror_r(errno, buf, sizeof(buf)) == 0) {
  1788. _malloc_message(_getprogname(),
  1789. ": (malloc) Error in munmap(): ", buf, "\n");
  1790. }
  1791. if (opt_abort)
  1792. abort();
  1793. }
  1794. ret = NULL;
  1795. }
  1796. if (ret != NULL) {
  1797. MozTagAnonymousMemory(ret, size, "jemalloc");
  1798. }
  1799. #if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__linux__)) || (defined(__sun) && defined(__x86_64__))
  1800. assert(ret == NULL || (!check_placement && ret != NULL)
  1801. || (check_placement && ret == addr));
  1802. #else
  1803. assert(ret == NULL || (addr == NULL && ret != addr)
  1804. || (addr != NULL && ret == addr));
  1805. #endif
  1806. return (ret);
  1807. }
  1808. static void
  1809. pages_unmap(void *addr, size_t size)
  1810. {
  1811. if (munmap(addr, size) == -1) {
  1812. char buf[STRERROR_BUF];
  1813. if (strerror_r(errno, buf, sizeof(buf)) == 0) {
  1814. _malloc_message(_getprogname(),
  1815. ": (malloc) Error in munmap(): ", buf, "\n");
  1816. }
  1817. if (opt_abort)
  1818. abort();
  1819. }
  1820. }
  1821. #endif
  1822. #ifdef MOZ_MEMORY_DARWIN
  1823. #define VM_COPY_MIN (pagesize << 5)
  1824. static inline void
  1825. pages_copy(void *dest, const void *src, size_t n)
  1826. {
  1827. assert((void *)((uintptr_t)dest & ~pagesize_mask) == dest);
  1828. assert(n >= VM_COPY_MIN);
  1829. assert((void *)((uintptr_t)src & ~pagesize_mask) == src);
  1830. vm_copy(mach_task_self(), (vm_address_t)src, (vm_size_t)n,
  1831. (vm_address_t)dest);
  1832. }
  1833. #endif
  1834. static inline malloc_rtree_t *
  1835. malloc_rtree_new(unsigned bits)
  1836. {
  1837. malloc_rtree_t *ret;
  1838. unsigned bits_per_level, height, i;
  1839. bits_per_level = ffs(pow2_ceil((MALLOC_RTREE_NODESIZE /
  1840. sizeof(void *)))) - 1;
  1841. height = bits / bits_per_level;
  1842. if (height * bits_per_level != bits)
  1843. height++;
  1844. RELEASE_ASSERT(height * bits_per_level >= bits);
  1845. ret = (malloc_rtree_t*)base_calloc(1, sizeof(malloc_rtree_t) +
  1846. (sizeof(unsigned) * (height - 1)));
  1847. if (ret == NULL)
  1848. return (NULL);
  1849. malloc_spin_init(&ret->lock);
  1850. ret->height = height;
  1851. if (bits_per_level * height > bits)
  1852. ret->level2bits[0] = bits % bits_per_level;
  1853. else
  1854. ret->level2bits[0] = bits_per_level;
  1855. for (i = 1; i < height; i++)
  1856. ret->level2bits[i] = bits_per_level;
  1857. ret->root = (void**)base_calloc(1, sizeof(void *) << ret->level2bits[0]);
  1858. if (ret->root == NULL) {
  1859. /*
  1860. * We leak the rtree here, since there's no generic base
  1861. * deallocation.
  1862. */
  1863. return (NULL);
  1864. }
  1865. return (ret);
  1866. }
  1867. #define MALLOC_RTREE_GET_GENERATE(f) \
  1868. /* The least significant bits of the key are ignored. */ \
  1869. static inline void * \
  1870. f(malloc_rtree_t *rtree, uintptr_t key) \
  1871. { \
  1872. void *ret; \
  1873. uintptr_t subkey; \
  1874. unsigned i, lshift, height, bits; \
  1875. void **node, **child; \
  1876. \
  1877. MALLOC_RTREE_LOCK(&rtree->lock); \
  1878. for (i = lshift = 0, height = rtree->height, node = rtree->root;\
  1879. i < height - 1; \
  1880. i++, lshift += bits, node = child) { \
  1881. bits = rtree->level2bits[i]; \
  1882. subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits); \
  1883. child = (void**)node[subkey]; \
  1884. if (child == NULL) { \
  1885. MALLOC_RTREE_UNLOCK(&rtree->lock); \
  1886. return (NULL); \
  1887. } \
  1888. } \
  1889. \
  1890. /* \
  1891. * node is a leaf, so it contains values rather than node \
  1892. * pointers. \
  1893. */ \
  1894. bits = rtree->level2bits[i]; \
  1895. subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits); \
  1896. ret = node[subkey]; \
  1897. MALLOC_RTREE_UNLOCK(&rtree->lock); \
  1898. \
  1899. MALLOC_RTREE_GET_VALIDATE \
  1900. return (ret); \
  1901. }
  1902. #ifdef MALLOC_DEBUG
  1903. # define MALLOC_RTREE_LOCK(l) malloc_spin_lock(l)
  1904. # define MALLOC_RTREE_UNLOCK(l) malloc_spin_unlock(l)
  1905. # define MALLOC_RTREE_GET_VALIDATE
  1906. MALLOC_RTREE_GET_GENERATE(malloc_rtree_get_locked)
  1907. # undef MALLOC_RTREE_LOCK
  1908. # undef MALLOC_RTREE_UNLOCK
  1909. # undef MALLOC_RTREE_GET_VALIDATE
  1910. #endif
  1911. #define MALLOC_RTREE_LOCK(l)
  1912. #define MALLOC_RTREE_UNLOCK(l)
  1913. #ifdef MALLOC_DEBUG
  1914. /*
  1915. * Suppose that it were possible for a jemalloc-allocated chunk to be
  1916. * munmap()ped, followed by a different allocator in another thread re-using
  1917. * overlapping virtual memory, all without invalidating the cached rtree
  1918. * value. The result would be a false positive (the rtree would claim that
  1919. * jemalloc owns memory that it had actually discarded). I don't think this
  1920. * scenario is possible, but the following assertion is a prudent sanity
  1921. * check.
  1922. */
  1923. # define MALLOC_RTREE_GET_VALIDATE \
  1924. assert(malloc_rtree_get_locked(rtree, key) == ret);
  1925. #else
  1926. # define MALLOC_RTREE_GET_VALIDATE
  1927. #endif
  1928. MALLOC_RTREE_GET_GENERATE(malloc_rtree_get)
  1929. #undef MALLOC_RTREE_LOCK
  1930. #undef MALLOC_RTREE_UNLOCK
  1931. #undef MALLOC_RTREE_GET_VALIDATE
  1932. static inline bool
  1933. malloc_rtree_set(malloc_rtree_t *rtree, uintptr_t key, void *val)
  1934. {
  1935. uintptr_t subkey;
  1936. unsigned i, lshift, height, bits;
  1937. void **node, **child;
  1938. malloc_spin_lock(&rtree->lock);
  1939. for (i = lshift = 0, height = rtree->height, node = rtree->root;
  1940. i < height - 1;
  1941. i++, lshift += bits, node = child) {
  1942. bits = rtree->level2bits[i];
  1943. subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits);
  1944. child = (void**)node[subkey];
  1945. if (child == NULL) {
  1946. child = (void**)base_calloc(1, sizeof(void *) <<
  1947. rtree->level2bits[i+1]);
  1948. if (child == NULL) {
  1949. malloc_spin_unlock(&rtree->lock);
  1950. return (true);
  1951. }
  1952. node[subkey] = child;
  1953. }
  1954. }
  1955. /* node is a leaf, so it contains values rather than node pointers. */
  1956. bits = rtree->level2bits[i];
  1957. subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits);
  1958. node[subkey] = val;
  1959. malloc_spin_unlock(&rtree->lock);
  1960. return (false);
  1961. }
  1962. /* pages_trim, chunk_alloc_mmap_slow and chunk_alloc_mmap were cherry-picked
  1963. * from upstream jemalloc 3.4.1 to fix Mozilla bug 956501. */
  1964. /* Return the offset between a and the nearest aligned address at or below a. */
  1965. #define ALIGNMENT_ADDR2OFFSET(a, alignment) \
  1966. ((size_t)((uintptr_t)(a) & (alignment - 1)))
  1967. /* Return the smallest alignment multiple that is >= s. */
  1968. #define ALIGNMENT_CEILING(s, alignment) \
  1969. (((s) + (alignment - 1)) & (-(alignment)))
  1970. static void *
  1971. pages_trim(void *addr, size_t alloc_size, size_t leadsize, size_t size)
  1972. {
  1973. void *ret = (void *)((uintptr_t)addr + leadsize);
  1974. assert(alloc_size >= leadsize + size);
  1975. #ifdef MOZ_MEMORY_WINDOWS
  1976. {
  1977. void *new_addr;
  1978. pages_unmap(addr, alloc_size);
  1979. new_addr = pages_map(ret, size);
  1980. if (new_addr == ret)
  1981. return (ret);
  1982. if (new_addr)
  1983. pages_unmap(new_addr, size);
  1984. return (NULL);
  1985. }
  1986. #else
  1987. {
  1988. size_t trailsize = alloc_size - leadsize - size;
  1989. if (leadsize != 0)
  1990. pages_unmap(addr, leadsize);
  1991. if (trailsize != 0)
  1992. pages_unmap((void *)((uintptr_t)ret + size), trailsize);
  1993. return (ret);
  1994. }
  1995. #endif
  1996. }
  1997. static void *
  1998. chunk_alloc_mmap_slow(size_t size, size_t alignment)
  1999. {
  2000. void *ret, *pages;
  2001. size_t alloc_size, leadsize;
  2002. alloc_size = size + alignment - pagesize;
  2003. /* Beware size_t wrap-around. */
  2004. if (alloc_size < size)
  2005. return (NULL);
  2006. do {
  2007. pages = pages_map(NULL, alloc_size);
  2008. if (pages == NULL)
  2009. return (NULL);
  2010. leadsize = ALIGNMENT_CEILING((uintptr_t)pages, alignment) -
  2011. (uintptr_t)pages;
  2012. ret = pages_trim(pages, alloc_size, leadsize, size);
  2013. } while (ret == NULL);
  2014. assert(ret != NULL);
  2015. return (ret);
  2016. }
  2017. static void *
  2018. chunk_alloc_mmap(size_t size, size_t alignment)
  2019. {
  2020. void *ret;
  2021. size_t offset;
  2022. /*
  2023. * Ideally, there would be a way to specify alignment to mmap() (like
  2024. * NetBSD has), but in the absence of such a feature, we have to work
  2025. * hard to efficiently create aligned mappings. The reliable, but
  2026. * slow method is to create a mapping that is over-sized, then trim the
  2027. * excess. However, that always results in one or two calls to
  2028. * pages_unmap().
  2029. *
  2030. * Optimistically try mapping precisely the right amount before falling
  2031. * back to the slow method, with the expectation that the optimistic
  2032. * approach works most of the time.
  2033. */
  2034. ret = pages_map(NULL, size);
  2035. if (ret == NULL)
  2036. return (NULL);
  2037. offset = ALIGNMENT_ADDR2OFFSET(ret, alignment);
  2038. if (offset != 0) {
  2039. pages_unmap(ret, size);
  2040. return (chunk_alloc_mmap_slow(size, alignment));
  2041. }
  2042. assert(ret != NULL);
  2043. return (ret);
  2044. }
  2045. bool
  2046. pages_purge(void *addr, size_t length)
  2047. {
  2048. bool unzeroed;
  2049. #ifdef MALLOC_DECOMMIT
  2050. pages_decommit(addr, length);
  2051. unzeroed = false;
  2052. #else
  2053. # ifdef MOZ_MEMORY_WINDOWS
  2054. /*
  2055. * The region starting at addr may have been allocated in multiple calls
  2056. * to VirtualAlloc and recycled, so resetting the entire region in one
  2057. * go may not be valid. However, since we allocate at least a chunk at a
  2058. * time, we may touch any region in chunksized increments.
  2059. */
  2060. size_t pages_size = min(length, chunksize -
  2061. CHUNK_ADDR2OFFSET((uintptr_t)addr));
  2062. while (length > 0) {
  2063. VirtualAlloc(addr, pages_size, MEM_RESET, PAGE_READWRITE);
  2064. addr = (void *)((uintptr_t)addr + pages_size);
  2065. length -= pages_size;
  2066. pages_size = min(length, chunksize);
  2067. }
  2068. unzeroed = true;
  2069. # else
  2070. # ifdef MOZ_MEMORY_LINUX
  2071. # define JEMALLOC_MADV_PURGE MADV_DONTNEED
  2072. # define JEMALLOC_MADV_ZEROS true
  2073. # else /* FreeBSD and Darwin. */
  2074. # define JEMALLOC_MADV_PURGE MADV_FREE
  2075. # define JEMALLOC_MADV_ZEROS false
  2076. # endif
  2077. #ifdef MOZ_MEMORY_SOLARIS
  2078. int err = posix_madvise(addr, length, JEMALLOC_MADV_PURGE);
  2079. unzeroed = (JEMALLOC_MADV_ZEROS == false || err != 0);
  2080. #else
  2081. int err = madvise(addr, length, JEMALLOC_MADV_PURGE);
  2082. unzeroed = (JEMALLOC_MADV_ZEROS == false || err != 0);
  2083. #endif
  2084. # undef JEMALLOC_MADV_PURGE
  2085. # undef JEMALLOC_MADV_ZEROS
  2086. # endif
  2087. #endif
  2088. return (unzeroed);
  2089. }
  2090. static void *
  2091. chunk_recycle(extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, size_t size,
  2092. size_t alignment, bool base, bool *zero)
  2093. {
  2094. void *ret;
  2095. extent_node_t *node;
  2096. extent_node_t key;
  2097. size_t alloc_size, leadsize, trailsize;
  2098. bool zeroed;
  2099. if (base) {
  2100. /*
  2101. * This function may need to call base_node_{,de}alloc(), but
  2102. * the current chunk allocation request is on behalf of the
  2103. * base allocator. Avoid deadlock (and if that weren't an
  2104. * issue, potential for infinite recursion) by returning NULL.
  2105. */
  2106. return (NULL);
  2107. }
  2108. alloc_size = size + alignment - chunksize;
  2109. /* Beware size_t wrap-around. */
  2110. if (alloc_size < size)
  2111. return (NULL);
  2112. key.addr = NULL;
  2113. key.size = alloc_size;
  2114. malloc_mutex_lock(&chunks_mtx);
  2115. node = extent_tree_szad_nsearch(chunks_szad, &key);
  2116. if (node == NULL) {
  2117. malloc_mutex_unlock(&chunks_mtx);
  2118. return (NULL);
  2119. }
  2120. leadsize = ALIGNMENT_CEILING((uintptr_t)node->addr, alignment) -
  2121. (uintptr_t)node->addr;
  2122. assert(node->size >= leadsize + size);
  2123. trailsize = node->size - leadsize - size;
  2124. ret = (void *)((uintptr_t)node->addr + leadsize);
  2125. zeroed = node->zeroed;
  2126. if (zeroed)
  2127. *zero = true;
  2128. /* Remove node from the tree. */
  2129. extent_tree_szad_remove(chunks_szad, node);
  2130. extent_tree_ad_remove(chunks_ad, node);
  2131. if (leadsize != 0) {
  2132. /* Insert the leading space as a smaller chunk. */
  2133. node->size = leadsize;
  2134. extent_tree_szad_insert(chunks_szad, node);
  2135. extent_tree_ad_insert(chunks_ad, node);
  2136. node = NULL;
  2137. }
  2138. if (trailsize != 0) {
  2139. /* Insert the trailing space as a smaller chunk. */
  2140. if (node == NULL) {
  2141. /*
  2142. * An additional node is required, but
  2143. * base_node_alloc() can cause a new base chunk to be
  2144. * allocated. Drop chunks_mtx in order to avoid
  2145. * deadlock, and if node allocation fails, deallocate
  2146. * the result before returning an error.
  2147. */
  2148. malloc_mutex_unlock(&chunks_mtx);
  2149. node = base_node_alloc();
  2150. if (node == NULL) {
  2151. chunk_dealloc(ret, size);
  2152. return (NULL);
  2153. }
  2154. malloc_mutex_lock(&chunks_mtx);
  2155. }
  2156. node->addr = (void *)((uintptr_t)(ret) + size);
  2157. node->size = trailsize;
  2158. node->zeroed = zeroed;
  2159. extent_tree_szad_insert(chunks_szad, node);
  2160. extent_tree_ad_insert(chunks_ad, node);
  2161. node = NULL;
  2162. }
  2163. if (config_munmap && config_recycle)
  2164. recycled_size -= size;
  2165. malloc_mutex_unlock(&chunks_mtx);
  2166. if (node != NULL)
  2167. base_node_dealloc(node);
  2168. #ifdef MALLOC_DECOMMIT
  2169. pages_commit(ret, size);
  2170. #endif
  2171. if (*zero) {
  2172. if (zeroed == false)
  2173. memset(ret, 0, size);
  2174. #ifdef DEBUG
  2175. else {
  2176. size_t i;
  2177. size_t *p = (size_t *)(uintptr_t)ret;
  2178. for (i = 0; i < size / sizeof(size_t); i++)
  2179. assert(p[i] == 0);
  2180. }
  2181. #endif
  2182. }
  2183. return (ret);
  2184. }
  2185. #ifdef MOZ_MEMORY_WINDOWS
  2186. /*
  2187. * On Windows, calls to VirtualAlloc and VirtualFree must be matched, making it
  2188. * awkward to recycle allocations of varying sizes. Therefore we only allow
  2189. * recycling when the size equals the chunksize, unless deallocation is entirely
  2190. * disabled.
  2191. */
  2192. #define CAN_RECYCLE(size) (size == chunksize)
  2193. #else
  2194. #define CAN_RECYCLE(size) true
  2195. #endif
  2196. static void *
  2197. chunk_alloc(size_t size, size_t alignment, bool base, bool zero)
  2198. {
  2199. void *ret;
  2200. assert(size != 0);
  2201. assert((size & chunksize_mask) == 0);
  2202. assert(alignment != 0);
  2203. assert((alignment & chunksize_mask) == 0);
  2204. if (!config_munmap || (config_recycle && CAN_RECYCLE(size))) {
  2205. ret = chunk_recycle(&chunks_szad_mmap, &chunks_ad_mmap,
  2206. size, alignment, base, &zero);
  2207. if (ret != NULL)
  2208. goto RETURN;
  2209. }
  2210. ret = chunk_alloc_mmap(size, alignment);
  2211. if (ret != NULL) {
  2212. goto RETURN;
  2213. }
  2214. /* All strategies for allocation failed. */
  2215. ret = NULL;
  2216. RETURN:
  2217. if (ret != NULL && base == false) {
  2218. if (malloc_rtree_set(chunk_rtree, (uintptr_t)ret, ret)) {
  2219. chunk_dealloc(ret, size);
  2220. return (NULL);
  2221. }
  2222. }
  2223. assert(CHUNK_ADDR2BASE(ret) == ret);
  2224. return (ret);
  2225. }
  2226. static void
  2227. chunk_record(extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, void *chunk,
  2228. size_t size)
  2229. {
  2230. bool unzeroed;
  2231. extent_node_t *xnode, *node, *prev, *xprev, key;
  2232. unzeroed = pages_purge(chunk, size);
  2233. /*
  2234. * Allocate a node before acquiring chunks_mtx even though it might not
  2235. * be needed, because base_node_alloc() may cause a new base chunk to
  2236. * be allocated, which could cause deadlock if chunks_mtx were already
  2237. * held.
  2238. */
  2239. xnode = base_node_alloc();
  2240. /* Use xprev to implement conditional deferred deallocation of prev. */
  2241. xprev = NULL;
  2242. malloc_mutex_lock(&chunks_mtx);
  2243. key.addr = (void *)((uintptr_t)chunk + size);
  2244. node = extent_tree_ad_nsearch(chunks_ad, &key);
  2245. /* Try to coalesce forward. */
  2246. if (node != NULL && node->addr == key.addr) {
  2247. /*
  2248. * Coalesce chunk with the following address range. This does
  2249. * not change the position within chunks_ad, so only
  2250. * remove/insert from/into chunks_szad.
  2251. */
  2252. extent_tree_szad_remove(chunks_szad, node);
  2253. node->addr = chunk;
  2254. node->size += size;
  2255. node->zeroed = (node->zeroed && (unzeroed == false));
  2256. extent_tree_szad_insert(chunks_szad, node);
  2257. } else {
  2258. /* Coalescing forward failed, so insert a new node. */
  2259. if (xnode == NULL) {
  2260. /*
  2261. * base_node_alloc() failed, which is an exceedingly
  2262. * unlikely failure. Leak chunk; its pages have
  2263. * already been purged, so this is only a virtual
  2264. * memory leak.
  2265. */
  2266. goto label_return;
  2267. }
  2268. node = xnode;
  2269. xnode = NULL; /* Prevent deallocation below. */
  2270. node->addr = chunk;
  2271. node->size = size;
  2272. node->zeroed = (unzeroed == false);
  2273. extent_tree_ad_insert(chunks_ad, node);
  2274. extent_tree_szad_insert(chunks_szad, node);
  2275. }
  2276. /* Try to coalesce backward. */
  2277. prev = extent_tree_ad_prev(chunks_ad, node);
  2278. if (prev != NULL && (void *)((uintptr_t)prev->addr + prev->size) ==
  2279. chunk) {
  2280. /*
  2281. * Coalesce chunk with the previous address range. This does
  2282. * not change the position within chunks_ad, so only
  2283. * remove/insert node from/into chunks_szad.
  2284. */
  2285. extent_tree_szad_remove(chunks_szad, prev);
  2286. extent_tree_ad_remove(chunks_ad, prev);
  2287. extent_tree_szad_remove(chunks_szad, node);
  2288. node->addr = prev->addr;
  2289. node->size += prev->size;
  2290. node->zeroed = (node->zeroed && prev->zeroed);
  2291. extent_tree_szad_insert(chunks_szad, node);
  2292. xprev = prev;
  2293. }
  2294. if (config_munmap && config_recycle)
  2295. recycled_size += size;
  2296. label_return:
  2297. malloc_mutex_unlock(&chunks_mtx);
  2298. /*
  2299. * Deallocate xnode and/or xprev after unlocking chunks_mtx in order to
  2300. * avoid potential deadlock.
  2301. */
  2302. if (xnode != NULL)
  2303. base_node_dealloc(xnode);
  2304. if (xprev != NULL)
  2305. base_node_dealloc(xprev);
  2306. }
  2307. static bool
  2308. chunk_dalloc_mmap(void *chunk, size_t size)
  2309. {
  2310. if (!config_munmap || (config_recycle && CAN_RECYCLE(size) &&
  2311. load_acquire_z(&recycled_size) < recycle_limit))
  2312. return true;
  2313. pages_unmap(chunk, size);
  2314. return false;
  2315. }
  2316. #undef CAN_RECYCLE
  2317. static void
  2318. chunk_dealloc(void *chunk, size_t size)
  2319. {
  2320. assert(chunk != NULL);
  2321. assert(CHUNK_ADDR2BASE(chunk) == chunk);
  2322. assert(size != 0);
  2323. assert((size & chunksize_mask) == 0);
  2324. malloc_rtree_set(chunk_rtree, (uintptr_t)chunk, NULL);
  2325. if (chunk_dalloc_mmap(chunk, size))
  2326. chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, size);
  2327. }
  2328. /*
  2329. * End chunk management functions.
  2330. */
  2331. /******************************************************************************/
  2332. /*
  2333. * Begin arena.
  2334. */
  2335. /*
  2336. * Choose an arena based on a per-thread value (fast-path code, calls slow-path
  2337. * code if necessary).
  2338. */
  2339. static inline arena_t *
  2340. choose_arena(void)
  2341. {
  2342. arena_t *ret;
  2343. /*
  2344. * We can only use TLS if this is a PIC library, since for the static
  2345. * library version, libc's malloc is used by TLS allocation, which
  2346. * introduces a bootstrapping issue.
  2347. */
  2348. #ifndef NO_TLS
  2349. # ifdef MOZ_MEMORY_WINDOWS
  2350. ret = (arena_t*)TlsGetValue(tlsIndex);
  2351. # else
  2352. ret = arenas_map;
  2353. # endif
  2354. if (ret == NULL) {
  2355. ret = choose_arena_hard();
  2356. RELEASE_ASSERT(ret != NULL);
  2357. }
  2358. #else
  2359. if (narenas > 1) {
  2360. unsigned long ind;
  2361. /*
  2362. * Hash _pthread_self() to one of the arenas. There is a prime
  2363. * number of arenas, so this has a reasonable chance of
  2364. * working. Even so, the hashing can be easily thwarted by
  2365. * inconvenient _pthread_self() values. Without specific
  2366. * knowledge of how _pthread_self() calculates values, we can't
  2367. * easily do much better than this.
  2368. */
  2369. ind = (unsigned long) _pthread_self() % narenas;
  2370. /*
  2371. * Optimistially assume that arenas[ind] has been initialized.
  2372. * At worst, we find out that some other thread has already
  2373. * done so, after acquiring the lock in preparation. Note that
  2374. * this lazy locking also has the effect of lazily forcing
  2375. * cache coherency; without the lock acquisition, there's no
  2376. * guarantee that modification of arenas[ind] by another thread
  2377. * would be seen on this CPU for an arbitrary amount of time.
  2378. *
  2379. * In general, this approach to modifying a synchronized value
  2380. * isn't a good idea, but in this case we only ever modify the
  2381. * value once, so things work out well.
  2382. */
  2383. ret = arenas[ind];
  2384. if (ret == NULL) {
  2385. /*
  2386. * Avoid races with another thread that may have already
  2387. * initialized arenas[ind].
  2388. */
  2389. malloc_spin_lock(&arenas_lock);
  2390. if (arenas[ind] == NULL)
  2391. ret = arenas_extend((unsigned)ind);
  2392. else
  2393. ret = arenas[ind];
  2394. malloc_spin_unlock(&arenas_lock);
  2395. }
  2396. } else
  2397. ret = arenas[0];
  2398. #endif
  2399. RELEASE_ASSERT(ret != NULL);
  2400. return (ret);
  2401. }
  2402. #ifndef NO_TLS
  2403. /*
  2404. * Choose an arena based on a per-thread value (slow-path code only, called
  2405. * only by choose_arena()).
  2406. */
  2407. static arena_t *
  2408. choose_arena_hard(void)
  2409. {
  2410. arena_t *ret;
  2411. if (narenas > 1) {
  2412. malloc_spin_lock(&arenas_lock);
  2413. if ((ret = arenas[next_arena]) == NULL)
  2414. ret = arenas_extend(next_arena);
  2415. next_arena = (next_arena + 1) % narenas;
  2416. malloc_spin_unlock(&arenas_lock);
  2417. } else
  2418. ret = arenas[0];
  2419. #ifdef MOZ_MEMORY_WINDOWS
  2420. TlsSetValue(tlsIndex, ret);
  2421. #else
  2422. arenas_map = ret;
  2423. #endif
  2424. return (ret);
  2425. }
  2426. #endif
  2427. static inline int
  2428. arena_chunk_comp(arena_chunk_t *a, arena_chunk_t *b)
  2429. {
  2430. uintptr_t a_chunk = (uintptr_t)a;
  2431. uintptr_t b_chunk = (uintptr_t)b;
  2432. assert(a != NULL);
  2433. assert(b != NULL);
  2434. return ((a_chunk > b_chunk) - (a_chunk < b_chunk));
  2435. }
  2436. /* Wrap red-black tree macros in functions. */
  2437. rb_wrap(static, arena_chunk_tree_dirty_, arena_chunk_tree_t,
  2438. arena_chunk_t, link_dirty, arena_chunk_comp)
  2439. static inline int
  2440. arena_run_comp(arena_chunk_map_t *a, arena_chunk_map_t *b)
  2441. {
  2442. uintptr_t a_mapelm = (uintptr_t)a;
  2443. uintptr_t b_mapelm = (uintptr_t)b;
  2444. assert(a != NULL);
  2445. assert(b != NULL);
  2446. return ((a_mapelm > b_mapelm) - (a_mapelm < b_mapelm));
  2447. }
  2448. /* Wrap red-black tree macros in functions. */
  2449. rb_wrap(static, arena_run_tree_, arena_run_tree_t, arena_chunk_map_t, link,
  2450. arena_run_comp)
  2451. static inline int
  2452. arena_avail_comp(arena_chunk_map_t *a, arena_chunk_map_t *b)
  2453. {
  2454. int ret;
  2455. size_t a_size = a->bits & ~pagesize_mask;
  2456. size_t b_size = b->bits & ~pagesize_mask;
  2457. ret = (a_size > b_size) - (a_size < b_size);
  2458. if (ret == 0) {
  2459. uintptr_t a_mapelm, b_mapelm;
  2460. if ((a->bits & CHUNK_MAP_KEY) == 0)
  2461. a_mapelm = (uintptr_t)a;
  2462. else {
  2463. /*
  2464. * Treat keys as though they are lower than anything
  2465. * else.
  2466. */
  2467. a_mapelm = 0;
  2468. }
  2469. b_mapelm = (uintptr_t)b;
  2470. ret = (a_mapelm > b_mapelm) - (a_mapelm < b_mapelm);
  2471. }
  2472. return (ret);
  2473. }
  2474. /* Wrap red-black tree macros in functions. */
  2475. rb_wrap(static, arena_avail_tree_, arena_avail_tree_t, arena_chunk_map_t, link,
  2476. arena_avail_comp)
  2477. static inline void *
  2478. arena_run_reg_alloc(arena_run_t *run, arena_bin_t *bin)
  2479. {
  2480. void *ret;
  2481. unsigned i, mask, bit, regind;
  2482. assert(run->magic == ARENA_RUN_MAGIC);
  2483. assert(run->regs_minelm < bin->regs_mask_nelms);
  2484. /*
  2485. * Move the first check outside the loop, so that run->regs_minelm can
  2486. * be updated unconditionally, without the possibility of updating it
  2487. * multiple times.
  2488. */
  2489. i = run->regs_minelm;
  2490. mask = run->regs_mask[i];
  2491. if (mask != 0) {
  2492. /* Usable allocation found. */
  2493. bit = ffs((int)mask) - 1;
  2494. regind = ((i << (SIZEOF_INT_2POW + 3)) + bit);
  2495. assert(regind < bin->nregs);
  2496. ret = (void *)(((uintptr_t)run) + bin->reg0_offset
  2497. + (bin->reg_size * regind));
  2498. /* Clear bit. */
  2499. mask ^= (1U << bit);
  2500. run->regs_mask[i] = mask;
  2501. return (ret);
  2502. }
  2503. for (i++; i < bin->regs_mask_nelms; i++) {
  2504. mask = run->regs_mask[i];
  2505. if (mask != 0) {
  2506. /* Usable allocation found. */
  2507. bit = ffs((int)mask) - 1;
  2508. regind = ((i << (SIZEOF_INT_2POW + 3)) + bit);
  2509. assert(regind < bin->nregs);
  2510. ret = (void *)(((uintptr_t)run) + bin->reg0_offset
  2511. + (bin->reg_size * regind));
  2512. /* Clear bit. */
  2513. mask ^= (1U << bit);
  2514. run->regs_mask[i] = mask;
  2515. /*
  2516. * Make a note that nothing before this element
  2517. * contains a free region.
  2518. */
  2519. run->regs_minelm = i; /* Low payoff: + (mask == 0); */
  2520. return (ret);
  2521. }
  2522. }
  2523. /* Not reached. */
  2524. RELEASE_ASSERT(0);
  2525. return (NULL);
  2526. }
  2527. static inline void
  2528. arena_run_reg_dalloc(arena_run_t *run, arena_bin_t *bin, void *ptr, size_t size)
  2529. {
  2530. /*
  2531. * To divide by a number D that is not a power of two we multiply
  2532. * by (2^21 / D) and then right shift by 21 positions.
  2533. *
  2534. * X / D
  2535. *
  2536. * becomes
  2537. *
  2538. * (X * size_invs[(D >> QUANTUM_2POW_MIN) - 3]) >> SIZE_INV_SHIFT
  2539. */
  2540. #define SIZE_INV_SHIFT 21
  2541. #define SIZE_INV(s) (((1U << SIZE_INV_SHIFT) / (s << QUANTUM_2POW_MIN)) + 1)
  2542. static const unsigned size_invs[] = {
  2543. SIZE_INV(3),
  2544. SIZE_INV(4), SIZE_INV(5), SIZE_INV(6), SIZE_INV(7),
  2545. SIZE_INV(8), SIZE_INV(9), SIZE_INV(10), SIZE_INV(11),
  2546. SIZE_INV(12),SIZE_INV(13), SIZE_INV(14), SIZE_INV(15),
  2547. SIZE_INV(16),SIZE_INV(17), SIZE_INV(18), SIZE_INV(19),
  2548. SIZE_INV(20),SIZE_INV(21), SIZE_INV(22), SIZE_INV(23),
  2549. SIZE_INV(24),SIZE_INV(25), SIZE_INV(26), SIZE_INV(27),
  2550. SIZE_INV(28),SIZE_INV(29), SIZE_INV(30), SIZE_INV(31)
  2551. #if (QUANTUM_2POW_MIN < 4)
  2552. ,
  2553. SIZE_INV(32), SIZE_INV(33), SIZE_INV(34), SIZE_INV(35),
  2554. SIZE_INV(36), SIZE_INV(37), SIZE_INV(38), SIZE_INV(39),
  2555. SIZE_INV(40), SIZE_INV(41), SIZE_INV(42), SIZE_INV(43),
  2556. SIZE_INV(44), SIZE_INV(45), SIZE_INV(46), SIZE_INV(47),
  2557. SIZE_INV(48), SIZE_INV(49), SIZE_INV(50), SIZE_INV(51),
  2558. SIZE_INV(52), SIZE_INV(53), SIZE_INV(54), SIZE_INV(55),
  2559. SIZE_INV(56), SIZE_INV(57), SIZE_INV(58), SIZE_INV(59),
  2560. SIZE_INV(60), SIZE_INV(61), SIZE_INV(62), SIZE_INV(63)
  2561. #endif
  2562. };
  2563. unsigned diff, regind, elm, bit;
  2564. assert(run->magic == ARENA_RUN_MAGIC);
  2565. assert(((sizeof(size_invs)) / sizeof(unsigned)) + 3
  2566. >= (SMALL_MAX_DEFAULT >> QUANTUM_2POW_MIN));
  2567. /*
  2568. * Avoid doing division with a variable divisor if possible. Using
  2569. * actual division here can reduce allocator throughput by over 20%!
  2570. */
  2571. diff = (unsigned)((uintptr_t)ptr - (uintptr_t)run - bin->reg0_offset);
  2572. if ((size & (size - 1)) == 0) {
  2573. /*
  2574. * log2_table allows fast division of a power of two in the
  2575. * [1..128] range.
  2576. *
  2577. * (x / divisor) becomes (x >> log2_table[divisor - 1]).
  2578. */
  2579. static const unsigned char log2_table[] = {
  2580. 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4,
  2581. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
  2582. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2583. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
  2584. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2585. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2586. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2587. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7
  2588. };
  2589. if (size <= 128)
  2590. regind = (diff >> log2_table[size - 1]);
  2591. else if (size <= 32768)
  2592. regind = diff >> (8 + log2_table[(size >> 8) - 1]);
  2593. else {
  2594. /*
  2595. * The run size is too large for us to use the lookup
  2596. * table. Use real division.
  2597. */
  2598. regind = diff / size;
  2599. }
  2600. } else if (size <= ((sizeof(size_invs) / sizeof(unsigned))
  2601. << QUANTUM_2POW_MIN) + 2) {
  2602. regind = size_invs[(size >> QUANTUM_2POW_MIN) - 3] * diff;
  2603. regind >>= SIZE_INV_SHIFT;
  2604. } else {
  2605. /*
  2606. * size_invs isn't large enough to handle this size class, so
  2607. * calculate regind using actual division. This only happens
  2608. * if the user increases small_max via the 'S' runtime
  2609. * configuration option.
  2610. */
  2611. regind = diff / size;
  2612. };
  2613. RELEASE_ASSERT(diff == regind * size);
  2614. RELEASE_ASSERT(regind < bin->nregs);
  2615. elm = regind >> (SIZEOF_INT_2POW + 3);
  2616. if (elm < run->regs_minelm)
  2617. run->regs_minelm = elm;
  2618. bit = regind - (elm << (SIZEOF_INT_2POW + 3));
  2619. RELEASE_ASSERT((run->regs_mask[elm] & (1U << bit)) == 0);
  2620. run->regs_mask[elm] |= (1U << bit);
  2621. #undef SIZE_INV
  2622. #undef SIZE_INV_SHIFT
  2623. }
  2624. static void
  2625. arena_run_split(arena_t *arena, arena_run_t *run, size_t size, bool large,
  2626. bool zero)
  2627. {
  2628. arena_chunk_t *chunk;
  2629. size_t old_ndirty, run_ind, total_pages, need_pages, rem_pages, i;
  2630. chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
  2631. old_ndirty = chunk->ndirty;
  2632. run_ind = (unsigned)(((uintptr_t)run - (uintptr_t)chunk)
  2633. >> pagesize_2pow);
  2634. total_pages = (chunk->map[run_ind].bits & ~pagesize_mask) >>
  2635. pagesize_2pow;
  2636. need_pages = (size >> pagesize_2pow);
  2637. assert(need_pages > 0);
  2638. assert(need_pages <= total_pages);
  2639. rem_pages = total_pages - need_pages;
  2640. arena_avail_tree_remove(&arena->runs_avail, &chunk->map[run_ind]);
  2641. /* Keep track of trailing unused pages for later use. */
  2642. if (rem_pages > 0) {
  2643. chunk->map[run_ind+need_pages].bits = (rem_pages <<
  2644. pagesize_2pow) | (chunk->map[run_ind+need_pages].bits &
  2645. pagesize_mask);
  2646. chunk->map[run_ind+total_pages-1].bits = (rem_pages <<
  2647. pagesize_2pow) | (chunk->map[run_ind+total_pages-1].bits &
  2648. pagesize_mask);
  2649. arena_avail_tree_insert(&arena->runs_avail,
  2650. &chunk->map[run_ind+need_pages]);
  2651. }
  2652. for (i = 0; i < need_pages; i++) {
  2653. #if defined(MALLOC_DECOMMIT) || defined(MALLOC_STATS) || defined(MALLOC_DOUBLE_PURGE)
  2654. /*
  2655. * Commit decommitted pages if necessary. If a decommitted
  2656. * page is encountered, commit all needed adjacent decommitted
  2657. * pages in one operation, in order to reduce system call
  2658. * overhead.
  2659. */
  2660. if (chunk->map[run_ind + i].bits & CHUNK_MAP_MADVISED_OR_DECOMMITTED) {
  2661. size_t j;
  2662. /*
  2663. * Advance i+j to just past the index of the last page
  2664. * to commit. Clear CHUNK_MAP_DECOMMITTED and
  2665. * CHUNK_MAP_MADVISED along the way.
  2666. */
  2667. for (j = 0; i + j < need_pages && (chunk->map[run_ind +
  2668. i + j].bits & CHUNK_MAP_MADVISED_OR_DECOMMITTED); j++) {
  2669. /* DECOMMITTED and MADVISED are mutually exclusive. */
  2670. assert(!(chunk->map[run_ind + i + j].bits & CHUNK_MAP_DECOMMITTED &&
  2671. chunk->map[run_ind + i + j].bits & CHUNK_MAP_MADVISED));
  2672. chunk->map[run_ind + i + j].bits &=
  2673. ~CHUNK_MAP_MADVISED_OR_DECOMMITTED;
  2674. }
  2675. # ifdef MALLOC_DECOMMIT
  2676. pages_commit((void *)((uintptr_t)chunk + ((run_ind + i)
  2677. << pagesize_2pow)), (j << pagesize_2pow));
  2678. # ifdef MALLOC_STATS
  2679. arena->stats.ncommit++;
  2680. # endif
  2681. # endif
  2682. # ifdef MALLOC_STATS
  2683. arena->stats.committed += j;
  2684. # endif
  2685. # ifndef MALLOC_DECOMMIT
  2686. }
  2687. # else
  2688. } else /* No need to zero since commit zeros. */
  2689. # endif
  2690. #endif
  2691. /* Zero if necessary. */
  2692. if (zero) {
  2693. if ((chunk->map[run_ind + i].bits & CHUNK_MAP_ZEROED)
  2694. == 0) {
  2695. memset((void *)((uintptr_t)chunk + ((run_ind
  2696. + i) << pagesize_2pow)), 0, pagesize);
  2697. /* CHUNK_MAP_ZEROED is cleared below. */
  2698. }
  2699. }
  2700. /* Update dirty page accounting. */
  2701. if (chunk->map[run_ind + i].bits & CHUNK_MAP_DIRTY) {
  2702. chunk->ndirty--;
  2703. arena->ndirty--;
  2704. /* CHUNK_MAP_DIRTY is cleared below. */
  2705. }
  2706. /* Initialize the chunk map. */
  2707. if (large) {
  2708. chunk->map[run_ind + i].bits = CHUNK_MAP_LARGE
  2709. | CHUNK_MAP_ALLOCATED;
  2710. } else {
  2711. chunk->map[run_ind + i].bits = (size_t)run
  2712. | CHUNK_MAP_ALLOCATED;
  2713. }
  2714. }
  2715. /*
  2716. * Set the run size only in the first element for large runs. This is
  2717. * primarily a debugging aid, since the lack of size info for trailing
  2718. * pages only matters if the application tries to operate on an
  2719. * interior pointer.
  2720. */
  2721. if (large)
  2722. chunk->map[run_ind].bits |= size;
  2723. if (chunk->ndirty == 0 && old_ndirty > 0)
  2724. arena_chunk_tree_dirty_remove(&arena->chunks_dirty, chunk);
  2725. }
  2726. static void
  2727. arena_chunk_init(arena_t *arena, arena_chunk_t *chunk)
  2728. {
  2729. arena_run_t *run;
  2730. size_t i;
  2731. #ifdef MALLOC_STATS
  2732. arena->stats.mapped += chunksize;
  2733. #endif
  2734. chunk->arena = arena;
  2735. /*
  2736. * Claim that no pages are in use, since the header is merely overhead.
  2737. */
  2738. chunk->ndirty = 0;
  2739. /* Initialize the map to contain one maximal free untouched run. */
  2740. run = (arena_run_t *)((uintptr_t)chunk + (arena_chunk_header_npages <<
  2741. pagesize_2pow));
  2742. for (i = 0; i < arena_chunk_header_npages; i++)
  2743. chunk->map[i].bits = 0;
  2744. chunk->map[i].bits = arena_maxclass | CHUNK_MAP_DECOMMITTED | CHUNK_MAP_ZEROED;
  2745. for (i++; i < chunk_npages-1; i++) {
  2746. chunk->map[i].bits = CHUNK_MAP_DECOMMITTED | CHUNK_MAP_ZEROED;
  2747. }
  2748. chunk->map[chunk_npages-1].bits = arena_maxclass | CHUNK_MAP_DECOMMITTED | CHUNK_MAP_ZEROED;
  2749. #ifdef MALLOC_DECOMMIT
  2750. /*
  2751. * Start out decommitted, in order to force a closer correspondence
  2752. * between dirty pages and committed untouched pages.
  2753. */
  2754. pages_decommit(run, arena_maxclass);
  2755. # ifdef MALLOC_STATS
  2756. arena->stats.ndecommit++;
  2757. arena->stats.decommitted += (chunk_npages - arena_chunk_header_npages);
  2758. # endif
  2759. #endif
  2760. #ifdef MALLOC_STATS
  2761. arena->stats.committed += arena_chunk_header_npages;
  2762. #endif
  2763. /* Insert the run into the runs_avail tree. */
  2764. arena_avail_tree_insert(&arena->runs_avail,
  2765. &chunk->map[arena_chunk_header_npages]);
  2766. #ifdef MALLOC_DOUBLE_PURGE
  2767. LinkedList_Init(&chunk->chunks_madvised_elem);
  2768. #endif
  2769. }
  2770. static void
  2771. arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk)
  2772. {
  2773. if (arena->spare != NULL) {
  2774. if (arena->spare->ndirty > 0) {
  2775. arena_chunk_tree_dirty_remove(
  2776. &chunk->arena->chunks_dirty, arena->spare);
  2777. arena->ndirty -= arena->spare->ndirty;
  2778. #ifdef MALLOC_STATS
  2779. arena->stats.committed -= arena->spare->ndirty;
  2780. #endif
  2781. }
  2782. #ifdef MALLOC_DOUBLE_PURGE
  2783. /* This is safe to do even if arena->spare is not in the list. */
  2784. LinkedList_Remove(&arena->spare->chunks_madvised_elem);
  2785. #endif
  2786. chunk_dealloc((void *)arena->spare, chunksize);
  2787. #ifdef MALLOC_STATS
  2788. arena->stats.mapped -= chunksize;
  2789. arena->stats.committed -= arena_chunk_header_npages;
  2790. #endif
  2791. }
  2792. /*
  2793. * Remove run from runs_avail, so that the arena does not use it.
  2794. * Dirty page flushing only uses the chunks_dirty tree, so leaving this
  2795. * chunk in the chunks_* trees is sufficient for that purpose.
  2796. */
  2797. arena_avail_tree_remove(&arena->runs_avail,
  2798. &chunk->map[arena_chunk_header_npages]);
  2799. arena->spare = chunk;
  2800. }
  2801. static arena_run_t *
  2802. arena_run_alloc(arena_t *arena, arena_bin_t *bin, size_t size, bool large,
  2803. bool zero)
  2804. {
  2805. arena_run_t *run;
  2806. arena_chunk_map_t *mapelm, key;
  2807. assert(size <= arena_maxclass);
  2808. assert((size & pagesize_mask) == 0);
  2809. /* Search the arena's chunks for the lowest best fit. */
  2810. key.bits = size | CHUNK_MAP_KEY;
  2811. mapelm = arena_avail_tree_nsearch(&arena->runs_avail, &key);
  2812. if (mapelm != NULL) {
  2813. arena_chunk_t *chunk =
  2814. (arena_chunk_t*)CHUNK_ADDR2BASE(mapelm);
  2815. size_t pageind = ((uintptr_t)mapelm -
  2816. (uintptr_t)chunk->map) /
  2817. sizeof(arena_chunk_map_t);
  2818. run = (arena_run_t *)((uintptr_t)chunk + (pageind
  2819. << pagesize_2pow));
  2820. arena_run_split(arena, run, size, large, zero);
  2821. return (run);
  2822. }
  2823. if (arena->spare != NULL) {
  2824. /* Use the spare. */
  2825. arena_chunk_t *chunk = arena->spare;
  2826. arena->spare = NULL;
  2827. run = (arena_run_t *)((uintptr_t)chunk +
  2828. (arena_chunk_header_npages << pagesize_2pow));
  2829. /* Insert the run into the runs_avail tree. */
  2830. arena_avail_tree_insert(&arena->runs_avail,
  2831. &chunk->map[arena_chunk_header_npages]);
  2832. arena_run_split(arena, run, size, large, zero);
  2833. return (run);
  2834. }
  2835. /*
  2836. * No usable runs. Create a new chunk from which to allocate
  2837. * the run.
  2838. */
  2839. {
  2840. arena_chunk_t *chunk = (arena_chunk_t *)
  2841. chunk_alloc(chunksize, chunksize, false, true);
  2842. if (chunk == NULL)
  2843. return (NULL);
  2844. arena_chunk_init(arena, chunk);
  2845. run = (arena_run_t *)((uintptr_t)chunk +
  2846. (arena_chunk_header_npages << pagesize_2pow));
  2847. }
  2848. /* Update page map. */
  2849. arena_run_split(arena, run, size, large, zero);
  2850. return (run);
  2851. }
  2852. static void
  2853. arena_purge(arena_t *arena, bool all)
  2854. {
  2855. arena_chunk_t *chunk;
  2856. size_t i, npages;
  2857. /* If all is set purge all dirty pages. */
  2858. size_t dirty_max = all ? 1 : opt_dirty_max;
  2859. #ifdef MALLOC_DEBUG
  2860. size_t ndirty = 0;
  2861. rb_foreach_begin(arena_chunk_t, link_dirty, &arena->chunks_dirty,
  2862. chunk) {
  2863. ndirty += chunk->ndirty;
  2864. } rb_foreach_end(arena_chunk_t, link_dirty, &arena->chunks_dirty, chunk)
  2865. assert(ndirty == arena->ndirty);
  2866. #endif
  2867. RELEASE_ASSERT(all || (arena->ndirty > opt_dirty_max));
  2868. #ifdef MALLOC_STATS
  2869. arena->stats.npurge++;
  2870. #endif
  2871. /*
  2872. * Iterate downward through chunks until enough dirty memory has been
  2873. * purged. Terminate as soon as possible in order to minimize the
  2874. * number of system calls, even if a chunk has only been partially
  2875. * purged.
  2876. */
  2877. while (arena->ndirty > (dirty_max >> 1)) {
  2878. #ifdef MALLOC_DOUBLE_PURGE
  2879. bool madvised = false;
  2880. #endif
  2881. chunk = arena_chunk_tree_dirty_last(&arena->chunks_dirty);
  2882. RELEASE_ASSERT(chunk != NULL);
  2883. for (i = chunk_npages - 1; chunk->ndirty > 0; i--) {
  2884. RELEASE_ASSERT(i >= arena_chunk_header_npages);
  2885. if (chunk->map[i].bits & CHUNK_MAP_DIRTY) {
  2886. #ifdef MALLOC_DECOMMIT
  2887. const size_t free_operation = CHUNK_MAP_DECOMMITTED;
  2888. #else
  2889. const size_t free_operation = CHUNK_MAP_MADVISED;
  2890. #endif
  2891. assert((chunk->map[i].bits &
  2892. CHUNK_MAP_MADVISED_OR_DECOMMITTED) == 0);
  2893. chunk->map[i].bits ^= free_operation | CHUNK_MAP_DIRTY;
  2894. /* Find adjacent dirty run(s). */
  2895. for (npages = 1;
  2896. i > arena_chunk_header_npages &&
  2897. (chunk->map[i - 1].bits & CHUNK_MAP_DIRTY);
  2898. npages++) {
  2899. i--;
  2900. assert((chunk->map[i].bits &
  2901. CHUNK_MAP_MADVISED_OR_DECOMMITTED) == 0);
  2902. chunk->map[i].bits ^= free_operation | CHUNK_MAP_DIRTY;
  2903. }
  2904. chunk->ndirty -= npages;
  2905. arena->ndirty -= npages;
  2906. #ifdef MALLOC_DECOMMIT
  2907. pages_decommit((void *)((uintptr_t)
  2908. chunk + (i << pagesize_2pow)),
  2909. (npages << pagesize_2pow));
  2910. # ifdef MALLOC_STATS
  2911. arena->stats.ndecommit++;
  2912. arena->stats.decommitted += npages;
  2913. # endif
  2914. #endif
  2915. #ifdef MALLOC_STATS
  2916. arena->stats.committed -= npages;
  2917. #endif
  2918. #ifndef MALLOC_DECOMMIT
  2919. #ifdef MOZ_MEMORY_SOLARIS
  2920. posix_madvise((void*)((uintptr_t)chunk + (i << pagesize_2pow)),
  2921. (npages << pagesize_2pow),MADV_FREE);
  2922. #else
  2923. madvise((void *)((uintptr_t)chunk + (i <<
  2924. pagesize_2pow)), (npages << pagesize_2pow),
  2925. MADV_FREE);
  2926. #endif
  2927. # ifdef MALLOC_DOUBLE_PURGE
  2928. madvised = true;
  2929. # endif
  2930. #endif
  2931. #ifdef MALLOC_STATS
  2932. arena->stats.nmadvise++;
  2933. arena->stats.purged += npages;
  2934. #endif
  2935. if (arena->ndirty <= (dirty_max >> 1))
  2936. break;
  2937. }
  2938. }
  2939. if (chunk->ndirty == 0) {
  2940. arena_chunk_tree_dirty_remove(&arena->chunks_dirty,
  2941. chunk);
  2942. }
  2943. #ifdef MALLOC_DOUBLE_PURGE
  2944. if (madvised) {
  2945. /* The chunk might already be in the list, but this
  2946. * makes sure it's at the front. */
  2947. LinkedList_Remove(&chunk->chunks_madvised_elem);
  2948. LinkedList_InsertHead(&arena->chunks_madvised, &chunk->chunks_madvised_elem);
  2949. }
  2950. #endif
  2951. }
  2952. }
  2953. static void
  2954. arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty)
  2955. {
  2956. arena_chunk_t *chunk;
  2957. size_t size, run_ind, run_pages;
  2958. chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
  2959. run_ind = (size_t)(((uintptr_t)run - (uintptr_t)chunk)
  2960. >> pagesize_2pow);
  2961. RELEASE_ASSERT(run_ind >= arena_chunk_header_npages);
  2962. RELEASE_ASSERT(run_ind < chunk_npages);
  2963. if ((chunk->map[run_ind].bits & CHUNK_MAP_LARGE) != 0)
  2964. size = chunk->map[run_ind].bits & ~pagesize_mask;
  2965. else
  2966. size = run->bin->run_size;
  2967. run_pages = (size >> pagesize_2pow);
  2968. /* Mark pages as unallocated in the chunk map. */
  2969. if (dirty) {
  2970. size_t i;
  2971. for (i = 0; i < run_pages; i++) {
  2972. RELEASE_ASSERT((chunk->map[run_ind + i].bits & CHUNK_MAP_DIRTY)
  2973. == 0);
  2974. chunk->map[run_ind + i].bits = CHUNK_MAP_DIRTY;
  2975. }
  2976. if (chunk->ndirty == 0) {
  2977. arena_chunk_tree_dirty_insert(&arena->chunks_dirty,
  2978. chunk);
  2979. }
  2980. chunk->ndirty += run_pages;
  2981. arena->ndirty += run_pages;
  2982. } else {
  2983. size_t i;
  2984. for (i = 0; i < run_pages; i++) {
  2985. chunk->map[run_ind + i].bits &= ~(CHUNK_MAP_LARGE |
  2986. CHUNK_MAP_ALLOCATED);
  2987. }
  2988. }
  2989. chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
  2990. pagesize_mask);
  2991. chunk->map[run_ind+run_pages-1].bits = size |
  2992. (chunk->map[run_ind+run_pages-1].bits & pagesize_mask);
  2993. /* Try to coalesce forward. */
  2994. if (run_ind + run_pages < chunk_npages &&
  2995. (chunk->map[run_ind+run_pages].bits & CHUNK_MAP_ALLOCATED) == 0) {
  2996. size_t nrun_size = chunk->map[run_ind+run_pages].bits &
  2997. ~pagesize_mask;
  2998. /*
  2999. * Remove successor from runs_avail; the coalesced run is
  3000. * inserted later.
  3001. */
  3002. arena_avail_tree_remove(&arena->runs_avail,
  3003. &chunk->map[run_ind+run_pages]);
  3004. size += nrun_size;
  3005. run_pages = size >> pagesize_2pow;
  3006. RELEASE_ASSERT((chunk->map[run_ind+run_pages-1].bits & ~pagesize_mask)
  3007. == nrun_size);
  3008. chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
  3009. pagesize_mask);
  3010. chunk->map[run_ind+run_pages-1].bits = size |
  3011. (chunk->map[run_ind+run_pages-1].bits & pagesize_mask);
  3012. }
  3013. /* Try to coalesce backward. */
  3014. if (run_ind > arena_chunk_header_npages && (chunk->map[run_ind-1].bits &
  3015. CHUNK_MAP_ALLOCATED) == 0) {
  3016. size_t prun_size = chunk->map[run_ind-1].bits & ~pagesize_mask;
  3017. run_ind -= prun_size >> pagesize_2pow;
  3018. /*
  3019. * Remove predecessor from runs_avail; the coalesced run is
  3020. * inserted later.
  3021. */
  3022. arena_avail_tree_remove(&arena->runs_avail,
  3023. &chunk->map[run_ind]);
  3024. size += prun_size;
  3025. run_pages = size >> pagesize_2pow;
  3026. RELEASE_ASSERT((chunk->map[run_ind].bits & ~pagesize_mask) ==
  3027. prun_size);
  3028. chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
  3029. pagesize_mask);
  3030. chunk->map[run_ind+run_pages-1].bits = size |
  3031. (chunk->map[run_ind+run_pages-1].bits & pagesize_mask);
  3032. }
  3033. /* Insert into runs_avail, now that coalescing is complete. */
  3034. arena_avail_tree_insert(&arena->runs_avail, &chunk->map[run_ind]);
  3035. /* Deallocate chunk if it is now completely unused. */
  3036. if ((chunk->map[arena_chunk_header_npages].bits & (~pagesize_mask |
  3037. CHUNK_MAP_ALLOCATED)) == arena_maxclass)
  3038. arena_chunk_dealloc(arena, chunk);
  3039. /* Enforce opt_dirty_max. */
  3040. if (arena->ndirty > opt_dirty_max)
  3041. arena_purge(arena, false);
  3042. }
  3043. static void
  3044. arena_run_trim_head(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
  3045. size_t oldsize, size_t newsize)
  3046. {
  3047. size_t pageind = ((uintptr_t)run - (uintptr_t)chunk) >> pagesize_2pow;
  3048. size_t head_npages = (oldsize - newsize) >> pagesize_2pow;
  3049. assert(oldsize > newsize);
  3050. /*
  3051. * Update the chunk map so that arena_run_dalloc() can treat the
  3052. * leading run as separately allocated.
  3053. */
  3054. chunk->map[pageind].bits = (oldsize - newsize) | CHUNK_MAP_LARGE |
  3055. CHUNK_MAP_ALLOCATED;
  3056. chunk->map[pageind+head_npages].bits = newsize | CHUNK_MAP_LARGE |
  3057. CHUNK_MAP_ALLOCATED;
  3058. arena_run_dalloc(arena, run, false);
  3059. }
  3060. static void
  3061. arena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
  3062. size_t oldsize, size_t newsize, bool dirty)
  3063. {
  3064. size_t pageind = ((uintptr_t)run - (uintptr_t)chunk) >> pagesize_2pow;
  3065. size_t npages = newsize >> pagesize_2pow;
  3066. assert(oldsize > newsize);
  3067. /*
  3068. * Update the chunk map so that arena_run_dalloc() can treat the
  3069. * trailing run as separately allocated.
  3070. */
  3071. chunk->map[pageind].bits = newsize | CHUNK_MAP_LARGE |
  3072. CHUNK_MAP_ALLOCATED;
  3073. chunk->map[pageind+npages].bits = (oldsize - newsize) | CHUNK_MAP_LARGE
  3074. | CHUNK_MAP_ALLOCATED;
  3075. arena_run_dalloc(arena, (arena_run_t *)((uintptr_t)run + newsize),
  3076. dirty);
  3077. }
  3078. static arena_run_t *
  3079. arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin)
  3080. {
  3081. arena_chunk_map_t *mapelm;
  3082. arena_run_t *run;
  3083. unsigned i, remainder;
  3084. /* Look for a usable run. */
  3085. mapelm = arena_run_tree_first(&bin->runs);
  3086. if (mapelm != NULL) {
  3087. /* run is guaranteed to have available space. */
  3088. arena_run_tree_remove(&bin->runs, mapelm);
  3089. run = (arena_run_t *)(mapelm->bits & ~pagesize_mask);
  3090. #ifdef MALLOC_STATS
  3091. bin->stats.reruns++;
  3092. #endif
  3093. return (run);
  3094. }
  3095. /* No existing runs have any space available. */
  3096. /* Allocate a new run. */
  3097. run = arena_run_alloc(arena, bin, bin->run_size, false, false);
  3098. if (run == NULL)
  3099. return (NULL);
  3100. /*
  3101. * Don't initialize if a race in arena_run_alloc() allowed an existing
  3102. * run to become usable.
  3103. */
  3104. if (run == bin->runcur)
  3105. return (run);
  3106. /* Initialize run internals. */
  3107. run->bin = bin;
  3108. for (i = 0; i < bin->regs_mask_nelms - 1; i++)
  3109. run->regs_mask[i] = UINT_MAX;
  3110. remainder = bin->nregs & ((1U << (SIZEOF_INT_2POW + 3)) - 1);
  3111. if (remainder == 0)
  3112. run->regs_mask[i] = UINT_MAX;
  3113. else {
  3114. /* The last element has spare bits that need to be unset. */
  3115. run->regs_mask[i] = (UINT_MAX >> ((1U << (SIZEOF_INT_2POW + 3))
  3116. - remainder));
  3117. }
  3118. run->regs_minelm = 0;
  3119. run->nfree = bin->nregs;
  3120. #if defined(MALLOC_DEBUG) || defined(MOZ_JEMALLOC_HARD_ASSERTS)
  3121. run->magic = ARENA_RUN_MAGIC;
  3122. #endif
  3123. #ifdef MALLOC_STATS
  3124. bin->stats.nruns++;
  3125. bin->stats.curruns++;
  3126. if (bin->stats.curruns > bin->stats.highruns)
  3127. bin->stats.highruns = bin->stats.curruns;
  3128. #endif
  3129. return (run);
  3130. }
  3131. /* bin->runcur must have space available before this function is called. */
  3132. static inline void *
  3133. arena_bin_malloc_easy(arena_t *arena, arena_bin_t *bin, arena_run_t *run)
  3134. {
  3135. void *ret;
  3136. RELEASE_ASSERT(run->magic == ARENA_RUN_MAGIC);
  3137. RELEASE_ASSERT(run->nfree > 0);
  3138. ret = arena_run_reg_alloc(run, bin);
  3139. RELEASE_ASSERT(ret != NULL);
  3140. run->nfree--;
  3141. return (ret);
  3142. }
  3143. /* Re-fill bin->runcur, then call arena_bin_malloc_easy(). */
  3144. static void *
  3145. arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
  3146. {
  3147. bin->runcur = arena_bin_nonfull_run_get(arena, bin);
  3148. if (bin->runcur == NULL)
  3149. return (NULL);
  3150. RELEASE_ASSERT(bin->runcur->magic == ARENA_RUN_MAGIC);
  3151. RELEASE_ASSERT(bin->runcur->nfree > 0);
  3152. return (arena_bin_malloc_easy(arena, bin, bin->runcur));
  3153. }
  3154. /*
  3155. * Calculate bin->run_size such that it meets the following constraints:
  3156. *
  3157. * *) bin->run_size >= min_run_size
  3158. * *) bin->run_size <= arena_maxclass
  3159. * *) bin->run_size <= RUN_MAX_SMALL
  3160. * *) run header overhead <= RUN_MAX_OVRHD (or header overhead relaxed).
  3161. *
  3162. * bin->nregs, bin->regs_mask_nelms, and bin->reg0_offset are
  3163. * also calculated here, since these settings are all interdependent.
  3164. */
  3165. static size_t
  3166. arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size)
  3167. {
  3168. size_t try_run_size, good_run_size;
  3169. unsigned good_nregs, good_mask_nelms, good_reg0_offset;
  3170. unsigned try_nregs, try_mask_nelms, try_reg0_offset;
  3171. assert(min_run_size >= pagesize);
  3172. assert(min_run_size <= arena_maxclass);
  3173. /*
  3174. * Calculate known-valid settings before entering the run_size
  3175. * expansion loop, so that the first part of the loop always copies
  3176. * valid settings.
  3177. *
  3178. * The do..while loop iteratively reduces the number of regions until
  3179. * the run header and the regions no longer overlap. A closed formula
  3180. * would be quite messy, since there is an interdependency between the
  3181. * header's mask length and the number of regions.
  3182. */
  3183. try_run_size = min_run_size;
  3184. try_nregs = ((try_run_size - sizeof(arena_run_t)) / bin->reg_size)
  3185. + 1; /* Counter-act try_nregs-- in loop. */
  3186. do {
  3187. try_nregs--;
  3188. try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +
  3189. ((try_nregs & ((1U << (SIZEOF_INT_2POW + 3)) - 1)) ? 1 : 0);
  3190. try_reg0_offset = try_run_size - (try_nregs * bin->reg_size);
  3191. } while (sizeof(arena_run_t) + (sizeof(unsigned) * (try_mask_nelms - 1))
  3192. > try_reg0_offset);
  3193. /* run_size expansion loop. */
  3194. do {
  3195. /*
  3196. * Copy valid settings before trying more aggressive settings.
  3197. */
  3198. good_run_size = try_run_size;
  3199. good_nregs = try_nregs;
  3200. good_mask_nelms = try_mask_nelms;
  3201. good_reg0_offset = try_reg0_offset;
  3202. /* Try more aggressive settings. */
  3203. try_run_size += pagesize;
  3204. try_nregs = ((try_run_size - sizeof(arena_run_t)) /
  3205. bin->reg_size) + 1; /* Counter-act try_nregs-- in loop. */
  3206. do {
  3207. try_nregs--;
  3208. try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +
  3209. ((try_nregs & ((1U << (SIZEOF_INT_2POW + 3)) - 1)) ?
  3210. 1 : 0);
  3211. try_reg0_offset = try_run_size - (try_nregs *
  3212. bin->reg_size);
  3213. } while (sizeof(arena_run_t) + (sizeof(unsigned) *
  3214. (try_mask_nelms - 1)) > try_reg0_offset);
  3215. } while (try_run_size <= arena_maxclass
  3216. && RUN_MAX_OVRHD * (bin->reg_size << 3) > RUN_MAX_OVRHD_RELAX
  3217. && (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size);
  3218. assert(sizeof(arena_run_t) + (sizeof(unsigned) * (good_mask_nelms - 1))
  3219. <= good_reg0_offset);
  3220. assert((good_mask_nelms << (SIZEOF_INT_2POW + 3)) >= good_nregs);
  3221. /* Copy final settings. */
  3222. bin->run_size = good_run_size;
  3223. bin->nregs = good_nregs;
  3224. bin->regs_mask_nelms = good_mask_nelms;
  3225. bin->reg0_offset = good_reg0_offset;
  3226. return (good_run_size);
  3227. }
  3228. static inline void *
  3229. arena_malloc_small(arena_t *arena, size_t size, bool zero)
  3230. {
  3231. void *ret;
  3232. arena_bin_t *bin;
  3233. arena_run_t *run;
  3234. if (size < small_min) {
  3235. /* Tiny. */
  3236. size = pow2_ceil(size);
  3237. bin = &arena->bins[ffs((int)(size >> (TINY_MIN_2POW +
  3238. 1)))];
  3239. #if (!defined(NDEBUG) || defined(MALLOC_STATS))
  3240. /*
  3241. * Bin calculation is always correct, but we may need
  3242. * to fix size for the purposes of assertions and/or
  3243. * stats accuracy.
  3244. */
  3245. if (size < (1U << TINY_MIN_2POW))
  3246. size = (1U << TINY_MIN_2POW);
  3247. #endif
  3248. } else if (size <= small_max) {
  3249. /* Quantum-spaced. */
  3250. size = QUANTUM_CEILING(size);
  3251. bin = &arena->bins[ntbins + (size >> opt_quantum_2pow)
  3252. - 1];
  3253. } else {
  3254. /* Sub-page. */
  3255. size = pow2_ceil(size);
  3256. bin = &arena->bins[ntbins + nqbins
  3257. + (ffs((int)(size >> opt_small_max_2pow)) - 2)];
  3258. }
  3259. RELEASE_ASSERT(size == bin->reg_size);
  3260. malloc_spin_lock(&arena->lock);
  3261. if ((run = bin->runcur) != NULL && run->nfree > 0)
  3262. ret = arena_bin_malloc_easy(arena, bin, run);
  3263. else
  3264. ret = arena_bin_malloc_hard(arena, bin);
  3265. if (ret == NULL) {
  3266. malloc_spin_unlock(&arena->lock);
  3267. return (NULL);
  3268. }
  3269. #ifdef MALLOC_STATS
  3270. bin->stats.nrequests++;
  3271. arena->stats.nmalloc_small++;
  3272. arena->stats.allocated_small += size;
  3273. #endif
  3274. malloc_spin_unlock(&arena->lock);
  3275. if (zero == false) {
  3276. #ifdef MALLOC_FILL
  3277. if (opt_junk)
  3278. memset(ret, 0xe4, size);
  3279. else if (opt_zero)
  3280. memset(ret, 0, size);
  3281. #endif
  3282. } else
  3283. memset(ret, 0, size);
  3284. return (ret);
  3285. }
  3286. static void *
  3287. arena_malloc_large(arena_t *arena, size_t size, bool zero)
  3288. {
  3289. void *ret;
  3290. /* Large allocation. */
  3291. size = PAGE_CEILING(size);
  3292. malloc_spin_lock(&arena->lock);
  3293. ret = (void *)arena_run_alloc(arena, NULL, size, true, zero);
  3294. if (ret == NULL) {
  3295. malloc_spin_unlock(&arena->lock);
  3296. return (NULL);
  3297. }
  3298. #ifdef MALLOC_STATS
  3299. arena->stats.nmalloc_large++;
  3300. arena->stats.allocated_large += size;
  3301. #endif
  3302. malloc_spin_unlock(&arena->lock);
  3303. if (zero == false) {
  3304. #ifdef MALLOC_FILL
  3305. if (opt_junk)
  3306. memset(ret, 0xe4, size);
  3307. else if (opt_zero)
  3308. memset(ret, 0, size);
  3309. #endif
  3310. }
  3311. return (ret);
  3312. }
  3313. static inline void *
  3314. arena_malloc(arena_t *arena, size_t size, bool zero)
  3315. {
  3316. assert(arena != NULL);
  3317. RELEASE_ASSERT(arena->magic == ARENA_MAGIC);
  3318. assert(size != 0);
  3319. assert(QUANTUM_CEILING(size) <= arena_maxclass);
  3320. if (size <= bin_maxclass) {
  3321. return (arena_malloc_small(arena, size, zero));
  3322. } else
  3323. return (arena_malloc_large(arena, size, zero));
  3324. }
  3325. static inline void *
  3326. imalloc(size_t size)
  3327. {
  3328. assert(size != 0);
  3329. if (size <= arena_maxclass)
  3330. return (arena_malloc(choose_arena(), size, false));
  3331. else
  3332. return (huge_malloc(size, false));
  3333. }
  3334. static inline void *
  3335. icalloc(size_t size)
  3336. {
  3337. if (size <= arena_maxclass)
  3338. return (arena_malloc(choose_arena(), size, true));
  3339. else
  3340. return (huge_malloc(size, true));
  3341. }
  3342. /* Only handles large allocations that require more than page alignment. */
  3343. static void *
  3344. arena_palloc(arena_t *arena, size_t alignment, size_t size, size_t alloc_size)
  3345. {
  3346. void *ret;
  3347. size_t offset;
  3348. arena_chunk_t *chunk;
  3349. assert((size & pagesize_mask) == 0);
  3350. assert((alignment & pagesize_mask) == 0);
  3351. malloc_spin_lock(&arena->lock);
  3352. ret = (void *)arena_run_alloc(arena, NULL, alloc_size, true, false);
  3353. if (ret == NULL) {
  3354. malloc_spin_unlock(&arena->lock);
  3355. return (NULL);
  3356. }
  3357. chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ret);
  3358. offset = (uintptr_t)ret & (alignment - 1);
  3359. assert((offset & pagesize_mask) == 0);
  3360. assert(offset < alloc_size);
  3361. if (offset == 0)
  3362. arena_run_trim_tail(arena, chunk, (arena_run_t*)ret, alloc_size, size, false);
  3363. else {
  3364. size_t leadsize, trailsize;
  3365. leadsize = alignment - offset;
  3366. if (leadsize > 0) {
  3367. arena_run_trim_head(arena, chunk, (arena_run_t*)ret, alloc_size,
  3368. alloc_size - leadsize);
  3369. ret = (void *)((uintptr_t)ret + leadsize);
  3370. }
  3371. trailsize = alloc_size - leadsize - size;
  3372. if (trailsize != 0) {
  3373. /* Trim trailing space. */
  3374. assert(trailsize < alloc_size);
  3375. arena_run_trim_tail(arena, chunk, (arena_run_t*)ret, size + trailsize,
  3376. size, false);
  3377. }
  3378. }
  3379. #ifdef MALLOC_STATS
  3380. arena->stats.nmalloc_large++;
  3381. arena->stats.allocated_large += size;
  3382. #endif
  3383. malloc_spin_unlock(&arena->lock);
  3384. #ifdef MALLOC_FILL
  3385. if (opt_junk)
  3386. memset(ret, 0xe4, size);
  3387. else if (opt_zero)
  3388. memset(ret, 0, size);
  3389. #endif
  3390. return (ret);
  3391. }
  3392. static inline void *
  3393. ipalloc(size_t alignment, size_t size)
  3394. {
  3395. void *ret;
  3396. size_t ceil_size;
  3397. /*
  3398. * Round size up to the nearest multiple of alignment.
  3399. *
  3400. * This done, we can take advantage of the fact that for each small
  3401. * size class, every object is aligned at the smallest power of two
  3402. * that is non-zero in the base two representation of the size. For
  3403. * example:
  3404. *
  3405. * Size | Base 2 | Minimum alignment
  3406. * -----+----------+------------------
  3407. * 96 | 1100000 | 32
  3408. * 144 | 10100000 | 32
  3409. * 192 | 11000000 | 64
  3410. *
  3411. * Depending on runtime settings, it is possible that arena_malloc()
  3412. * will further round up to a power of two, but that never causes
  3413. * correctness issues.
  3414. */
  3415. ceil_size = (size + (alignment - 1)) & (-alignment);
  3416. /*
  3417. * (ceil_size < size) protects against the combination of maximal
  3418. * alignment and size greater than maximal alignment.
  3419. */
  3420. if (ceil_size < size) {
  3421. /* size_t overflow. */
  3422. return (NULL);
  3423. }
  3424. if (ceil_size <= pagesize || (alignment <= pagesize
  3425. && ceil_size <= arena_maxclass))
  3426. ret = arena_malloc(choose_arena(), ceil_size, false);
  3427. else {
  3428. size_t run_size;
  3429. /*
  3430. * We can't achieve sub-page alignment, so round up alignment
  3431. * permanently; it makes later calculations simpler.
  3432. */
  3433. alignment = PAGE_CEILING(alignment);
  3434. ceil_size = PAGE_CEILING(size);
  3435. /*
  3436. * (ceil_size < size) protects against very large sizes within
  3437. * pagesize of SIZE_T_MAX.
  3438. *
  3439. * (ceil_size + alignment < ceil_size) protects against the
  3440. * combination of maximal alignment and ceil_size large enough
  3441. * to cause overflow. This is similar to the first overflow
  3442. * check above, but it needs to be repeated due to the new
  3443. * ceil_size value, which may now be *equal* to maximal
  3444. * alignment, whereas before we only detected overflow if the
  3445. * original size was *greater* than maximal alignment.
  3446. */
  3447. if (ceil_size < size || ceil_size + alignment < ceil_size) {
  3448. /* size_t overflow. */
  3449. return (NULL);
  3450. }
  3451. /*
  3452. * Calculate the size of the over-size run that arena_palloc()
  3453. * would need to allocate in order to guarantee the alignment.
  3454. */
  3455. if (ceil_size >= alignment)
  3456. run_size = ceil_size + alignment - pagesize;
  3457. else {
  3458. /*
  3459. * It is possible that (alignment << 1) will cause
  3460. * overflow, but it doesn't matter because we also
  3461. * subtract pagesize, which in the case of overflow
  3462. * leaves us with a very large run_size. That causes
  3463. * the first conditional below to fail, which means
  3464. * that the bogus run_size value never gets used for
  3465. * anything important.
  3466. */
  3467. run_size = (alignment << 1) - pagesize;
  3468. }
  3469. if (run_size <= arena_maxclass) {
  3470. ret = arena_palloc(choose_arena(), alignment, ceil_size,
  3471. run_size);
  3472. } else if (alignment <= chunksize)
  3473. ret = huge_malloc(ceil_size, false);
  3474. else
  3475. ret = huge_palloc(ceil_size, alignment, false);
  3476. }
  3477. assert(((uintptr_t)ret & (alignment - 1)) == 0);
  3478. return (ret);
  3479. }
  3480. /* Return the size of the allocation pointed to by ptr. */
  3481. static size_t
  3482. arena_salloc(const void *ptr)
  3483. {
  3484. size_t ret;
  3485. arena_chunk_t *chunk;
  3486. size_t pageind, mapbits;
  3487. assert(ptr != NULL);
  3488. assert(CHUNK_ADDR2BASE(ptr) != ptr);
  3489. chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
  3490. pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> pagesize_2pow);
  3491. mapbits = chunk->map[pageind].bits;
  3492. RELEASE_ASSERT((mapbits & CHUNK_MAP_ALLOCATED) != 0);
  3493. if ((mapbits & CHUNK_MAP_LARGE) == 0) {
  3494. arena_run_t *run = (arena_run_t *)(mapbits & ~pagesize_mask);
  3495. RELEASE_ASSERT(run->magic == ARENA_RUN_MAGIC);
  3496. ret = run->bin->reg_size;
  3497. } else {
  3498. ret = mapbits & ~pagesize_mask;
  3499. RELEASE_ASSERT(ret != 0);
  3500. }
  3501. return (ret);
  3502. }
  3503. /*
  3504. * Validate ptr before assuming that it points to an allocation. Currently,
  3505. * the following validation is performed:
  3506. *
  3507. * + Check that ptr is not NULL.
  3508. *
  3509. * + Check that ptr lies within a mapped chunk.
  3510. */
  3511. static inline size_t
  3512. isalloc_validate(const void *ptr)
  3513. {
  3514. arena_chunk_t *chunk;
  3515. chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
  3516. if (chunk == NULL)
  3517. return (0);
  3518. if (malloc_rtree_get(chunk_rtree, (uintptr_t)chunk) == NULL)
  3519. return (0);
  3520. if (chunk != ptr) {
  3521. RELEASE_ASSERT(chunk->arena->magic == ARENA_MAGIC);
  3522. return (arena_salloc(ptr));
  3523. } else {
  3524. size_t ret;
  3525. extent_node_t *node;
  3526. extent_node_t key;
  3527. /* Chunk. */
  3528. key.addr = (void *)chunk;
  3529. malloc_mutex_lock(&huge_mtx);
  3530. node = extent_tree_ad_search(&huge, &key);
  3531. if (node != NULL)
  3532. ret = node->size;
  3533. else
  3534. ret = 0;
  3535. malloc_mutex_unlock(&huge_mtx);
  3536. return (ret);
  3537. }
  3538. }
  3539. static inline size_t
  3540. isalloc(const void *ptr)
  3541. {
  3542. size_t ret;
  3543. arena_chunk_t *chunk;
  3544. assert(ptr != NULL);
  3545. chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
  3546. if (chunk != ptr) {
  3547. /* Region. */
  3548. assert(chunk->arena->magic == ARENA_MAGIC);
  3549. ret = arena_salloc(ptr);
  3550. } else {
  3551. extent_node_t *node, key;
  3552. /* Chunk (huge allocation). */
  3553. malloc_mutex_lock(&huge_mtx);
  3554. /* Extract from tree of huge allocations. */
  3555. key.addr = __DECONST(void *, ptr);
  3556. node = extent_tree_ad_search(&huge, &key);
  3557. RELEASE_ASSERT(node != NULL);
  3558. ret = node->size;
  3559. malloc_mutex_unlock(&huge_mtx);
  3560. }
  3561. return (ret);
  3562. }
  3563. static inline void
  3564. arena_dalloc_small(arena_t *arena, arena_chunk_t *chunk, void *ptr,
  3565. arena_chunk_map_t *mapelm)
  3566. {
  3567. arena_run_t *run;
  3568. arena_bin_t *bin;
  3569. size_t size;
  3570. run = (arena_run_t *)(mapelm->bits & ~pagesize_mask);
  3571. RELEASE_ASSERT(run->magic == ARENA_RUN_MAGIC);
  3572. bin = run->bin;
  3573. size = bin->reg_size;
  3574. #ifdef MALLOC_FILL
  3575. if (opt_poison)
  3576. memset(ptr, 0xe5, size);
  3577. #endif
  3578. arena_run_reg_dalloc(run, bin, ptr, size);
  3579. run->nfree++;
  3580. if (run->nfree == bin->nregs) {
  3581. /* Deallocate run. */
  3582. if (run == bin->runcur)
  3583. bin->runcur = NULL;
  3584. else if (bin->nregs != 1) {
  3585. size_t run_pageind = (((uintptr_t)run -
  3586. (uintptr_t)chunk)) >> pagesize_2pow;
  3587. arena_chunk_map_t *run_mapelm =
  3588. &chunk->map[run_pageind];
  3589. /*
  3590. * This block's conditional is necessary because if the
  3591. * run only contains one region, then it never gets
  3592. * inserted into the non-full runs tree.
  3593. */
  3594. RELEASE_ASSERT(arena_run_tree_search(&bin->runs, run_mapelm) ==
  3595. run_mapelm);
  3596. arena_run_tree_remove(&bin->runs, run_mapelm);
  3597. }
  3598. #if defined(MALLOC_DEBUG) || defined(MOZ_JEMALLOC_HARD_ASSERTS)
  3599. run->magic = 0;
  3600. #endif
  3601. arena_run_dalloc(arena, run, true);
  3602. #ifdef MALLOC_STATS
  3603. bin->stats.curruns--;
  3604. #endif
  3605. } else if (run->nfree == 1 && run != bin->runcur) {
  3606. /*
  3607. * Make sure that bin->runcur always refers to the lowest
  3608. * non-full run, if one exists.
  3609. */
  3610. if (bin->runcur == NULL)
  3611. bin->runcur = run;
  3612. else if ((uintptr_t)run < (uintptr_t)bin->runcur) {
  3613. /* Switch runcur. */
  3614. if (bin->runcur->nfree > 0) {
  3615. arena_chunk_t *runcur_chunk =
  3616. (arena_chunk_t*)CHUNK_ADDR2BASE(bin->runcur);
  3617. size_t runcur_pageind =
  3618. (((uintptr_t)bin->runcur -
  3619. (uintptr_t)runcur_chunk)) >> pagesize_2pow;
  3620. arena_chunk_map_t *runcur_mapelm =
  3621. &runcur_chunk->map[runcur_pageind];
  3622. /* Insert runcur. */
  3623. RELEASE_ASSERT(arena_run_tree_search(&bin->runs,
  3624. runcur_mapelm) == NULL);
  3625. arena_run_tree_insert(&bin->runs,
  3626. runcur_mapelm);
  3627. }
  3628. bin->runcur = run;
  3629. } else {
  3630. size_t run_pageind = (((uintptr_t)run -
  3631. (uintptr_t)chunk)) >> pagesize_2pow;
  3632. arena_chunk_map_t *run_mapelm =
  3633. &chunk->map[run_pageind];
  3634. RELEASE_ASSERT(arena_run_tree_search(&bin->runs, run_mapelm) ==
  3635. NULL);
  3636. arena_run_tree_insert(&bin->runs, run_mapelm);
  3637. }
  3638. }
  3639. #ifdef MALLOC_STATS
  3640. arena->stats.allocated_small -= size;
  3641. arena->stats.ndalloc_small++;
  3642. #endif
  3643. }
  3644. static void
  3645. arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk, void *ptr)
  3646. {
  3647. /* Large allocation. */
  3648. malloc_spin_lock(&arena->lock);
  3649. #ifdef MALLOC_FILL
  3650. #ifndef MALLOC_STATS
  3651. if (opt_poison)
  3652. #endif
  3653. #endif
  3654. {
  3655. size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >>
  3656. pagesize_2pow;
  3657. size_t size = chunk->map[pageind].bits & ~pagesize_mask;
  3658. #ifdef MALLOC_FILL
  3659. #ifdef MALLOC_STATS
  3660. if (opt_poison)
  3661. #endif
  3662. memset(ptr, 0xe5, size);
  3663. #endif
  3664. #ifdef MALLOC_STATS
  3665. arena->stats.allocated_large -= size;
  3666. #endif
  3667. }
  3668. #ifdef MALLOC_STATS
  3669. arena->stats.ndalloc_large++;
  3670. #endif
  3671. arena_run_dalloc(arena, (arena_run_t *)ptr, true);
  3672. malloc_spin_unlock(&arena->lock);
  3673. }
  3674. static inline void
  3675. arena_dalloc(void *ptr, size_t offset)
  3676. {
  3677. arena_chunk_t *chunk;
  3678. arena_t *arena;
  3679. size_t pageind;
  3680. arena_chunk_map_t *mapelm;
  3681. assert(ptr != NULL);
  3682. assert(offset != 0);
  3683. assert(CHUNK_ADDR2OFFSET(ptr) == offset);
  3684. chunk = (arena_chunk_t *) ((uintptr_t)ptr - offset);
  3685. arena = chunk->arena;
  3686. assert(arena != NULL);
  3687. RELEASE_ASSERT(arena->magic == ARENA_MAGIC);
  3688. pageind = offset >> pagesize_2pow;
  3689. mapelm = &chunk->map[pageind];
  3690. RELEASE_ASSERT((mapelm->bits & CHUNK_MAP_ALLOCATED) != 0);
  3691. if ((mapelm->bits & CHUNK_MAP_LARGE) == 0) {
  3692. /* Small allocation. */
  3693. malloc_spin_lock(&arena->lock);
  3694. arena_dalloc_small(arena, chunk, ptr, mapelm);
  3695. malloc_spin_unlock(&arena->lock);
  3696. } else
  3697. arena_dalloc_large(arena, chunk, ptr);
  3698. }
  3699. static inline void
  3700. idalloc(void *ptr)
  3701. {
  3702. size_t offset;
  3703. assert(ptr != NULL);
  3704. offset = CHUNK_ADDR2OFFSET(ptr);
  3705. if (offset != 0)
  3706. arena_dalloc(ptr, offset);
  3707. else
  3708. huge_dalloc(ptr);
  3709. }
  3710. static void
  3711. arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk, void *ptr,
  3712. size_t size, size_t oldsize)
  3713. {
  3714. assert(size < oldsize);
  3715. /*
  3716. * Shrink the run, and make trailing pages available for other
  3717. * allocations.
  3718. */
  3719. malloc_spin_lock(&arena->lock);
  3720. arena_run_trim_tail(arena, chunk, (arena_run_t *)ptr, oldsize, size,
  3721. true);
  3722. #ifdef MALLOC_STATS
  3723. arena->stats.allocated_large -= oldsize - size;
  3724. #endif
  3725. malloc_spin_unlock(&arena->lock);
  3726. }
  3727. static bool
  3728. arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
  3729. size_t size, size_t oldsize)
  3730. {
  3731. size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> pagesize_2pow;
  3732. size_t npages = oldsize >> pagesize_2pow;
  3733. RELEASE_ASSERT(oldsize == (chunk->map[pageind].bits & ~pagesize_mask));
  3734. /* Try to extend the run. */
  3735. assert(size > oldsize);
  3736. malloc_spin_lock(&arena->lock);
  3737. if (pageind + npages < chunk_npages && (chunk->map[pageind+npages].bits
  3738. & CHUNK_MAP_ALLOCATED) == 0 && (chunk->map[pageind+npages].bits &
  3739. ~pagesize_mask) >= size - oldsize) {
  3740. /*
  3741. * The next run is available and sufficiently large. Split the
  3742. * following run, then merge the first part with the existing
  3743. * allocation.
  3744. */
  3745. arena_run_split(arena, (arena_run_t *)((uintptr_t)chunk +
  3746. ((pageind+npages) << pagesize_2pow)), size - oldsize, true,
  3747. false);
  3748. chunk->map[pageind].bits = size | CHUNK_MAP_LARGE |
  3749. CHUNK_MAP_ALLOCATED;
  3750. chunk->map[pageind+npages].bits = CHUNK_MAP_LARGE |
  3751. CHUNK_MAP_ALLOCATED;
  3752. #ifdef MALLOC_STATS
  3753. arena->stats.allocated_large += size - oldsize;
  3754. #endif
  3755. malloc_spin_unlock(&arena->lock);
  3756. return (false);
  3757. }
  3758. malloc_spin_unlock(&arena->lock);
  3759. return (true);
  3760. }
  3761. /*
  3762. * Try to resize a large allocation, in order to avoid copying. This will
  3763. * always fail if growing an object, and the following run is already in use.
  3764. */
  3765. static bool
  3766. arena_ralloc_large(void *ptr, size_t size, size_t oldsize)
  3767. {
  3768. size_t psize;
  3769. psize = PAGE_CEILING(size);
  3770. if (psize == oldsize) {
  3771. /* Same size class. */
  3772. #ifdef MALLOC_FILL
  3773. if (opt_poison && size < oldsize) {
  3774. memset((void *)((uintptr_t)ptr + size), 0xe5, oldsize -
  3775. size);
  3776. }
  3777. #endif
  3778. return (false);
  3779. } else {
  3780. arena_chunk_t *chunk;
  3781. arena_t *arena;
  3782. chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
  3783. arena = chunk->arena;
  3784. RELEASE_ASSERT(arena->magic == ARENA_MAGIC);
  3785. if (psize < oldsize) {
  3786. #ifdef MALLOC_FILL
  3787. /* Fill before shrinking in order avoid a race. */
  3788. if (opt_poison) {
  3789. memset((void *)((uintptr_t)ptr + size), 0xe5,
  3790. oldsize - size);
  3791. }
  3792. #endif
  3793. arena_ralloc_large_shrink(arena, chunk, ptr, psize,
  3794. oldsize);
  3795. return (false);
  3796. } else {
  3797. bool ret = arena_ralloc_large_grow(arena, chunk, ptr,
  3798. psize, oldsize);
  3799. #ifdef MALLOC_FILL
  3800. if (ret == false && opt_zero) {
  3801. memset((void *)((uintptr_t)ptr + oldsize), 0,
  3802. size - oldsize);
  3803. }
  3804. #endif
  3805. return (ret);
  3806. }
  3807. }
  3808. }
  3809. static void *
  3810. arena_ralloc(void *ptr, size_t size, size_t oldsize)
  3811. {
  3812. void *ret;
  3813. size_t copysize;
  3814. /* Try to avoid moving the allocation. */
  3815. if (size < small_min) {
  3816. if (oldsize < small_min &&
  3817. ffs((int)(pow2_ceil(size) >> (TINY_MIN_2POW + 1)))
  3818. == ffs((int)(pow2_ceil(oldsize) >> (TINY_MIN_2POW + 1))))
  3819. goto IN_PLACE; /* Same size class. */
  3820. } else if (size <= small_max) {
  3821. if (oldsize >= small_min && oldsize <= small_max &&
  3822. (QUANTUM_CEILING(size) >> opt_quantum_2pow)
  3823. == (QUANTUM_CEILING(oldsize) >> opt_quantum_2pow))
  3824. goto IN_PLACE; /* Same size class. */
  3825. } else if (size <= bin_maxclass) {
  3826. if (oldsize > small_max && oldsize <= bin_maxclass &&
  3827. pow2_ceil(size) == pow2_ceil(oldsize))
  3828. goto IN_PLACE; /* Same size class. */
  3829. } else if (oldsize > bin_maxclass && oldsize <= arena_maxclass) {
  3830. assert(size > bin_maxclass);
  3831. if (arena_ralloc_large(ptr, size, oldsize) == false)
  3832. return (ptr);
  3833. }
  3834. /*
  3835. * If we get here, then size and oldsize are different enough that we
  3836. * need to move the object. In that case, fall back to allocating new
  3837. * space and copying.
  3838. */
  3839. ret = arena_malloc(choose_arena(), size, false);
  3840. if (ret == NULL)
  3841. return (NULL);
  3842. /* Junk/zero-filling were already done by arena_malloc(). */
  3843. copysize = (size < oldsize) ? size : oldsize;
  3844. #ifdef VM_COPY_MIN
  3845. if (copysize >= VM_COPY_MIN)
  3846. pages_copy(ret, ptr, copysize);
  3847. else
  3848. #endif
  3849. memcpy(ret, ptr, copysize);
  3850. idalloc(ptr);
  3851. return (ret);
  3852. IN_PLACE:
  3853. #ifdef MALLOC_FILL
  3854. if (opt_poison && size < oldsize)
  3855. memset((void *)((uintptr_t)ptr + size), 0xe5, oldsize - size);
  3856. else if (opt_zero && size > oldsize)
  3857. memset((void *)((uintptr_t)ptr + oldsize), 0, size - oldsize);
  3858. #endif
  3859. return (ptr);
  3860. }
  3861. static inline void *
  3862. iralloc(void *ptr, size_t size)
  3863. {
  3864. size_t oldsize;
  3865. assert(ptr != NULL);
  3866. assert(size != 0);
  3867. oldsize = isalloc(ptr);
  3868. if (size <= arena_maxclass)
  3869. return (arena_ralloc(ptr, size, oldsize));
  3870. else
  3871. return (huge_ralloc(ptr, size, oldsize));
  3872. }
  3873. static bool
  3874. arena_new(arena_t *arena)
  3875. {
  3876. unsigned i;
  3877. arena_bin_t *bin;
  3878. size_t pow2_size, prev_run_size;
  3879. if (malloc_spin_init(&arena->lock))
  3880. return (true);
  3881. #ifdef MALLOC_STATS
  3882. memset(&arena->stats, 0, sizeof(arena_stats_t));
  3883. #endif
  3884. /* Initialize chunks. */
  3885. arena_chunk_tree_dirty_new(&arena->chunks_dirty);
  3886. #ifdef MALLOC_DOUBLE_PURGE
  3887. LinkedList_Init(&arena->chunks_madvised);
  3888. #endif
  3889. arena->spare = NULL;
  3890. arena->ndirty = 0;
  3891. arena_avail_tree_new(&arena->runs_avail);
  3892. /* Initialize bins. */
  3893. prev_run_size = pagesize;
  3894. /* (2^n)-spaced tiny bins. */
  3895. for (i = 0; i < ntbins; i++) {
  3896. bin = &arena->bins[i];
  3897. bin->runcur = NULL;
  3898. arena_run_tree_new(&bin->runs);
  3899. bin->reg_size = (1ULL << (TINY_MIN_2POW + i));
  3900. prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
  3901. #ifdef MALLOC_STATS
  3902. memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
  3903. #endif
  3904. }
  3905. /* Quantum-spaced bins. */
  3906. for (; i < ntbins + nqbins; i++) {
  3907. bin = &arena->bins[i];
  3908. bin->runcur = NULL;
  3909. arena_run_tree_new(&bin->runs);
  3910. bin->reg_size = quantum * (i - ntbins + 1);
  3911. pow2_size = pow2_ceil(quantum * (i - ntbins + 1));
  3912. prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
  3913. #ifdef MALLOC_STATS
  3914. memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
  3915. #endif
  3916. }
  3917. /* (2^n)-spaced sub-page bins. */
  3918. for (; i < ntbins + nqbins + nsbins; i++) {
  3919. bin = &arena->bins[i];
  3920. bin->runcur = NULL;
  3921. arena_run_tree_new(&bin->runs);
  3922. bin->reg_size = (small_max << (i - (ntbins + nqbins) + 1));
  3923. prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
  3924. #ifdef MALLOC_STATS
  3925. memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
  3926. #endif
  3927. }
  3928. #if defined(MALLOC_DEBUG) || defined(MOZ_JEMALLOC_HARD_ASSERTS)
  3929. arena->magic = ARENA_MAGIC;
  3930. #endif
  3931. return (false);
  3932. }
  3933. /* Create a new arena and insert it into the arenas array at index ind. */
  3934. static arena_t *
  3935. arenas_extend(unsigned ind)
  3936. {
  3937. arena_t *ret;
  3938. /* Allocate enough space for trailing bins. */
  3939. ret = (arena_t *)base_alloc(sizeof(arena_t)
  3940. + (sizeof(arena_bin_t) * (ntbins + nqbins + nsbins - 1)));
  3941. if (ret != NULL && arena_new(ret) == false) {
  3942. arenas[ind] = ret;
  3943. return (ret);
  3944. }
  3945. /* Only reached if there is an OOM error. */
  3946. /*
  3947. * OOM here is quite inconvenient to propagate, since dealing with it
  3948. * would require a check for failure in the fast path. Instead, punt
  3949. * by using arenas[0]. In practice, this is an extremely unlikely
  3950. * failure.
  3951. */
  3952. _malloc_message(_getprogname(),
  3953. ": (malloc) Error initializing arena\n", "", "");
  3954. if (opt_abort)
  3955. abort();
  3956. return (arenas[0]);
  3957. }
  3958. /*
  3959. * End arena.
  3960. */
  3961. /******************************************************************************/
  3962. /*
  3963. * Begin general internal functions.
  3964. */
  3965. static void *
  3966. huge_malloc(size_t size, bool zero)
  3967. {
  3968. return huge_palloc(size, chunksize, zero);
  3969. }
  3970. static void *
  3971. huge_palloc(size_t size, size_t alignment, bool zero)
  3972. {
  3973. void *ret;
  3974. size_t csize;
  3975. size_t psize;
  3976. extent_node_t *node;
  3977. /* Allocate one or more contiguous chunks for this request. */
  3978. csize = CHUNK_CEILING(size);
  3979. if (csize == 0) {
  3980. /* size is large enough to cause size_t wrap-around. */
  3981. return (NULL);
  3982. }
  3983. /* Allocate an extent node with which to track the chunk. */
  3984. node = base_node_alloc();
  3985. if (node == NULL)
  3986. return (NULL);
  3987. ret = chunk_alloc(csize, alignment, false, zero);
  3988. if (ret == NULL) {
  3989. base_node_dealloc(node);
  3990. return (NULL);
  3991. }
  3992. /* Insert node into huge. */
  3993. node->addr = ret;
  3994. psize = PAGE_CEILING(size);
  3995. node->size = psize;
  3996. malloc_mutex_lock(&huge_mtx);
  3997. extent_tree_ad_insert(&huge, node);
  3998. #ifdef MALLOC_STATS
  3999. huge_nmalloc++;
  4000. /* Although we allocated space for csize bytes, we indicate that we've
  4001. * allocated only psize bytes.
  4002. *
  4003. * If DECOMMIT is defined, this is a reasonable thing to do, since
  4004. * we'll explicitly decommit the bytes in excess of psize.
  4005. *
  4006. * If DECOMMIT is not defined, then we're relying on the OS to be lazy
  4007. * about how it allocates physical pages to mappings. If we never
  4008. * touch the pages in excess of psize, the OS won't allocate a physical
  4009. * page, and we won't use more than psize bytes of physical memory.
  4010. *
  4011. * A correct program will only touch memory in excess of how much it
  4012. * requested if it first calls malloc_usable_size and finds out how
  4013. * much space it has to play with. But because we set node->size =
  4014. * psize above, malloc_usable_size will return psize, not csize, and
  4015. * the program will (hopefully) never touch bytes in excess of psize.
  4016. * Thus those bytes won't take up space in physical memory, and we can
  4017. * reasonably claim we never "allocated" them in the first place. */
  4018. huge_allocated += psize;
  4019. huge_mapped += csize;
  4020. #endif
  4021. malloc_mutex_unlock(&huge_mtx);
  4022. #ifdef MALLOC_DECOMMIT
  4023. if (csize - psize > 0)
  4024. pages_decommit((void *)((uintptr_t)ret + psize), csize - psize);
  4025. #endif
  4026. #ifdef MALLOC_FILL
  4027. if (zero == false) {
  4028. if (opt_junk)
  4029. # ifdef MALLOC_DECOMMIT
  4030. memset(ret, 0xe4, psize);
  4031. # else
  4032. memset(ret, 0xe4, csize);
  4033. # endif
  4034. else if (opt_zero)
  4035. # ifdef MALLOC_DECOMMIT
  4036. memset(ret, 0, psize);
  4037. # else
  4038. memset(ret, 0, csize);
  4039. # endif
  4040. }
  4041. #endif
  4042. return (ret);
  4043. }
  4044. static void *
  4045. huge_ralloc(void *ptr, size_t size, size_t oldsize)
  4046. {
  4047. void *ret;
  4048. size_t copysize;
  4049. /* Avoid moving the allocation if the size class would not change. */
  4050. if (oldsize > arena_maxclass &&
  4051. CHUNK_CEILING(size) == CHUNK_CEILING(oldsize)) {
  4052. size_t psize = PAGE_CEILING(size);
  4053. #ifdef MALLOC_FILL
  4054. if (opt_poison && size < oldsize) {
  4055. memset((void *)((uintptr_t)ptr + size), 0xe5, oldsize
  4056. - size);
  4057. }
  4058. #endif
  4059. #ifdef MALLOC_DECOMMIT
  4060. if (psize < oldsize) {
  4061. extent_node_t *node, key;
  4062. pages_decommit((void *)((uintptr_t)ptr + psize),
  4063. oldsize - psize);
  4064. /* Update recorded size. */
  4065. malloc_mutex_lock(&huge_mtx);
  4066. key.addr = __DECONST(void *, ptr);
  4067. node = extent_tree_ad_search(&huge, &key);
  4068. assert(node != NULL);
  4069. assert(node->size == oldsize);
  4070. # ifdef MALLOC_STATS
  4071. huge_allocated -= oldsize - psize;
  4072. /* No need to change huge_mapped, because we didn't
  4073. * (un)map anything. */
  4074. # endif
  4075. node->size = psize;
  4076. malloc_mutex_unlock(&huge_mtx);
  4077. } else if (psize > oldsize) {
  4078. pages_commit((void *)((uintptr_t)ptr + oldsize),
  4079. psize - oldsize);
  4080. }
  4081. #endif
  4082. /* Although we don't have to commit or decommit anything if
  4083. * DECOMMIT is not defined and the size class didn't change, we
  4084. * do need to update the recorded size if the size increased,
  4085. * so malloc_usable_size doesn't return a value smaller than
  4086. * what was requested via realloc(). */
  4087. if (psize > oldsize) {
  4088. /* Update recorded size. */
  4089. extent_node_t *node, key;
  4090. malloc_mutex_lock(&huge_mtx);
  4091. key.addr = __DECONST(void *, ptr);
  4092. node = extent_tree_ad_search(&huge, &key);
  4093. assert(node != NULL);
  4094. assert(node->size == oldsize);
  4095. # ifdef MALLOC_STATS
  4096. huge_allocated += psize - oldsize;
  4097. /* No need to change huge_mapped, because we didn't
  4098. * (un)map anything. */
  4099. # endif
  4100. node->size = psize;
  4101. malloc_mutex_unlock(&huge_mtx);
  4102. }
  4103. #ifdef MALLOC_FILL
  4104. if (opt_zero && size > oldsize) {
  4105. memset((void *)((uintptr_t)ptr + oldsize), 0, size
  4106. - oldsize);
  4107. }
  4108. #endif
  4109. return (ptr);
  4110. }
  4111. /*
  4112. * If we get here, then size and oldsize are different enough that we
  4113. * need to use a different size class. In that case, fall back to
  4114. * allocating new space and copying.
  4115. */
  4116. ret = huge_malloc(size, false);
  4117. if (ret == NULL)
  4118. return (NULL);
  4119. copysize = (size < oldsize) ? size : oldsize;
  4120. #ifdef VM_COPY_MIN
  4121. if (copysize >= VM_COPY_MIN)
  4122. pages_copy(ret, ptr, copysize);
  4123. else
  4124. #endif
  4125. memcpy(ret, ptr, copysize);
  4126. idalloc(ptr);
  4127. return (ret);
  4128. }
  4129. static void
  4130. huge_dalloc(void *ptr)
  4131. {
  4132. extent_node_t *node, key;
  4133. malloc_mutex_lock(&huge_mtx);
  4134. /* Extract from tree of huge allocations. */
  4135. key.addr = ptr;
  4136. node = extent_tree_ad_search(&huge, &key);
  4137. assert(node != NULL);
  4138. assert(node->addr == ptr);
  4139. extent_tree_ad_remove(&huge, node);
  4140. #ifdef MALLOC_STATS
  4141. huge_ndalloc++;
  4142. huge_allocated -= node->size;
  4143. huge_mapped -= CHUNK_CEILING(node->size);
  4144. #endif
  4145. malloc_mutex_unlock(&huge_mtx);
  4146. /* Unmap chunk. */
  4147. chunk_dealloc(node->addr, CHUNK_CEILING(node->size));
  4148. base_node_dealloc(node);
  4149. }
  4150. /*
  4151. * Platform-specific methods to determine the number of CPUs in a system.
  4152. * This will be used to determine the desired number of arenas.
  4153. */
  4154. #if (defined(MOZ_MEMORY_LINUX))
  4155. #include <fcntl.h>
  4156. static inline unsigned
  4157. malloc_ncpus(void)
  4158. {
  4159. unsigned ret;
  4160. int fd, nread, column;
  4161. char buf[1024];
  4162. static const char matchstr[] = "processor\t:";
  4163. int i;
  4164. /*
  4165. * sysconf(3) would be the preferred method for determining the number
  4166. * of CPUs, but it uses malloc internally, which causes untennable
  4167. * recursion during malloc initialization.
  4168. */
  4169. fd = open("/proc/cpuinfo", O_RDONLY);
  4170. if (fd == -1)
  4171. return (1); /* Error. */
  4172. /*
  4173. * Count the number of occurrences of matchstr at the beginnings of
  4174. * lines. This treats hyperthreaded CPUs as multiple processors.
  4175. */
  4176. column = 0;
  4177. ret = 0;
  4178. while (true) {
  4179. nread = read(fd, &buf, sizeof(buf));
  4180. if (nread <= 0)
  4181. break; /* EOF or error. */
  4182. for (i = 0;i < nread;i++) {
  4183. char c = buf[i];
  4184. if (c == '\n')
  4185. column = 0;
  4186. else if (column != -1) {
  4187. if (c == matchstr[column]) {
  4188. column++;
  4189. if (column == sizeof(matchstr) - 1) {
  4190. column = -1;
  4191. ret++;
  4192. }
  4193. } else
  4194. column = -1;
  4195. }
  4196. }
  4197. }
  4198. if (ret == 0)
  4199. ret = 1; /* Something went wrong in the parser. */
  4200. close(fd);
  4201. return (ret);
  4202. }
  4203. #elif (defined(MOZ_MEMORY_DARWIN))
  4204. #include <mach/mach_init.h>
  4205. #include <mach/mach_host.h>
  4206. static inline unsigned
  4207. malloc_ncpus(void)
  4208. {
  4209. kern_return_t error;
  4210. natural_t n;
  4211. processor_info_array_t pinfo;
  4212. mach_msg_type_number_t pinfocnt;
  4213. error = host_processor_info(mach_host_self(), PROCESSOR_BASIC_INFO,
  4214. &n, &pinfo, &pinfocnt);
  4215. if (error != KERN_SUCCESS)
  4216. return (1); /* Error. */
  4217. else
  4218. return (n);
  4219. }
  4220. #elif (defined(MOZ_MEMORY_SOLARIS) || defined(MOZ_MEMORY_BSD))
  4221. static inline unsigned
  4222. malloc_ncpus(void)
  4223. {
  4224. return sysconf(_SC_NPROCESSORS_ONLN);
  4225. }
  4226. #elif (defined(MOZ_MEMORY_WINDOWS))
  4227. static inline unsigned
  4228. malloc_ncpus(void)
  4229. {
  4230. SYSTEM_INFO info;
  4231. GetSystemInfo(&info);
  4232. return (info.dwNumberOfProcessors);
  4233. }
  4234. #else
  4235. static inline unsigned
  4236. malloc_ncpus(void)
  4237. {
  4238. /*
  4239. * We lack a way to determine the number of CPUs on this platform, so
  4240. * assume 1 CPU.
  4241. */
  4242. return (1);
  4243. }
  4244. #endif
  4245. static void
  4246. malloc_print_stats(void)
  4247. {
  4248. if (opt_print_stats) {
  4249. char s[UMAX2S_BUFSIZE];
  4250. _malloc_message("___ Begin malloc statistics ___\n", "", "",
  4251. "");
  4252. _malloc_message("Assertions ",
  4253. #ifdef NDEBUG
  4254. "disabled",
  4255. #else
  4256. "enabled",
  4257. #endif
  4258. "\n", "");
  4259. _malloc_message("Boolean MALLOC_OPTIONS: ",
  4260. opt_abort ? "A" : "a", "", "");
  4261. #ifdef MALLOC_FILL
  4262. _malloc_message(opt_poison ? "C" : "c", "", "", "");
  4263. _malloc_message(opt_junk ? "J" : "j", "", "", "");
  4264. #endif
  4265. _malloc_message("P", "", "", "");
  4266. #ifdef MALLOC_SYSV
  4267. _malloc_message(opt_sysv ? "V" : "v", "", "", "");
  4268. #endif
  4269. #ifdef MALLOC_XMALLOC
  4270. _malloc_message(opt_xmalloc ? "X" : "x", "", "", "");
  4271. #endif
  4272. #ifdef MALLOC_FILL
  4273. _malloc_message(opt_zero ? "Z" : "z", "", "", "");
  4274. #endif
  4275. _malloc_message("\n", "", "", "");
  4276. #ifndef MOZ_MEMORY_NARENAS_DEFAULT_ONE
  4277. _malloc_message("CPUs: ", umax2s(ncpus, 10, s), "\n", "");
  4278. #endif
  4279. _malloc_message("Max arenas: ", umax2s(narenas, 10, s), "\n",
  4280. "");
  4281. _malloc_message("Pointer size: ", umax2s(sizeof(void *), 10, s),
  4282. "\n", "");
  4283. _malloc_message("Quantum size: ", umax2s(quantum, 10, s), "\n",
  4284. "");
  4285. _malloc_message("Max small size: ", umax2s(small_max, 10, s),
  4286. "\n", "");
  4287. _malloc_message("Max dirty pages per arena: ",
  4288. umax2s(opt_dirty_max, 10, s), "\n", "");
  4289. _malloc_message("Chunk size: ", umax2s(chunksize, 10, s), "",
  4290. "");
  4291. _malloc_message(" (2^", umax2s(opt_chunk_2pow, 10, s), ")\n",
  4292. "");
  4293. #ifdef MALLOC_STATS
  4294. {
  4295. size_t allocated, mapped = 0;
  4296. unsigned i;
  4297. arena_t *arena;
  4298. /* Calculate and print allocated/mapped stats. */
  4299. /* arenas. */
  4300. for (i = 0, allocated = 0; i < narenas; i++) {
  4301. if (arenas[i] != NULL) {
  4302. malloc_spin_lock(&arenas[i]->lock);
  4303. allocated +=
  4304. arenas[i]->stats.allocated_small;
  4305. allocated +=
  4306. arenas[i]->stats.allocated_large;
  4307. mapped += arenas[i]->stats.mapped;
  4308. malloc_spin_unlock(&arenas[i]->lock);
  4309. }
  4310. }
  4311. /* huge/base. */
  4312. malloc_mutex_lock(&huge_mtx);
  4313. allocated += huge_allocated;
  4314. mapped += huge_mapped;
  4315. malloc_mutex_unlock(&huge_mtx);
  4316. malloc_mutex_lock(&base_mtx);
  4317. mapped += base_mapped;
  4318. malloc_mutex_unlock(&base_mtx);
  4319. #ifdef MOZ_MEMORY_WINDOWS
  4320. malloc_printf("Allocated: %lu, mapped: %lu\n",
  4321. allocated, mapped);
  4322. #else
  4323. malloc_printf("Allocated: %zu, mapped: %zu\n",
  4324. allocated, mapped);
  4325. #endif
  4326. /* Print chunk stats. */
  4327. malloc_printf(
  4328. "huge: nmalloc ndalloc allocated\n");
  4329. #ifdef MOZ_MEMORY_WINDOWS
  4330. malloc_printf(" %12llu %12llu %12lu\n",
  4331. huge_nmalloc, huge_ndalloc, huge_allocated);
  4332. #else
  4333. malloc_printf(" %12llu %12llu %12zu\n",
  4334. huge_nmalloc, huge_ndalloc, huge_allocated);
  4335. #endif
  4336. /* Print stats for each arena. */
  4337. for (i = 0; i < narenas; i++) {
  4338. arena = arenas[i];
  4339. if (arena != NULL) {
  4340. malloc_printf(
  4341. "\narenas[%u]:\n", i);
  4342. malloc_spin_lock(&arena->lock);
  4343. stats_print(arena);
  4344. malloc_spin_unlock(&arena->lock);
  4345. }
  4346. }
  4347. }
  4348. #endif /* #ifdef MALLOC_STATS */
  4349. _malloc_message("--- End malloc statistics ---\n", "", "", "");
  4350. }
  4351. }
  4352. #if (defined(MOZ_MEMORY_WINDOWS) || defined(MOZ_MEMORY_DARWIN))
  4353. #define malloc_init() false
  4354. #else
  4355. static inline bool
  4356. malloc_init(void)
  4357. {
  4358. if (malloc_initialized == false)
  4359. return (malloc_init_hard());
  4360. return (false);
  4361. }
  4362. #endif
  4363. #ifdef __FreeBSD__
  4364. // There are several problematic interactions between FreeBSD's libthr and this
  4365. // jemalloc.
  4366. //
  4367. // 1. This malloc calls pthread_mutex_init at init, but in libthr this triggers
  4368. // an allocation, causing an infinite recursion.
  4369. // 2. Actually, this malloc assumes that lock initialization never triggers a
  4370. // memory allocation, even after initialization (see 'arena_new').
  4371. // 3. First use of a lock routine ('pthread_mutex_lock') in libthr triggers
  4372. // initialization of the process as a multi-threaded process. Unfortunately,
  4373. // libthr calls regular malloc as part of this bootstrap process.
  4374. //
  4375. // If there was no problem 3, we could have resolved this easily by using
  4376. // constant mutex initializers, since then libthr's uses its own internal
  4377. // allocator instead of regular malloc (this appears to have been the case for
  4378. // years now). However, problem 3 requires this malloc to provide some memory
  4379. // at places where it is not able to, so we need a way to divert standard
  4380. // allocator functions to some simple bootstrap allocator. And once we have
  4381. // done this, using constant mutex initializers looses most of its appeal,
  4382. // because allocations for problems 1 & 2 can be fulfilled by the simple
  4383. // allocator as well, without the drawback of being dependent on libthr's
  4384. // specific behavior.
  4385. //
  4386. // Since the init lock controls the 'malloc_initialized' flag, it is not
  4387. // possible to reliably check whether jemalloc is initialized in the case of
  4388. // multiple threads with the given tools (pthread cannot be used yet, but
  4389. // mutual exclusion is required). One solution would be to code simple
  4390. // user-space locks for this (e.g., spinlocks using GCC's builtins). But an
  4391. // even "simpler" solution is in fact to just remove the lock, on the ground
  4392. // that there must be some memory allocation before multithreading is enabled,
  4393. // so jemalloc is in fact always initialized before that point. And if there
  4394. // is not, we'll provoke it.
  4395. //
  4396. // At some point, I implemented a solution using __constructor__, as
  4397. // 'jemalloc_darwin_init', and tweaked the build so that it is included in
  4398. // executables (in platform/build/gecko_templates.mozbuild). But this was not
  4399. // enough: Clearly it could happen that some other library would be initialized
  4400. // before jemalloc, calling malloc in its contructor. Could have tried to work
  4401. // around this with constructor priorities, but this seemed fragile as well. So
  4402. // in the end, I kept the calls to 'malloc_init' from the interface's
  4403. // functions, and had to introduce 'malloc_initializing' to know when (part of
  4404. // the) calls should be diverted. I finally kept the constructor as well, just
  4405. // to absolutely guarantee that jemalloc is initialized during executable load,
  4406. // that is to say, before multi-threading happens, in case initialization in
  4407. // libthr or glib is removed at some point. It just doesn't call
  4408. // 'malloc_init_hard', contrary to Darwin's, but 'malloc_init' (because
  4409. // jemalloc normally has already been initialized at this point).
  4410. //
  4411. // During lock initialization, malloc is temporarily diverted to the bootstrap
  4412. // allocator to avoid harmful recursion. This is achieved using a flag
  4413. // indicating whether lock initialization is under way (in order to work also
  4414. // after malloc_init_hard() has completed). The flag *must* be per-thread,
  4415. // because creation of new arenas, which causes creation of new locks, can
  4416. // happen at unpredictable moments after multi-threading has been enabled (and
  4417. // malloc has been initialized), which means concurrent allocation requests can
  4418. // occur, and must not all be diverted. With this flag in place, and an
  4419. // additional change to ensure that libthr's multi-thread init is indeed done
  4420. // during mutex init (through 'pthread_lock_mutex'), there was no need to keep
  4421. // the 'malloc_initializing' flag (see previous paragraph).
  4422. //
  4423. // The most likely change this whole architecture is not immune to would be if
  4424. // jemalloc starts initializing new locks after malloc_init_hard() has finished
  4425. // but not under an existing lock (new arena's lock is currently initialized
  4426. // under the arenas lock), because bootstrap allocator functions are not
  4427. // thread-safe per se. If this happens, then a very simple spinlock
  4428. // implementation on top of GCC's atomics will be in order. But I don't think
  4429. // this is very likely to happen.
  4430. // Diverts key (de)allocation functions when jemalloc's mutexes are
  4431. // initializing (malloc_init_hard(), but also arena_new() and
  4432. // malloc_rtree_new(), as of this writing).
  4433. #define BA_DIVERT(code) \
  4434. do { \
  4435. if (in_mutex_init) { \
  4436. code; \
  4437. } \
  4438. } while (0)
  4439. // Bootstrap allocator
  4440. //
  4441. // It is not FreeBSD-specific, and could be used by any POSIX-compliant
  4442. // platform if needed.
  4443. //
  4444. // Allocates one page at a time (relies on 'pagesize' as defined above in this
  4445. // file), and returns memory from it. Does not accept allocations larger than a
  4446. // single page (minus alignment). Will waste space at end of pages. Never frees
  4447. // memory.
  4448. //
  4449. // All these constraints are not a problem, since this allocator is meant to
  4450. // serve only some requests at initialization (no more than a few kB).
  4451. // Number of really allocated bytes
  4452. static size_t ba_allocated_bn = 0;
  4453. // Number of requested bytes
  4454. static size_t ba_requested_bn = 0;
  4455. // Current address we are allocating from, or NULL if a new page has to be
  4456. // allocated.
  4457. static void *ba_cur_free = NULL;
  4458. static void ba_alloc_new_page()
  4459. {
  4460. ba_cur_free = mmap(NULL, pagesize, PROT_READ | PROT_WRITE,
  4461. MAP_ANON | MAP_PRIVATE, -1, 0);
  4462. if (ba_cur_free == MAP_FAILED)
  4463. abort();
  4464. ba_allocated_bn += pagesize;
  4465. }
  4466. // Returns the offset to point to have point a multiple of alignment
  4467. static size_t
  4468. ba_offset_to_aligned(uintptr_t point, size_t alignment) {
  4469. if (alignment != 0) {
  4470. size_t rest = point % alignment;
  4471. if (rest != 0)
  4472. return alignment - rest;
  4473. }
  4474. return 0;
  4475. }
  4476. static void * ba_memalign(size_t alignment, size_t size)
  4477. {
  4478. // We don't care about alignment being a power of 2, nor pagesize. Code
  4479. // below supports everything, provided that alignment divides the page
  4480. // size.
  4481. // Impose cache-line size minimum alignment, so that there is no cache
  4482. // trashing between fundamental structures.
  4483. if (alignment < CACHELINE)
  4484. alignment = CACHELINE;
  4485. if (size > pagesize ||
  4486. alignment > pagesize ||
  4487. size + alignment > pagesize ||
  4488. pagesize % alignment != 0)
  4489. abort();
  4490. // Address to be returned
  4491. uintptr_t cur_free;
  4492. // Allocate a new page if no current page (startup or previous one was
  4493. // exhausted) or there is not enough remaining space in it.
  4494. if (ba_cur_free == NULL) {
  4495. // No current page
  4496. ba_alloc_new_page();
  4497. cur_free = (uintptr_t)ba_cur_free;
  4498. } else {
  4499. cur_free = (uintptr_t)ba_cur_free;
  4500. uintptr_t off = cur_free % pagesize;
  4501. uintptr_t al_off = ba_offset_to_aligned(off, alignment);
  4502. if (off + al_off + size > pagesize) {
  4503. // Not enough room. Need a new page.
  4504. ba_alloc_new_page();
  4505. cur_free = (uintptr_t)ba_cur_free;
  4506. } else
  4507. // Account for alignment
  4508. cur_free += al_off;
  4509. }
  4510. // Compute the next free address
  4511. uintptr_t next_free = cur_free + size;
  4512. if (next_free % pagesize == 0 && size != 0)
  4513. next_free = 0;
  4514. // Set it
  4515. ba_cur_free = (void *)next_free;
  4516. // Stats
  4517. ba_requested_bn += size;
  4518. // Done
  4519. return (void *)cur_free;
  4520. }
  4521. static void * ba_malloc(size_t size)
  4522. {
  4523. // 64-bit alignment by default. ba_memalign imposes an even greater
  4524. // alignment anyway.
  4525. return ba_memalign(8, size);
  4526. }
  4527. static void * ba_calloc(size_t number, size_t size)
  4528. {
  4529. size_t const bn = number * size;
  4530. if ((bn < number || bn < size) && bn != 0)
  4531. // Overflow
  4532. abort();
  4533. void * const res = ba_malloc(bn);
  4534. memset(res, 0, bn);
  4535. return res;
  4536. }
  4537. static void ba_free(void * ptr) {
  4538. #ifdef MALLOC_DEBUG
  4539. malloc_printf("Bootstrap allocator: Request to free at %p\n", ptr);
  4540. #endif
  4541. // Do nothing
  4542. return;
  4543. }
  4544. #ifdef MALLOC_STATS
  4545. static void ba_print_stats() {
  4546. malloc_printf("Bootstrap allocator: %zu bytes requested, "
  4547. "%zu allocated\n",
  4548. ba_requested_bn, ba_allocated_bn);
  4549. }
  4550. #endif
  4551. __attribute__((constructor))
  4552. void
  4553. jemalloc_FreeBSD_init(void)
  4554. {
  4555. if (malloc_init())
  4556. abort();
  4557. }
  4558. #endif // #ifdef __FreeBSD__
  4559. #if !defined(MOZ_MEMORY_WINDOWS)
  4560. static
  4561. #endif
  4562. bool
  4563. malloc_init_hard(void)
  4564. {
  4565. unsigned i;
  4566. char buf[PATH_MAX + 1];
  4567. const char *opts;
  4568. long result;
  4569. #ifndef MOZ_MEMORY_WINDOWS
  4570. int linklen;
  4571. #endif
  4572. #ifdef MOZ_MEMORY_DARWIN
  4573. malloc_zone_t* default_zone;
  4574. #endif
  4575. #if !(defined(MOZ_MEMORY_WINDOWS) || defined(__FreeBSD__))
  4576. malloc_mutex_lock(&init_lock);
  4577. #endif
  4578. if (malloc_initialized) {
  4579. /*
  4580. * Another thread initialized the allocator before this one
  4581. * acquired init_lock.
  4582. */
  4583. #if !(defined(MOZ_MEMORY_WINDOWS) || defined(__FreeBSD__))
  4584. malloc_mutex_unlock(&init_lock);
  4585. #endif
  4586. return (false);
  4587. }
  4588. #ifdef MOZ_MEMORY_WINDOWS
  4589. /* get a thread local storage index */
  4590. tlsIndex = TlsAlloc();
  4591. #endif
  4592. /* Get page size and number of CPUs */
  4593. #ifdef MOZ_MEMORY_WINDOWS
  4594. {
  4595. SYSTEM_INFO info;
  4596. GetSystemInfo(&info);
  4597. result = info.dwPageSize;
  4598. }
  4599. #else
  4600. result = sysconf(_SC_PAGESIZE);
  4601. assert(result != -1);
  4602. #endif
  4603. #ifndef MOZ_MEMORY_NARENAS_DEFAULT_ONE
  4604. ncpus = malloc_ncpus();
  4605. #endif
  4606. /* We assume that the page size is a power of 2. */
  4607. assert(((result - 1) & result) == 0);
  4608. #ifdef MALLOC_STATIC_SIZES
  4609. if (pagesize % (size_t) result) {
  4610. _malloc_message(_getprogname(),
  4611. "Compile-time page size does not divide the runtime one.\n",
  4612. "", "");
  4613. abort();
  4614. }
  4615. #else
  4616. pagesize = (size_t) result;
  4617. pagesize_mask = (size_t) result - 1;
  4618. pagesize_2pow = ffs((int)result) - 1;
  4619. #endif
  4620. for (i = 0; i < 3; i++) {
  4621. unsigned j;
  4622. /* Get runtime configuration. */
  4623. switch (i) {
  4624. case 0:
  4625. #ifndef MOZ_MEMORY_WINDOWS
  4626. if ((linklen = readlink("/etc/malloc.conf", buf,
  4627. sizeof(buf) - 1)) != -1) {
  4628. /*
  4629. * Use the contents of the "/etc/malloc.conf"
  4630. * symbolic link's name.
  4631. */
  4632. buf[linklen] = '\0';
  4633. opts = buf;
  4634. } else
  4635. #endif
  4636. {
  4637. /* No configuration specified. */
  4638. buf[0] = '\0';
  4639. opts = buf;
  4640. }
  4641. break;
  4642. case 1:
  4643. if ((opts = getenv("MALLOC_OPTIONS")) != NULL) {
  4644. /*
  4645. * Do nothing; opts is already initialized to
  4646. * the value of the MALLOC_OPTIONS environment
  4647. * variable.
  4648. */
  4649. } else {
  4650. /* No configuration specified. */
  4651. buf[0] = '\0';
  4652. opts = buf;
  4653. }
  4654. break;
  4655. case 2:
  4656. if (_malloc_options != NULL) {
  4657. /*
  4658. * Use options that were compiled into the
  4659. * program.
  4660. */
  4661. opts = _malloc_options;
  4662. } else {
  4663. /* No configuration specified. */
  4664. buf[0] = '\0';
  4665. opts = buf;
  4666. }
  4667. break;
  4668. default:
  4669. /* NOTREACHED */
  4670. buf[0] = '\0';
  4671. opts = buf;
  4672. assert(false);
  4673. }
  4674. for (j = 0; opts[j] != '\0'; j++) {
  4675. unsigned k, nreps;
  4676. bool nseen;
  4677. /* Parse repetition count, if any. */
  4678. for (nreps = 0, nseen = false;; j++, nseen = true) {
  4679. switch (opts[j]) {
  4680. case '0': case '1': case '2': case '3':
  4681. case '4': case '5': case '6': case '7':
  4682. case '8': case '9':
  4683. nreps *= 10;
  4684. nreps += opts[j] - '0';
  4685. break;
  4686. default:
  4687. goto MALLOC_OUT;
  4688. }
  4689. }
  4690. MALLOC_OUT:
  4691. if (nseen == false)
  4692. nreps = 1;
  4693. for (k = 0; k < nreps; k++) {
  4694. switch (opts[j]) {
  4695. case 'a':
  4696. opt_abort = false;
  4697. break;
  4698. case 'A':
  4699. opt_abort = true;
  4700. break;
  4701. case 'b':
  4702. case 'B':
  4703. // Balancing option is ignored
  4704. break;
  4705. #ifdef MALLOC_FILL
  4706. #ifndef MALLOC_PRODUCTION
  4707. case 'c':
  4708. opt_poison = false;
  4709. break;
  4710. case 'C':
  4711. opt_poison = true;
  4712. break;
  4713. #endif
  4714. #endif
  4715. case 'f':
  4716. opt_dirty_max >>= 1;
  4717. break;
  4718. case 'F':
  4719. if (opt_dirty_max == 0)
  4720. opt_dirty_max = 1;
  4721. else if ((opt_dirty_max << 1) != 0)
  4722. opt_dirty_max <<= 1;
  4723. break;
  4724. #ifdef MALLOC_FILL
  4725. #ifndef MALLOC_PRODUCTION
  4726. case 'j':
  4727. opt_junk = false;
  4728. break;
  4729. case 'J':
  4730. opt_junk = true;
  4731. break;
  4732. #endif
  4733. #endif
  4734. #ifndef MALLOC_STATIC_SIZES
  4735. case 'k':
  4736. /*
  4737. * Chunks always require at least one
  4738. * header page, so chunks can never be
  4739. * smaller than two pages.
  4740. */
  4741. if (opt_chunk_2pow > pagesize_2pow + 1)
  4742. opt_chunk_2pow--;
  4743. break;
  4744. case 'K':
  4745. if (opt_chunk_2pow + 1 <
  4746. (sizeof(size_t) << 3))
  4747. opt_chunk_2pow++;
  4748. break;
  4749. #endif
  4750. case 'n':
  4751. opt_narenas_lshift--;
  4752. break;
  4753. case 'N':
  4754. opt_narenas_lshift++;
  4755. break;
  4756. case 'p':
  4757. opt_print_stats = false;
  4758. break;
  4759. case 'P':
  4760. opt_print_stats = true;
  4761. break;
  4762. #ifndef MALLOC_STATIC_SIZES
  4763. case 'q':
  4764. if (opt_quantum_2pow > QUANTUM_2POW_MIN)
  4765. opt_quantum_2pow--;
  4766. break;
  4767. case 'Q':
  4768. if (opt_quantum_2pow < pagesize_2pow -
  4769. 1)
  4770. opt_quantum_2pow++;
  4771. break;
  4772. case 's':
  4773. if (opt_small_max_2pow >
  4774. QUANTUM_2POW_MIN)
  4775. opt_small_max_2pow--;
  4776. break;
  4777. case 'S':
  4778. if (opt_small_max_2pow < pagesize_2pow
  4779. - 1)
  4780. opt_small_max_2pow++;
  4781. break;
  4782. #endif
  4783. #ifdef MALLOC_SYSV
  4784. case 'v':
  4785. opt_sysv = false;
  4786. break;
  4787. case 'V':
  4788. opt_sysv = true;
  4789. break;
  4790. #endif
  4791. #ifdef MALLOC_XMALLOC
  4792. case 'x':
  4793. opt_xmalloc = false;
  4794. break;
  4795. case 'X':
  4796. opt_xmalloc = true;
  4797. break;
  4798. #endif
  4799. #ifdef MALLOC_FILL
  4800. #ifndef MALLOC_PRODUCTION
  4801. case 'z':
  4802. opt_zero = false;
  4803. break;
  4804. case 'Z':
  4805. opt_zero = true;
  4806. break;
  4807. #endif
  4808. #endif
  4809. default: {
  4810. char cbuf[2];
  4811. cbuf[0] = opts[j];
  4812. cbuf[1] = '\0';
  4813. _malloc_message(_getprogname(),
  4814. ": (malloc) Unsupported character "
  4815. "in malloc options: '", cbuf,
  4816. "'\n");
  4817. }
  4818. }
  4819. }
  4820. }
  4821. }
  4822. /* Take care to call atexit() only once. */
  4823. if (opt_print_stats) {
  4824. #ifndef MOZ_MEMORY_WINDOWS
  4825. /* Print statistics at exit. */
  4826. atexit(malloc_print_stats);
  4827. #endif
  4828. }
  4829. #ifndef MALLOC_STATIC_SIZES
  4830. /* Set variables according to the value of opt_small_max_2pow. */
  4831. if (opt_small_max_2pow < opt_quantum_2pow)
  4832. opt_small_max_2pow = opt_quantum_2pow;
  4833. small_max = (1U << opt_small_max_2pow);
  4834. /* Set bin-related variables. */
  4835. bin_maxclass = (pagesize >> 1);
  4836. assert(opt_quantum_2pow >= TINY_MIN_2POW);
  4837. ntbins = opt_quantum_2pow - TINY_MIN_2POW;
  4838. assert(ntbins <= opt_quantum_2pow);
  4839. nqbins = (small_max >> opt_quantum_2pow);
  4840. nsbins = pagesize_2pow - opt_small_max_2pow - 1;
  4841. /* Set variables according to the value of opt_quantum_2pow. */
  4842. quantum = (1U << opt_quantum_2pow);
  4843. quantum_mask = quantum - 1;
  4844. if (ntbins > 0)
  4845. small_min = (quantum >> 1) + 1;
  4846. else
  4847. small_min = 1;
  4848. assert(small_min <= quantum);
  4849. /* Set variables according to the value of opt_chunk_2pow. */
  4850. chunksize = (1LU << opt_chunk_2pow);
  4851. chunksize_mask = chunksize - 1;
  4852. chunk_npages = (chunksize >> pagesize_2pow);
  4853. arena_chunk_header_npages = calculate_arena_header_pages();
  4854. arena_maxclass = calculate_arena_maxclass();
  4855. recycle_limit = CHUNK_RECYCLE_LIMIT * chunksize;
  4856. #endif
  4857. recycled_size = 0;
  4858. /* Various sanity checks that regard configuration. */
  4859. assert(quantum >= sizeof(void *));
  4860. assert(quantum <= pagesize);
  4861. assert(chunksize >= pagesize);
  4862. assert(quantum * 4 <= chunksize);
  4863. /* Initialize chunks data. */
  4864. malloc_mutex_init(&chunks_mtx);
  4865. extent_tree_szad_new(&chunks_szad_mmap);
  4866. extent_tree_ad_new(&chunks_ad_mmap);
  4867. /* Initialize huge allocation data. */
  4868. malloc_mutex_init(&huge_mtx);
  4869. extent_tree_ad_new(&huge);
  4870. #ifdef MALLOC_STATS
  4871. huge_nmalloc = 0;
  4872. huge_ndalloc = 0;
  4873. huge_allocated = 0;
  4874. huge_mapped = 0;
  4875. #endif
  4876. /* Initialize base allocation data structures. */
  4877. #ifdef MALLOC_STATS
  4878. base_mapped = 0;
  4879. base_committed = 0;
  4880. #endif
  4881. base_nodes = NULL;
  4882. malloc_mutex_init(&base_mtx);
  4883. #ifdef MOZ_MEMORY_NARENAS_DEFAULT_ONE
  4884. narenas = 1;
  4885. #else
  4886. if (ncpus > 1) {
  4887. /*
  4888. * For SMP systems, create four times as many arenas as there
  4889. * are CPUs by default.
  4890. */
  4891. opt_narenas_lshift += 2;
  4892. }
  4893. /* Determine how many arenas to use. */
  4894. narenas = ncpus;
  4895. #endif
  4896. if (opt_narenas_lshift > 0) {
  4897. if ((narenas << opt_narenas_lshift) > narenas)
  4898. narenas <<= opt_narenas_lshift;
  4899. /*
  4900. * Make sure not to exceed the limits of what base_alloc() can
  4901. * handle.
  4902. */
  4903. if (narenas * sizeof(arena_t *) > chunksize)
  4904. narenas = chunksize / sizeof(arena_t *);
  4905. } else if (opt_narenas_lshift < 0) {
  4906. if ((narenas >> -opt_narenas_lshift) < narenas)
  4907. narenas >>= -opt_narenas_lshift;
  4908. /* Make sure there is at least one arena. */
  4909. if (narenas == 0)
  4910. narenas = 1;
  4911. }
  4912. #ifdef NO_TLS
  4913. if (narenas > 1) {
  4914. static const unsigned primes[] = {1, 3, 5, 7, 11, 13, 17, 19,
  4915. 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
  4916. 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149,
  4917. 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211,
  4918. 223, 227, 229, 233, 239, 241, 251, 257, 263};
  4919. unsigned nprimes, parenas;
  4920. /*
  4921. * Pick a prime number of hash arenas that is more than narenas
  4922. * so that direct hashing of pthread_self() pointers tends to
  4923. * spread allocations evenly among the arenas.
  4924. */
  4925. assert((narenas & 1) == 0); /* narenas must be even. */
  4926. nprimes = (sizeof(primes) >> SIZEOF_INT_2POW);
  4927. parenas = primes[nprimes - 1]; /* In case not enough primes. */
  4928. for (i = 1; i < nprimes; i++) {
  4929. if (primes[i] > narenas) {
  4930. parenas = primes[i];
  4931. break;
  4932. }
  4933. }
  4934. narenas = parenas;
  4935. }
  4936. #endif
  4937. #ifndef NO_TLS
  4938. next_arena = 0;
  4939. #endif
  4940. /* Allocate and initialize arenas. */
  4941. arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas);
  4942. if (arenas == NULL) {
  4943. #if !(defined(MOZ_MEMORY_WINDOWS) || defined(__FreeBSD__))
  4944. malloc_mutex_unlock(&init_lock);
  4945. #endif
  4946. return (true);
  4947. }
  4948. /*
  4949. * Zero the array. In practice, this should always be pre-zeroed,
  4950. * since it was just mmap()ed, but let's be sure.
  4951. */
  4952. memset(arenas, 0, sizeof(arena_t *) * narenas);
  4953. /*
  4954. * Initialize one arena here. The rest are lazily created in
  4955. * choose_arena_hard().
  4956. */
  4957. arenas_extend(0);
  4958. if (arenas[0] == NULL) {
  4959. #if !(defined(MOZ_MEMORY_WINDOWS) || defined(__FreeBSD__))
  4960. malloc_mutex_unlock(&init_lock);
  4961. #endif
  4962. return (true);
  4963. }
  4964. #ifndef NO_TLS
  4965. /*
  4966. * Assign the initial arena to the initial thread, in order to avoid
  4967. * spurious creation of an extra arena if the application switches to
  4968. * threaded mode.
  4969. */
  4970. #ifdef MOZ_MEMORY_WINDOWS
  4971. TlsSetValue(tlsIndex, arenas[0]);
  4972. #else
  4973. arenas_map = arenas[0];
  4974. #endif
  4975. #endif
  4976. malloc_spin_init(&arenas_lock);
  4977. chunk_rtree = malloc_rtree_new((SIZEOF_PTR << 3) - opt_chunk_2pow);
  4978. if (chunk_rtree == NULL)
  4979. return (true);
  4980. malloc_initialized = true;
  4981. #if !defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_DARWIN)
  4982. /* Prevent potential deadlock on malloc locks after fork. */
  4983. pthread_atfork(_malloc_prefork, _malloc_postfork, _malloc_postfork);
  4984. #endif
  4985. #if defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_REPLACE_MALLOC)
  4986. /*
  4987. * Overwrite the default memory allocator to use jemalloc everywhere.
  4988. */
  4989. default_zone = malloc_default_zone();
  4990. /*
  4991. * We only use jemalloc with MacOS 10.6 and 10.7. jemalloc is disabled
  4992. * on 32-bit builds (10.5 and 32-bit 10.6) due to bug 702250, an
  4993. * apparent MacOS bug. In fact, this code isn't even compiled on
  4994. * 32-bit builds.
  4995. *
  4996. * We'll have to update our code to work with newer versions, because
  4997. * the malloc zone layout is likely to change.
  4998. */
  4999. osx_use_jemalloc = (default_zone->version == SNOW_LEOPARD_MALLOC_ZONE_T_VERSION ||
  5000. default_zone->version == LION_MALLOC_ZONE_T_VERSION);
  5001. /* Allow us dynamically turn off jemalloc for testing. */
  5002. if (getenv("NO_MAC_JEMALLOC")) {
  5003. osx_use_jemalloc = false;
  5004. #ifdef __i386__
  5005. malloc_printf("Warning: NO_MAC_JEMALLOC has no effect on "
  5006. "i386 machines (such as this one).\n");
  5007. #endif
  5008. }
  5009. if (osx_use_jemalloc) {
  5010. /*
  5011. * Convert the default szone to an "overlay zone" that is capable
  5012. * of deallocating szone-allocated objects, but allocating new
  5013. * objects from jemalloc.
  5014. */
  5015. size_t size = zone_version_size(default_zone->version);
  5016. szone2ozone(default_zone, size);
  5017. }
  5018. else {
  5019. szone = default_zone;
  5020. }
  5021. #endif
  5022. #if defined(__FreeBSD__) && defined(MALLOC_STATS)
  5023. malloc_printf("Bootstrap allocator: malloc_init_hard stats:\n");
  5024. ba_print_stats();
  5025. #endif
  5026. #if !(defined(MOZ_MEMORY_WINDOWS) || defined(__FreeBSD__))
  5027. malloc_mutex_unlock(&init_lock);
  5028. #endif
  5029. return (false);
  5030. }
  5031. /* XXX Why not just expose malloc_print_stats()? */
  5032. #ifdef MOZ_MEMORY_WINDOWS
  5033. void
  5034. malloc_shutdown()
  5035. {
  5036. malloc_print_stats();
  5037. }
  5038. #endif
  5039. /*
  5040. * End general internal functions.
  5041. */
  5042. /******************************************************************************/
  5043. /*
  5044. * Begin malloc(3)-compatible functions.
  5045. */
  5046. /*
  5047. * Even though we compile with MOZ_MEMORY, we may have to dynamically decide
  5048. * not to use jemalloc, as discussed above. However, we call jemalloc
  5049. * functions directly from mozalloc. Since it's pretty dangerous to mix the
  5050. * allocators, we need to call the OSX allocators from the functions below,
  5051. * when osx_use_jemalloc is not (dynamically) set.
  5052. *
  5053. * Note that we assume jemalloc is enabled on i386. This is safe because the
  5054. * only i386 versions of MacOS are 10.5 and 10.6, which we support. We have to
  5055. * do this because madvise isn't in the malloc zone struct for 10.5.
  5056. *
  5057. * This means that NO_MAC_JEMALLOC doesn't work on i386.
  5058. */
  5059. #if defined(MOZ_MEMORY_DARWIN) && !defined(__i386__) && !defined(MOZ_REPLACE_MALLOC)
  5060. #define DARWIN_ONLY(A) if (!osx_use_jemalloc) { A; }
  5061. #else
  5062. #define DARWIN_ONLY(A)
  5063. #endif
  5064. #ifdef __FreeBSD__
  5065. #define FREEBSD_ONLY(code) code
  5066. #else
  5067. #define FREEBSD_ONLY(code)
  5068. #endif
  5069. MOZ_MEMORY_API void *
  5070. malloc_impl(size_t size)
  5071. {
  5072. DARWIN_ONLY(return (szone->malloc)(szone, size));
  5073. FREEBSD_ONLY(BA_DIVERT(return ba_malloc(size)));
  5074. void *ret;
  5075. if (malloc_init()) {
  5076. ret = NULL;
  5077. goto RETURN;
  5078. }
  5079. if (size == 0) {
  5080. #ifdef MALLOC_SYSV
  5081. if (opt_sysv == false)
  5082. #endif
  5083. size = 1;
  5084. #ifdef MALLOC_SYSV
  5085. else {
  5086. ret = NULL;
  5087. goto RETURN;
  5088. }
  5089. #endif
  5090. }
  5091. ret = imalloc(size);
  5092. RETURN:
  5093. if (ret == NULL) {
  5094. #ifdef MALLOC_XMALLOC
  5095. if (opt_xmalloc) {
  5096. _malloc_message(_getprogname(),
  5097. ": (malloc) Error in malloc(): out of memory\n", "",
  5098. "");
  5099. abort();
  5100. }
  5101. #endif
  5102. errno = ENOMEM;
  5103. }
  5104. return (ret);
  5105. }
  5106. /*
  5107. * In ELF systems the default visibility allows symbols to be preempted at
  5108. * runtime. This in turn prevents the uses of memalign in this file from being
  5109. * optimized. What we do in here is define two aliasing symbols (they point to
  5110. * the same code): memalign and memalign_internal. The internal version has
  5111. * hidden visibility and is used in every reference from this file.
  5112. *
  5113. * For more information on this technique, see section 2.2.7 (Avoid Using
  5114. * Exported Symbols) in http://www.akkadia.org/drepper/dsohowto.pdf.
  5115. */
  5116. #ifndef MOZ_REPLACE_MALLOC
  5117. #if defined(__GNUC__) && !defined(MOZ_MEMORY_DARWIN)
  5118. #define MOZ_MEMORY_ELF
  5119. #endif
  5120. #ifdef MOZ_MEMORY_SOLARIS
  5121. # if (defined(__GNUC__))
  5122. __attribute__((noinline))
  5123. # endif
  5124. #else
  5125. #if (defined(MOZ_MEMORY_ELF))
  5126. __attribute__((visibility ("hidden")))
  5127. #endif
  5128. #endif
  5129. #endif /* MOZ_REPLACE_MALLOC */
  5130. #ifdef MOZ_MEMORY_ELF
  5131. #define MEMALIGN memalign_internal
  5132. #else
  5133. #define MEMALIGN memalign_impl
  5134. #endif
  5135. #ifndef MOZ_MEMORY_ELF
  5136. MOZ_MEMORY_API
  5137. #endif
  5138. void *
  5139. MEMALIGN(size_t alignment, size_t size)
  5140. {
  5141. DARWIN_ONLY(return (szone->memalign)(szone, alignment, size));
  5142. FREEBSD_ONLY(BA_DIVERT(return ba_memalign(alignment, size)));
  5143. void *ret;
  5144. assert(((alignment - 1) & alignment) == 0);
  5145. if (malloc_init()) {
  5146. ret = NULL;
  5147. goto RETURN;
  5148. }
  5149. if (size == 0) {
  5150. #ifdef MALLOC_SYSV
  5151. if (opt_sysv == false)
  5152. #endif
  5153. size = 1;
  5154. #ifdef MALLOC_SYSV
  5155. else {
  5156. ret = NULL;
  5157. goto RETURN;
  5158. }
  5159. #endif
  5160. }
  5161. alignment = alignment < sizeof(void*) ? sizeof(void*) : alignment;
  5162. ret = ipalloc(alignment, size);
  5163. RETURN:
  5164. #ifdef MALLOC_XMALLOC
  5165. if (opt_xmalloc && ret == NULL) {
  5166. _malloc_message(_getprogname(),
  5167. ": (malloc) Error in memalign(): out of memory\n", "", "");
  5168. abort();
  5169. }
  5170. #endif
  5171. return (ret);
  5172. }
  5173. #ifdef MOZ_MEMORY_ELF
  5174. extern void *
  5175. memalign_impl(size_t alignment, size_t size) __attribute__((alias ("memalign_internal"), visibility ("default")));
  5176. #endif
  5177. MOZ_MEMORY_API int
  5178. posix_memalign_impl(void **memptr, size_t alignment, size_t size)
  5179. {
  5180. void *result;
  5181. /* Make sure that alignment is a large enough power of 2. */
  5182. if (((alignment - 1) & alignment) != 0 || alignment < sizeof(void *)) {
  5183. #ifdef MALLOC_XMALLOC
  5184. if (opt_xmalloc) {
  5185. _malloc_message(_getprogname(),
  5186. ": (malloc) Error in posix_memalign(): "
  5187. "invalid alignment\n", "", "");
  5188. abort();
  5189. }
  5190. #endif
  5191. return (EINVAL);
  5192. }
  5193. /* The 0-->1 size promotion is done in the memalign() call below */
  5194. result = MEMALIGN(alignment, size);
  5195. if (result == NULL)
  5196. return (ENOMEM);
  5197. *memptr = result;
  5198. return (0);
  5199. }
  5200. MOZ_MEMORY_API void *
  5201. aligned_alloc_impl(size_t alignment, size_t size)
  5202. {
  5203. if (size % alignment) {
  5204. #ifdef MALLOC_XMALLOC
  5205. if (opt_xmalloc) {
  5206. _malloc_message(_getprogname(),
  5207. ": (malloc) Error in aligned_alloc(): "
  5208. "size is not multiple of alignment\n", "", "");
  5209. abort();
  5210. }
  5211. #endif
  5212. return (NULL);
  5213. }
  5214. return MEMALIGN(alignment, size);
  5215. }
  5216. MOZ_MEMORY_API void *
  5217. valloc_impl(size_t size)
  5218. {
  5219. return (MEMALIGN(pagesize, size));
  5220. }
  5221. MOZ_MEMORY_API void *
  5222. calloc_impl(size_t num, size_t size)
  5223. {
  5224. DARWIN_ONLY(return (szone->calloc)(szone, num, size));
  5225. FREEBSD_ONLY(BA_DIVERT(return ba_calloc(num, size)));
  5226. void *ret;
  5227. size_t num_size;
  5228. if (malloc_init()) {
  5229. num_size = 0;
  5230. ret = NULL;
  5231. goto RETURN;
  5232. }
  5233. num_size = num * size;
  5234. if (num_size == 0) {
  5235. #ifdef MALLOC_SYSV
  5236. if ((opt_sysv == false) && ((num == 0) || (size == 0)))
  5237. #endif
  5238. num_size = 1;
  5239. #ifdef MALLOC_SYSV
  5240. else {
  5241. ret = NULL;
  5242. goto RETURN;
  5243. }
  5244. #endif
  5245. /*
  5246. * Try to avoid division here. We know that it isn't possible to
  5247. * overflow during multiplication if neither operand uses any of the
  5248. * most significant half of the bits in a size_t.
  5249. */
  5250. } else if (((num | size) & (SIZE_T_MAX << (sizeof(size_t) << 2)))
  5251. && (num_size / size != num)) {
  5252. /* size_t overflow. */
  5253. ret = NULL;
  5254. goto RETURN;
  5255. }
  5256. ret = icalloc(num_size);
  5257. RETURN:
  5258. if (ret == NULL) {
  5259. #ifdef MALLOC_XMALLOC
  5260. if (opt_xmalloc) {
  5261. _malloc_message(_getprogname(),
  5262. ": (malloc) Error in calloc(): out of memory\n", "",
  5263. "");
  5264. abort();
  5265. }
  5266. #endif
  5267. errno = ENOMEM;
  5268. }
  5269. return (ret);
  5270. }
  5271. MOZ_MEMORY_API void *
  5272. realloc_impl(void *ptr, size_t size)
  5273. {
  5274. void *ret;
  5275. DARWIN_ONLY(return (szone->realloc)(szone, ptr, size));
  5276. if (size == 0) {
  5277. #ifdef MALLOC_SYSV
  5278. if (opt_sysv == false)
  5279. #endif
  5280. size = 1;
  5281. #ifdef MALLOC_SYSV
  5282. else {
  5283. if (ptr != NULL)
  5284. idalloc(ptr);
  5285. ret = NULL;
  5286. goto RETURN;
  5287. }
  5288. #endif
  5289. }
  5290. if (ptr != NULL) {
  5291. assert(malloc_initialized);
  5292. ret = iralloc(ptr, size);
  5293. if (ret == NULL) {
  5294. #ifdef MALLOC_XMALLOC
  5295. if (opt_xmalloc) {
  5296. _malloc_message(_getprogname(),
  5297. ": (malloc) Error in realloc(): out of "
  5298. "memory\n", "", "");
  5299. abort();
  5300. }
  5301. #endif
  5302. errno = ENOMEM;
  5303. }
  5304. } else {
  5305. if (malloc_init())
  5306. ret = NULL;
  5307. else
  5308. ret = imalloc(size);
  5309. if (ret == NULL) {
  5310. #ifdef MALLOC_XMALLOC
  5311. if (opt_xmalloc) {
  5312. _malloc_message(_getprogname(),
  5313. ": (malloc) Error in realloc(): out of "
  5314. "memory\n", "", "");
  5315. abort();
  5316. }
  5317. #endif
  5318. errno = ENOMEM;
  5319. }
  5320. }
  5321. #ifdef MALLOC_SYSV
  5322. RETURN:
  5323. #endif
  5324. return (ret);
  5325. }
  5326. MOZ_MEMORY_API void
  5327. free_impl(void *ptr)
  5328. {
  5329. DARWIN_ONLY((szone->free)(szone, ptr); return);
  5330. FREEBSD_ONLY(BA_DIVERT(return ba_free(ptr)));
  5331. size_t offset;
  5332. /*
  5333. * A version of idalloc that checks for NULL pointer but only for
  5334. * huge allocations assuming that CHUNK_ADDR2OFFSET(NULL) == 0.
  5335. */
  5336. assert(CHUNK_ADDR2OFFSET(NULL) == 0);
  5337. offset = CHUNK_ADDR2OFFSET(ptr);
  5338. if (offset != 0)
  5339. arena_dalloc(ptr, offset);
  5340. else if (ptr != NULL)
  5341. huge_dalloc(ptr);
  5342. }
  5343. /*
  5344. * End malloc(3)-compatible functions.
  5345. */
  5346. /******************************************************************************/
  5347. /*
  5348. * Begin non-standard functions.
  5349. */
  5350. /* This was added by Mozilla for use by SQLite. */
  5351. #if defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_REPLACE_MALLOC)
  5352. static
  5353. #else
  5354. MOZ_MEMORY_API
  5355. #endif
  5356. size_t
  5357. malloc_good_size_impl(size_t size)
  5358. {
  5359. /*
  5360. * This duplicates the logic in imalloc(), arena_malloc() and
  5361. * arena_malloc_small().
  5362. */
  5363. if (size < small_min) {
  5364. /* Small (tiny). */
  5365. size = pow2_ceil(size);
  5366. /*
  5367. * We omit the #ifdefs from arena_malloc_small() --
  5368. * it can be inaccurate with its size in some cases, but this
  5369. * function must be accurate.
  5370. */
  5371. if (size < (1U << TINY_MIN_2POW))
  5372. size = (1U << TINY_MIN_2POW);
  5373. } else if (size <= small_max) {
  5374. /* Small (quantum-spaced). */
  5375. size = QUANTUM_CEILING(size);
  5376. } else if (size <= bin_maxclass) {
  5377. /* Small (sub-page). */
  5378. size = pow2_ceil(size);
  5379. } else if (size <= arena_maxclass) {
  5380. /* Large. */
  5381. size = PAGE_CEILING(size);
  5382. } else {
  5383. /*
  5384. * Huge. We use PAGE_CEILING to get psize, instead of using
  5385. * CHUNK_CEILING to get csize. This ensures that this
  5386. * malloc_usable_size(malloc(n)) always matches
  5387. * malloc_good_size(n).
  5388. */
  5389. size = PAGE_CEILING(size);
  5390. }
  5391. return size;
  5392. }
  5393. MOZ_MEMORY_API size_t
  5394. malloc_usable_size_impl(MALLOC_USABLE_SIZE_CONST_PTR void *ptr)
  5395. {
  5396. DARWIN_ONLY(return (szone->size)(szone, ptr));
  5397. return (isalloc_validate(ptr));
  5398. }
  5399. #ifdef MALLOC_STATS
  5400. MOZ_JEMALLOC_API void
  5401. jemalloc_stats_impl(jemalloc_stats_t *stats)
  5402. {
  5403. size_t i, non_arena_mapped, chunk_header_size;
  5404. assert(stats != NULL);
  5405. /*
  5406. * Gather runtime settings.
  5407. */
  5408. stats->opt_abort = opt_abort;
  5409. stats->opt_junk =
  5410. #ifdef MALLOC_FILL
  5411. opt_junk ? true :
  5412. #endif
  5413. false;
  5414. stats->opt_poison =
  5415. #ifdef MALLOC_FILL
  5416. opt_poison ? true :
  5417. #endif
  5418. false;
  5419. stats->opt_sysv =
  5420. #ifdef MALLOC_SYSV
  5421. opt_sysv ? true :
  5422. #endif
  5423. false;
  5424. stats->opt_xmalloc =
  5425. #ifdef MALLOC_XMALLOC
  5426. opt_xmalloc ? true :
  5427. #endif
  5428. false;
  5429. stats->opt_zero =
  5430. #ifdef MALLOC_FILL
  5431. opt_zero ? true :
  5432. #endif
  5433. false;
  5434. stats->narenas = narenas;
  5435. stats->balance_threshold = SIZE_T_MAX;
  5436. stats->quantum = quantum;
  5437. stats->small_max = small_max;
  5438. stats->large_max = arena_maxclass;
  5439. stats->chunksize = chunksize;
  5440. stats->dirty_max = opt_dirty_max;
  5441. /*
  5442. * Gather current memory usage statistics.
  5443. */
  5444. stats->mapped = 0;
  5445. stats->allocated = 0;
  5446. stats->waste = 0;
  5447. stats->page_cache = 0;
  5448. stats->bookkeeping = 0;
  5449. stats->bin_unused = 0;
  5450. non_arena_mapped = 0;
  5451. /* Get huge mapped/allocated. */
  5452. malloc_mutex_lock(&huge_mtx);
  5453. non_arena_mapped += huge_mapped;
  5454. stats->allocated += huge_allocated;
  5455. assert(huge_mapped >= huge_allocated);
  5456. malloc_mutex_unlock(&huge_mtx);
  5457. /* Get base mapped/allocated. */
  5458. malloc_mutex_lock(&base_mtx);
  5459. non_arena_mapped += base_mapped;
  5460. stats->bookkeeping += base_committed;
  5461. assert(base_mapped >= base_committed);
  5462. malloc_mutex_unlock(&base_mtx);
  5463. /* Iterate over arenas. */
  5464. for (i = 0; i < narenas; i++) {
  5465. arena_t *arena = arenas[i];
  5466. size_t arena_mapped, arena_allocated, arena_committed, arena_dirty, j,
  5467. arena_unused, arena_headers;
  5468. arena_run_t* run;
  5469. arena_chunk_map_t* mapelm;
  5470. if (arena == NULL) {
  5471. continue;
  5472. }
  5473. arena_headers = 0;
  5474. arena_unused = 0;
  5475. malloc_spin_lock(&arena->lock);
  5476. arena_mapped = arena->stats.mapped;
  5477. /* "committed" counts dirty and allocated memory. */
  5478. arena_committed = arena->stats.committed << pagesize_2pow;
  5479. arena_allocated = arena->stats.allocated_small +
  5480. arena->stats.allocated_large;
  5481. arena_dirty = arena->ndirty << pagesize_2pow;
  5482. for (j = 0; j < ntbins + nqbins + nsbins; j++) {
  5483. arena_bin_t* bin = &arena->bins[j];
  5484. size_t bin_unused = 0;
  5485. rb_foreach_begin(arena_chunk_map_t, link, &bin->runs, mapelm) {
  5486. run = (arena_run_t *)(mapelm->bits & ~pagesize_mask);
  5487. bin_unused += run->nfree * bin->reg_size;
  5488. } rb_foreach_end(arena_chunk_map_t, link, &bin->runs, mapelm)
  5489. if (bin->runcur) {
  5490. bin_unused += bin->runcur->nfree * bin->reg_size;
  5491. }
  5492. arena_unused += bin_unused;
  5493. arena_headers += bin->stats.curruns * bin->reg0_offset;
  5494. }
  5495. malloc_spin_unlock(&arena->lock);
  5496. assert(arena_mapped >= arena_committed);
  5497. assert(arena_committed >= arena_allocated + arena_dirty);
  5498. /* "waste" is committed memory that is neither dirty nor
  5499. * allocated. */
  5500. stats->mapped += arena_mapped;
  5501. stats->allocated += arena_allocated;
  5502. stats->page_cache += arena_dirty;
  5503. stats->waste += arena_committed -
  5504. arena_allocated - arena_dirty - arena_unused - arena_headers;
  5505. stats->bin_unused += arena_unused;
  5506. stats->bookkeeping += arena_headers;
  5507. }
  5508. /* Account for arena chunk headers in bookkeeping rather than waste. */
  5509. chunk_header_size =
  5510. ((stats->mapped / stats->chunksize) * arena_chunk_header_npages) <<
  5511. pagesize_2pow;
  5512. stats->mapped += non_arena_mapped;
  5513. stats->bookkeeping += chunk_header_size;
  5514. stats->waste -= chunk_header_size;
  5515. assert(stats->mapped >= stats->allocated + stats->waste +
  5516. stats->page_cache + stats->bookkeeping);
  5517. }
  5518. #endif // MALLOC_STATS
  5519. #ifdef MALLOC_DOUBLE_PURGE
  5520. /* Explicitly remove all of this chunk's MADV_FREE'd pages from memory. */
  5521. static void
  5522. hard_purge_chunk(arena_chunk_t *chunk)
  5523. {
  5524. /* See similar logic in arena_purge(). */
  5525. size_t i;
  5526. for (i = arena_chunk_header_npages; i < chunk_npages; i++) {
  5527. /* Find all adjacent pages with CHUNK_MAP_MADVISED set. */
  5528. size_t npages;
  5529. for (npages = 0;
  5530. chunk->map[i + npages].bits & CHUNK_MAP_MADVISED && i + npages < chunk_npages;
  5531. npages++) {
  5532. /* Turn off the chunk's MADV_FREED bit and turn on its
  5533. * DECOMMITTED bit. */
  5534. RELEASE_ASSERT(!(chunk->map[i + npages].bits & CHUNK_MAP_DECOMMITTED));
  5535. chunk->map[i + npages].bits ^= CHUNK_MAP_MADVISED_OR_DECOMMITTED;
  5536. }
  5537. /* We could use mincore to find out which pages are actually
  5538. * present, but it's not clear that's better. */
  5539. if (npages > 0) {
  5540. pages_decommit(((char*)chunk) + (i << pagesize_2pow), npages << pagesize_2pow);
  5541. pages_commit(((char*)chunk) + (i << pagesize_2pow), npages << pagesize_2pow);
  5542. }
  5543. i += npages;
  5544. }
  5545. }
  5546. /* Explicitly remove all of this arena's MADV_FREE'd pages from memory. */
  5547. static void
  5548. hard_purge_arena(arena_t *arena)
  5549. {
  5550. malloc_spin_lock(&arena->lock);
  5551. while (!LinkedList_IsEmpty(&arena->chunks_madvised)) {
  5552. LinkedList* next = arena->chunks_madvised.next;
  5553. arena_chunk_t *chunk =
  5554. LinkedList_Get(arena->chunks_madvised.next,
  5555. arena_chunk_t, chunks_madvised_elem);
  5556. hard_purge_chunk(chunk);
  5557. LinkedList_Remove(&chunk->chunks_madvised_elem);
  5558. }
  5559. malloc_spin_unlock(&arena->lock);
  5560. }
  5561. MOZ_JEMALLOC_API void
  5562. jemalloc_purge_freed_pages_impl()
  5563. {
  5564. size_t i;
  5565. for (i = 0; i < narenas; i++) {
  5566. arena_t *arena = arenas[i];
  5567. if (arena != NULL)
  5568. hard_purge_arena(arena);
  5569. }
  5570. if (!config_munmap || config_recycle) {
  5571. malloc_mutex_lock(&chunks_mtx);
  5572. extent_node_t *node = extent_tree_szad_first(&chunks_szad_mmap);
  5573. while (node) {
  5574. pages_decommit(node->addr, node->size);
  5575. pages_commit(node->addr, node->size);
  5576. node->zeroed = true;
  5577. node = extent_tree_szad_next(&chunks_szad_mmap, node);
  5578. }
  5579. malloc_mutex_unlock(&chunks_mtx);
  5580. }
  5581. }
  5582. #else /* !defined MALLOC_DOUBLE_PURGE */
  5583. MOZ_JEMALLOC_API void
  5584. jemalloc_purge_freed_pages_impl()
  5585. {
  5586. /* Do nothing. */
  5587. }
  5588. #endif /* defined MALLOC_DOUBLE_PURGE */
  5589. #ifdef MOZ_MEMORY_WINDOWS
  5590. void*
  5591. _recalloc(void *ptr, size_t count, size_t size)
  5592. {
  5593. size_t oldsize = (ptr != NULL) ? isalloc(ptr) : 0;
  5594. size_t newsize = count * size;
  5595. /*
  5596. * In order for all trailing bytes to be zeroed, the caller needs to
  5597. * use calloc(), followed by recalloc(). However, the current calloc()
  5598. * implementation only zeros the bytes requested, so if recalloc() is
  5599. * to work 100% correctly, calloc() will need to change to zero
  5600. * trailing bytes.
  5601. */
  5602. ptr = realloc_impl(ptr, newsize);
  5603. if (ptr != NULL && oldsize < newsize) {
  5604. memset((void *)((uintptr_t)ptr + oldsize), 0, newsize -
  5605. oldsize);
  5606. }
  5607. return ptr;
  5608. }
  5609. /*
  5610. * This impl of _expand doesn't ever actually expand or shrink blocks: it
  5611. * simply replies that you may continue using a shrunk block.
  5612. */
  5613. void*
  5614. _expand(void *ptr, size_t newsize)
  5615. {
  5616. if (isalloc(ptr) >= newsize)
  5617. return ptr;
  5618. return NULL;
  5619. }
  5620. size_t
  5621. _msize(void *ptr)
  5622. {
  5623. return malloc_usable_size_impl(ptr);
  5624. }
  5625. #endif
  5626. MOZ_JEMALLOC_API void
  5627. jemalloc_free_dirty_pages_impl(void)
  5628. {
  5629. size_t i;
  5630. for (i = 0; i < narenas; i++) {
  5631. arena_t *arena = arenas[i];
  5632. if (arena != NULL) {
  5633. malloc_spin_lock(&arena->lock);
  5634. arena_purge(arena, true);
  5635. malloc_spin_unlock(&arena->lock);
  5636. }
  5637. }
  5638. }
  5639. /*
  5640. * End non-standard functions.
  5641. */
  5642. /******************************************************************************/
  5643. /*
  5644. * Begin library-private functions, used by threading libraries for protection
  5645. * of malloc during fork(). These functions are only called if the program is
  5646. * running in threaded mode, so there is no need to check whether the program
  5647. * is threaded here.
  5648. */
  5649. static void
  5650. _malloc_prefork(void)
  5651. {
  5652. unsigned i;
  5653. /* Acquire all mutexes in a safe order. */
  5654. malloc_spin_lock(&arenas_lock);
  5655. for (i = 0; i < narenas; i++) {
  5656. if (arenas[i] != NULL)
  5657. malloc_spin_lock(&arenas[i]->lock);
  5658. }
  5659. malloc_mutex_lock(&base_mtx);
  5660. malloc_mutex_lock(&huge_mtx);
  5661. }
  5662. static void
  5663. _malloc_postfork(void)
  5664. {
  5665. unsigned i;
  5666. /* Release all mutexes, now that fork() has completed. */
  5667. malloc_mutex_unlock(&huge_mtx);
  5668. malloc_mutex_unlock(&base_mtx);
  5669. for (i = 0; i < narenas; i++) {
  5670. if (arenas[i] != NULL)
  5671. malloc_spin_unlock(&arenas[i]->lock);
  5672. }
  5673. malloc_spin_unlock(&arenas_lock);
  5674. }
  5675. /*
  5676. * End library-private functions.
  5677. */
  5678. /******************************************************************************/
  5679. #ifdef HAVE_DLOPEN
  5680. # include <dlfcn.h>
  5681. #endif
  5682. #if defined(MOZ_MEMORY_DARWIN)
  5683. #if !defined(MOZ_REPLACE_MALLOC)
  5684. static void *
  5685. zone_malloc(malloc_zone_t *zone, size_t size)
  5686. {
  5687. return (malloc_impl(size));
  5688. }
  5689. static void *
  5690. zone_calloc(malloc_zone_t *zone, size_t num, size_t size)
  5691. {
  5692. return (calloc_impl(num, size));
  5693. }
  5694. static void *
  5695. zone_valloc(malloc_zone_t *zone, size_t size)
  5696. {
  5697. void *ret = NULL; /* Assignment avoids useless compiler warning. */
  5698. posix_memalign_impl(&ret, pagesize, size);
  5699. return (ret);
  5700. }
  5701. static void *
  5702. zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)
  5703. {
  5704. return (memalign_impl(alignment, size));
  5705. }
  5706. static void *
  5707. zone_destroy(malloc_zone_t *zone)
  5708. {
  5709. /* This function should never be called. */
  5710. assert(false);
  5711. return (NULL);
  5712. }
  5713. static size_t
  5714. zone_good_size(malloc_zone_t *zone, size_t size)
  5715. {
  5716. return malloc_good_size_impl(size);
  5717. }
  5718. static size_t
  5719. ozone_size(malloc_zone_t *zone, void *ptr)
  5720. {
  5721. size_t ret = isalloc_validate(ptr);
  5722. if (ret == 0)
  5723. ret = szone->size(zone, ptr);
  5724. return ret;
  5725. }
  5726. static void
  5727. ozone_free(malloc_zone_t *zone, void *ptr)
  5728. {
  5729. if (isalloc_validate(ptr) != 0)
  5730. free_impl(ptr);
  5731. else {
  5732. size_t size = szone->size(zone, ptr);
  5733. if (size != 0)
  5734. (szone->free)(zone, ptr);
  5735. /* Otherwise we leak. */
  5736. }
  5737. }
  5738. static void *
  5739. ozone_realloc(malloc_zone_t *zone, void *ptr, size_t size)
  5740. {
  5741. size_t oldsize;
  5742. if (ptr == NULL)
  5743. return (malloc_impl(size));
  5744. oldsize = isalloc_validate(ptr);
  5745. if (oldsize != 0)
  5746. return (realloc_impl(ptr, size));
  5747. else {
  5748. oldsize = szone->size(zone, ptr);
  5749. if (oldsize == 0)
  5750. return (malloc_impl(size));
  5751. else {
  5752. void *ret = malloc_impl(size);
  5753. if (ret != NULL) {
  5754. memcpy(ret, ptr, (oldsize < size) ? oldsize :
  5755. size);
  5756. (szone->free)(zone, ptr);
  5757. }
  5758. return (ret);
  5759. }
  5760. }
  5761. }
  5762. static unsigned
  5763. ozone_batch_malloc(malloc_zone_t *zone, size_t size, void **results,
  5764. unsigned num_requested)
  5765. {
  5766. /* Don't bother implementing this interface, since it isn't required. */
  5767. return 0;
  5768. }
  5769. static void
  5770. ozone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num)
  5771. {
  5772. unsigned i;
  5773. for (i = 0; i < num; i++)
  5774. ozone_free(zone, to_be_freed[i]);
  5775. }
  5776. static void
  5777. ozone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size)
  5778. {
  5779. if (isalloc_validate(ptr) != 0) {
  5780. assert(isalloc_validate(ptr) == size);
  5781. free_impl(ptr);
  5782. } else {
  5783. assert(size == szone->size(zone, ptr));
  5784. l_szone.m16(zone, ptr, size);
  5785. }
  5786. }
  5787. static void
  5788. ozone_force_lock(malloc_zone_t *zone)
  5789. {
  5790. _malloc_prefork();
  5791. szone->introspect->force_lock(zone);
  5792. }
  5793. static void
  5794. ozone_force_unlock(malloc_zone_t *zone)
  5795. {
  5796. szone->introspect->force_unlock(zone);
  5797. _malloc_postfork();
  5798. }
  5799. static size_t
  5800. zone_version_size(int version)
  5801. {
  5802. switch (version)
  5803. {
  5804. case SNOW_LEOPARD_MALLOC_ZONE_T_VERSION:
  5805. return sizeof(snow_leopard_malloc_zone);
  5806. case LEOPARD_MALLOC_ZONE_T_VERSION:
  5807. return sizeof(leopard_malloc_zone);
  5808. default:
  5809. case LION_MALLOC_ZONE_T_VERSION:
  5810. return sizeof(lion_malloc_zone);
  5811. }
  5812. }
  5813. /*
  5814. * Overlay the default scalable zone (szone) such that existing allocations are
  5815. * drained, and further allocations come from jemalloc. This is necessary
  5816. * because Core Foundation directly accesses and uses the szone before the
  5817. * jemalloc library is even loaded.
  5818. */
  5819. static void
  5820. szone2ozone(malloc_zone_t *default_zone, size_t size)
  5821. {
  5822. lion_malloc_zone *l_zone;
  5823. assert(malloc_initialized);
  5824. /*
  5825. * Stash a copy of the original szone so that we can call its
  5826. * functions as needed. Note that internally, the szone stores its
  5827. * bookkeeping data structures immediately following the malloc_zone_t
  5828. * header, so when calling szone functions, we need to pass a pointer to
  5829. * the original zone structure.
  5830. */
  5831. memcpy(szone, default_zone, size);
  5832. /* OSX 10.7 allocates the default zone in protected memory. */
  5833. if (default_zone->version >= LION_MALLOC_ZONE_T_VERSION) {
  5834. void* start_of_page = (void*)((size_t)(default_zone) & ~pagesize_mask);
  5835. mprotect (start_of_page, size, PROT_READ | PROT_WRITE);
  5836. }
  5837. default_zone->size = (void *)ozone_size;
  5838. default_zone->malloc = (void *)zone_malloc;
  5839. default_zone->calloc = (void *)zone_calloc;
  5840. default_zone->valloc = (void *)zone_valloc;
  5841. default_zone->free = (void *)ozone_free;
  5842. default_zone->realloc = (void *)ozone_realloc;
  5843. default_zone->destroy = (void *)zone_destroy;
  5844. default_zone->batch_malloc = NULL;
  5845. default_zone->batch_free = ozone_batch_free;
  5846. default_zone->introspect = ozone_introspect;
  5847. /* Don't modify default_zone->zone_name; Mac libc may rely on the name
  5848. * being unchanged. See Mozilla bug 694896. */
  5849. ozone_introspect->enumerator = NULL;
  5850. ozone_introspect->good_size = (void *)zone_good_size;
  5851. ozone_introspect->check = NULL;
  5852. ozone_introspect->print = NULL;
  5853. ozone_introspect->log = NULL;
  5854. ozone_introspect->force_lock = (void *)ozone_force_lock;
  5855. ozone_introspect->force_unlock = (void *)ozone_force_unlock;
  5856. ozone_introspect->statistics = NULL;
  5857. /* Platform-dependent structs */
  5858. l_zone = (lion_malloc_zone*)(default_zone);
  5859. if (default_zone->version >= SNOW_LEOPARD_MALLOC_ZONE_T_VERSION) {
  5860. l_zone->m15 = (void (*)())zone_memalign;
  5861. l_zone->m16 = (void (*)())ozone_free_definite_size;
  5862. l_ozone_introspect.m9 = NULL;
  5863. }
  5864. if (default_zone->version >= LION_MALLOC_ZONE_T_VERSION) {
  5865. l_zone->m17 = NULL;
  5866. l_ozone_introspect.m10 = NULL;
  5867. l_ozone_introspect.m11 = NULL;
  5868. l_ozone_introspect.m12 = NULL;
  5869. l_ozone_introspect.m13 = NULL;
  5870. }
  5871. }
  5872. #endif
  5873. __attribute__((constructor))
  5874. void
  5875. jemalloc_darwin_init(void)
  5876. {
  5877. if (malloc_init_hard())
  5878. abort();
  5879. }
  5880. #endif
  5881. /*
  5882. * is_malloc(malloc_impl) is some macro magic to detect if malloc_impl is
  5883. * defined as "malloc" in mozmemory_wrap.h
  5884. */
  5885. #define malloc_is_malloc 1
  5886. #define is_malloc_(a) malloc_is_ ## a
  5887. #define is_malloc(a) is_malloc_(a)
  5888. #if !(defined(MOZ_MEMORY_DARWIN) || defined(MOZ_MEMORY_BSD)) && \
  5889. (is_malloc(malloc_impl) == 1)
  5890. # if defined(__GLIBC__) && !defined(__UCLIBC__)
  5891. /*
  5892. * glibc provides the RTLD_DEEPBIND flag for dlopen which can make it possible
  5893. * to inconsistently reference libc's malloc(3)-compatible functions
  5894. * (bug 493541).
  5895. *
  5896. * These definitions interpose hooks in glibc. The functions are actually
  5897. * passed an extra argument for the caller return address, which will be
  5898. * ignored.
  5899. */
  5900. MOZ_MEMORY_API void (*__free_hook)(void *ptr) = free_impl;
  5901. MOZ_MEMORY_API void *(*__malloc_hook)(size_t size) = malloc_impl;
  5902. MOZ_MEMORY_API void *(*__realloc_hook)(void *ptr, size_t size) = realloc_impl;
  5903. MOZ_MEMORY_API void *(*__memalign_hook)(size_t alignment, size_t size) = MEMALIGN;
  5904. # elif defined(RTLD_DEEPBIND)
  5905. /*
  5906. * XXX On systems that support RTLD_GROUP or DF_1_GROUP, do their
  5907. * implementations permit similar inconsistencies? Should STV_SINGLETON
  5908. * visibility be used for interposition where available?
  5909. */
  5910. # error "Interposing malloc is unsafe on this system without libc malloc hooks."
  5911. # endif
  5912. #endif
  5913. #ifdef MOZ_MEMORY_WINDOWS
  5914. /*
  5915. * In the new style jemalloc integration jemalloc is built as a separate
  5916. * shared library. Since we're no longer hooking into the CRT binary,
  5917. * we need to initialize the heap at the first opportunity we get.
  5918. * DLL_PROCESS_ATTACH in DllMain is that opportunity.
  5919. */
  5920. BOOL APIENTRY DllMain(HINSTANCE hModule,
  5921. DWORD reason,
  5922. LPVOID lpReserved)
  5923. {
  5924. switch (reason) {
  5925. case DLL_PROCESS_ATTACH:
  5926. /* Don't force the system to page DllMain back in every time
  5927. * we create/destroy a thread */
  5928. DisableThreadLibraryCalls(hModule);
  5929. /* Initialize the heap */
  5930. malloc_init_hard();
  5931. break;
  5932. case DLL_PROCESS_DETACH:
  5933. break;
  5934. }
  5935. return TRUE;
  5936. }
  5937. #endif