From a606b6087e59e59897859f144d261af72bb4140c Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Sat, 18 Apr 2026 20:28:31 -0400 Subject: [PATCH] asm-gc: movb-not-orq type patch (kills residual "unbound variable") MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root-cause fix for the residual crashes I had documented as known issues in §6.6.4. Every heap_alloc call site was setting its type byte with `orq $(HT_X << 8), -8(%rax)` — but OR merges with the stale type byte from a free-list-reused block. A pair previously used as a vector (type 5 = 0b101) re-allocated as pair (type 1 = 0b001) ends up with merged type 0b101 = still vector. Walker then treats the pair as a vector, reads the pair's car as a "length", and walks off the block end — hence the hash-set bench's "unbound variable: t", memory bench's "unbound variable: lst", arena bench's "unbound variable: k". Fix: overwrite the byte instead of OR-ing. 18 sites converted from `orq $(HT_X << 8), -8(%rax)` to `movb $HT_X, -7(%rax)`. Every previously-residual crash gone on first rerun. Refreshed benchmark numbers throughout §6.6: §6.6 Memory table: 122× less memory at 26% slowdown (was 124×, 30%). Range shifted because the fix also accelerated the common paths; ratio stable. §6.6.4 HTTP soak at 50,000 requests × 16 concurrent × 4 cells: no-GC + snapshot 630 req/s peak 100 KB growth 4 KB GC + snapshot 633 req/s peak 120 KB growth 4 KB no-GC + no snapshot 625 req/s peak 458 MB OOM at cap GC + no snapshot 610 req/s peak 1,092 KB growth 852 KB Cell 4 now sustains 50K requests with steady-state 1-chunk memory. Previous residual edge at 50K (cell 4 failing to start) was a manifestation of the same type-byte bug, now gone. §6.6.3 Adaptive numbers collapsed to within ~1% across all three workloads (was 6% / 7% / 17% deltas). Paper updated to honestly report adaptive as a null experiment on these shapes — neutral cost, same stats surface, default on. §6.6 diagram: bench-gc.png refreshed to match new numbers. 137 asm no-GC + 137 asm GC + 189 shared functional all pass. Hash-set / memory / arena / adaptive / HTTP benches all clean. --- asm/uncommonlisp-gc | Bin 59600 -> 59640 bytes asm/uncommonlisp-gc.o | Bin 61960 -> 61952 bytes asm/uncommonlisp.s | 59 +- docs/benchmark-gc.dot | 6 +- docs/benchmark-gc.png | Bin 29200 -> 28750 bytes whitepaper/diagrams/benchmark-gc.png | Bin 29200 -> 28750 bytes whitepaper/uncommonlisp-whitepaper.pdf | 1032 ++++++++++++------------ whitepaper/uncommonlisp-whitepaper.rst | 46 +- 8 files changed, 577 insertions(+), 566 deletions(-) diff --git a/asm/uncommonlisp-gc b/asm/uncommonlisp-gc index 784582635fd760ef71b4178a41b3fbb8cca7b813..b8ea325e271ec3c2324c6d6554601430d1363ca9 100755 GIT binary patch delta 16389 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 L?LmQUxfJ|=*OO*I diff --git a/asm/uncommonlisp-gc.o b/asm/uncommonlisp-gc.o index 60f018aacbea49816d1488ec5c5a8a3e4f453f3d..b1504f836cfd9784f2c1b218ed15af92595ec577 100644 GIT binary patch delta 17049 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 reject + # type==0 fallback path + movq -8(%rdi), %rax + shrq $16, %rax + cmpq $24, %rax jne .gme_end + movq (%rdi), %rax + andq $7, %rax + cmpq $TAG_SYM, %rax + jne .gme_end +.gme_typed_ok: # Already marked? Skip. testq $1, -8(%rdi) jnz .gme_end @@ -1333,7 +1348,7 @@ make_pair: popq %rsi popq %rdi .ifdef GC_NAIVE - orq $(HT_PAIR << 8), -8(%rax) + movb $HT_PAIR, -7(%rax) .endif movq %rdi, (%rax) movq %rsi, 8(%rax) @@ -1351,7 +1366,7 @@ make_closure: popq %rsi popq %rdi .ifdef GC_NAIVE - orq $(HT_CLOSURE << 8), -8(%rax) + movb $HT_CLOSURE, -7(%rax) .endif movq %rdi, (%rax) # params movq %rsi, 8(%rax) # body @@ -1381,7 +1396,7 @@ env_define: popq %rsi popq %rdi .ifdef GC_NAIVE - orq $(HT_ENVNODE << 8), -8(%rax) + movb $HT_ENVNODE, -7(%rax) .endif movq %rdi, (%rax) movq %rsi, 8(%rax) @@ -1511,7 +1526,7 @@ intern_symbol: leaq 1(%r12), %rdi call heap_alloc .ifdef GC_NAIVE - orq $(HT_SYMBOL << 8), -8(%rax) + movb $HT_SYMBOL, -7(%rax) .endif # %rax = sym_ptr; fill symbol: length byte + chars movb %r12b, (%rax) @@ -1535,7 +1550,7 @@ intern_symbol: movq $16, %rdi call heap_alloc .ifdef GC_NAIVE - orq $(HT_CHAINNODE << 8), -8(%rax) + movb $HT_CHAINNODE, -7(%rax) .endif # Fill chain node: %rax = node_ptr, stack top = sym_ptr popq %rcx # rcx = sym_ptr @@ -1893,7 +1908,7 @@ scheme_read: leaq 8(%rbx), %rdi call heap_alloc .ifdef GC_NAIVE - orq $(HT_STRING << 8), -8(%rax) + movb $HT_STRING, -7(%rax) .endif popq %rbx movq %rbx, (%rax) # 8-byte length @@ -4303,7 +4318,7 @@ bi_strref: call heap_alloc popq %r8 .ifdef GC_NAIVE - orq $(HT_STRING << 8), -8(%rax) + movb $HT_STRING, -7(%rax) .endif movq $1, (%rax) # length movb %r8b, 8(%rax) @@ -4336,7 +4351,7 @@ bi_strappend: addq $8, %rdi call heap_alloc .ifdef GC_NAIVE - orq $(HT_STRING << 8), -8(%rax) + movb $HT_STRING, -7(%rax) .endif movq %rax, %rbp # string object base movq %rbx, (%rbp) # store length @@ -4432,7 +4447,7 @@ bi_numtostr: addq $8, %rdi call heap_alloc .ifdef GC_NAIVE - orq $(HT_STRING << 8), -8(%rax) + movb $HT_STRING, -7(%rax) .endif popq %rcx popq %rdi @@ -4635,7 +4650,7 @@ bi_vector: leaq 8(,%rcx,8), %rdi # 8 (length) + count * 8 call heap_alloc .ifdef GC_NAIVE - orq $(HT_VECTOR << 8), -8(%rax) + movb $HT_VECTOR, -7(%rax) .endif popq %rcx popq %rdi # restore arg list @@ -4672,7 +4687,7 @@ bi_makevec: leaq 8(,%rdx,8), %rdi # bytes: 8 (length) + n*8 call heap_alloc .ifdef GC_NAIVE - orq $(HT_VECTOR << 8), -8(%rax) + movb $HT_VECTOR, -7(%rax) .endif popq %rcx # fill popq %rdx # n @@ -4771,7 +4786,7 @@ bi_listtovec: leaq 8(,%rcx,8), %rdi # 8 + count*8 call heap_alloc .ifdef GC_NAIVE - orq $(HT_VECTOR << 8), -8(%rax) + movb $HT_VECTOR, -7(%rax) .endif popq %rcx popq %rsi @@ -4811,7 +4826,7 @@ bi_substr: addq $8, %rdi # total payload call heap_alloc .ifdef GC_NAIVE - orq $(HT_STRING << 8), -8(%rax) + movb $HT_STRING, -7(%rax) .endif popq %rdx # length (restore) popq %rcx # start @@ -5466,7 +5481,7 @@ bi_file_to_string: addq $8, %rdi call heap_alloc # %rax = ptr .ifdef GC_NAIVE - orq $(HT_STRING << 8), -8(%rax) + movb $HT_STRING, -7(%rax) .endif movq %rax, %r12 # save heap pointer movq %rbp, (%r12) # store length @@ -5603,7 +5618,7 @@ bi_symbol_to_string: addq $8, %rdi # cell size: 8-byte length + bytes call heap_alloc .ifdef GC_NAIVE - orq $(HT_STRING << 8), -8(%rax) + movb $HT_STRING, -7(%rax) .endif popq %r8 popq %rcx @@ -5724,7 +5739,7 @@ bi_make_hash_table: movq $HT_TOTAL_BYTES, %rdi call heap_alloc .ifdef GC_NAIVE - orq $(HT_HASHTABLE << 8), -8(%rax) + movb $HT_HASHTABLE, -7(%rax) .endif movq $HT_SENTINEL, (%rax) movq $0, 8(%rax) # count @@ -6107,7 +6122,7 @@ bi_make_hash_set: movq $HT_TOTAL_BYTES, %rdi call heap_alloc .ifdef GC_NAIVE - orq $(HT_HASHSET << 8), -8(%rax) + movb $HT_HASHSET, -7(%rax) .endif movq $HS_SENTINEL, (%rax) movq $0, 8(%rax) @@ -6808,7 +6823,7 @@ bi_tcp_recv: addq $8, %rdi call heap_alloc .ifdef GC_NAIVE - orq $(HT_STRING << 8), -8(%rax) + movb $HT_STRING, -7(%rax) .endif movq %rax, %r12 # string object base diff --git a/docs/benchmark-gc.dot b/docs/benchmark-gc.dot index ff62293..f82e1bb 100644 --- a/docs/benchmark-gc.dot +++ b/docs/benchmark-gc.dot @@ -9,9 +9,9 @@ digraph bench_gc { fontsize=14 fontname="Helvetica Bold" - bump [label="{Asm bump-only|peak RSS: 133.9 MB\nunbounded growth}" fillcolor="#e17055" fontcolor=white width=13.0] - gc [label="{Asm naive GC|peak RSS: 1.1 MB\nsteady state\n-30% throughput}" fillcolor="#00b894" fontcolor=white width=1.0] - arena [label="{Asm meta-GC arena|peak RSS: 1.2 MB\n2000/2000 resets\n-1% throughput vs naive}" fillcolor="#6c5ce7" fontcolor=white width=1.0] + bump [label="{Asm bump-only|peak RSS: 133.1 MB\nunbounded growth}" fillcolor="#e17055" fontcolor=white width=13.0] + gc [label="{Asm naive GC|peak RSS: 1.1 MB\nsteady state\n-26% throughput}" fillcolor="#00b894" fontcolor=white width=1.0] + arena [label="{Asm meta-GC arena|peak RSS: 1.2 MB\n2000/2000 resets\nsame throughput as naive}" fillcolor="#6c5ce7" fontcolor=white width=1.0] bump -> gc -> arena } diff --git a/docs/benchmark-gc.png b/docs/benchmark-gc.png index 7f419668ee6f1b9d3cbe784137c208f729783bdd..e1165861c67aaad58dae33300fef24c4eeb6f491 100644 GIT binary patch literal 28750 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 literal 29200 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 DY!ZUx diff --git a/whitepaper/diagrams/benchmark-gc.png b/whitepaper/diagrams/benchmark-gc.png index 7f419668ee6f1b9d3cbe784137c208f729783bdd..e1165861c67aaad58dae33300fef24c4eeb6f491 100644 GIT binary patch literal 28750 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 literal 29200 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 DY!ZUx diff --git a/whitepaper/uncommonlisp-whitepaper.pdf b/whitepaper/uncommonlisp-whitepaper.pdf index 56aea33..214fcfe 100644 --- a/whitepaper/uncommonlisp-whitepaper.pdf +++ b/whitepaper/uncommonlisp-whitepaper.pdf @@ -213,11 +213,11 @@ endobj endobj 27 0 obj << -/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 101 /Length 30274 /Subtype /Image - /Type /XObject /Width 2004 +/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 101 /Length 29887 /Subtype /Image + /Type /XObject /Width 2016 >> stream -Gb",k#C$s7fsZTSgah$;m5W'>[Z`@>>iXInPP@qDI'M_AI'JMi(`_;_66O[fke2nK!XK?+6@e:b84!q=W:sV!de;OAB4q6gpIIflQJ!!>&to!5T$,a03G2*X?/]GA^14Vs#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jdb.!.kW&rB/1JqATT;W/?EE6C).EEUtG=Le@go>Ul3.MWYRN/Y,jl9BYf\pmZKIr.)%2Ng/hq!mB@\P$g38]g\ngI\PKX6!shCs1R]8AF#fZa71Wde)>M>_,-?#=jdonM+S\Jfk>N+:*QA#_F0i+$"`DE.A`grqL!0g"apM5PjRgW9UOtmdd8pC20cXc2_4#q'@U1*?G+J_[j?nGk90=S"#nX(&D)"Wl)./e>ZAb]'1Qqkl(85^N]-Q=s+t3iQaORUq'8crH(P"a&U7K%t.V4O+`7BP$X8'\X^60>$=N*KS>+cPmY(cp%hA]spQs-7luUIL4eSU((rV]U3F&_`k@-Vm(6jQ'k:QU5UtI.9Y(T:A+Bm'CfgVk:p4Jj"JSOG85\e"?X*?iR_3hL"4+jN*I;KnYVXSt8\K-*A$q!mD'oZ]>P$ug*$PtIllHLg,gd\VbULjnL[PQ#pt/mNPf]heFqh?Rqd&:ZU(%j=-Kp[Q9G6S@/C*cjtH8g*liQXBHm\JJRs!Qoogl)3TAYLeu?lqUo:+^":fbOn>nga27)eIeGQWL)tBY['d;)j(/&\m3KZs@KXI&GM`j(LP1?-PinZg*`?0omQMi4baE\FQjFf#58kfbak;q,S&I)M\M7ueR?)A3Yqa?%2NSN:n.h7@aLNuti7X]MR("J1nOJ)MeRWV#iIe'QYDqtE$+1q;Umqnb@?p+0n`^1uRVCZEEoEk0tJ*>6&rb"TJrpuafS:$J$CBS"K[lK#uOK=tB*7D-5nF/b&-P91"@8,5iQ[l9-KH1kgqg:tc":1cA-k1snH0:aE9>@^;GsJn^@KDs!??!gl)#=SArp76n,9le^*%=*+#td2+E?+9at(i.D#B1^n[:>r!&*g1P[(aN-oX[iBpNH1U1kaa84l2&Ha?^%E08hRiI3>D^6h9+o7')<4Wd^b$5G%.DlUkHW&KK0Jl["OFUU=bY0cq[AL']C!%NhKan-nAGu9^cF[Xo[>YY`>;nR)0s?M%blE6XT&YuLlRKBJQW9Jj[1,Pn:0C""pU7/io4D["hh@Qen=_^fX,?+AAK&f9l]D^\X`"$-U:lj0eqN3kLd%Ld-0;0h`Yc+XFg`gOp-H\4Z`<.kKbO!8)i:m[,pmCo\Y#Ab/t'1Ic8b2XU'M$#_F0)Jfk>N+@n`eB[3ENVNR<&ACGd*=;WLYo#iZk#7!K``"R*;o?B4\QBjl*\8gP"mU-"jf73hthiBtt-ooPqbHkRD]b.tdNoODH2@0tAS#GK58uLsTES`9ORgn":\?*eA(.Q^Xk]TJ\[f8_G4"kO:E#4_X4hi%^"W/b:Vf)gF'80*VR%Lr\'eT`s3)n^8Bl&pYL8`Z,arMNZC4J^:nQbp\p(Xr.5puR?XI1/D2MrOSfPTI5$?5_QSRmXXb6(Eda.OJc]^bg[X?qerd4)GhffKj:[#/5[9cPhgZ_C?[:au0k85Mgn^_kE\.U_6G<+lVbRgKGN$DmhE""U7!G5LmQ#/aMBbWO4T"KOm`#2!\%coik3-H_!MuZjL-.PBo[-0_6=E/G!U0^Lj,XH;\;7]+\TcqZpP9D+%NRUkZ)cB$T.j[TbHd3B+!49V8>Q35HLJ&OqC3KBHgeWnKSWkcVZpj;=;\Ed>`R,;8\k&?*d`k4hc;4lJ,J=KiJ&VN+:*QA6c%WI0F-i9O0UjHop!qkCR!Wc"@+Y8*6S);lqkIhgo7e6$p-n'mX*YAuM$A=+e\NG.gG53YAe+_aLT:EcHp$TH\DV;pf=B[r:/!4uah7b+k"]8j>pR?!Zm[q8_TppC=N(hoe8#Oo&C64?did9O0r>IBKZb0+/$B3TNcJQX>25CMRa&bfIku>I&OgE2`M+/+f`d/s%4@7un^f.6cYb98r1$rTR,G\$8=F+[7f6cPJ%37&Mj?="[-cNCi[.Y5%io02N)pJ)q./6]F%A"s<]+:*QA#_F0)JfmTkTdIu&DnJC'[>9VE)OTXIaccb^YuiPic^lFk+%D;4rSDnic'U5:,cZWZRdEiYWijRTZo@OUR^0nbY'#Wda(LCcnD^XeOXf^[$`JYP]_Bc_lDh%Z=roAAEnrtS%BQ&0TG<=tR#re!"]X[-rHgL_&hCC*,ammB1)sQJ;g"@Y@b.Mp8$hTj)l6cGo=2,s,OSnY*#@a+V>C#A!B>!%b/j#[3r8[@sHfqOVn_VBP')9075'>N@b1c`uE+6)>SBd`khdbR=^Mp.G:.*_3dleMgjM4h=:%@J]PBWqAkKEf^5'QE73KB/]Vrb\giemeLkSX%I/$mo&@bnfqlDsi"q7I5J@q/)]'e<=(CH-S.+A$c9mHFh%"@3S%5nF/b&-P91Un;nd(eMiqcR/m^/R+P"L.\9d2UQm?]gp;LP*-H\'h5n2n`.ZRa:Gc:H>@##UW9gU]k_cUe>^sldqZ:c7ZG"J^AC+moM_+"a_'8]DS+/.[JF$bS%`=KL=!ZPNMb"_o?TWKIK&T>ca[o#A/N=7>;((5;Ek*Tj8S+cm"X=64e$\Q^fOlkjfOp+bJ*]e??cKKSpg<8H]RL9I;G%9S4kR*l+KHTj;:p]?b>'o(!+p$8`Y1rtc1\s4qbTLHk\[AF8-\O/BGBaam3#89Wp(5Pl>Zrpuc^FMEh"f@kcX#AADZ?K7?;QKOcW?c53=o).W/^Ys+SkC#n9]j63t/RQ5^U`V[AN$a](%N+T9-SpTDnWL_Vgbg,+t%[9=@t=:c;d\9@8nio4Ef3K6f#ESpZ\\)5Ib9MS=maa3jO[lq1]c$Q'EG:lJ5aN1U[D!_)9%t;;'$3<<#s8MltS8k,lMP%ilJt4uIOq,)o[^#SNalq-IaY)oCk\*jR+sNbR\aE_4E.LLUEH`NgFq"07J,`/h?2CUWn%SZ/:+&f,85@9B,#'E5='pAE;LEfZ:a,'*b^X\T1Z[hC3q>8MRg$rAThm08LD(T?*h"2d55t?;G)l=2H1U/a?7'Uc'0b78\9tGGs1S.jFkE=OmF/oakBYRU;<4P^1uA,uJ,akf?T@K1q\@n2^\cjU+D^5iV)3n\J#uaEK%Ra8qWjrBIJ``#>U\`@RoCj`\UXCl+7skBUf:Dshg+CU!R@8'oN;9tNnJ6'gq:9^&fM//d:Z\]pEBM/L?;B3;Fl9E$O]PERh6l7d)Ve59D@7d?bkcmo+;*k&-P91"@3S%6'2*(dsD<8/6G0[]^sE1e#,ukn\lP"7GlG3kk8pqdCl5W\-pJ:I#k%1*=aVt\tfcen`q2\J-(E!>)[SAMQ931oP&cbKAF]>+@p>51cXDFLE%R.G!n.1$D_[es+J.rK4DFF6pL#_U7qpR\Ei;4n;\Zq[%\Ffg]O$=thnG.D(fk9R7CGZrjo.t+/,Z=WX#9S?hjd0ntm5AuW^'NnjF2g>F3d!'7[csZG/C1TUS=NY8ZpCJq!US9ARUOm7uuf`!->boku+h3T!34p7S*R8ms`N+Gg%s<`YBn`7`hsr$?,oC\R;T^NT"uq"T*#c+SgbKc;sg4E04D='$3]ZE%$.,'>XL",5]aqkh,qQl(ujUc^m9M=0@LBNm>kmFG\o3Vd`^>M+$>T3'9.h\3clKH1E6))g%,[BtXJV/oVghpJW\dZ!cORPETF`Nu^:dD/mbOCpqfj:Tn!3%LPk*;S$CX,=*sSLRaN%\Lse5MMd;4aN3l?n=#daO[qkI'GM7+m#o[%iI6DIW"?N\'c#j$-;_3LGOOD%HM-P:-Vh2$4:'-k%Lb/Cq(?0L-2GU#^C%2[E(nMk]/.$YbIAZ2;A'TTY#^>F]IVagK`dtP=>fljJZkWqelHZ(cPOm[ZY/O-s4qaO7')!;af3N+:*QA#_F0)Jfk>N>[7gZ3"Y#,cp#r")%6iZ$3H`K\L\N>;"k,Z&-P91"@3S%5nF/b&-TOPTs&sjbfh'l^'m!i^ABOAPl"3j"@3S%5nF/b&-P91"@3S%)$l+WMT1SmoC^^B%s:AHQIaX<-_Gd,m+AR1h%9cU&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91"@3S%5nF/b&-P91";s=2@q,TP"M%Ebq@hWlI[1QK),T6aAuNK-&-P91"@3S%5nN+'U>)l@3rq4k!oEs,6f/@&'ap>rg@O2$n],UunC5>d]Drl@DP1lHU%aQi#_F0)Jfk>N+FU*@HVY&;%CX>&O!3rrlA@HC_DUPj#C\!f%8VuZakNI3mfr&H'mfN+:*QA#guf$HQP#:pO9d`]m%u6,kTqj""Ns"&HkB2"@3S%5nKiqT_CW\6LXl!(OGPKCJ!a'UBX]qhKs-XmKX#L+:*QA#_F0)Ec!LtNZ::I]apOXHb\EkhE1"+&pj#F!>WBD:;257HL`d)$ACg?:fPb*1)g0VU/36P$8omKIt%^POlH\[pEA!^Gjg]`hu0JN@m5g18rJ#/i&K*l\ZqpYU>3rISJqKsS3rt(P'?\nj\sMG1jW.oP#;/)D7i*Zg^!)ijrAOdllYeYr\S]"^V*))*H`su`phj:LWUB+On^K9HG44eE]Ign;YfW>`hDNSaQT\08qT:5GTGgeE.>g?\-kR6@tRF7@AU`gC>5"FQe?K`Fe!U2DS(:ahhZuWha\@fKgMI;=lf&??oi?+T_CW\)@Gs3X3,OJNU^0<+.#a>]htSkAB6i*1f=]sM\A!F,Q3XeS`,/mUQ)8&b+XdL@Z1jt4d<[=5DrmX-L[='T@]`;8^0_7fNb7LAMk:(`FH4IqjpUUhGMmfD@Gu>WF/K>C4$e4Bsd*3[Y>]AA"?btZ74nZcLhO5)n&onm'Q&b[amp+6H4*RXLknhI:i"b?)XhMhl'T0=OqrpR+>KH.H?)CX4>ju@RoNl'72dsCLJ%`Hu^`p:#*[h/*5h*]lAnaA[!<@]\1N#N:T2$='b%'UJN?Q$Ir4OpPqS6:ajiO$b^a`\#t#FrMA:/Er&Db&M%W)D(Hg-X."sRN9.UAIH.d^n!Hq6p:Sl3k/lW7"6i\+RkB]Bg-<2%f?W]\qd5MFU0b%Ygfd/\J"F33[G)Ym.MqQE%ecLDL^L7H9@tZ)RhKrg*[q.^6S?TBIBJQmBs6J;K53lFXg!!dH0ML`a%)6n]oOs2<5Kfr77&lui.&W"?=fj69pHEqefP"ZfHMm]3lP1sdLMOS_66]rVN#f'qM>>g/8@2al^!jfL@Nnd5]4H\DOI$0bG8(C<6D=6*o\NFn'FKO4I%g:plBWOK3t2cX.P9rIMar5\Z,`]V/]g)Gc].nj`OK,4d9Z05N?f*8?HYS0j,E16SFS;hq].+IU"C#rHbV\[XAq=cU>O7^P6'Co!AM-8PaSaolo`'g"/Wt*P"Kduq,*U'a0T)T_`i]eer-gLpJ_;`HfMb;IG44;bPjor`[6p?J?>K2i;(*+cL$G_cHUjc+-kpFcL#+nk>CLhc?WEt-=PKF-)R7sllAY\I]tK#D_V\C*.'9?^K;M,9OBIPB/365JT?B6b+n#Qq.#!ahW"r=PS*RaPI"""bALTZ1\V5*KZ(lf1Zs@-!`!IC(l,r-4Z]0O9mSAa_\WA0H`3AU>Q4j0??Zki9fpoqeMs6el1F06IT`2On4MUX)X.rj/f)+k;HLIeJ8OMLN.ht`HYt6*K3ng\S[3PCgRK_Nmo=W3)\gk&*bdOu_9LcItcktOOr;:r:SjZCp6tJ*Z$&:@m$EDsPj;fu0QnQT\i:rl&1QXJr2Ofp>Wl\.Ac0d4\XiWYbMOG0SD6uXh^&KSZ@%1#7TW@K]:Tm,3G4[^nk?fl%rbh6Dk^\\u]R95Tah9iKkLR(^/Ros?>Jf+:IrXFtcR_n]>VN-,K7CsDh0XneltESY(H"P%+7kQ0nF'#0FSFY6@/jPX@U=JSJ[,3`1>R-rd!J8g9,];KSRLmN(H_Qg.H?(-"\,cD)Doau3O^qO7%Mp)P8uaAB29.u]<$hq*\?Ud9B9,(9=Co,p3?%FH0Q9J<&bjunKQ:=M?K4XXpq::i%,Q#teZ8g`4F#U:a$X+REe4iDfdsc8&RdOeNakF3kePK`ck']=+?m!)VK2I[(0ThheLQj1Cqn1$[S'AZp[c>1i?'RGGP\sd*X7o?n$ei!Wg"^!"Cq%hOYn!5LHUjc+-kr\b6LPqK6D75S_&%FdW,DFu^&Ln%6(2huX.BH:8WsP)1btL`+u-1LTF'kfi^&Wsht-EX,Hhn'T3%Xtm"qB%]_B/USkrS7bF/dOKiR*GI^I4iB'jbNpiH+\V!YAH*LU)PTiS(EqOo'^Z@$C0]Q`qjir6=+-p\U$^$kC&PJLi[3noU^>c!NGB]'PMn#1"n6fl"&:%'CWV06KJQ]4WYd9X8RF%iCPBOL(BoABp!&l3-2Ek+TVSF"qp%MbQuVCa5N9#]#;),bD?dasPg1fu;@[\M[D'"]L;\a_jmU[hlK_.L#TQ'o-$h0H;Rb(&l.h'*a/mF"Fu[fXKpLP+l4;sG7VJgh=uFmRt/pYP/H1-%&\e>gW`"@SNaSJcRSfFS'cWEgsdS*)BRDr[qN-9)q-P`(ebl5mkSp"DVYUjWB1te7/30+'L\g(d!Ma;DMi??E,:R3pKK_GtsFZO)QblsB_9Hs)t`1.^-(q-6FctHo1ceR]Y&*U^%XsFOBpWbXj-\!bU0og3$#Br1[^dN$:P24ibfP!dt]ZH2#MB7c))"an7atu%Z)J[Jc".P^[V\NCZ/6'Jr]E_aaL1S18M-=UDbjc\)"VeShdBpqJmlXb0jJVadI$Ra0[FJjHaYA3#cH^jD9\+!1[a*]2s/?^+Gj95b>-Lsnlhg_N^BF9-raQ-hE)'e"mT4b[:nkmT>^qS^D)HW&dd17'[3')U!0Sk]%0O[[86h@s"'dok+GS4SUmAV/t:W3nfN@e4K+WISX\]9j-4K>bb656%`LoB%2pPmSlgu$R+i?YWc,;]H^u8\`CZV7&]0toPX-RA7IeP9/bOlTUIEMmCLrt2^`IGf.52?"Ko;[/POE_Y'TY,J1&N9%?U>!0H%c'.8hOT"_+@@1f+Xg-Fs_Ag=GHLJZ`6q.8o2R>pI3I8R2]n>l/(j&s9+KmYKmjJkWKgPH4ke3`f=!7=tSZLB$Z^?"#Eqi_7=jUu"X>5",YRI9[ae_IQqomBn\LC@97G&)]CjN3A2mm/p=8Z5!K$'?k%U#VpRna&[F0gN=k!1jFC8t]!8ul2@hQb:;QFiA/pTnIqV6cFab,gaYlCrVF4!7cePFE%V5bbNdgjP&R/TitHhV?uOnGe8iM,C4&(4,GJDY`\5J(>;%jeehjeN1\;NbUN`CF_V&n)+D0JRd]f(T>7k>>&],_6/+]jk`'=]NoX5BO_f7jEYRnh2\)jm)ek0YlW-OOo@E)&C%dHBfktPU/Jq%"o<;V1&BI&DfU'ODbo'^HGT,AcgUC,dc2a3p\pA8]c$Cdl*WMsMr/l2/cR5pHr?9s@g18,7pSb+.dpXo[*k=0&A[\,/NV!/7%Y?VWo=3@MERML#+nk>Q/p:XPGKal_i6;Gd$o/$$!<*CAqAu?H@F84fV\`3%\kCUb)>d9;dAVZ7`+&s!g&Mi!c$JZC8P-3Y/.#3iWXJeaDS5#<88nNRb>KV8U&QG<>Yej;hMQrLpB?30*7'1YN\Un=N.I4t92tQF33Q1$&/:5Rbi=o@+c-X*O6=(EAJI<'etYM@T12a(4RmP]&Q8C%YNTj!_DjH_p<,Y1:9$,YY.-X4Jk1DRhtjn1=4g;:gtcb'Q(:fSX-:`(&jNI;4D+bt.,CdGsr#[2RfA36dJ+MEPCjb[c-3XZ=c(hGq8?s;J-[Bf2EQC(4nNjXaC8$pXD\gm=4c\4Ja:]m6)kK'-$4uZ;3K'+hH4YOtY#LmZFbVf_g?S3V1A]2n.gAod[0-dgREL:2Y:3%.GM>b]d+K-lKhrK/nlm7Hf9eiH0;k9-i'B'VikWY["aofj3luip\1W#I.7JIo(7VQDW8UWoMh6/eFT#Y"DI>4Ubtp"YcOhn-Q.8F0qKq0CD+ZSGL7""UItl`GDa]L35a@sA,_W48&=QmeXGW0qTsd-,>+;H*9sO7Y.8LqC:N^I7.2.=/SV/rpQKTc\7g$47:Tnc.5kASI;eB(7C'!oI8.8O0ZO/r_-cp&Fe9u)8_;QnQm$mu>)/Lc^VAMp0$-%ADsn0+'D-u4rL=?qAq'%aHj6TF5,mS>OKJ*#PZ3DMHMd>1oOW4TesOR+TPShSp&]f&e7D9Cj.P^1AH]RUFEcGOM(rOa+o%jdAK;`@R)+3TToC$8p0smiBq1o\QcqU%aSYQA"*VC-[L03sp[.Thp.PHLIfk+QC(YXU:pSqP%d=eAYNs@HhUq/K?n(WfSVApuC,j;n]sDNZaF@l\l:!R4j3]c[T#C6ZM`DG5QHW7iddMth[R$Sk<9V#j]&e_ANk2*AhE1"+dZA_BW8SunhGG[8$AIcGd!J7l#EaH'K%XMX'Qs7DMmrj!XAYa%Y;M1&hBQ#u4Cm]7F%e0.1qni(H@qdK]sCatCu8ijYpte$p=?CIYoN=sGRg#Rti:R7XDl+M^c#+`6U1-A]E$0I2UgMHGj#]F3#hRheq"(i4A]GlJTo\NHsP0ePG%B.X#8"ll?obDH#WtOFsZk`"uk,qWSpMPS>,$"[N2*?TL4)-a2Gjhr*/_qkl@kFDb?%+gSCG$kN)_*KK)A>6!\Fepl7SUm:R]\3l!j5bbB=kZ_E-ak_=,5'gm`mcq9fXRbG$riGf2T8LNQ3u36=ZJ)4)"JR4$?Q(hn7PK1Z\$6V8]lW]h;e)*`7!DIUId^RLAV"?rp2(lAgBN?M:gM]0q].+I2-()iom4IETm&]V['RG$>M4.Al[1C7f=oO6UQ)8'.5*/>;R956dP#Jh\2AO:/J-B2#6cTbncG(Ya&mAI_S6d1po]"k^%WVGmiJ-U;d%B&bTEHI0$:O_iuUacJ@(,P9hi.&,#+hnf=JS(ej_Ef%72Zr]][]q\C_JC&X5%0r",0oSSu34;>_CQ5$^ct5+V0)6!_"S3sB6lh#^,2']TP403DA%U"Q9dJH'.Oj4deB?kri)H24c1nH\k`m>UasuY]LcYc]a7Eqd/t6[$^'g3*/snlNgt!l<]E@:gPBE0KS&@CTH0baeHZtV(GHGae/3gMtdCQ9oj`(8-FlV_tp>3P4:GLRj16$*gBC1cuT&(2[S%Z53r$k`,3\@ART[$OEa(4Qb.3k%b_'CG2VT1HdiUm,Va9K=-7k+@=k$CsDhUIAKm1kD1otK`6FRT17ne>3rJZ/AoHLH:IjM6br03uo\qnAUNMhUP3\)q$O%(W;!;n3d#L)TXu?U!d[YuJq(2cphklh3,e^2V;H6#W57j@G^7NE@B6Rd2QTn=9$V-nA;)FO<)/A+s=tik69?Ct+d=Gjd`G.p1AO+AtX':W@)WH8[Uu0r6S/HEHSiEG^325f"+%Ai%&=WI4CbnK9bRR"F)cm'36uRRcSTUJO@YF)d..fsQ-ph*"kUa@BMdV[D&#Uq`R@Es?LsD-[DPn:0-.%C8,_^Er,@7^ul%kOKa6#!R/N"EV>2Or]IpTimqE-]'b,jVAVK=U5K0WB!^FfD<0P0RFeH.pOm$CT$pX1M=@>I;b$\*:Fn#K`CB$:('V&I[3LQ!/8"HK\ee*3/ILKK"li)XE2CM'(*Y;majOJq(%KmesGJ9Wf&_PVhJo!FD$;TUc>s/:f.M_Whan0Nb,*-.^I*!'!]ke>=NCY5;'tP$MX:n_B1G@Uhdr6b<*&J=BA8_JNqW1U*Fi-8Zk,M./`b6`H\\]/btN"DhHT,???LI,DfSuZ5aAe/uHJokjm'C%W:H![df[F#^Xgr!1nS#`i1u;(g^928?rOfcf:>#&AFbZKmhOPS1c+5DOr;#.#?X>^2F4,6##cGGZ3'Ac@d8PaaNcBcC=J0W2ne;BqliBN2DX9#/*9^0G^%J2),J*`_T"XmpC3+C/0fE3P2RClH&ok89FO`M,ZC0,`cDFr.>rbC^#P0<9eh*'0r'jB.kBnX`(Fkmn./)4g?S@r>[2=cQT.QW3H$@Dol-d^P;b*="o5Zj);/j!%8ku)Llq(Mf-d#'/)t^4YZ.8GWZbCQ-AgVjWY\BM\IIB9mPJKT3U!F[Eb!RM5]FB`[1\2rOf.QE\RD+]AC.Q!]kTT\"ctY![1;O!M<2Hgi:XmjpeC-I\`YS3c'kWTWLlG"dKjrO2.iRKG\QU()>;/K$AXj;q.I.fEG%5u_"A[d^XM`l.G*1etpT!"%JWeBD]IX/q#IkinDj:`kd!J9V*"!a&Q&3W_d[Jp[\F4q]D4]'%AQH@[gt$/fBp>N)8@l^$?l8ZGHcS'g1tu/6S"1sg%;.LiF*j\,A2)T#EIV@k74s8n8S>C[F([!CCU94\F07WJ^oEK8$aXFYPj_Ol4S=&c3oq2o[91#o)3p^h/*K_j;NE^pKi':l#q2R^Qq"B[pYJ+*1Rh7fNS,hL5ETNYZ@gndISE\nOp$9:UT"0oig](8qH;n(4fu?^e9W)$WW\QD39=[MmVNJ8)1iH\]7FG\Wl6*?2,H]J<)tYVDN>Yfh)D7uT0^:9i,o5&Ig0!:kh;pF5ncK1ZY+"6FGI]=:]Q);h((PSG?r/!Y"I_*6\)YU/R0Ee:e`Kb\h3sJ3#3fnh-+IqY!>'[W\fC,_jDm`n_ZchBmmif[E]=L!K(9H1/MoM\d5Y>r#6Nd`ALOZ--k*XAMt*E.h.uaic='U+7k'+5Qu27BD/LqXjb)Y1RJ!dd3lV6ogmJeXZC6D\Z=pKJds&X1!__+::3u4t?Uo52FkqB4Mh36+CYu[/1%SU(@qFnB@8Q;3[E6L5[TbiIX`>ksIBA*s(ZlPSM/ChH%]`"9=KUrhE)h(m?E%>dRk5%YpU3fJrsP``(M0H,Tg4s[W`IiH4P>:5m!qR-Z5N:N6]DsOH4-""e$`kH`QVZ"BVa$c>Vu7tTjDNHR-Aa?5:M\\jmW1uSu,r#0[f(fMaYWO!LRM1:G(J^724h5p?P3,5ME-tiUb`H.6(-0XS@)t@s@AO1%Bs-C^XXH*D#=QpR.'lBK,0WU`jq7Uu:S)^L*?&i"EZ#$o,*^!JmPAJ_6"S4#7[[;?K/`]-5c6)(.8ihG6^l:@LaZO&FFjLJ(#Z*ncN),4V9i7hi'mf>Ii?7dL;(0r%VX)i\?eea+2&h&'gt$pZgdEBfhk%.&b1]$4:EcVHTATT==`QcgKaphi?ZMI&*pTb\djRN4aJ"ai5L2;g`3GEi1Y^pD+p#u37d"c>Cfehfg4^7>?O.>+p?D)3T0^g#/!@F3ShjV4+WN>5ZBs-4cTou1FVF5,;3JE0nYVn7fE'M:!)PIcVF(S?dBsg]%08-0!=A63uChpek:@e&"%TB[7Sa8mkOoH5pT@6pom"QgHXl_q0KZ3c,`h&4\a..^09#]#2=H1AVH'?4oij"-L\TCn5BPsKq]n$-'BpoHRIsCFg%%]bI_Rk,gVEcFC\)/>'*$&*Jm_'^$;UMo/\3phIg`I$->9nic/M#m`Q:3,sYI3c]Goef09tNrq?qa%5`LLgMIe)[=p1B5]dlMuaj%c1/8M';8-71\n.W&H?\(U+i>Pm[h1=?9K`^KG1G)o"jB+*cU>mIZ%k[%W']qn2&tZi+pN`fTnZh(WV8S#0s&ouTj*H400*h:fg^El9":.oI95eZgilFn?&;$C:Hs%aV*F>RNIH(d\D=]XhWKU>&a[CW:[?YIlO!'$aE)th>@lW]Qs(`;S)[PD%^cSP;]jY(QsQ>k:THTY`bJ$Sqid_DeUG;%<%%@Hm=;(4QQA+&6gMFh>9kFtoZ8P()hu7ia0L#B_ogiE>&e+VJPHU,A7XMG!\amS]1Ao/Emf<$FlQB?[IaJ5-mhi'1pF3?E4O5*?TH/Lo/t>FJSs>V[n6j-ke3`fJluHbAs9A?K3HadNYYPd*Q]%5S8/^\g@SQ9H%Fu-DX'[&lin0JRfFNJn]p5Q`N`i8-eZ0no'/9AR@Hfj/san`g3go1nZOsVonWI#`eL==4#Ej142GcrRcj+n*N`5%lKmIf[s+qmCJ4=H\SrYt?NEmmKX!t>DA])AN^BF9.+I2@3q_?$'URaH$Y7l`h[<5ID9Rm79-j84b&k25fPFASGLh.HQ:+*Sa)okZ/]s^s9$T^K\+PE1JRWTp;-B'/F"S7mQ4XQP?d!Y0[/N]a!]2/[4(=7]a?/.8RL60e']XN.5KVPn@p*:-#M!@!X;2G(r5gLFNPDQoOR?K]=]cX!X&!k>8iY>)['@t(rIOSh]@2-$-E"ucX4f4pJM4kAlA^K#B5m3_W1(rf?8h=P?NsJXkA^4))WRm\\Jj)/aX6HN^X-M(ee=DMpS:6YQE\^';&o#!O3SP^m?o-Uj;dsJRYBhTJ-3rPjClj2@?4;hX/8:(^LO(B3pQ$Db(l?AT*Zdkn92P!<[0$_/L2XfM7,\f3[0HCP81/qR8es-dAJtc(o+S=Mf-km#B)LPhghYVl,3g!Q@!c&HLlP(@/*JkgNi-^sWD_K,TW68m6C?\4[JahNM-N1s8d[PR:h:>V(l,e8WV9%AOMjrXt6mI]XEF43[Ym79Ye&]%/!WBXkS9m1%<8q/Zcm=g#mr4f#''6)\mMG`mMU-j$f4ohW$i7faFQe4@8ajp'DU>HXn,g%QQGN;@!lD*L_OI7hqN.MMHhP<;"mdtk0@Y#"N"0ZU+hfr.1G&p@HD$AQ8n&erLAn^\hkp+hpp]9SSi;M1cJNA&ukWn.*uXABlkpZsMl9"0T+8oIR&s14%@/X%3#>1nRJ6-SIWoM4PH5*?NMn)U4Pr07V=#qDH2$/9TkMMIP8cOCe$`bH+3PWFa]_fC2_u+a(::8jSu`3&h\Ge0:o%.H'``f_@UVTjHdRH$m+iB-(aG9PN_"uou+Eh)O%RY>t^#mkB=YRG??ME9V+->^$nET:S]-$8Aj0(cc\C>E3=oTH^pE=W5KW8#5^]!XFB/RmqAo'djaPAO0MG9S9jXchI=ib$S$!Elg]g$?TZBYPY;Ta-f"+ZqA%aE7rh).9/f3u)hIOYgM`3<(Cca\*f'%U_Em>WFS]l-]W2&0@Iu;*AaWLu)GLS3oGc8'-'>KD:F?#?&%Vke[j9-RI%96(o0nga!QB3G#%HH!-PP$Mi3'nnQ@Jc*j%@/`Q`6)QBZP=2L:a+deE>u:+7@a95"hd%61^1+H!@pQWecT6@<:)G"9Vu?8>HZqm$EW#9XF2hGej.fF0UsOHYU&5^QmoLjVTA@GqCLebhW,"fQU\Fa^eTi+W5&u+]97"-<(+3pCl9\18:-#6Oi]i>rrMMKO==m)caF3M[MU"hrr56t$Z)*9n'O:p_lHO[2L(kDe`,+AGr=eg=dkW+UrrtQM$_=Ja>O+PJ6/SY0Z//^Jj<0MGr/Ko[kQ8BAWXCbR\3/,br4PP3&miQ--JI."1hCCcO\N3AoejHjpHO%fqbD!f=4n87Cfh%d,oP$]p?e;"GIV?3#/+;7Yf<)]VmFL9Ej-&Y)Z-[ePh%?<4]U6+3f%eeah6f\^H`OHWc>55Ar9j4IK,TKLk@GO(I+W0;<*3.8ZIsO+DC6EE'Y'N=Lt\rc^/gA`TJ[Y?XAll[M>&Xf[-G'-LlK*Q;cYR8%aqY'Y1.8sZd\U%f-iCQ*$J83oHPmJ['$^AGIjZ",oX.fh)K1smi'rD8LNFB_b\tE^PmjP:HUeNda^V[slRU\%IcceGgb?du==%3.]m\JpnGhGCdYij;6?UGUNmM]9!LGal$"f6>Pi"0MVJ*9\.2)?c[n&.<=ud<)(i)aN(K7l\D'3,RRqelSemtB:>TO"OTRn8%g=:aI/#nc_IU#"RmjUP>[7>8MH6pb+da^PS[Zo=D7dc0JUs$2ucs+"uU,)=>m;TuFS`j,f>5<_O+.TC)XSEqh^Bg,u!3o+ear:rl/Dos6oFmd?f2lIe;7F0XIEC#5o'PpEbWHNg0s0%!(JUN:U*B(&:"/Eg8#mBV;hrsJbD1F`QV)3&%lGg9!/))qs\%!4XYn*=1MG.(J`Vghut5#L$W9Ce+8AF*UYFQp0.2,;dXV<.i9X:C\#T=:].R$Rbn_6FDo-f(U]12.\trhUaR]k3T=+&(Pq-%DJ,#`_EO7BLAY3[\c+->NC[3oc^0o6WN58?n91D#-%lU=j\"E$9MM.T\j[LgJY3GXg*gPq6[kJ(X.n!`r0'LfrG6GXC0oKAG'T4f^40Z&E@6JR;_C!*qW3Bn7/SdT/j2Du8+9H1,sRKMS_\E(&1]I>2n?0rMML(8!T1,d#!@n$ED3/.V_!pD;EiJqHV,H=BmVCCOo$`6IX:?X0#9Z?hIq#0K>M;9NSW?^-He%H]?2_C4Pe3sm-:"^h&IC8l9UgnWFb\tJB-ZrF#NfpZpl9i26H!(@NYqMLtL!%Ss9JFnQ)28f[2=lGGg]GZ28tjOf@M9/7,=s!>kp;hs9tLh"Io%bOB29/X<31&Q:\+o_(H=h>]6i%lCsG[E@7oL-X!p!hV!D)eri4>ZAk@Xaq2k`LeNn!)>p];9Q_.-*eh3+sV)kb2bV?o5d0EA26=lQ6HR,+63GmP*8SZRiO"UDp;h-"$aJh9b\cj394R>Ta"6T]q^=[q#,0$:=HU[MW6PS5DJH4;c>Qu@Mso:"`L%,OhNZu.d:ul-k#j3V6e]S=&+3mf!R![VUqf2O'[*9N_"0WL@PE:)_TOX\L_7Xp;Va*RbO;_if9$fhm>Cr]NN1DWhak]=1JT/ME@L2AF$sK_eeN^f6_.)`nha&hFC)qh%;_SG&TOm$1e7K:YQktr,/!)9l,*90k\-n1(#m4K\eej>;r;N4sk(F42ki9%%=EDIt2KJ$GCZ5[A4boHUh?L6LPqK]#!GK.qV&C34d:8=0>:_M8+F.%4e.HNZ+MKpVSj+VeMGZ2V_n$cn'T:0$WZd*X)Ma'Q7>&g9SN^Yb6>eDQD5!*#lbuZn9[kKhu40WaM9l/'K3o36@?OmX67gr6TW-eqVl-bZ(!$]8Jq%WX?b%@B&-aS8g#K6:/OtLGbC(Cfo(56-NQYgU6I!qAlUgknOShW`Ui\0aRcc.:nX"@ilL_p9$@3/L7$8kM1hE.`A2kp%1]S,-'l<4gHn#-7%HLE6r$ACh>+cRZdbr\`#G'1hZ?rX`bH,MSZ6a6+O=%?P3uN>kK26tNuke3`fmR$@_eLgFMYBQ]7Nk1O0hE,I;L#+luKgMJ0I2.(sW8T2+9[k(-h'li.M4`Y:,J^oIL3]9;G)!*DV1BY\hm/2@*Z*4.@9pFC\b:p8E`U8sBm3VI=GsDSGiKg&^4s)7@A2K8O=fZY=1P8NnKb`+Jc>D0ltl@W^%7:[0RogfAKf#p;sHm[q2`dn1Y.jP-EB_1I2'R%,2).BY5aA,=N^BF9-raQ-hE,Is8tC@ZB$eY0_^1GGFSY1&aloYscC.I^b"In'CD=g4gPgGQele048j!/Xb*+QCW7AJ2%*)E!GQ9+Ddc"KongB2:1.LMkilA[id/(`bFY%iok8Oe/EaLT!P6@A$>Yt#;UK[_`tRE$%'dn^-!K4[Fr5H/r*(N_KP.F3%S#_Go?7HF(OGt2#LrI^8SE-tm\Nbi9.VP4`aDbf#hYaF8s3X*QdJuXH/oq_La(LeY%_kZDhn2(_'W613GE`6j0n(iDBIL3]3e?u)&oA1!GWhQpMVi2EpXXr(N?bJ^:2R.>;'18(i_g5ut\(SJ[>h.P=RJ]'PSPh3&@cQ?RhRiXbY7]l/)dkr:W,hOe;(*+cL$G_cHUeNDL&=G\FLRs<5[U$5Nt%HDgS?L98@%/=[VmrR.Gh>Z=C9IF'sg=@+/LX90iSn0O$qAYn/uH;#"U](Q>(E']@K[EB3S1g'S]XRMW<+4]c.u3e9adp2pBZ]-Q-\mFdKD,)ng.rkIp.96-1@6[%o0#hC97cm$3XZ3M$E@2DnO_2n)+F3#-@=644(]:K46a1fP8Y\o@U!*s5$,L54-&7s4._`LI76c"?A:4&U7=n\MC);N6oQ]iB.]_]S")hjS/;/Zs4Ekki?\@l)1-h)(XLoU%t]tZ\8ZtihOPPp:#,.V#SH.3RMS1s*.GC4spA4:]^kU%aSYQIO6J1G7O29SBFBd6`l";Y6A+H8q;fX]V^2XdUWtWFtTBR7^o2b;*m?/dKZ!7NC(@IKt9E>Wc9nQNr#n]8M,dW,09aacpd3870-A\)sMCV/SKiHSN##:!;VQ'Y"],Vl)i@*01Ln;oagY#>&TG5$NdMQctPo=Wi?7ph\.6!4d\.QHt_7;eCG.L6Aq"3T#[e&u^n))S8)nWR#NURU/!U)DY1.]aCcF'J/dP%j3Vrrbp^bmi@*KThq]%$GCWtC3YX5mSo:IWCC6X464(ATn\WTHUi5El?Vja>>!rlis=gfX$O)*]n0kPRi2=.r(Y`;;/)'BF-HATE13O9"urC)'WT,2-#M\A4JXl>B[Wr_AeO3;@V'k9e,:oL82D!O[5qm07V8q\?THSL&Y?+'da#!JGP8\F-gha>P7;<.Y"954sG+u>q]!I."ohoZIFE1(+IQ/C>(6u#gdP2Lc0=)L>G>ppF1!fZ"0@S#5<2'T1$9FhmXC##(n[IV"J:7ghf]VS'tq&Mer=MaGF^Q+"(.H]@QQ@M=u]/1:TLb@X>"*EKl)"t@p"9=`(##pS*FrSbHe\rRr_^uaX%blX;2c=k_9N]&C-PSKTC.N<5V^NE*6BXbjdE8d5h1B+^E%Zma0"Kb:)$i6SV-2"VTC7b@6&-R&f2RBNF(9*[8Bs]F_k1TUnl1=^=4__K#@"kTn%eX`(V_Mh/q>eS--B%2ibSE"hhI82Wg![ao)os9Fd=")Sf&UNoEDY;b2s&8p%^DEK/hiOb?Qq3;VOHm4*CrkcT1YS3BNJ2>5.MKaY)W*&/gSe0WeRXY3Ms<(^?c\5?.;@Q:A09mcn*Mjl%,"/0J:G\tJ72=ZkPfUnF_oYC--CDE*(nI92D'@HVn(r2n;Db9:"3[Fl>H7OmJ5$Y.JTD?*sJmsW4-,/)QNk,:0b;IqbmX6.M^/sRqtbd=QA_-`(#c^2nJjLX6TaXP6]m$(!)9,EpaMYD^K32dr)TUHq`rU2q)BrTmqi8&k3[1u3HO*hWb&'$uh.jZMJS`dj\]7C'^GFgulr`n+4Ck:i>5M=En=@YTN`2!'e6D74(<*t@93smi='g,M4ZUK'eb>sVmn\ieiD;ecA07W3ag1Vu8s-u"JqIDjdmk[<_4&ZO^W=)nb?.e'(W!qd[&?^$V'dQ@J^p/5S;-XTf$[cdG@\cVRga&:fau_8m]cj8^%W.7A=KJL`'Cr\kJi[dHG,JRND/&0J-N2#WSbtDmDM1dC30*S2q#4(uSQBn!La,i?+K[:79\qKD_2sArYm7NGAGkBk')s.[u;B$&rc,rW0e#\O%jDZoYiG9i:3N^bFCp]BIrU)n,:NFUkc3/Cm"bAbD+L;_WTnCWY[<1e!b_jH$E;T]gioFm4GAA37)f@]/@H-+`B%aakebDN$`o/QTCqbQ&*&\9M!H]ZZj)1%uo)"'niP8\!Ig(U[mJ6PBFgUr6HNm4QTnMH]j/shGLC(pY^;FhNT2Z0X&uk5fqg?5P*0i4j1_*iH!B0)qC9WOZrHkH\Bf>;b^BDmIcDZfPQX&J$G?74DVGqmucd\,\u%EobY=+BQM;mBXdepo)o$*ctDh+k-.(p/C.8OII4d'3>qfPlOq'`O[2S4NeiK.X(:[TLkmi?ffKCcFS4L?=EZsdb*Qj=a`6E=cdA>-X\#W$=$a=XPBkn%7g<;!4#:fV+H3ba?*;`0MU@A?He13UK(H1sk@nSCIqcZfq:Xl)EdXbQet0M*[3cWmJ#?iGdfl^kn2oI5IpJ7")I<&S0_ak1>&?/ENtoG@2ce!=N(UC"N$f]abo+4`Y3[/Hp8Yel]=ZiJZsU)J7m;&=GNt,EHe14Dr+&X8eSfJSE0&]4)-%ipbN[4(3M)#h*Xq,gWW2Qsorg'mYsR=*,ZcP]Z.jY]pR9\b29Ou9[L_V,AX(M)(aq@TOWeaf'8u"0D-H%.RBKu*0(4VM$$Y(@loj,Dj?S%S*KeIp6t>pXm3F@3huiQ8Ubud^3ja8s@^m=3jAX/,0=DP3a4Lam%"*S$+l5A-I#3N]'u4fWt#>$,,o/>P6SZMl"$Hh0HOE[Ub@]HXFP#fAlS(+dCRtSK4gbFkgX%S38boa_UPZQ&#D:m9Zu/1js-^O\T$>T0njr]CkD[!(8K+5Q*eUTWupW`JS(Qo*fni\2boaqKK[#qUr6U:X4a>hS[TH?%PqFn>G_L=E6W?@Nd%E7mob(n@p@KFgSr>qLgN9:dVLWQS*intgWcRi(5c`qfO9,]ER5B;3NWiu=n6\2o4:\FNJ^O/^laVn+OrlaR?DP)-"B>_U?;]FGj>X%V6k#0b%Ms:sriI>`E0;q#_9tamciNi3>F'(?o<<>006VAfk>6g)XXW]WDSKulM+sLKtP.`(a,0mi3mhkO;ZM19fPF#T+b.cJRZM.sOB>^pQ:Zu#T\WHYoHd0+8gH"),WXt0HFfgpI1`#B&r3kbKiLV!VGHZKl[um`J0B@!IkOhKgN9qDd\m?Jj<]\ph@F/?Me\\\fJ\+,pb78Df^//f'p!0uCrm#rd=r'l'dXp2:qsUp62g0"RX-/f@5Mn"a=&!^BEXR0kSOkd+IU@:g5-FL81*Vd^@X72oXfG#'hJ]UF^&ejSXPb%V9!WZ"-Qamd:JNZ>W]bC!H@52/jf`gYTk3,NBBifN"\)V[-WY0*p)R!%_M""j8jO&'Lgmf%$!`bfU4QgL/k9SPj$.3U,\G3eqr*C\Z]TOZoNfj:M18^p5.Z(/T1bg!:OYY)j/2NbUXSqT<*'7,\t;I6hD(ULaI4o+?2aJuif+_OTuoR\6_91gRV*sk3snL29F^MQg>_)&M[>.h@U>3B3qlf$qU(UPs;61P&dJj9])u5c3@:oI7ck-]U:CohD(ULbd7%s7K0%FeRc/nK;7A3A]$`YUU_jb`>]5"1thbXn'4Ek6q#9AIH/NKI7-IkS70t*hjI1!,")&fCQcBWFiiJpSp\bgGFWOqBCFsDjaR71z!/M.t16IJ'g&%jBp-.(SHcLAollE"SaOrWTz!!!-hp-*8T^!CiChD(TIHcKicll?'+z+BHS?B2,]+\LuPs`fjs%33A@W!rr<$!!!#;$JGendstream +Gb",k#C$s7fsZT]046lMitTPd:;/]-NFO>2i\0\Wj8LDL[UU6bNbrSUOQ^!BhM$WE!!/fb#UHuBlDUB4He7uJG@tRgGP=X`@E\!ET`TQ/la_DfS9*iBfbJtuloR*EJfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*RX/?5_MK!/_\o&W_G;.X3:OTH[L+kNMV/ioQkOoqskm'a^&0%25hBk@1LE'o0-)\8<"I6&(p\T=[n?2oEFPFqW\!+.^'X+EFXhr"IrRr>/Ma,M#Chn:::X4;[oiJ637*dQh/F6CirbPBoP\I[rVqqAGn\c&5d)`MZA>-1RbrUfKdhqll4FHs1h+:*QA#_F0)Jfk>N>V4I(H2-?RJ*MQ"BWk[OEe*giSNf>^lr_](B:jVGZ,[o\rAf#c'GO28:8XU4o_.C5?\\F!l1<4c:UcD]=DT\D[r3@&kXRl6dC\k]HiO'=_stu1hcs,["M*d]l(hgM5Q:F^DnU;VSThs@P>=A62U)^WGCU+WT+;57+U]Y3$>kFRcTB\'c_X:$aL/X'm;cE=n1n?Vg^rE:`iH2B]]GG`i-U*(;)n5UYLg\W6\1k98UPougY15\>=Y.Z_%2"ap=jNCGMdgfI+rMI^Ko>r]Ric9#ae)i[j>27MFg/#5k-1^Qq7HL!.I`thg76is9a:7WS7g:_k-!-8Cd_#8O+Y.6dS0>./QK==O10,rDr&[1$fpu@DY(N)IH\YZ.!OSe=DYPQo,9/!s]jo=qEs,^0M:.Mb2Y?8%2:*4fG+ZOrNrV&l9HkhjZ`PofAD2\EXo[09iR7sCe,paj$NX.o^"@3S%5nF/b&-TNjGVX5oTlfnN2k/'(P1%q4()%@f@Ddi0\2_0.mo3(X:/6%Y3)jqV^k(Y1At&-uq(`AbIf4R*jP4E*3`Y1]Tc9Z,W-qWs6fO/[e^%XkB5s[dnji&$CKToPEH,XO+P!,sTIJ"?"*B.jUUjVaT-NhI2Gdk5AQ(O\`IJ`_:VbV46A]Mg1_V0!J(&H&Q'%l(j9Xe5M]q_?4s8Ms/&J5H]%K5t_h1dZ!FQjFf#58kfbh_+2,S\0-!D)OdnFQ#.f-Mi5*FQ7]0Ke?T@5oSKeT[N+:*#4nRUPhU[kS"mUB>MC:,[$^76-)q4WQb3d^QO.B-,l?@2&s57TX.FOTU0ZUq<`5QC,[hi\&GZ*CI&n`8"D-74mtkQ[RVl;t_EQ)n3!c;SCrhhtc]//HD[#;@-dpkrMW!]gDse^;c1`^7,Z&mfhA"\AI^YCA]sgk#3i/CrX$h[Q-SX#Y(Q\ErQu;W+2Ir26/3ncld\/f=tmm58-r6pq12UCP)U_M&Bpjj-#ZlLk"gs8DEAHgg[_D^R.c/P-dDI_8V(K==N:1V@Y`^*fLs!rC-U&3T"DAJIE-oM[``j,Q4XHga+$_c'>o"mbsMZd7'aQX>3pCQp1g4)FMsZG%t3+Y"t!"G%`3QOeM'_Z,>Mn*a$b91hfI<;*o73j7@\@dDUIO9Ju61rZHojDqQhS,dCp7n7opS.d8F5bn)1Hgfb#Et9?V9GRmdGO+NI>-s):+,Qi3e!AV_d!'t'.kAfhnV'a\a6?6123l+h+e-eF6:+52='pA50JN!qVk/M#>Ah!JXK2hN-Vg1&ErYd05Q0Uas*4J3a2r%EI_P2AJ"F/VIXSD)FG8G-DnPTEfr_i-l-c5t+;0;*LHk\[$-5fXL(g4Es8(?^eurFVJiQbW/2dW9\o`eIPb'aJ9!;_!dT':HhQgre5%"\a3P@Okk3P7-b$o4GMGKC_u]`+Bk_;B'^g`8hgCW'3F87@:S/lI]a+;jq!mCdBgP,f$p6X7S=IGJ<)?E,]0phFeM?YO5s@oE]^cDZ:O'ljo@]``5_$l$":05.GpftJgMOE^;bs%(rcZr[b5/hk[Q^nIcgf_F%mKdHM'nl;VdX"B2K)q^e=Zd*:ObtHlK[[2HfL78=OX0DV^YC>s*t(;s,kdfr8opO-;:r8Y.OTO[XUY3K;U/e2fG90#P_gqYFNaOgpds1@nAm<>e!$3H.qh8+8YEOlh,T!8r",W0FgA["@3S%5nF/b&-NjPW)<0"msU6"IegejIR$W'rVQ?_;&!m"2frq,I(`9^d8A;R50:n,jt(LD?;)Zf!OZ")*Es1E-P^\m1Hg_Wf`=DUg5XfWnq(ES)(EIgAO=BJ,j^pQY*5CSUt&-L$sD-AES55F9'IXOt$?=)L%pYIuDba9VFNk"I+p#d\uT$4JkUr:6kOVAH(It7Orl`\&5a7nJ@57(C8PKBb[)A3Ya/M^De[6bKkreW"o+T&qh$H;I_pH,l.M2\eo%focL:1>>-`/MXPEWnTRBOC)R_L46G*mbjD>d^!i\6E64-og2`F?*6:GI^BcMrScrHTfWOce&Hg^N(J?G#A'/0\Un6q#B9VuBJ_3q[E@qqKo:F%L7qH900%FLS_6%4V>?5Q<_t0T\DX\GP^+@3N/J^@TW3UtEpNh`QDfI$2S"QIl#\GCLZYk*]jE9aH=n#_F0)Jfk>N+:'_n:nu#FIt)s6AZMl4als$PHk>'IW>_/DjZL\`KE0mX^#fm^nOmMpj9-AqZV&lJS(CSfnpHot@bsMa/D@O,mYRABCJDr+?q\ih-8KkLC<*N/ZQGIs122_)&b2#mp@`Im5dafOKu-QBp5a0;dO3BbN)l]ANS4c`uSS+LuAO5f-.j3Ct/q8RoqVd2OP#JlohLGS(mG#+fm7Jo'h4MHjbN)iVBP8gii/jTaO$EV'r@%@2oXL4M+.&&f4No^3:BXfgm^!#dLs>TKFVPqj]!AdD/0''#OJ`ClI.7BBXf89K,9qhYmH45]U&I0Vd$O/\6%ZZi5CT-"G^W@B0t2Z4qqo$B`aZ3?r*TOh?_jnuV0_d]7nIuD,quh(q>%s:p[e=K#25BpqljH,4Gau`FQl]4N?SX[+:*QA#_F0)Jfo[H2/<-gk.9T0oLmXl$6Qp#dSf.Q*<9Hbrl\Bn/egr>us0XiO0o.I.?48,[SVd0>5l_d6Z48g=jW%bEa`TKh8ZO?iB7k"3L3mjQY-ke)'Y_o/=n3'Q,*$YArHJpXoc5cW=+HOlJ#t[a<3=EcO_1ebSej(?dR1*)?;)c[S\60DXVR&&pB8[dr3pc[!*OS9@^BprDKk5L3V*im3f;-1Lg'rT^W=Q*p9tiC"k%3F0"*Ok[V?J)O4RSqbhjV0bt!aapWZRc;ki-guD9c^3s7I/a%hEZ>l38'?D]q<*3e0K$"?<[O#e`86"Bp"0#onp2Ct`5I`=X&lLeeo:ER@?U%nm*gsj#_F0)Jfk>N+:*QAa:R9DK-d@eTR[_Y\T289$VI7Y=@jT^n,Y8^8kVgfFrBu9-V^$tU.j?kqs@*P9lA_VoR>F11M0I%:nuEs*BWtG#9NZdJ,\JM3SBXD`uTA+//B=cERQjbhAk=#\C'-CI.l6+UsGZ^qC2.jS.*HkpK5rTS_akaP7g/#_F0)Jfk>N+:*QAaC+&YT3&)D`%IN>F!aJ`==f@H0D>/7hlpNV8P'6!S46.p]79h*47?\s-9!lMAA.T[4)WgDjNfJ]Y^iN^A7X?h2Mg49l`JqB'[W$K++2G]&U0\>pfM>dfX5K2l*+q;*F%EkN#O^9m+.2SMB[aun(p4C>Z\5;ZY@'Ta=WUP>=AVj7r6#[VZuCAb(L-iS;,,bNgVdgn4%:LOE=YIOuOZVoOf<93r5sj3Rbf2o"nZL#_IE?cA$!lX0Z1Z<"&/5uY;lf4Zud@*Y6[^.DKgE8U`(GBJ(SWL%M:AW/*jn))Gk5I8gQ[oY:P>pg(GP+$gG@5nF/b&-P91";u$gqX_M^`J[7\A3PFmqqu6/Q^Q9iiKWFV*i=qU.cggW4HN*<@hu;k9Ij4jem^qp1\%]SJ'S`$"CXE[L13paWf<+V)bNgVdYs30u@:f>DE:CsqKtmAqn,;jMs!3P-71Jq]P)>j:ZMTL7+BpkHunFpYhuDS*48K]'D!>&dgs5?m+iFD/HDI_m,P!,lDG;+:*QA#_F0)Jfk>N>XNo/kD_skGMdg=4[;6P:/i-k@J/p92#X"mmb,0o.li(Sjd3)MX-5bT?XHUaUo0f1MJJjs4SeTU::`S'])C]R:\nA=:O_jJi_OSbk=`'qMc;2!o)LX='+tr!^/i+sIeGR8bb'II3Y_huAgEapc1LIFiq.-PSq\9Q'CJmcGUXf2WZ6J)9M6p1rW'NYg3.*TdL7-^QJn:9sZ0E8:<]rOq_lFS^@Q]pJH5WW*L6"/3p"nl)G]_7W).\<5)BT'HO2Kl]E=65L"F/ibp0B)BN''@7N(N7DZ+F6:]dN>nRq6mADgQ@V\:2_e>)g1W+^$F7O4*gCm;p@\69Wl/bK,sDfp0*W/>l:W&Ws6Vod'bqYq)F?AEZl_P+lQUIfZ(P/rEVA_C4K<:0-'c@BkqMEB(:9-S3(qT*rFeW=%IEaBUYI&]p&'Zo3k8#Dr2&84o1k$OcnQ6,:]Vo5OF-5nF/b&-P91"@3S%5nF/:e^.CKAnGWbG@(QFpYUHB7`p.?2M*%WJfk>N+:*QA#_F0)Jd`I7`PplXO8nLGYD0Y6K1fEQgXAq_4^l3\iU-u'+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F0)Jfk>N+:*QA#_F2:6VL14++bV:bA_r_08#m."@7b_p`^XEmm7.C&-P91"@3S%\Xr$XoG1+i%CL]ss*+7MJ\#U4nr5b]rboOZ7u^8,qTqm.@IFD81^j8-"@3S%5nF/b&-V5N^&ECg#\p;,*fCGR2c*SX"d;HL5O\WO!&ZepreKrmL:nP)d4FqQ&HkB2"@3S%5nKj,TKbYW6@\u\(]*a%OX0S^;8Y$Yk7Ih_&-P91"@3Tp^S!eUCdNXNH5HGLW0&@tk>B,LIXaO70CPM=Jfk>N+:*QA#Vn.P9%T(Fo]M!(kg*W)6@U%6P(`fsC=pMoc]dgr^H_Z"$ACg?:ai=[*ufub+&OF#$ABC-Oh\Xul.YZ[rqs!73;iTm0'rOb_$R[Z8uJgE4k)ja/5pksOGnuB7XLpjIN_<(U6!^7F%Qm5`i?P51uk]IS7j+Zne'9GET/"tF"6#.6,Aq%j'k>9;;J%g?N^JH%7_qe82lMAQO+hQ,1UBBk1%0AiB#DXF;FC%t>A0DGLaHfT>!h;bB^fB_n0^,bk?Gb)>5UB?PWE0icrl3nQQK5\VqfWC5dQ%XOaCo]K'r8N3Y6YE1OfA(4hC[5OFq)J`ibWN"aM]e/%fKaCLaTU[(r>4=BX3umY&SYZ0;o*OK25_,pI]t-6mjac=:9""alUd98qZE*G]3H1VRG2b\=:(ke,$USr32)77/3ik>c5K:<4il.VG4%:aj\Du]WMa^LA`dp@-@i&k0?H71psN'TX\#330t=1oHC-*ppZ0YQ<]1b^XNVNbI6`9'23Kd_r-8p8-=EQUq/"1L`R=!'EFosiLc6oL3X(1>]22+p[0047,$Kng5JM6AAEujUC\SeqbBhKX"ah_k1N:!P\UFMRN\t_@CS!'gF:u/!n@=l/oDA-cr[Zd6<6@r"CbqCo)r29a;&!@ooQ46q%]W&,b_F6\Sj'$VH1pF!:D0t7%E]+VlD$S)6D74(<.BW$4:6d/Thn*0o]K)bo"gsuZ7=\S>5*0iMG3k%8"?!oN_8RUIoDo3YS^U;l<:;pC,W_1I%$kGOF&fOed]c%#U$fO-).P%f:RQb_Ht=+P';t0#qtaX=l5Y^.Q6O$"c_Sb9hVb5b!8r;VFL5\Ng+AmSUOJpg2'FP1Zj;I8tE@hk/fTZ'**bT*`ia-hTiA=D[[E35o4'Klu"'\f:#j_r=IN_QYU:&Vu^mNc-,AM+Me=St2brfQ"fVPl*Sd>\;DXA6sO`8dG=WsGpbm.0KBq*okni-57b[#Cbq9>KAfFiJPF=`2UDC#iospn4h=]Pm&Q3H4:6d/Tht\&qXZ*L$ACeU^!NBAou]4C*nD`Ge9m`qHi.[Ta%TOro845AI]qf`ABh4!+XI5*Z]l5hX4)NEEnGA?F/#J$<_3/aTB@232lI8[eDK]^'s>K\rjqsCRt^D$Q^ia>BGpEB(QX^64&^=iBWoc:AeHL=UqPccfn[4PJ^S)";l__LLO@AFH0@Lq7qJ3p#uZ4RDutdo5\btQ5>ML\f:nH:)tNZ\jhFg[hYVj&4DH-UjS8W^tWL8PF)5CN!N3ZWL>8p"dC/T81TgcY@S@ldh?hpU[glR9LWTgK)F>XH=MbTRr=Q"U:F-D7-IOboYTpBX#,=L\Ib2Y'?P>"(B?l>#QR4)dWF>l-CH3[)\ntf]kZ=4n7\O:(pd4[T2qc%i=N3:!'<@)hX^[GqrLKT'_E$7WWd/Kt]]n(kqrO$ACg?;#M.*o-b:[KgH6^d%i[>e$hopcc$C+?Z]U"E>hth_qHEm')7A.?=pjpk8W/C*[NSq"%a#I/,=Mbn33Qb6iSA)6PV5*MG=R=h8B3E3bSDY1^6U-5JA7qY&-#L$)3E8dc(@&[Qkn`)F;?Q)UmFB![?]lEE7eamjRki8;4:EA9h![G%Y(NSG!74BZ"P]0F&MW>,2Pl(Z!m!TMGC5u!%forN?,F>:tmIg+cqcdVX+G-mWZ=t=^123cJ7$iP>b$ACg?qCD4$;(*+cKc5925EG)pDuRD7AT(>t8Q1p3(6Hlnh+$cLE>s`j:K48,mI%'1XRBfgb>egiN29K*acq"9X6mpP360Tr;PD4T*:0igC"FfpbDN/@UQp+bo9b'/]2Eg[lIFR.2dtlpZ92hTr-:9)f.$i;Z]u:>M#tU/he#PkaRZ2PK9^^;o73/kTKeJU8K'Vg4P-[+p6i_=fL)h^hI@'U'=hC7G(#!PU?j<:VqGF1H9>B5fLmfChBu5$#:(1!/HFGO!NCgSo]HS;G_%\(Cf=\GGgPpbn$3`%%T@-VZPdX,m6B$ACg?;#M.*o-i*gW,'LV_Au:^(@,5pKd\468?d)/kJG>Yb09gsBDjAXa/i'acgiQ!%N9KE)SLpdK`4*6=$H)F^Fs^g:"dls;QH)#6).3.DGZNVo2I6/MBM5`THR)S\1;,,\`@+/M,;;]l+R)/dE6i7Snt\f!OZ(%g3'^&Db1:Qcmd97"j+tfN00nGn^U>6D=6+o]K)MX,u]30%OM*>"l;=(&TT3eCe;IW]#"-Z4*KYc(elta.,p_GpuRN=jR1\X?)=f0=>TCQi("aK$"g@O'!Y/X&][(F0c"=kr#$^<;UO)%.5Q>G)CmgcUG1L?gHb4%N32F7IJujkLTE^F5P@(7&D.tMql%aU(CfgK)E:?Wm)2"2WgmIQ=?!#3qMPDOPk/I*U?D%(Pg`nZAQD@@@eO>1R57@+=_@uQ9[@ZIE]&/p]lcm12ddLd1pWN;XX"mTF\C,`CQPJ"tp]UjQ(3lt$@JT1=kdN?!FS,d>Yj0`+0NX9)hY!OkI!.H4=D[Y!A3_E-g/U'@qZ62bft8\=+;9G5U,\2/IE%VB3H8!?=,Q_rHZcCj-k]@e%DY(IinUa\ginG^^U,*UHaf+Thm.:Itdka$?[*KQTm.U1ln.6[k+ad).d8.3E;n&YXX7Q_eaAI1%So.O\ilK3W*%Xl4KCUEXgijMY*PM`rn3hSCsP"PXinJOP]GS[-poQBg138N%`ULu,9(Ot;fiKgMrk"VtSY3if(f!cr\ob_gAH5b^$\u4CmA`1G7Mbeh%Ss1en0KEUro4NUkQJLc-3MP-sj5)>Ghq_EE9p:Ar`02:8FV%HbiOi:D;b=Hni4bkMb1$5rs&bXB\MC9QVgu>>rbTEad%>N5<_`#[3Kd\^?F\R!*J&f01FW,&k,m0qbfqX^')7,`Ro&nt>qBTK`JH8MIc>aN]`mqALelgS4@ZG!L4Gh%oG-mX3,EuUUjJS&QTNCg:VJ2Y/GdGE^PE$X@2N3tQ6$O7-XW+=="AWAZbtnAD@6ja-A9D4=gqMu[SEticP=e'@>X"cnY-%_1jt%c1AH-A3/mLlA`E]I;r?X2sl/0BU4iHh_F:m.+Z)[hl0d,o,2'SF;jGeaK_GQ_UqcL[_k41+Q8?WY&-2@X+)bS3!TeH_cQR_bP1kTfTkW[=uE=?R3.PZAR[3Lb>;F*ae&g;P)lr.Kfe$;e.!l!k>Aq`c(?puR@e%4g`;5+O7lTJaBF(Rlc;FFEoLWu$i5--p0nEtbHNV5HpI8NhPS9Rmo)LtcABN@UKVI[IC4(?DS!!ZdKJfC)si<#gqd=+\[9-`("sW'-K&r2qKXZgbk]7=cj`sDHqMRV+^=B.-iT,r!6:kbKfT"pEarF1Id[aMm1iFJJM:YFXXVUa7%1?>Ei3#&AOX;`qWVK.HG"L6fJT[)::g=)nM#j,a5)EkJbaktD5a9hl=DJ7Z!tXa7*<-8pdnXBN#VpDT2IfJ'orl:XbjUc[S=pg:2.c_'Z0r*RN#2V3%'pqj"9-hFlYk!rI38lqHO:0":`/7X723YtJ1\r\9IA@#H>(JaK2frKTTN`^)c>@/@p+1$?u^N]&1B3B@\ETB0DBTWX51#`'0]I#k6;(IG#SjB%S>NjD.HKDIt5Q"eU\J=u4W0*md0b^phm55^,*uu$Ze`@4Q'fn'f\N9`?ub7RkQ#BR$9$6!X`O2ce61s;UOe)G;.h9MXIeB.$Y3qLPT>\?+0m9o]P%0odEZ=/QuM8tPKD.7ja6r$@u"r;Eg(WWq=\O[^'#dbF8dFdJ"B>r-u>a>lk.fbP/Zc+p3R!t)Jl*3O6RJVo@LV$T1=kdTg+SVG+h-]6D74(<.BW$4DH^/q"$Xa")3Xq3/7Wu0f2ju]A"qS%\-phMrb9BBhI"*Y6:?XMaE$_f!31fG23g]?50ibC=&rCO*_5R_L;6Z74P[L/9rYZM=IbC*[MHq"*9[1oSeKo]K("'FKQZYL&n3N<\)7H'W:XqDV,GSrY$\<#DH:?X6@bbS-DuRl#Dim<3.ACL^!XCGM?i>)c66k3b/&-Y;JXag=C#Z"T'$GhR9IhP*]$@kHi7F[9mQGKfm4+qkobC\sCY8RD@:fs(f2+POB-?Wk+p:]5Pu[YT:knPN>>Nl2FeMf07gJ]q$dMXQ;u[R$Sk^tW0dfYerd3rE-gA1^C)?8u.nK"FHO7*t+)[;!7!hhi>lI?@)cbE=rr:(0lL:nNn/bJ4',>%+FUP<('f6kR$2Kc6LKIi^Hc7/V=Eo_..+^^4U]QaS"WNn)g>L;p5D!n7?J+ATYM]h+c7L8O9oF)4qSoBhQ>WPX5WgekQJ\sgsNULEk\%aI`jQ*N/,b]g;YnrH[Aq`V.83Y\i$2)\d$`F^=n9GGXY(>Kh':Rt^CMmuFtm=%?8NU?C7]q/H2%"5S)(.oW?G>Z:tT-A0+4>LlbuHZBrT&D^7q"faDb6D[5rR.D#D58GSjYC+Fiq"mgQB+029#B*!ol$E'dK-gtc"r=Aq[RrIESt9"8T.O3X:ca[Vk"QR*jQOj#%(%Acl@YPp:>FWiUq\A8WVb\:/(/\4s+oT%h&r43c+k+H-dNp]f_nNWeL&O1A7F]$;>PR)j;gY9.-MA,cpR2BdGnfNJ&Gl!sd3''^L/BJ_-h`DkXOgMh=Uk5qjkiC*kJG>Q@@+^>=F+AE3./.3`*QA41PriK9T$.pFL'QTE2q#UB?_cmMa-+eE6G@Q^&#T[f61HEkDkrP1Ffr<,R9@;Qa37s\59hb%K&@Ee'W$8$b%`&K`l2^;P@e;Z%ojTWjIsdXn5EqoL^/@BbC*,7GXLB-Lk_kYFK3G]YE!4rGK[$IB>)da7mL>>UDNFC2[D1jn-UoKt?er?2O5c=/6\79Y"?<^UnC99Ms+CWls)C??$E)*1%GoXB4L4"QQfuP*DH"G/>LQ/B0%mU>Y[[["q2B105XoETV^Ji;V6^TcKCg"V'>S+*)l1du"iAn\M1")Z'((lK$l_arqq=Q9!arQlECt5l\F.Ht*P-[!_(#jhuMcf/-rQg:&(8[.H"MsVL6*\J.\"EUIE,hOs*Xg*CCh+0k^*]4j(ra>hkRA+JokR%S1&3MZ)JZ@?9jg$pDQD)3NW>]\/6,6?/PSfJ%X^&T%2;nlqEe?^4Oi:J#8o.IJf="5dKVcH&9ji*0OZR>0SYAd_(%tuCDcf\^4o<8QULX=AZ;KgGJ?e'PGk4n\=A/ju<*U5Kp>rQluD+rMdE&r7rf'g__^-`V_Ricp0YVW@.WbdC%U!m*@W?Qq@\o0i9EaM4OI=OIHEOCDTTEcB/6K[L0q:Re[RU=>WabEN+'*f-6AAs'*mj@-I`BOf*s1Hf==p6r7^M4NXtVH;g-UP#R\a]@njkIHI,E[[G\sh6/tO\e5#D-<)UQUOYXlT1SPF'-7jj4-pd9K?i=k')4R.I<-T]=$'mT_T&ALu9I4,8;[;5h;FqX^Z5TGueo?RQWR#1N82cTdhCJ@4(e/NtsK/^e0@VGsD@XJs_fC5]Vh/M1$sg[sd?/tF?Rd67/a=JhB`Bk32aV:!FZX@NfhXQhQS0<)m%ef*=CkdE(Q&?a0?GLpOD:]jttARBMB.T8-6h4PsW8C(CuoJBATQH$E0;c*T)m:RDCq!Z2"+m#-YBO]idCp/LQ.lFURUCR.o<8[CoY/V`AaNTCP>rA3#KG<(j^`@PfZ[7NRF)\HRgkoO>2bW_<>^ijp(\iMAt#nsm9:=>&@p%H=I92CmC/7^:Ip0bBc-XEX31EA&ZL9Z$Xh!=ikdjGI.;KPa.VphA<=J7k1[s[1s>,AUkF_kQi#t0(IQ&sJg(:2]4?FjgCO_UCCm5';gA%e8onRhp!5^o$&^E_ZN)?pQoD.thb"Ul)qH1j'C=r<-RH7Ua=;!)_mdVBLY)Bo*me(i*B%%7#>1W47!mbOS0\[sfT5JPBS92Sns,[+]$MPSG&;-OWMdlnNQTCg3*+,%=`F0)r#jdj67r'3%`pMKOiR4I$>Yd%f//W8EoVl%b*c37RjC%q1:mB=F%;eU,IXg4pk'608Q2S+=/DKL4#>WY,-!7sZ*31pXIak+nPeqX:^8/'C,EH,-g>EoFdU'$9CNqE-oN\`_+pfqb_sST:=>g@aM$o4&D#>4q1R/L@db0k""h]XPeJgWBq*L2=*/,q1ZOcq(LQHMkWDkekWU*1HGn^9.:*a"H_$/^Q]kRQh=H!0^*:Dbgl?XsT>P]1.EuYN.6Y#Q_>98rID"Re+i+TT\?Pk!Vd&3JE/CZW8i4E'M8IS"LB,he$Y.=cHHW08-0aRuMXcD3)HC:@e&?Vl(s:B36fXnPJ+n]6PM(e,e3!;[(p&0>/5>B2,+:%0`:M5%\>tK_L).=Ys9UIQesQC*?A3+d%1GZQ6VrpM0Y&WHk>PLgJ"(rcc,06c_PSSm#>+*m+*M@.J\\3/_03gY2Z/bEgp\Ydko%\!9M8S?ip:YeB(sMTgL4"W=):Ne0XIt]AJ[M`Tq=CggCu=Q2@@:)BZ6Z%O*e+0$47FZZk2,?R)M;>App&SoDBs>A;qJ`7Y[=BoOkh7j2XB<9b@f1k!RMf3/aJ,lSp!a,*7[cQVEN,1=r[4Tt&/ZNKp<1%dG.W+a3r.<;q)`D-UOdRdEPW2Cm3ICUa\BO_cs'Q'YGI;V5g^09K:[d.L!-T!gR@r`S+(\UnTXNd4]O9(6@U&1lC@`3CGKW41T5_=l=r2bers@tQ3Ckt[oK?R6!FI]trqpR-a6L#==HRi*1Q;9`eDBEfY&8El;0tdf`gquRV.d>J>Pn.Np>mb,3lY(_#W,M`[Mr-jl@,4/]o3VlBM;k@g^NiRYY!9'(l*JO(kfCeCSmoX)/!KTaOM2<7Y:TM:/S<(e9:;AH$ZT!7$kO!'HT^mm+j8U'5%L[=;si?%@D&0=G`nu%a^Am70DCZ[:eigQ.)9/6MdrYJ:D5i/;?$Kn\Iu$a>$#:0k5!_bcK7#>^c)HjY:e#UnR_gRGPDYBdnWf^R8^AWJ)bKmNs\Lrh+lQb-H_pcE11IoB7d3aS_7fi@ZuqMU\inn0(F/Uk<2g#lp?1CKp'F-NT_nLg=C$=9do`fGhoD%A4ON[SPdKj(J\iiTKdA$dJ,^E.&,,q,l5agHGH*ilH6n_fRL0;I=Rg:gYsD$]77[J^C#ZThm-OC?Tf2qX]Jgl@gQ*$1pqkUQp$@Zm8P/TAp*V^Ub7D]0<^ATV3=Y#K*/M(j0':b&6K[G@u86PrjI:PToLN(H')rWEKq^kKnZB@inZMY*O+K!r>FOH.QpJ.ReUiJQ!cckM`p9.Ekj#>qbj7[A8HNITShT4Faa,X7C`W1dRm5MOJ(@&O>HO2QZ00;M)>3f=tXBr42Vu-eW#J7+kgsTkZ8u2I!]g.dl[E5t0^LIAYCEcR'cB^Q\TQpD1IZ9A&jS8>_6"6+rg/M\lRXBA^mD$rNg5[2`r&]TWHW2P3S+F&OlE\M.>PDHLf*tI'Y![q>&2sej<2fb>,#7G6U2M+ZRNgOl7[A?iCGrGq*#J0QioJF4Wasb9r]CO!Cou8BKGX7PN1f'b(_:6J$uU!\4?gD2dR\AGYmG0g0#4fjW:XN=,?Z)hKn`aN4N'P[o,r]CPL]AQJbiq/pQBj)Q"7=Lpg"BSlM_*8%5Q[_(`AeKe9+hA`nq>4*7lP[liO/j!4Ge7\Bj^4TU@D@k2n##uGBX;:T83*6a5hNa?].\UogL1dN\mQFie"7I%-LeR^<^eETi/7OA&9=2]K:YRiaEjmoi_NI6o)SeQrAJUdTcD0nBNL6bIW,edGI^ioV>h=](W]FrV>,Rfd!Zg:(F)55E=;NP&sr]4_T^9.aIJ,]c3H72Mm7KENmQ#4_ZHq,-F-PmO5;(9Z\ljCo02ZXObo6j_L1A5n"8/Ec2l+fm8"k;HqX[c9qk)]_fF]m&.+AOMp#s_O?%'Q3ZB&;Dl]b_LQGs7MT?3+rf.,oA>^X0YoY8S48lXg2_;%8I-1A"baSo2*32%lX>Mc,f/=ucbBLm#!MG8Eb)bWK#kJombNqS>@9@(:YEct#a6'G(>E;CWbA"QbfCM'\Gh6kVb?].ZSW_>Q'Bk(82^@ZSDI3'*TdoH"#ddqB_3k_8e87aN0G#Wd3G6cBbLNV;"=phV7:@T3(+@4o9oV\u)6I0)Qs'$=9K)%Wq*XS$O7bm]/GqsJ*TJl,!8kag"l0mE!i@mH+*CVinr)7#87AEI8Fs%>"t=0UkZ`XAka+qaMtZ%lsp5Cfi"1YSk7b7cl,9Atsim4'K5*Yc4nV,:Gm`S*ONE/2=o!6[uPk2ptg9U';T3]VR/[2LP)N8s.8&DXj9%mW/aC(WHV9OCpNO,N@lq6AZTK!`MM0O8W?g:7VqkD$M8>4NDU@ji"O%JtaO:dZK"k>A!Q_Au:\(B9_m_V[c?eqLe?>8MH9RgOW`i/a44_sECdT?q&\Y&_lZ4fbIg2U-;kjZ<=1&oLplXnf!OZ7G,`_5=ac89]41mIb:"e@j)fYr1uMSk>1"\@mLA6'l8ZgX/$m4m2B,[kI/P2tMoX0DZ=\`%t"GI5t'cJk;K#oIt4uC)#lXo]J0@QL=%:E_ZS6l9_5@rO1dk+(jkHeU6V?\1Lb.35%5>7!](iCrfu@;F8S,U$tI)XIJX$^,]mTSGocI_6mmQ$Qi.$"!rGZHN]ALVF@Y%.6]D!59XkB[O1&#l3mL#C.Y\'\fCPN>G?E9H#OpP1FuTlaG=$Q>]a$%#*g`V/9o\+d0!IrA4Nh:.QT"nJ\gd=WgR(`pI%Ib\%p=q%mcOWMd'To[^VTeIGis>B`@om.H*'tZ]>E^T[0hp5N)2-rK=KW"V'_%/ilk6=95g4a+_e$,]-c>b$N.P9%%WL$MCUEKGn6aQ8]PpTO9,2VY@!pU;K'n;PY@i+jUXgRN<+":H;-i&,KqhVDgY![\&m@6'^c&Ln6A<3af_Dlt,E:J$idRe:UWNi87&9gqc1o8ep5CH4hHKOelh5r2=NO>YJIGnN74r;$!p=4&4@/&tRBK\(9;cRE\.l*VXY$(7bL_`'l=C$Btcqn45'Ofn\53Ek^ngSEu\\2NIPj6=r$X`0t4s@3>/9sZG[$dcUcK<\9eZ5J(%/FjWB^ciH\?j0GUW/Du@8*dJ8h?J)3%L9+L.(WA)G5#M)omF4594YC+#tJ$[&pLA^t#cL[,TmAeS9K@:>f5T?"]ZVp2B(?Ogi*U.(5NPX&e'HO8n6&n-L]>Bn-i:]])CO[B+K-CgHGUaS#Tg+T)h-b9ZpHA_C*nY'86/VG+!en5EL&O2LF:/#]8.Y0bVi$ZC(o<02_h#P-a(WRK_3oIE9r-#5E,3a8[T]rn*fE^2Y2=#gS5DJrCIF=g(=Bp"6\/EFibSjk(l^;m6R[g,ZAG<@O/Ir`G,]b@\t#+Q#YbgmP@_BmPZnn&lXVRcU,8"iD/Y"*s_2(0C(q")D%:WemGXOZPa`XSm4d%Y74)&J-P$%+;5bWOqX^Z5.=TUuW`AepSo-b%qR=29`7S<^ZWMr*>KT$>I\\L;[toCtn^)meD=29te5q`=Z1Y1-[-G#ujPs>!Q9?^'LVBLEr"_u9AHBtVHN!HN$)W_pZ`'p?l.><_J9#7![k]DXb>h;hP+jSm5PYV9@.QME,hJZ$NJ>VP79C.t>WZ@g`0[e4A#do&ijp;s;Q&:cFbHj3e@9jN%!3l75iuVsmd]W)4l5k>A!Qr1:G[isa1q`IqG)HCCZ\c(eFtWrh3$RA/'i_X37uG+8@!%WGEOJph/)e[?dZ^'#qP=W9ort@^o>'5P--'cP]?$8H^\IZC6T#&GuUtb7"=(.-8SZU\Y6Fl%X7Br^!VN44DH,JrHZns$iP>b$ACg?qCD4$;57(fSiQPqV:+Sp2QN*T?1EN0^^2nL,E(@e!S/B`H)MW2igih+D'G!XB9I@EbeGED/n,c#N6rJKbf-h3P1pZfu].ggVESL-SW:gX6%_.](-d,iDk7s,OMm6MgsNI'9?:f?09qdI%!N'`L:Tg+V'eW&e=O"R+jNuCSVIi^K66@U&16D75SrX/ULeE@T^2G"F7dSmb>m@->dh=]SYk>V.GVI]]BnXfDm^jU4&r:h>!@I0\+Y,X'O@HY;LBpL5+Jb\EVKA.QmfMk5T\PmXSo]Nd-8Wl4U>Y<"CiQlRk`BQE*riN9@/DRfJL=nE0%.3:4rtS7!+S&HBCYkuZ5t-mY0A*3tj#k:.j%0:Q^_1=6'E-+hnoq=FNZlWc9c`j1\8W%G?R"T@)Tf,Eqsm1\#O*\(6fSD\PjrHT(arHVAG#2mgW>*2^`Q&AB59.I3J\_\*c:BT7m2+C*`'?o&hqaPqJIJk,'QfbfL^pE:rC_\*c;m&L()5,r%\A8frdGUcac^KghW_;>7lfBMf=q*N8eiAni9KWM^MGqp^aE?4R%/Z@]/IMd2Q7D9teY&8$fEZ9X.uU'@lCZ7\n$-V,MDL%,]@TUIDcLG@V_;-5\]RM/N&/g2q=2/XaS!-MHq-b^gKsE2%V4j>JU_LZ'D@Vg>t"daC2trAC`P,_$TariU6+\%JiL9-l6EeF2ZXon;fkg-"nP--Hf?6Wk(S[cN_^;9_mf)^mC($+Qh748D?EqJNl-km#BlEAR,7u^CMrEF_uYJ.;==-=ed$'uXaW[k\PZJ[uo?lL[H$Vcf$>7B>>R*iL/pS1paF8`/bZ^BI3f&dkA,+$%!?.893KW$bAT<%^$5qja^YpiUbXCE+q_ERQ']nOT,6iO2HA58bsFu]'nn9<"ZdGo;5Ko5f9AP3@+/@6"%T%SLX;Y`okFL+r*P=VE_j0OPpn:3EZA2NX^THJEOO=04dgQqQCGOqoj;9e<>l`H:QoorX3'@8l^@,'Zf8DK[H,TLGS&Bba)T0B^Td0.(LnO\MkK0]Q@7t`\OXY!0)T"kM7Z^'8c&0;pAH=&Nk93O"=8PdI>FKORi2c2h!''h5QnX$kJrQVMnCFVSja\]G\nH2T#c`aou1FrT+uTcbO#:X')M3uOX/i_q>&p*2Ct+GSpnZHm^3G!gK)E]CDKHmV?j_8RtC$]"$RMPT-[XT=?:k.Df0NU)![O^?_LEsMZUhdQLX>`LT?Y[COVS@ZoI5aOaiuj%]q:O-&0\JIN`gu_"h!o!1h%aiL\WA8T\6Cqohu!<4at`9ZjH*/)b*brC-pVE9m&*PYOPp*ecqS:oO@#rHT)lFGft0=-0\t<`b_Km(G`Z7ZYog8+l0$`LfBI?.YfPOlJ!E7mnhRTu;r1fX#dR]2+;f$s'6--&-a(^XN?]PdEr'f@%*6abtjJNmB`la5bSlEtgc@`XLt*B#EK.)TX*,4+HSXC2(C[fVh_8#BYpdMommU[bMA>-_Wbc)G0M=T:bhFi*qGtA7F;^bRtN:g14MJZe'N:OJlrr21^'7/PmSKaQ:\-$9;$h@?aEQN`NJiAQ:1\+_tX@%;&Iu7F5m+)VA>bjJ:kRBqkH=PM*l@8OtKb1'C?qG+SXQ>I_pi<[M6GMsD-O8LkOp7^7L.CbnF_d)q(hQd,-E&gNWr/1:TL/*BM->o'!N$7Q_uHR\E(6Z@?*r:9jVpqpjVS/e_>/60b.(d_<9"V/\5NG>;T2Sn93,^+<4i**X0rF.4*>Aa]0,Yo*!ZUR^LkqgY#deG`i?_uNrnG2/Q;pT,cFO1'GQdSIhc_F;b'FNAtTg+T)ND@TUma;k_8>8"8p2/6CgZ.#o2U*37?D12j8*J9oH?G5Fq>\PsCpGhNg<.O:d%i`LDQV@.C:*OYSPj>`rhhlHA>Mm[j+L,KPamBuJD.*0BotPJh+N#J2^RjE8pL&h]8^_22p]7]'$9CNqE-oN\]:sTSn(Qq9VmGe[T@ViZp2jk&'+FBmOh\OpZKg_Y?$f)aM.4o/kOEXB$:r%_ZbbFR)PeCU).-AJPYH\",&1N)jF7/of5PTgZi7rC25"lnk8,@Q1-]I4"/k0akTFMl,0#cC6sb5SPL,plou^osrkYrI&pa`R>g?bqf!r*.HE@6jDea2-)5Y:TbPHAS"`h2]Z,"Rea]2j",.G"GSJ&F.f49n]R*o3mb&0ubbE-j*lW#-m5,>m/D$Skmo;-1.4aeY=)B+#Y08=!pkS,l>k+nP;.l44YQ_qE])@U5E^%n3att'XTBBq%a/HV\mhZ!`-11%SBNI).n[.D$J3F;'p:UFo$rRol*rsH6:OMO6$!>R\p$>d*j(Z^(!.CAVr\a7d`ctOJla/V#Qq@_qF<+N8(*$jDjSQ?L>bOBC6D74(<.BW$4:6d/Thn*0o]K)bo%BXb3A6,??3(Y=RHWMWn3WtM_k?gf@r",&RpI['l0.AKa^Jf43j1`nWQmF0Nl-QI_cKhSb14pEP;EcMDh[bfNlb>8U/BIZkjdj7r4.X_5e[k\@]1l_pJ-V_,@[oL\8mUILDoN,OoFW\^.35t`trFPMl/a.q12SNS5k9;B&&en!.6RE<..\C8&g1K/Ct9kJ^_@u]L\c2MX0I:4;kC-oJTX#b/6ZqkkqgL+C=6Ru*:ad"beR,"7O$]O:.+HTOrHVAG"r?+YcBMTPZ>P4jkOcdEF-=!3hqko`2KdkrGh%PUIG$YuP?+fcVJ/u*Fo/C8qc$;=UimP22RTQ^>su)PVN%V&d7Sr3=sf58J?0J"&kE97&;ZKI$6c3)R#h]deZjbmOH>+uRYE)2&j%GS`qIO2pc'X6[W?gk=`%e6O.Hm-H%"PmH&3aDo^Y5[5.CBG-PG,jCfOhFALd&7SURlVmW7pX1WluuNgU2r>oH/,q7O<'/*:]V?a3XQ3:%^A-Sb]qpR(@NgU7W\-4W7h,?(bBg#G-+";I+1cg7>;9q9A4PJcY,cEUU=F:@S>'%a*B4D5CG,Gsk%gUQWqJ+sLW+np*oR(]!tY;dnMC/QXq$rVnKo,@'-T&<91$LmMrp4q\CDs.G7iKeEtDf=5_@T3i]*WZ2t>57dU'jNp*4]sm?Fnb:-TlHeXI]frn\KQ-fRLG(^_eOq4JF6R@VZg,'tf)E,R`QZ!Pk;bNMUGVB8fKQJlT8uOJD_M*FJqk8*c:P9R5.[[Usj!WJjYP3^*#80t(F@JK>Ijl5LAe3"Oq(",.@aY"WrJB$Mj4]2Ikfi4\it8,pMs*G`a[u/GA#3J(>)`d$g`E<'gmkcr1T?Q8Pm79Pa-"gu(=(YbDh'^PQ"nG(&J5V78j8;lLmWV4k:tq$jRX*rr@pliTs$na9.uNfY(+8ef]j?`H!S1sHJqZnq>n@/fmR)(a"I9be$7#6n=diiK)K@ePs60ikI@m/YZ"g,ZFMr;\3E(!i]DXsf8EMef>nlQkF\uKNC^=k&]Yf*mAoc'pm_.ajJKsLB>ol1\m\`Y4XZ\'iP>A#B)Z#hq5>S+*k)%$>5Q=DeJk]ms):V"`mMb)qg<99>@F_]/KTVYI#YC/(T:!tH-@Z/jR^D&bma9#X3/*\G.B,aG^ZnQ\SfX"%8Qq>bha'c.WAITHJMNI\N.cF56$$.*;f)nKg%piAc"Vbp&;=://<=b#KB4XibNmJS)3^;BBgl`q7Ns"oP?K)`d$g`E<'gmkcr1F\qLfJ+\\:[D8kfrsgKs&Q-GT1;:;1b/;`+sLLi-(i52GEL4DSet?TdOTe2i^(+TI+[01M&XKQ?[j?_1qr>>9a>"9IcZ"@d,jN>p$mAt-bG.Naqqe>:b!g]_q)u[-J9KM=-n;TXaY$G`*!$XCTY0^[Ir=sZ%4^Vi>mQAibP9\D`*j&9g?+WXVr9<9oTkBm!btH:Af0]Yd%G[F?-oKI?ooeM@Zm$FkpsgaZ*>d!d.'uO85TsqDJNWS8,Y!^Le"!?3qV.[o6(fETb3,fh#g5m1AR1jm)Tjj^'[3\5=eL3D6P1e(cQaVX)O5[k&J6bpP0[XT];n0rJ+"3>MsaOB\9#aN$jZ4DFB@blrQe=2H-@Z/f:Tfj>E%#g9Kg(Mb=OmYLko_Dnp*Vk`9^,\NsWqk21dX^P@;0qsPO1r)cg-pF*YB"3W9!Q+Lks`NHl`racY)gRNqX$3dSi)MX(]EpQ^?$3g?L_kQ/qP(:Qj%:FQ;)/,41]IJAW-XTD-%qGF+o5dT4u9[-Gcr=+B[)6psFBr6YURj6n3:,%?k's8HUd[F9kX5%g&)YB7nL0qT_`a.03$caUV+X"5q'>buk$7J&z!!!"oOO*)`o(eP'q)mf'jR\a[al`[)z!/s6.T/4UP=1[JaQqrmkA'QBm#64`(!!!!Q8g9mWGo^L$_37+,rA="B/%.,2o(cYlj:L1;Ie2ld$?JB?]U'q:#64`(!!!!Q8g9l4J58V:ItO*GG8UC$%f&3ezzzzzzzzzzzzzz_#K)f!!m.K#Q~>endstream endobj 28 0 obj << @@ -231,7 +231,7 @@ endobj << /Contents 143 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 132 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject << -/FormXob.873240933f8ffe126f95df55e941dd3a 27 0 R /FormXob.ac4d2a97676ca8c002b2001987b87b9d 28 0 R +/FormXob.ac4d2a97676ca8c002b2001987b87b9d 28 0 R /FormXob.ddff3fe796cb06f610a0e90e16a0db7d 27 0 R >> >> /Rotate 0 /Trans << @@ -584,7 +584,7 @@ endobj endobj 69 0 obj << -/Author () /CreationDate (D:20260418195221-04'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260418195221-04'00') /Producer (ReportLab PDF Library - \(opensource\)) +/Author () /CreationDate (D:20260418202758-04'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260418202758-04'00') /Producer (ReportLab PDF Library - \(opensource\)) /Subject (\(unspecified\)) /Title () /Trapped /False >> endobj @@ -710,7 +710,7 @@ endobj endobj 93 0 obj << -/Dest [ 29 0 R /XYZ 57.02362 435.8127 0 ] /Next 94 0 R /Parent 92 0 R /Title (6.6.1 Meta-GC: Arena Fast Path with Mark-Phase Verifier) +/Dest [ 29 0 R /XYZ 57.02362 435.9366 0 ] /Next 94 0 R /Parent 92 0 R /Title (6.6.1 Meta-GC: Arena Fast Path with Mark-Phase Verifier) >> endobj 94 0 obj @@ -725,70 +725,70 @@ endobj endobj 96 0 obj << -/Dest [ 34 0 R /XYZ 57.02362 765.0236 0 ] /Next 97 0 R /Parent 92 0 R /Prev 95 0 R /Title (6.6.4 Validation: HTTP Server Under Sustained Load) +/Dest [ 34 0 R /XYZ 57.02362 717.0236 0 ] /Next 97 0 R /Parent 92 0 R /Prev 95 0 R /Title (6.6.4 Validation: HTTP Server Under Sustained Load) >> endobj 97 0 obj << -/Dest [ 35 0 R /XYZ 57.02362 765.0236 0 ] /Parent 92 0 R /Prev 96 0 R /Title (6.6.5 Precise Block Typing: Killing a Class of Bugs) +/Dest [ 35 0 R /XYZ 57.02362 699.0236 0 ] /Parent 92 0 R /Prev 96 0 R /Title (6.6.5 Precise Block Typing: Killing a Class of Bugs) >> endobj 98 0 obj << -/Count 8 /Dest [ 35 0 R /XYZ 57.02362 446.6236 0 ] /First 99 0 R /Last 106 0 R /Next 107 0 R /Parent 71 0 R +/Count 8 /Dest [ 35 0 R /XYZ 57.02362 380.6236 0 ] /First 99 0 R /Last 106 0 R /Next 107 0 R /Parent 71 0 R /Prev 86 0 R /Title (7. Portal: Feedback Across Time) >> endobj 99 0 obj << -/Dest [ 35 0 R /XYZ 57.02362 243.4236 0 ] /Next 100 0 R /Parent 98 0 R /Title (7.1 S-Expression Portal \204 the Portable One) +/Dest [ 35 0 R /XYZ 57.02362 177.4236 0 ] /Next 100 0 R /Parent 98 0 R /Title (7.1 S-Expression Portal \204 the Portable One) >> endobj 100 0 obj << -/Dest [ 37 0 R /XYZ 57.02362 685.0236 0 ] /Next 101 0 R /Parent 98 0 R /Prev 99 0 R /Title (7.2 Cross-Implementation Exchange Matrix) +/Dest [ 37 0 R /XYZ 57.02362 631.0236 0 ] /Next 101 0 R /Parent 98 0 R /Prev 99 0 R /Title (7.2 Cross-Implementation Exchange Matrix) >> endobj 101 0 obj << -/Dest [ 37 0 R /XYZ 57.02362 455.0236 0 ] /Next 102 0 R /Parent 98 0 R /Prev 100 0 R /Title (7.3 JSON Portal \204 Graph-Aware, Continuation-Preserving) +/Dest [ 37 0 R /XYZ 57.02362 401.0236 0 ] /Next 102 0 R /Parent 98 0 R /Prev 100 0 R /Title (7.3 JSON Portal \204 Graph-Aware, Continuation-Preserving) >> endobj 102 0 obj << -/Count 1 /Dest [ 37 0 R /XYZ 57.02362 168.2236 0 ] /First 103 0 R /Last 103 0 R /Next 104 0 R /Parent 98 0 R +/Count 1 /Dest [ 37 0 R /XYZ 57.02362 114.2236 0 ] /First 103 0 R /Last 103 0 R /Next 104 0 R /Parent 98 0 R /Prev 101 0 R /Title (7.4 Binary Heap Dump \204 the Fast One) >> endobj 103 0 obj << -/Dest [ 38 0 R /XYZ 57.02362 603.4236 0 ] /Parent 102 0 R /Title (7.4.1 The GC Build Uses S-Expressions) +/Dest [ 38 0 R /XYZ 57.02362 565.0236 0 ] /Parent 102 0 R /Title (7.4.1 The GC Build Uses S-Expressions) >> endobj 104 0 obj << -/Dest [ 38 0 R /XYZ 57.02362 341.8236 0 ] /Next 105 0 R /Parent 98 0 R /Prev 102 0 R /Title (7.5 Cross-Process Benchmarks) +/Dest [ 38 0 R /XYZ 57.02362 303.4236 0 ] /Next 105 0 R /Parent 98 0 R /Prev 102 0 R /Title (7.5 Cross-Process Benchmarks) >> endobj 105 0 obj << -/Dest [ 39 0 R /XYZ 57.02362 715.0236 0 ] /Next 106 0 R /Parent 98 0 R /Prev 104 0 R /Title (7.6 Mismatch Cases: Graceful Degradation) +/Dest [ 39 0 R /XYZ 57.02362 691.0236 0 ] /Next 106 0 R /Parent 98 0 R /Prev 104 0 R /Title (7.6 Mismatch Cases: Graceful Degradation) >> endobj 106 0 obj << -/Dest [ 39 0 R /XYZ 57.02362 449.0236 0 ] /Parent 98 0 R /Prev 105 0 R /Title (7.7 Use Case: Distributed Primality Testing) +/Dest [ 39 0 R /XYZ 57.02362 425.0236 0 ] /Parent 98 0 R /Prev 105 0 R /Title (7.7 Use Case: Distributed Primality Testing) >> endobj 107 0 obj << -/Count 6 /Dest [ 39 0 R /XYZ 57.02362 248.2236 0 ] /First 108 0 R /Last 113 0 R /Next 114 0 R /Parent 71 0 R +/Count 6 /Dest [ 39 0 R /XYZ 57.02362 224.2236 0 ] /First 108 0 R /Last 113 0 R /Next 114 0 R /Parent 71 0 R /Prev 98 0 R /Title (8. The EML Universality Proof) >> endobj 108 0 obj << -/Dest [ 39 0 R /XYZ 57.02362 171.0236 0 ] /Next 109 0 R /Parent 107 0 R /Title (8.1 The Operator) +/Dest [ 39 0 R /XYZ 57.02362 147.0236 0 ] /Next 109 0 R /Parent 107 0 R /Title (8.1 The Operator) >> endobj 109 0 obj @@ -4473,7 +4473,7 @@ endstream endobj 143 0 obj << -/Length 8527 +/Length 8523 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -4565,14 +4565,14 @@ q 1 0 0 1 169.6176 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1,097 ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (727 ms) Tj T* ET Q Q q 1 0 0 1 256.2387 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (133.9 MB) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (133.1 MB) Tj T* ET Q Q q @@ -4592,7 +4592,7 @@ q 1 0 0 1 169.6176 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1,431 ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (918 ms) Tj T* ET Q Q q @@ -4632,22 +4632,22 @@ Q q 1 0 0 1 57.02362 556.6236 cm q -BT 1 0 0 1 0 26 Tm .105917 Tw 12 TL /F3 10 Tf 0 0 0 rg (124\327 less memory at a ~30% throughput cost.) Tj /F1 10 Tf ( That is the honest GC tax at the naive end of the spectrum) Tj T* 0 Tw 7.017739 Tw (\227 the number we had been guessing at before building the control group. Every future) Tj T* 0 Tw (memory-management proposal \(generational, incremental, region-based\) now has a concrete floor to beat.) Tj T* ET +BT 1 0 0 1 0 26 Tm .105917 Tw 12 TL /F3 10 Tf 0 0 0 rg (122\327 less memory at a ~26% throughput cost.) Tj /F1 10 Tf ( That is the honest GC tax at the naive end of the spectrum) Tj T* 0 Tw 7.017739 Tw (\227 the number we had been guessing at before building the control group. Every future) Tj T* 0 Tw (memory-management proposal \(generational, incremental, region-based\) now has a concrete floor to beat.) Tj T* ET Q Q q 1 0 0 1 57.02362 548.6236 cm Q q -1 0 0 1 57.02362 455.8127 cm +1 0 0 1 57.02362 455.9366 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET q 1 0 0 1 34.1537 69 cm q -412.9209 0 0 20.81089 0 0 cm -/FormXob.873240933f8ffe126f95df55e941dd3a Do +412.9209 0 0 20.68701 0 0 cm +/FormXob.ddff3fe796cb06f610a0e90e16a0db7d Do Q Q q @@ -4662,28 +4662,28 @@ Q Q Q q -1 0 0 1 57.02362 447.8127 cm +1 0 0 1 57.02362 447.9366 cm Q q -1 0 0 1 57.02362 423.8127 cm +1 0 0 1 57.02362 423.9366 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (6.6.1 Meta-GC: Arena Fast Path with Mark-Phase Verifier) Tj T* ET Q Q q -1 0 0 1 57.02362 381.8127 cm +1 0 0 1 57.02362 381.9366 cm q BT 1 0 0 1 0 26 Tm .669314 Tw 12 TL /F1 10 Tf 0 0 0 rg (On top of the naive sweep, the GC build exposes a Lumbda primitive ) Tj /F5 10 Tf (\(with-arena) Tj ( ) Tj (thunk\)) Tj /F1 10 Tf ( that takes a) Tj T* 0 Tw 1.104556 Tw (zero-argument procedure, runs it, and attempts an ) Tj /F3 10 Tf (O\(1\) bulk reclaim) Tj /F1 10 Tf ( of every allocation the thunk made.) Tj T* 0 Tw (The decision logic is a three-way policy:) Tj T* ET Q Q q -1 0 0 1 57.02362 375.8127 cm +1 0 0 1 57.02362 375.9366 cm Q q -1 0 0 1 57.02362 375.8127 cm +1 0 0 1 57.02362 375.9366 cm Q q -1 0 0 1 57.02362 351.8127 cm +1 0 0 1 57.02362 351.9366 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4705,10 +4705,10 @@ Q Q Q q -1 0 0 1 57.02362 345.8127 cm +1 0 0 1 57.02362 345.9366 cm Q q -1 0 0 1 57.02362 309.8127 cm +1 0 0 1 57.02362 309.9366 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4730,10 +4730,10 @@ Q Q Q q -1 0 0 1 57.02362 303.8127 cm +1 0 0 1 57.02362 303.9366 cm Q q -1 0 0 1 57.02362 279.8127 cm +1 0 0 1 57.02362 279.9366 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4755,19 +4755,19 @@ Q Q Q q -1 0 0 1 57.02362 279.8127 cm +1 0 0 1 57.02362 279.9366 cm Q q -1 0 0 1 57.02362 201.8127 cm +1 0 0 1 57.02362 201.9366 cm q BT 1 0 0 1 0 62 Tm 2.481079 Tw 12 TL /F1 10 Tf 0 0 0 rg (Free-list reuse is disabled while an arena is active so the chain stays pristine for a verbatim restore;) Tj T* 0 Tw 4.369862 Tw /F5 10 Tf (heap_alloc) Tj /F1 10 Tf ( enforces this via a global ) Tj /F5 10 Tf (arena_active) Tj /F1 10 Tf ( flag. One critical correctness detail: after) Tj T* 0 Tw .105596 Tw /F5 10 Tf (apply_proc_raw) Tj /F1 10 Tf ( returns from the thunk, volatile registers contain stale tagged pointers into the arena. The) Tj T* 0 Tw 1.244897 Tw (conservative stack scan would otherwise treat those residuals as live roots and trigger a false escape on) Tj T* 0 Tw 2.046796 Tw (every call. Zero-ing ) Tj /F5 10 Tf (%rax,) Tj ( ) Tj (%rcx,) Tj ( ) Tj (%rdx,) Tj ( ) Tj (%rsi,) Tj ( ) Tj (%rdi,) Tj ( ) Tj (%rbp,) Tj ( ) Tj (%r8-%r12) Tj /F1 10 Tf ( before the verifier runs) Tj T* 0 Tw (removes this hazard.) Tj T* ET Q Q q -1 0 0 1 57.02362 193.8127 cm +1 0 0 1 57.02362 193.9366 cm Q q -1 0 0 1 57.02362 77.85291 cm +1 0 0 1 57.02362 77.97679 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -4790,14 +4790,14 @@ Q Q Q q -1 0 0 1 57.02362 69.85291 cm +1 0 0 1 57.02362 69.97679 cm Q endstream endobj 144 0 obj << -/Length 10896 +/Length 10897 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -4869,7 +4869,7 @@ q 1 0 0 1 175.8453 33 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (932 ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (945 ms) Tj T* ET Q Q q @@ -4904,7 +4904,7 @@ q 1 0 0 1 175.8453 15 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (945 ms) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1030 ms) Tj T* ET Q Q q @@ -5167,7 +5167,7 @@ endstream endobj 145 0 obj << -/Length 12577 +/Length 12449 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -5381,7 +5381,7 @@ q 1 0 0 1 179.2422 93 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (732) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (356) Tj T* ET Q Q q @@ -5430,7 +5430,7 @@ q 1 0 0 1 179.2422 75 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (691) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (351) Tj T* ET Q Q q @@ -5479,7 +5479,7 @@ q 1 0 0 1 179.2422 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (568) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (287) Tj T* ET Q Q q @@ -5528,7 +5528,7 @@ q 1 0 0 1 179.2422 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (607) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (285) Tj T* ET Q Q q @@ -5577,7 +5577,7 @@ q 1 0 0 1 179.2422 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1981) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (863) Tj T* ET Q Q q @@ -5626,7 +5626,7 @@ q 1 0 0 1 179.2422 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1694) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (858) Tj T* ET Q Q q @@ -5698,12 +5698,12 @@ q 1 0 0 1 57.02362 372.2236 cm Q q -1 0 0 1 57.02362 348.2236 cm +1 0 0 1 57.02362 336.2236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 9 cm +1 0 0 1 6 21 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET @@ -5712,7 +5712,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 14 Tm .22755 Tw 12 TL /F3 10 Tf 0 0 0 rg (Friendly) Tj /F1 10 Tf ( workload: adaptive is ~6% faster. EMA stays at 0 \(every arena resets\), so the skip path never) Tj T* 0 Tw (fires \227 the small win is measurement noise plus a slightly shorter decision path for the common case.) Tj T* ET +BT 1 0 0 1 0 26 Tm .866772 Tw 12 TL /F3 10 Tf 0 0 0 rg (Friendly) Tj /F1 10 Tf ( workload: adaptive and greedy are within ~1%. EMA stays at 0 \(every arena resets\), so the) Tj T* 0 Tw .102018 Tw (skip path never fires \227 a null result for the adaptive policy, which is exactly what we want on workloads) Tj T* 0 Tw (that are already arena-scoped cleanly.) Tj T* ET Q Q q @@ -5720,10 +5720,10 @@ Q Q Q q -1 0 0 1 57.02362 342.2236 cm +1 0 0 1 57.02362 330.2236 cm Q q -1 0 0 1 57.02362 294.2236 cm +1 0 0 1 57.02362 282.2236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -5737,7 +5737,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 38 Tm .426796 Tw 12 TL /F3 10 Tf 0 0 0 rg (Hostile) Tj /F1 10 Tf ( workload: greedy happens to edge adaptive by ~7%. Both modes trigger implicit ) Tj /F5 10 Tf (gc_collect) Tj /F1 10 Tf T* 0 Tw 1.624556 Tw (982 times out of 1000 arenas \227 heap overflow during the thunk clears ) Tj /F5 10 Tf (arena_active) Tj /F1 10 Tf ( before the) Tj T* 0 Tw .29402 Tw (dispatcher sees it, so the adaptive skip path only activated 11 times. The policy's signal is drowned out) Tj T* 0 Tw (by pressure-driven GC.) Tj T* ET +BT 1 0 0 1 0 38 Tm 1.549168 Tw 12 TL /F3 10 Tf 0 0 0 rg (Hostile) Tj /F1 10 Tf ( workload: also within ~1%. Both modes trigger implicit ) Tj /F5 10 Tf (gc_collect) Tj /F1 10 Tf ( 982 times out of 1000) Tj T* 0 Tw .66189 Tw (arenas \227 heap overflow during the thunk clears ) Tj /F5 10 Tf (arena_active) Tj /F1 10 Tf ( before the dispatcher sees it, so the) Tj T* 0 Tw .105522 Tw (adaptive skip path only activates 11 times. The policy's signal is drowned out by pressure-driven GC on) Tj T* 0 Tw (this shape. Adaptive isn't helping, but it's not hurting either.) Tj T* ET Q Q q @@ -5745,10 +5745,10 @@ Q Q Q q -1 0 0 1 57.02362 288.2236 cm +1 0 0 1 57.02362 276.2236 cm Q q -1 0 0 1 57.02362 228.2236 cm +1 0 0 1 57.02362 216.2236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -5762,7 +5762,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 50 Tm .78402 Tw 12 TL /F3 10 Tf 0 0 0 rg (Mixed) Tj /F1 10 Tf ( workload: adaptive is ~**17% faster** \(1694 ms vs 1981 ms\). This is the shape the policy was) Tj T* 0 Tw .68189 Tw (designed for \227 escape rate is moderate, arena entries interleave friendly and hostile phases, and the) Tj T* 0 Tw .815522 Tw (probe lets the EMA recover when the workload shifts. The number of resets stays comparable \(14 vs) Tj T* 0 Tw 2.160596 Tw (17\), but the verifier runs less often on the doomed-to-escape arenas, and the overall mark-phase) Tj T* 0 Tw (budget goes down.) Tj T* ET +BT 1 0 0 1 0 50 Tm .504395 Tw 12 TL /F3 10 Tf 0 0 0 rg (Mixed) Tj /F1 10 Tf ( workload: adaptive and greedy within ~1%. Earlier measurements \(before the precise-type-byte) Tj T* 0 Tw .372844 Tw (fix\) had shown a 17% adaptive win here; after the fix the numbers converged. The fix both accelerated) Tj T* 0 Tw .359873 Tw (the common paths \(fewer redundant checks\) and closed one correctness hole, so whatever advantage) Tj T* 0 Tw .674897 Tw (adaptive was extracting from the specific crash pattern it had tolerated is now available to greedy too.) Tj T* 0 Tw (Honest result is that adaptive is neutral here, not a win.) Tj T* ET Q Q q @@ -5770,18 +5770,12 @@ Q Q Q q -1 0 0 1 57.02362 210.2236 cm +1 0 0 1 57.02362 198.2236 cm Q q -1 0 0 1 57.02362 120.2236 cm +1 0 0 1 57.02362 96.22362 cm q -BT 1 0 0 1 0 74 Tm .423597 Tw 12 TL /F3 10 Tf 0 0 0 rg (Honest read.) Tj /F1 10 Tf ( Adaptive is a clear win when the policy's signal is visible \(mixed, friendly\) and a wash when it) Tj T* 0 Tw .29631 Tw (isn't \(hostile, where implicit GC dominates\). The 137-test asm-gc suite passes identically under both modes,) Tj T* 0 Tw .93989 Tw (so choosing adaptive costs nothing on workloads where it doesn't help. The benchmark also surfaced two) Tj T* 0 Tw .518797 Tw (real bugs in the conservative stack scan that the greedy policy had been hiding \227 a 24-byte string misread) Tj T* 0 Tw .490966 Tw (as an env node, and a 40-byte string misread as a 25-element vector. Both are fixed \(offset-0 tag check for) Tj T* 0 Tw .898022 Tw (env; length-fits-block check for vector/hash walkers\), and the four strategies \(arena reset / arena skip / full) Tj T* 0 Tw (sweep / sweep fallback\) now co-exist safely.) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 78.22362 cm -q -BT 1 0 0 1 0 26 Tm 22.60709 Tw 12 TL /F3 10 Tf 0 0 0 rg (Reproduce:) Tj /F1 10 Tf ( ) Tj /F5 10 Tf (make) Tj ( ) Tj (bench-gc-adaptive) Tj /F1 10 Tf ( \(source: ) Tj /F5 10 Tf (tests/bench-gc-adaptive.sh) Tj /F1 10 Tf (,) Tj T* 0 Tw .950696 Tw /F5 10 Tf (examples/bench-gc-adaptive.lsp) Tj /F1 10 Tf (\). Each \(workload \327 mode\) pair runs in a fresh asm-gc process so) Tj T* 0 Tw (results don't contaminate each other across phases.) Tj T* ET +BT 1 0 0 1 0 86 Tm 3.071223 Tw 12 TL /F3 10 Tf 0 0 0 rg (Honest read.) Tj /F1 10 Tf ( The adaptive policy is currently a null experiment on these three workloads \227 within) Tj T* 0 Tw 3.592397 Tw (measurement noise of greedy in all three cases. It may still win on workloads we haven't probed) Tj T* 0 Tw 3.328196 Tw (\(long-running servers with occasional large bursts, mixed short/long transactions\), but nothing in the) Tj T* 0 Tw 1.51218 Tw (three-way benchmark tells us to prefer it. Shipping it as default \() Tj /F5 10 Tf (arena_adaptive_mode=1) Tj /F1 10 Tf ( at ) Tj /F5 10 Tf (_start) Tj /F1 10 Tf (\)) Tj T* 0 Tw 1.318647 Tw (costs nothing and keeps the counters \() Tj /F5 10 Tf (arena-stats) Tj /F1 10 Tf ( fifth field = ) Tj /F5 10 Tf (skipped) Tj /F1 10 Tf (, sixth field = EMA rate \327256\)) Tj T* 0 Tw 2.773196 Tw (available for observability. The benchmark also drove the original precise-type-byte work \(\2476.6.5\) that) Tj T* 0 Tw .583432 Tw (eliminated the latent class of conservative-scan bugs \227 so even the null result paid for itself in correctness) Tj T* 0 Tw (progress.) Tj T* ET Q Q @@ -5789,27 +5783,33 @@ endstream endobj 146 0 obj << -/Length 9939 +/Length 10559 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 753.0236 cm +1 0 0 1 57.02362 729.0236 cm +q +BT 1 0 0 1 0 26 Tm 22.60709 Tw 12 TL /F3 10 Tf 0 0 0 rg (Reproduce:) Tj /F1 10 Tf ( ) Tj /F5 10 Tf (make) Tj ( ) Tj (bench-gc-adaptive) Tj /F1 10 Tf ( \(source: ) Tj /F5 10 Tf (tests/bench-gc-adaptive.sh) Tj /F1 10 Tf (,) Tj T* 0 Tw .950696 Tw /F5 10 Tf (examples/bench-gc-adaptive.lsp) Tj /F1 10 Tf (\). Each \(workload \327 mode\) pair runs in a fresh asm-gc process so) Tj T* 0 Tw (results don't contaminate each other across phases.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 705.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (6.6.4 Validation: HTTP Server Under Sustained Load) Tj T* ET Q Q q -1 0 0 1 57.02362 687.0236 cm +1 0 0 1 57.02362 639.0236 cm q BT 1 0 0 1 0 50 Tm .613797 Tw 12 TL /F1 10 Tf 0 0 0 rg (The reason we built the GC at all was to let long-running asm HTTP servers not leak. Bench-gc-http drives) Tj T* 0 Tw 2.274261 Tw /F5 10 Tf (examples/http-server.lsp) Tj /F1 10 Tf ( \(uses the portable ) Tj /F5 10 Tf (heap-snapshot) Tj /F1 10 Tf ( / ) Tj /F5 10 Tf (heap-restore) Tj /F1 10 Tf ( arena loop\) and) Tj T* 0 Tw 1.382038 Tw /F5 10 Tf (examples/http-server-noarena.lsp) Tj /F1 10 Tf ( \(same server with the snapshot pattern removed\) under 5,000) Tj T* 0 Tw 1.91989 Tw (concurrent requests against each asm build. The matrix has four cells because the snapshot pattern is) Tj T* 0 Tw (orthogonal to the collector: either, both, or neither.) Tj T* ET Q Q q -1 0 0 1 57.02362 681.0236 cm +1 0 0 1 57.02362 633.0236 cm Q q -1 0 0 1 57.02362 579.0236 cm +1 0 0 1 57.02362 531.0236 cm q 1 1 1 rg n 0 102 481.2283 -30 re f* @@ -5855,7 +5855,7 @@ q 1 0 0 1 390.9827 75 cm q 0 0 0 rg -BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL 8.232835 0 Td (growth KB \(20) Tj T* 14.715 0 Td (000 req\)) Tj T* -22.94783 0 Td ET +BT 1 0 0 1 0 14 Tm /F3 10 Tf 12 TL 8.232835 0 Td (growth KB \(50) Tj T* 14.715 0 Td (000 req\)) Tj T* -22.94783 0 Td ET Q Q 0 0 0 rg @@ -5870,7 +5870,7 @@ q 1 0 0 1 188.8668 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~240) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~630) Tj T* ET Q Q q @@ -5884,14 +5884,14 @@ q 1 0 0 1 323.6107 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (96) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (100) Tj T* ET Q Q q 1 0 0 1 390.9827 57 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (0) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (4) Tj T* ET Q Q q @@ -5904,14 +5904,14 @@ q 1 0 0 1 188.8668 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~235) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~633) Tj T* ET Q Q q 1 0 0 1 256.2387 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (120) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (116) Tj T* ET Q Q q @@ -5925,7 +5925,7 @@ q 1 0 0 1 390.9827 39 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (0) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (4) Tj T* ET Q Q q @@ -5939,28 +5939,28 @@ q 1 0 0 1 188.8668 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~470) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~625) Tj T* ET Q Q q 1 0 0 1 256.2387 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (264) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (100) Tj T* ET Q Q q 1 0 0 1 323.6107 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (185,000) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (458,812) Tj T* ET Q Q q 1 0 0 1 390.9827 21 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (185,000) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (\(OOM\)) Tj T* ET Q Q q @@ -5974,28 +5974,28 @@ q 1 0 0 1 188.8668 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~450) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (~610) Tj T* ET Q Q q 1 0 0 1 256.2387 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (112) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (240) Tj T* ET Q Q q 1 0 0 1 323.6107 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1,084) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (1,092) Tj T* ET Q Q q 1 0 0 1 390.9827 3 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (972) Tj T* ET +BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (852) Tj T* ET Q Q q @@ -6019,22 +6019,22 @@ Q Q Q q -1 0 0 1 57.02362 579.0236 cm +1 0 0 1 57.02362 531.0236 cm Q q -1 0 0 1 57.02362 561.0236 cm +1 0 0 1 57.02362 513.0236 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (All four cells validate cleanly now at ) Tj /F3 10 Tf (20,000 requests per cell) Tj /F1 10 Tf ( \(up from the original 5,000\):) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (All four cells validate cleanly at ) Tj /F3 10 Tf (50,000 requests per cell) Tj /F1 10 Tf ( \(up from the original 5,000\):) Tj T* ET Q Q q -1 0 0 1 57.02362 555.0236 cm +1 0 0 1 57.02362 507.0236 cm Q q -1 0 0 1 57.02362 555.0236 cm +1 0 0 1 57.02362 507.0236 cm Q q -1 0 0 1 57.02362 519.0236 cm +1 0 0 1 57.02362 471.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -6056,10 +6056,10 @@ Q Q Q q -1 0 0 1 57.02362 513.0236 cm +1 0 0 1 57.02362 465.0236 cm Q q -1 0 0 1 57.02362 477.0236 cm +1 0 0 1 57.02362 429.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -6081,10 +6081,10 @@ Q Q Q q -1 0 0 1 57.02362 471.0236 cm +1 0 0 1 57.02362 423.0236 cm Q q -1 0 0 1 57.02362 423.0236 cm +1 0 0 1 57.02362 375.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -6106,36 +6106,30 @@ Q Q Q q -1 0 0 1 57.02362 405.0236 cm +1 0 0 1 57.02362 357.0236 cm Q q -1 0 0 1 57.02362 327.0236 cm +1 0 0 1 57.02362 279.0236 cm q BT 1 0 0 1 0 62 Tm 5.961223 Tw 12 TL /F3 10 Tf 0 0 0 rg (Precise-type dispatch was the fix.) Tj /F1 10 Tf ( Cell 4 was crashing at first GC until we replaced the) Tj T* 0 Tw 1.538941 Tw (conservative-scan-plus-sentinel-checks walker with a precise one. Every heap block's 8-byte header now) Tj T* 0 Tw 3.27789 Tw (carries an explicit type byte at bits 8\22615 \(see \2476.6.5 below for the redesign\), so ) Tj /F5 10 Tf (gc_mark_drain) Tj /F1 10 Tf (,) Tj T* 0 Tw .88989 Tw /F5 10 Tf (gc_mark_env) Tj /F1 10 Tf (, and the arena-escape scan dispatch on the type byte instead of guessing from block size.) Tj T* 0 Tw 1.226147 Tw (This eliminated the entire class of "24-byte env vs string" / "40-byte vector vs string" type-confusion bugs) Tj T* 0 Tw (we'd been patching one-by-one.) Tj T* ET Q Q q -1 0 0 1 57.02362 285.0236 cm +1 0 0 1 57.02362 237.0236 cm q BT 1 0 0 1 0 26 Tm .666772 Tw 12 TL /F3 10 Tf 0 0 0 rg (Honest read.) Tj /F1 10 Tf ( The GC build now succeeds at the "GC instead of snapshots" use case. ) Tj /F5 10 Tf (heap-snapshot) Tj /F1 10 Tf ( +) Tj T* 0 Tw .132362 Tw /F5 10 Tf (heap-restore) Tj /F1 10 Tf ( remain the idiomatic production pattern \(they're cheaper per-request and portable across all) Tj T* 0 Tw (tiers\), but the GC is finally a correct fallback for code that doesn't manage arenas explicitly.) Tj T* ET Q Q q -1 0 0 1 57.02362 219.0236 cm +1 0 0 1 57.02362 159.0236 cm q -BT 1 0 0 1 0 50 Tm .974609 Tw 12 TL /F3 10 Tf 0 0 0 rg (Soak result.) Tj /F1 10 Tf ( At 20,000 HTTP requests \327 16 concurrent clients, the GC build serves ~450 req/s with peak) Tj T* 0 Tw .635702 Tw (RSS of 1,084 KB \227 one heap chunk, steady state. 972 KB of growth represents the heap filling up exactly) Tj T* 0 Tw .734556 Tw (once after which the collector keeps reusing reclaimed space. This is the production validation we needed:) Tj T* 0 Tw .602844 Tw (naive mark-sweep is a correct, if not optimal, allocator for long-running asm servers that don't want to think) Tj T* 0 Tw (about arena discipline.) Tj T* ET +BT 1 0 0 1 0 62 Tm .974609 Tw 12 TL /F3 10 Tf 0 0 0 rg (Soak result.) Tj /F1 10 Tf ( At 50,000 HTTP requests \327 16 concurrent clients, the GC build serves ~610 req/s with peak) Tj T* 0 Tw .635702 Tw (RSS of 1,092 KB \227 one heap chunk, steady state. 852 KB of growth represents the heap filling up exactly) Tj T* 0 Tw 1.068556 Tw (once, after which the collector cycles through reclaimed space indefinitely. Throughput is within 4% of the) Tj T* 0 Tw 1.959104 Tw (no-GC bump-only configuration on idiomatic snapshot-based code, and within 3% of the leaking no-GC) Tj T* 0 Tw 2.864029 Tw (baseline on the no-snapshot configuration. Naive mark-sweep is now a production-grade allocator for) Tj T* 0 Tw (long-running asm servers that don't want to think about arena discipline.) Tj T* ET Q Q q -1 0 0 1 57.02362 141.0236 cm +1 0 0 1 57.02362 81.02362 cm q -BT 1 0 0 1 0 62 Tm .006147 Tw 12 TL /F1 10 Tf 0 0 0 rg (Remaining rough edges: at larger scales \(50k+ requests with 512 MB ) Tj /F5 10 Tf (ulimit) Tj ( ) Tj (-v) Tj /F1 10 Tf ( and the bump-only no-GC) Tj T* 0 Tw .22135 Tw (case saturating the cap right before cell 4 starts\) we've seen cell 4 die at server startup; this appears to be a) Tj T* 0 Tw .776147 Tw (process-environment issue rather than a GC bug, but we don't have a clean explanation yet. The hash-set) Tj T* 0 Tw 4.063453 Tw (benchmark on the GC build under the ~1 MB-per-iteration scale also still surfaces an occasional) Tj T* 0 Tw 1.755223 Tw (unbound-variable error pointing to a root-scan edge case the precise-type fix didn't fully close. Both are) Tj T* 0 Tw (tracked as follow-ups.) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 111.0236 cm -q -BT 1 0 0 1 0 14 Tm 91.99278 Tw 12 TL /F3 10 Tf 0 0 0 rg (Reproduce:) Tj /F1 10 Tf ( ) Tj /F5 10 Tf (make) Tj ( ) Tj (bench-gc-http) Tj /F1 10 Tf (. Tuning:) Tj T* 0 Tw /F5 10 Tf (REQUESTS=10000) Tj ( ) Tj (CONCURRENCY=16) Tj ( ) Tj (VCAP=524288) Tj ( ) Tj (bash) Tj ( ) Tj (tests/bench-gc-http.sh) Tj /F1 10 Tf (.) Tj T* ET +BT 1 0 0 1 0 62 Tm 1.51589 Tw 12 TL /F3 10 Tf 0 0 0 rg (Root-cause fix that made this work.) Tj /F1 10 Tf ( The earlier residual crashes \(hash-set bench under the GC build,) Tj T* 0 Tw -0.094803 Tw (arena bench, memory bench all surfacing ) Tj /F5 10 Tf (unbound) Tj ( ) Tj (variable) Tj /F1 10 Tf ( errors\) traced to a single bug in how the type) Tj T* 0 Tw .943022 Tw (byte was being set on reused free-list blocks. The patching was using ) Tj /F5 10 Tf (orq) Tj ( ) Tj ($\(HT_X) Tj ( ) Tj (<) Tj (<) Tj ( ) Tj (8\),) Tj ( ) Tj (-8\(%rax\)) Tj /F1 10 Tf T* 0 Tw .347417 Tw (which MERGES bits \227 if a block was previously a vector \(type 5, binary ) Tj /F5 10 Tf (101) Tj /F1 10 Tf (\) and got re-allocated as a pair) Tj T* 0 Tw .774908 Tw (\(type 1, binary ) Tj /F5 10 Tf (001) Tj /F1 10 Tf (\), the resulting merged type byte was still ) Tj /F5 10 Tf (101) Tj /F1 10 Tf ( \(still vector\). The walker then treated the) Tj T* 0 Tw 2.153071 Tw (pair as a vector, read its ) Tj /F5 10 Tf (length) Tj /F1 10 Tf ( from the header's size field, and walked off the block end. Fix: use) Tj T* 0 Tw ET Q Q @@ -6143,31 +6137,43 @@ endstream endobj 147 0 obj << -/Length 8922 +/Length 8970 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 753.0236 cm +1 0 0 1 57.02362 741.0236 cm +q +BT 1 0 0 1 0 14 Tm 1.249882 Tw 12 TL /F5 10 Tf 0 0 0 rg (movb) Tj ( ) Tj ($HT_X,) Tj ( ) Tj (-7\(%rax\)) Tj /F1 10 Tf ( to OVERWRITE the byte instead of OR'ing. One-instruction change at 18 call) Tj T* 0 Tw (sites, and every previously-residual crash went away on the first rerun.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 711.0236 cm +q +BT 1 0 0 1 0 14 Tm 91.99278 Tw 12 TL /F3 10 Tf 0 0 0 rg (Reproduce:) Tj /F1 10 Tf ( ) Tj /F5 10 Tf (make) Tj ( ) Tj (bench-gc-http) Tj /F1 10 Tf (. Tuning:) Tj T* 0 Tw /F5 10 Tf (REQUESTS=10000) Tj ( ) Tj (CONCURRENCY=16) Tj ( ) Tj (VCAP=524288) Tj ( ) Tj (bash) Tj ( ) Tj (tests/bench-gc-http.sh) Tj /F1 10 Tf (.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 687.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (6.6.5 Precise Block Typing: Killing a Class of Bugs) Tj T* ET Q Q q -1 0 0 1 57.02362 675.0236 cm +1 0 0 1 57.02362 609.0236 cm q BT 1 0 0 1 0 62 Tm .088797 Tw 12 TL /F1 10 Tf 0 0 0 rg (Earlier versions of the meta-GC walkers inferred block type from ) Tj /F4 10 Tf (size) Tj /F1 10 Tf ( alone. A 24-byte block could be an env) Tj T* 0 Tw 1.498138 Tw (node, a closure, or a 16-character string; a 40-byte block could be a 4-element vector or a 25-character) Tj T* 0 Tw .485197 Tw (string. The walkers tried to guess and guessed wrong under the conservative stack scan \227 any stack word) Tj T* 0 Tw .905522 Tw (whose low 3 bits happened to match ) Tj /F5 10 Tf (TAG_SYM) Tj /F1 10 Tf ( or ) Tj /F5 10 Tf (7) Tj /F1 10 Tf ( \(vector-family\) would be dereferenced, its block's size) Tj T* 0 Tw 1.69589 Tw (read from the header, and the walker would interpret subsequent payload bytes as tagged child values.) Tj T* 0 Tw (Strings-as-vectors reading 200 bytes past their end was the canonical failure.) Tj T* ET Q Q q -1 0 0 1 57.02362 657.0236 cm +1 0 0 1 57.02362 591.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (We fixed this by adding an explicit type byte to every heap block's header:) Tj T* ET Q Q q -1 0 0 1 57.02362 616.6236 cm +1 0 0 1 57.02362 550.6236 cm q q 1 0 0 1 0 0 cm @@ -6188,40 +6194,40 @@ Q Q Q q -1 0 0 1 57.02362 560.6236 cm +1 0 0 1 57.02362 494.6236 cm q BT 1 0 0 1 0 38 Tm 5.818335 Tw 12 TL /F1 10 Tf 0 0 0 rg (Type constants \() Tj /F5 10 Tf (HT_PAIR) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (HT_CLOSURE) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (HT_STRING) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (HT_SYMBOL) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (HT_VECTOR) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (HT_HASHTABLE) Tj /F1 10 Tf (,) Tj T* 0 Tw .948196 Tw /F5 10 Tf (HT_HASHSET) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (HT_ENVNODE) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (HT_CHAINNODE) Tj /F1 10 Tf (, ) Tj /F5 10 Tf (HT_PADDING) Tj /F1 10 Tf (\) are set at every ) Tj /F5 10 Tf (heap_alloc) Tj /F1 10 Tf ( call site in the) Tj T* 0 Tw .427686 Tw (GC build. Every walker \227 mark, escape-scan, sweep \227 now dispatches on the type byte instead of size. A) Tj T* 0 Tw (string can never be walked as a vector; an env node can never be confused with a closure.) Tj T* ET Q Q q -1 0 0 1 57.02362 506.6236 cm +1 0 0 1 57.02362 440.6236 cm q BT 1 0 0 1 0 38 Tm .051917 Tw 12 TL /F1 10 Tf 0 0 0 rg (Cost: one extra ) Tj /F5 10 Tf (orq) Tj /F1 10 Tf ( at each of ~15 allocation sites \(a few nanoseconds per call\) and 16 bits of header space) Tj T* 0 Tw 1.318726 Tw (per block \(negligible given minimum block size is 16 payload bytes + 8 header bytes\). Benefit: the entire) Tj T* 0 Tw .669353 Tw ("conservative scan misidentifies X as Y" class of bugs goes away. Cell 4 of \2476.6.4 flipped from "crashes at) Tj T* 0 Tw (first GC" to "working correctly" when this landed.) Tj T* ET Q Q q -1 0 0 1 57.02362 464.6236 cm +1 0 0 1 57.02362 398.6236 cm q BT 1 0 0 1 0 26 Tm .608647 Tw 12 TL /F1 10 Tf 0 0 0 rg (The precise-type change also simplified the walkers: the special-case "is the first word -1 \(hash-table\) or -2) Tj T* 0 Tw .998453 Tw (\(hash-set\) or a small positive number \(vector length\)" dispatch in ) Tj /F5 10 Tf (gc_mark_drain) Tj /F1 10 Tf ( collapsed into a single) Tj T* 0 Tw /F5 10 Tf (cmp) Tj /F1 10 Tf ( on the type byte. ~50 lines of heuristic-guessing code deleted.) Tj T* ET Q Q q -1 0 0 1 57.02362 433.4236 cm +1 0 0 1 57.02362 367.4236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (7. Portal: Feedback Across Time) Tj T* ET Q Q q -1 0 0 1 57.02362 389.4236 cm +1 0 0 1 57.02362 323.4236 cm q BT 1 0 0 1 0 26 Tm .17989 Tw 12 TL /F1 10 Tf 0 0 0 rg (A continuation is feedback within a process. A portal is feedback across processes. Same primitive, different) Tj T* 0 Tw 1.06631 Tw (scope: capture machine state, serialize it, reload it elsewhere, resume. Lumbda ships three portal formats) Tj T* 0 Tw (with different tradeoffs & constituencies.) Tj T* ET Q Q q -1 0 0 1 57.02362 383.4236 cm +1 0 0 1 57.02362 317.4236 cm Q q -1 0 0 1 57.02362 287.4236 cm +1 0 0 1 57.02362 221.4236 cm q 1 1 1 rg n 0 96 481.2283 -18 re f* @@ -6424,29 +6430,29 @@ Q Q Q q -1 0 0 1 57.02362 287.4236 cm +1 0 0 1 57.02362 221.4236 cm Q q -1 0 0 1 57.02362 257.4236 cm +1 0 0 1 57.02362 191.4236 cm q 0 0 0 rg BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .49713 Tw (Times measured on a 4-binding workload \(int + list + string + fib\(30\) result\) excluding process startup. "k" =) Tj T* 0 Tw (continuation.) Tj T* ET Q Q q -1 0 0 1 57.02362 231.4236 cm +1 0 0 1 57.02362 165.4236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.1 S-Expression Portal \227 the Portable One) Tj T* ET Q Q q -1 0 0 1 57.02362 213.4236 cm +1 0 0 1 57.02362 147.4236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The most boring format is the most portable. An S-expression portal is a sequence of ) Tj /F5 10 Tf (define) Tj /F1 10 Tf ( forms:) Tj T* ET Q Q q -1 0 0 1 57.02362 144.2236 cm +1 0 0 1 57.02362 78.22362 cm q q 1 0 0 1 0 0 cm @@ -6466,51 +6472,45 @@ Q Q Q Q -q -1 0 0 1 57.02362 112.2236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .550522 Tw (Every Scheme implementation in the world can already read this. No schema, no decoder, no version field.) Tj T* 0 Tw (The file is a Scheme program; loading it is evaluating it.) Tj T* ET -Q -Q -q -1 0 0 1 57.02362 82.22362 cm -q -BT 1 0 0 1 0 14 Tm .702256 Tw 12 TL /F3 10 Tf 0 0 0 rg (The key insight: the language IS the interchange format.) Tj /F1 10 Tf ( We did not design this. R. Kent Dybvig didn't.) Tj T* 0 Tw 1.188726 Tw (John McCarthy didn't. It is a structural consequence of homoiconicity: if the syntax of the language is the) Tj T* 0 Tw ET -Q -Q endstream endobj 148 0 obj << -/Length 10433 +/Length 10633 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q 1 0 0 1 57.02362 741.0236 cm q -BT 1 0 0 1 0 14 Tm 5.458196 Tw 12 TL /F1 10 Tf 0 0 0 rg (syntax of its data structures, then data serialization is language serialization. Portability across) Tj T* 0 Tw (implementations is free \227 it arrives with the parser.) Tj T* ET +0 0 0 rg +BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .550522 Tw (Every Scheme implementation in the world can already read this. No schema, no decoder, no version field.) Tj T* 0 Tw (The file is a Scheme program; loading it is evaluating it.) Tj T* ET Q Q q -1 0 0 1 57.02362 699.0236 cm +1 0 0 1 57.02362 687.0236 cm +q +BT 1 0 0 1 0 38 Tm .702256 Tw 12 TL /F3 10 Tf 0 0 0 rg (The key insight: the language IS the interchange format.) Tj /F1 10 Tf ( We did not design this. R. Kent Dybvig didn't.) Tj T* 0 Tw 1.188726 Tw (John McCarthy didn't. It is a structural consequence of homoiconicity: if the syntax of the language is the) Tj T* 0 Tw 5.458196 Tw (syntax of its data structures, then data serialization is language serialization. Portability across) Tj T* 0 Tw (implementations is free \227 it arrives with the parser.) Tj T* ET +Q +Q +q +1 0 0 1 57.02362 645.0236 cm q BT 1 0 0 1 0 26 Tm .511772 Tw 12 TL /F1 10 Tf 0 0 0 rg (Producer side: assemble the file with ) Tj /F5 10 Tf (\(display) Tj ( ) Tj (...\)) Tj /F1 10 Tf ( & ) Tj /F5 10 Tf (\(write) Tj ( ) Tj (...\)) Tj /F1 10 Tf ( to an output port. Consumer side:) Tj T* 0 Tw 3.693453 Tw /F5 10 Tf (\(load) Tj ( ) Tj ("file.sexp"\)) Tj /F1 10 Tf (. Both sides exist in every implementation, giving us a 3\3273 matrix of valid) Tj T* 0 Tw (exchanges.) Tj T* ET Q Q q -1 0 0 1 57.02362 673.0236 cm +1 0 0 1 57.02362 619.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.2 Cross-Implementation Exchange Matrix) Tj T* ET Q Q q -1 0 0 1 57.02362 661.0236 cm +1 0 0 1 57.02362 607.0236 cm Q q -1 0 0 1 57.02362 553.0236 cm +1 0 0 1 57.02362 499.0236 cm q 1 1 1 rg n 0 108 481.2283 -18 re f* @@ -6732,111 +6732,35 @@ Q Q Q q -1 0 0 1 57.02362 553.0236 cm +1 0 0 1 57.02362 499.0236 cm Q q -1 0 0 1 57.02362 511.0236 cm +1 0 0 1 57.02362 457.0236 cm q BT 1 0 0 1 0 26 Tm .856835 Tw 12 TL /F1 10 Tf 0 0 0 rg (16 of 16. Verified by ) Tj /F5 10 Tf (tests/portal-cross-test.sh) Tj /F1 10 Tf ( \() Tj /F3 10 Tf (make bench-portal-cross) Tj /F1 10 Tf (\). The ) Tj /F5 10 Tf (asm-gc) Tj /F1 10 Tf ( column) Tj T* 0 Tw .316962 Tw (expands the matrix from 9 to 16 cells \227 the GC build's ) Tj /F5 10 Tf (portal-save) Tj /F1 10 Tf ( emits the same S-expression format,) Tj T* 0 Tw (so it exchanges with every other tier \(\2477.4.1 below\).) Tj T* ET Q Q q -1 0 0 1 57.02362 469.0236 cm +1 0 0 1 57.02362 415.0236 cm q 0 0 0 rg BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .526019 Tw (This matters because it defeats the "version lock-in" trap. If the JSON portal were the only option, a Python) Tj T* 0 Tw 2.478453 Tw (3.15 producer could emit structures a C consumer couldn't parse. With S-expression portals, the only) Tj T* 0 Tw (dependency is a parser that handles the subset of forms in the file. Every implementation already has one.) Tj T* ET Q Q q -1 0 0 1 57.02362 443.0236 cm +1 0 0 1 57.02362 389.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.3 JSON Portal \227 Graph-Aware, Continuation-Preserving) Tj T* ET Q Q q -1 0 0 1 57.02362 413.0236 cm +1 0 0 1 57.02362 359.0236 cm q BT 1 0 0 1 0 14 Tm .373453 Tw 12 TL /F1 10 Tf 0 0 0 rg (When you need to preserve shared references, cycles, closures, or a ) Tj /F4 10 Tf (live continuation) Tj /F1 10 Tf (, S-expressions aren't) Tj T* 0 Tw (enough. The JSON portal \(Python & C\) performs graph-aware serialization:) Tj T* ET Q Q q -1 0 0 1 57.02362 407.0236 cm -Q -q -1 0 0 1 57.02362 407.0236 cm -Q -q -1 0 0 1 57.02362 395.0236 cm -q -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Tracks ) Tj /F5 10 Tf (id\(obj\)) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (ref_id) Tj /F1 10 Tf ( for object identity \(handles shared refs & cycles\)) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 389.0236 cm -Q -q -1 0 0 1 57.02362 377.0236 cm -q -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Serializes environments as chains of binding dictionaries with parent pointers) Tj T* ET -Q -Q -q -Q -Q -Q -q -1 0 0 1 57.02362 371.0236 cm -Q -q -1 0 0 1 57.02362 359.0236 cm -q -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 6 -3 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET -Q -Q -q -1 0 0 1 23 -3 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Serializes compiled procedures as ) Tj /F5 10 Tf (CodeObj) Tj /F1 10 Tf ( + captured environment) Tj T* ET -Q -Q -q -Q -Q +1 0 0 1 57.02362 353.0236 cm Q q 1 0 0 1 57.02362 353.0236 cm @@ -6856,8 +6780,7 @@ Q q 1 0 0 1 23 -3 cm q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Serializes continuations as the full frame stack + machine state) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Tracks ) Tj /F5 10 Tf (id\(obj\)) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (ref_id) Tj /F1 10 Tf ( for object identity \(handles shared refs & cycles\)) Tj T* ET Q Q q @@ -6883,6 +6806,83 @@ q 1 0 0 1 23 -3 cm q 0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Serializes environments as chains of binding dictionaries with parent pointers) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 317.0236 cm +Q +q +1 0 0 1 57.02362 305.0236 cm +q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 -3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET +Q +Q +q +1 0 0 1 23 -3 cm +q +BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Serializes compiled procedures as ) Tj /F5 10 Tf (CodeObj) Tj /F1 10 Tf ( + captured environment) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 299.0236 cm +Q +q +1 0 0 1 57.02362 287.0236 cm +q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 -3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET +Q +Q +q +1 0 0 1 23 -3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Serializes continuations as the full frame stack + machine state) Tj T* ET +Q +Q +q +Q +Q +Q +q +1 0 0 1 57.02362 281.0236 cm +Q +q +1 0 0 1 57.02362 269.0236 cm +q +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q +1 0 0 1 6 -3 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F5 10 Tf 12 TL 8 0 Td (\177) Tj T* -8 0 Td ET +Q +Q +q +1 0 0 1 23 -3 cm +q +0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Skips builtins \(reconstructed from the prelude on resume\)) Tj T* ET Q Q @@ -6891,22 +6891,22 @@ Q Q Q q -1 0 0 1 57.02362 305.0236 cm +1 0 0 1 57.02362 251.0236 cm Q q -1 0 0 1 57.02362 275.0236 cm +1 0 0 1 57.02362 221.0236 cm q BT 1 0 0 1 0 14 Tm 2.974168 Tw 12 TL /F1 10 Tf 0 0 0 rg (Deserialization is two-pass: shell pass creates empty object shells & assigns reference IDs, fill pass) Tj T* 0 Tw (populates pointers & values. This handles the closure-that-captures-itself pattern cleanly.) Tj T* ET Q Q q -1 0 0 1 57.02362 233.0236 cm +1 0 0 1 57.02362 179.0236 cm q BT 1 0 0 1 0 26 Tm 4.719816 Tw 12 TL /F1 10 Tf 0 0 0 rg (During VM execution, ) Tj /F5 10 Tf (portal-checkpoint!) Tj /F1 10 Tf ( triggers at ) Tj /F5 10 Tf (OP_JUMP) Tj /F1 10 Tf ( & ) Tj /F5 10 Tf (OP_TAIL_CALL) Tj /F1 10 Tf ( instructions,) Tj T* 0 Tw 1.439168 Tw (capturing the current continuation, serializing it to a ) Tj /F5 10 Tf (.portal) Tj /F1 10 Tf ( file, & continuing. Resumption restores the) Tj T* 0 Tw (saved state & continues execution from the exact instruction where the checkpoint occurred.) Tj T* ET Q Q q -1 0 0 1 57.02362 202.2236 cm +1 0 0 1 57.02362 148.2236 cm q q 1 0 0 1 0 0 cm @@ -6927,56 +6927,35 @@ Q Q Q q -1 0 0 1 57.02362 182.2236 cm +1 0 0 1 57.02362 128.2236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The computation does not need to restart from the beginning.) Tj T* ET Q Q q -1 0 0 1 57.02362 156.2236 cm +1 0 0 1 57.02362 102.2236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.4 Binary Heap Dump \227 the Fast One) Tj T* ET Q Q q -1 0 0 1 57.02362 126.2236 cm +1 0 0 1 57.02362 72.22362 cm q BT 1 0 0 1 0 14 Tm .625197 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (no-GC) Tj /F1 10 Tf ( asm implementation ships a direct-dump portal: write the raw heap bytes, the ) Tj /F5 10 Tf (r14) Tj /F1 10 Tf ( \(env\) & ) Tj /F5 10 Tf (r15) Tj /F1 10 Tf T* 0 Tw (\(bump pointer\) registers, the heap base address, & a magic header. No parsing, no encoding.) Tj T* ET Q Q -q -1 0 0 1 57.02362 66.62362 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .960784 rg -n -6 -6 480.0283 50.4 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 30.4 Tm /F5 8 Tf 9.6 TL (bi_portal_save:) Tj T* ( # Magic | heap_size | heap_base | r14 | r15 | reserved | heap_bytes) Tj T* T* (bi_portal_resume:) Tj T* ET -Q -Q -Q -Q -Q endstream endobj 149 0 obj << -/Length 8524 +/Length 8326 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 713.4236 cm +1 0 0 1 57.02362 675.0236 cm q q 1 0 0 1 0 0 cm @@ -6986,42 +6965,42 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .960784 rg -n -6 -6 480.0283 50.4 re B* +n -6 -6 480.0283 88.8 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 30.4 Tm /F5 8 Tf 9.6 TL ( # Read 48-byte header, verify magic + sanity,) Tj T* ( # mmap MAP_FIXED at saved heap_base so pointers stay valid,) Tj T* ( # read heap bytes into fixed-address region,) Tj T* ( # restore r14/r15.) Tj T* ET +BT 1 0 0 1 0 68.8 Tm /F5 8 Tf 9.6 TL (bi_portal_save:) Tj T* ( # Magic | heap_size | heap_base | r14 | r15 | reserved | heap_bytes) Tj T* T* (bi_portal_resume:) Tj T* ( # Read 48-byte header, verify magic + sanity,) Tj T* ( # mmap MAP_FIXED at saved heap_base so pointers stay valid,) Tj T* ( # read heap bytes into fixed-address region,) Tj T* ( # restore r14/r15.) Tj T* ET Q Q Q Q Q q -1 0 0 1 57.02362 669.4236 cm +1 0 0 1 57.02362 631.0236 cm q BT 1 0 0 1 0 26 Tm 1.387739 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sub-millisecond save & resume. The MAP_FIXED trick is why it works across processes: because every) Tj T* 0 Tw 1.474556 Tw (pointer inside the heap is an absolute address, resuming at a different address would require relocation.) Tj T* 0 Tw (Mapping at the same address keeps pointers live.) Tj T* ET Q Q q -1 0 0 1 57.02362 615.4236 cm +1 0 0 1 57.02362 577.0236 cm q BT 1 0 0 1 0 38 Tm 1.067739 Tw 12 TL /F1 10 Tf 0 0 0 rg (Constraints: same architecture, same binary layout, same process model. An asm binary portal written on) Tj T* 0 Tw .022545 Tw (one box resumes on another x86_64 Linux box running the same asm binary. It does not resume on a rebuilt) Tj T* 0 Tw 1.065522 Tw (binary \227 the BSS-resident symbol table ) Tj /F5 10 Tf (sym_table) Tj /F1 10 Tf ( is not in the heap dump, so interned symbols would) Tj T* 0 Tw (need to be reinterned. That's the price of trivial serialization.) Tj T* ET Q Q q -1 0 0 1 57.02362 591.4236 cm +1 0 0 1 57.02362 553.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.4.1 The GC Build Uses S-Expressions) Tj T* ET Q Q q -1 0 0 1 57.02362 525.4236 cm +1 0 0 1 57.02362 487.0236 cm q BT 1 0 0 1 0 50 Tm 1.037917 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F3 10 Tf (GC) Tj /F1 10 Tf ( asm build can't use the binary heap dump because the heap is a linked list of chunks with typed) Tj T* 0 Tw .619897 Tw (block headers and a free list \227 raw-byte serialization would lose the structure. Rather than inventing portal) Tj T* 0 Tw 1.255596 Tw (v2 with chunk tables and pointer-relocation metadata, the GC build's ) Tj /F5 10 Tf (portal-save) Tj /F1 10 Tf ( walks the global env) Tj T* 0 Tw .200596 Tw (chain from ) Tj /F5 10 Tf (%r14) Tj /F1 10 Tf ( and emits one ) Tj /F5 10 Tf (\(define) Tj ( ) Tj (<) Tj (sym) Tj (>) Tj ( ) Tj (\(quote) Tj ( ) Tj (<) Tj (val) Tj (>) Tj (\)\)) Tj /F1 10 Tf ( form per binding. ) Tj /F5 10 Tf (portal-resume) Tj /F1 10 Tf ( is) Tj T* 0 Tw (equivalent to ) Tj /F5 10 Tf (\(load) Tj ( ) Tj (") Tj (<) Tj (filename) Tj (>) Tj ("\)) Tj /F1 10 Tf ( \227 read every form and eval it.) Tj T* ET Q Q q -1 0 0 1 57.02362 465.8236 cm +1 0 0 1 57.02362 427.4236 cm q q 1 0 0 1 0 0 cm @@ -7042,69 +7021,67 @@ Q Q Q q -1 0 0 1 57.02362 421.8236 cm +1 0 0 1 57.02362 383.4236 cm q 0 0 0 rg BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 1.557565 Tw (Every non-builtin, non-closure binding round-trips. Closures and builtins are skipped \227 closures can't be) Tj T* 0 Tw .869223 Tw (faithfully re-read from their printed form, builtins get re-created from the target interpreter's prelude. This is) Tj T* 0 Tw (the same treatment the JSON portal already gives to builtins \(\2477.3\).) Tj T* ET Q Q q -1 0 0 1 57.02362 355.8236 cm +1 0 0 1 57.02362 317.4236 cm q BT 1 0 0 1 0 50 Tm .145197 Tw 12 TL /F3 10 Tf 0 0 0 rg (Trade-off.) Tj /F1 10 Tf ( The GC build's portal is slower than the binary dump \(walks each binding through the printer\) and) Tj T* 0 Tw 1.91989 Tw (stricter about what it can preserve \(data only, no closures or continuations\). In exchange: ) Tj /F3 10 Tf (every portal) Tj T* 0 Tw 2.369223 Tw (produced by the GC build resumes on every other tier) Tj /F1 10 Tf (, with no MAP_FIXED trick, no architecture) Tj T* 0 Tw -0.128333 Tw (constraint, no "same binary" requirement. A GC-asm producer can hand a portal to a Python consumer \227 we) Tj T* 0 Tw (added the asm-gc column to the \2477.2 matrix and all 16 cells are green.) Tj T* ET Q Q q -1 0 0 1 57.02362 329.8236 cm +1 0 0 1 57.02362 291.4236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.5 Cross-Process Benchmarks) Tj T* ET Q Q q -1 0 0 1 57.02362 287.8236 cm +1 0 0 1 57.02362 249.4236 cm q BT 1 0 0 1 0 26 Tm 2.703647 Tw 12 TL /F1 10 Tf 0 0 0 rg (Producer process A saves state to a file; consumer process B starts fresh, loads the file, continues.) Tj T* 0 Tw 10.67759 Tw (Wall-clock time for both processes end-to-end, 50 iterations, same-laptop. ) Tj /F3 10 Tf (Reproduce:) Tj /F1 10 Tf T* 0 Tw /F5 10 Tf (make) Tj ( ) Tj (bench-portal) Tj /F1 10 Tf ( \(source: ) Tj /F5 10 Tf (tests/portal-benchmark.sh) Tj /F1 10 Tf (\).) Tj T* ET Q Q q -1 0 0 1 57.02362 281.8236 cm +1 0 0 1 57.02362 243.4236 cm Q q -1 0 0 1 57.02362 83.82362 cm +1 0 0 1 57.02362 63.42362 cm q 1 1 1 rg -n 0 198 481.2283 -18 re f* -.878431 .878431 .878431 rg n 0 180 481.2283 -18 re f* -1 1 1 rg +.878431 .878431 .878431 rg n 0 162 481.2283 -18 re f* -.878431 .878431 .878431 rg +1 1 1 rg n 0 144 481.2283 -18 re f* -1 1 1 rg +.878431 .878431 .878431 rg n 0 126 481.2283 -18 re f* -.878431 .878431 .878431 rg +1 1 1 rg n 0 108 481.2283 -18 re f* -1 1 1 rg +.878431 .878431 .878431 rg n 0 90 481.2283 -18 re f* -.878431 .878431 .878431 rg +1 1 1 rg n 0 72 481.2283 -18 re f* -1 1 1 rg -n 0 54 481.2283 -18 re f* .878431 .878431 .878431 rg -n 0 36 481.2283 -18 re f* +n 0 54 481.2283 -18 re f* 1 1 1 rg +n 0 36 481.2283 -18 re f* +.878431 .878431 .878431 rg n 0 18 481.2283 -18 re f* 0 0 0 rg BT /F3 10 Tf 12 TL ET q -1 0 0 1 6 183 cm +1 0 0 1 6 165 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 93.12904 0 Td (Pair \(producer ) Tj /F6 10 Tf 12 TL (\256) Tj /F3 10 Tf 12 TL ( consumer\)) Tj T* -93.12904 0 Td ET Q Q q -1 0 0 1 339.1581 183 cm +1 0 0 1 339.1581 165 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL 47.19513 0 Td (Time/iter) Tj T* -47.19513 0 Td ET @@ -7113,132 +7090,170 @@ Q 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 6 165 cm +1 0 0 1 6 147 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( Python \(sexp\)) Tj T* ET Q Q q -1 0 0 1 339.1581 165 cm +1 0 0 1 339.1581 147 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (260 ms) Tj T* ET Q Q q -1 0 0 1 6 147 cm +1 0 0 1 6 129 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (C ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( C \(sexp\)) Tj T* ET Q Q q -1 0 0 1 339.1581 147 cm +1 0 0 1 339.1581 129 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (6 ms) Tj T* ET Q Q q -1 0 0 1 6 129 cm +1 0 0 1 6 111 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (asm ) Tj /F6 10 Tf 12 TL (\256) Tj /F3 10 Tf 12 TL ( asm \(sexp\)) Tj T* ET Q Q q -1 0 0 1 339.1581 129 cm +1 0 0 1 339.1581 111 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (1.6 ms) Tj T* ET Q Q q -1 0 0 1 6 111 cm +1 0 0 1 6 93 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (asm ) Tj /F6 10 Tf 12 TL (\256) Tj /F3 10 Tf 12 TL ( asm \(binary portal\)) Tj T* ET Q Q q -1 0 0 1 339.1581 111 cm +1 0 0 1 339.1581 93 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (1.5 ms) Tj T* ET Q Q q -1 0 0 1 6 93 cm +1 0 0 1 6 75 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( C \(sexp\)) Tj T* ET Q Q q -1 0 0 1 339.1581 93 cm +1 0 0 1 339.1581 75 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (133 ms) Tj T* ET Q Q q -1 0 0 1 6 75 cm +1 0 0 1 6 57 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Python ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( asm \(sexp\)) Tj T* ET Q Q q -1 0 0 1 339.1581 75 cm +1 0 0 1 339.1581 57 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (145 ms) Tj T* ET Q Q q -1 0 0 1 6 57 cm +1 0 0 1 6 39 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (C ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( Python \(sexp\)) Tj T* ET Q Q q -1 0 0 1 339.1581 57 cm +1 0 0 1 339.1581 39 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (154 ms) Tj T* ET Q Q q -1 0 0 1 6 39 cm +1 0 0 1 6 21 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (C ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( asm \(sexp\)) Tj T* ET Q Q q -1 0 0 1 339.1581 39 cm +1 0 0 1 339.1581 21 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.1 ms) Tj T* ET Q Q q -1 0 0 1 6 21 cm +1 0 0 1 6 3 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (asm ) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL ( Python \(sexp\)) Tj T* ET Q Q q -1 0 0 1 339.1581 21 cm +1 0 0 1 339.1581 3 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (167 ms) Tj T* ET Q Q q +1 J +1 j +0 0 0 RG +.25 w +n 0 0 m 481.2283 0 l S +n 0 162 m 481.2283 162 l S +n 0 144 m 481.2283 144 l S +n 0 126 m 481.2283 126 l S +n 0 108 m 481.2283 108 l S +n 0 90 m 481.2283 90 l S +n 0 72 m 481.2283 72 l S +n 0 54 m 481.2283 54 l S +n 0 36 m 481.2283 36 l S +n 0 18 m 481.2283 18 l S +n 333.1581 0 m 333.1581 180 l S +n 0 180 m 481.2283 180 l S +n 0 0 m 0 180 l S +n 481.2283 0 m 481.2283 180 l S +Q +Q +Q + +endstream +endobj +150 0 obj +<< +/Length 8648 +>> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +q +1 0 0 1 57.02362 747.0236 cm +q +1 1 1 rg +n 0 18 481.2283 -18 re f* +0 0 0 rg +BT /F1 10 Tf 12 TL ET +q 1 0 0 1 6 3 cm q 0 0 0 rg @@ -7257,60 +7272,41 @@ q 1 j 0 0 0 RG .25 w -n 0 180 m 481.2283 180 l S -n 0 162 m 481.2283 162 l S -n 0 144 m 481.2283 144 l S -n 0 126 m 481.2283 126 l S -n 0 108 m 481.2283 108 l S -n 0 90 m 481.2283 90 l S -n 0 72 m 481.2283 72 l S -n 0 54 m 481.2283 54 l S -n 0 36 m 481.2283 36 l S n 0 18 m 481.2283 18 l S -n 333.1581 0 m 333.1581 198 l S -n 0 198 m 481.2283 198 l S +n 333.1581 0 m 333.1581 18 l S +n 0 0 m 0 18 l S +n 481.2283 0 m 481.2283 18 l S n 0 0 m 481.2283 0 l S -n 0 0 m 0 198 l S -n 481.2283 0 m 481.2283 198 l S Q Q Q q -1 0 0 1 57.02362 83.82362 cm +1 0 0 1 57.02362 747.0236 cm Q - -endstream -endobj -150 0 obj -<< -/Length 8126 ->> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 57.02362 729.0236 cm +1 0 0 1 57.02362 705.0236 cm q BT 1 0 0 1 0 26 Tm .698334 Tw 12 TL /F1 10 Tf 0 0 0 rg (The asm) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL (asm cross-process is ~160\327 faster than Python) Tj /F6 10 Tf 12 TL (\256) Tj /F1 10 Tf 12 TL (Python. The binary & S-expression portals are) Tj T* 0 Tw .812256 Tw (within 10% of each other on this workload \227 the bottleneck is process startup, not serialization. For larger) Tj T* 0 Tw (heaps the binary format pulls further ahead; for portability, S-expression always wins.) Tj T* ET Q Q q -1 0 0 1 57.02362 703.0236 cm +1 0 0 1 57.02362 679.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.6 Mismatch Cases: Graceful Degradation) Tj T* ET Q Q q -1 0 0 1 57.02362 685.0236 cm +1 0 0 1 57.02362 661.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (A usable persistence layer fails well. What happens when the consumer meets unexpected input?) Tj T* ET Q Q q -1 0 0 1 57.02362 679.0236 cm +1 0 0 1 57.02362 655.0236 cm Q q -1 0 0 1 57.02362 529.0236 cm +1 0 0 1 57.02362 505.0236 cm q 1 1 1 rg n 0 150 481.2283 -18 re f* @@ -7543,22 +7539,22 @@ Q Q Q q -1 0 0 1 57.02362 529.0236 cm +1 0 0 1 57.02362 505.0236 cm Q q -1 0 0 1 57.02362 463.0236 cm +1 0 0 1 57.02362 439.0236 cm q BT 1 0 0 1 0 50 Tm 1.476556 Tw 12 TL /F1 10 Tf 0 0 0 rg (All defects surfaced & fixed during benchmark development: an asm segfault on ) Tj /F5 10 Tf (\(define) Tj ( ) Tj (x\)) Tj /F1 10 Tf ( without a) Tj T* 0 Tw 1.838453 Tw (value \(now binds to ) Tj /F5 10 Tf (VOID) Tj /F1 10 Tf (\), an asm portal-resume that accepted short headers \(now verifies ) Tj /F5 10 Tf (sys_read) Tj /F1 10 Tf T* 0 Tw 1.204272 Tw (returned a full 48 bytes & sanity-checks heap metadata\), a Python ) Tj /F5 10 Tf (file) Tj ( ) Tj (not) Tj ( ) Tj (found) Tj /F1 10 Tf ( error reporting the) Tj T* 0 Tw 1.304862 Tw (outer script path instead of the inner missing file \(now uses ) Tj /F5 10 Tf (FileNotFoundError.filename) Tj /F1 10 Tf (\). Graceful) Tj T* 0 Tw (degradation is not free; it is tested.) Tj T* ET Q Q q -1 0 0 1 57.02362 437.0236 cm +1 0 0 1 57.02362 413.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (7.7 Use Case: Distributed Primality Testing) Tj T* ET Q Q q -1 0 0 1 57.02362 310.2236 cm +1 0 0 1 57.02362 286.2236 cm q q 1 0 0 1 0 0 cm @@ -7578,38 +7574,38 @@ Q Q Q q -1 0 0 1 57.02362 266.2236 cm +1 0 0 1 57.02362 242.2236 cm q BT 1 0 0 1 0 26 Tm 1.105522 Tw 12 TL /F1 10 Tf 0 0 0 rg (Machine A starts the computation. Every 10,000 iterations, it writes a checkpoint. Machine B picks up the) Tj T* 0 Tw 2.790642 Tw /F5 10 Tf (.portal) Tj /F1 10 Tf ( file & continues from the last checkpoint. The computation migrates without either machine) Tj T* 0 Tw (needing to know about the other. Feedback \227 the continuation \227 carries the entire execution context.) Tj T* ET Q Q q -1 0 0 1 57.02362 235.0236 cm +1 0 0 1 57.02362 211.0236 cm q BT 1 0 0 1 0 2.2 Tm 13.2 TL /F2 11 Tf .133333 .133333 .133333 rg (8. The EML Universality Proof) Tj T* ET Q Q q -1 0 0 1 57.02362 203.0236 cm +1 0 0 1 57.02362 179.0236 cm q BT 1 0 0 1 0 14 Tm 3.669104 Tw 12 TL /F1 10 Tf 0 0 0 rg (Lumbda ships with a mathematical proof that a single operator generates all elementary functions:) Tj T* 0 Tw /F5 10 Tf (eml\(x,) Tj ( ) Tj (y\)) Tj ( ) Tj (=) Tj ( ) Tj (exp\(x\)) Tj ( ) Tj (-) Tj ( ) Tj (ln\(y\)) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 57.02362 185.0236 cm +1 0 0 1 57.02362 161.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Reference: "All elementary functions from a single operator" \(arXiv:2603.21852v2\).) Tj T* ET Q Q q -1 0 0 1 57.02362 159.0236 cm +1 0 0 1 57.02362 135.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (8.1 The Operator) Tj T* ET Q Q q -1 0 0 1 57.02362 128.2236 cm +1 0 0 1 57.02362 104.2236 cm q q 1 0 0 1 0 0 cm @@ -7630,7 +7626,7 @@ Q Q Q q -1 0 0 1 57.02362 108.2236 cm +1 0 0 1 57.02362 84.22362 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (With this operator & the constant ) Tj /F5 10 Tf (1) Tj /F1 10 Tf (, the following derivation chain constructs every elementary function:) Tj T* ET Q @@ -12025,182 +12021,182 @@ xref 0001707049 00000 n 0001707370 00000 n 0001707578 00000 n -0001738046 00000 n -0001841524 00000 n -0001841845 00000 n -0001841956 00000 n -0001842164 00000 n -0001842278 00000 n -0001842486 00000 n -0001842694 00000 n -0001842902 00000 n -0001842986 00000 n -0001843194 00000 n -0001843402 00000 n -0001843610 00000 n -0001843818 00000 n -0001844026 00000 n -0001844234 00000 n -0001844412 00000 n -0001844639 00000 n -0001979530 00000 n -0001983794 00000 n -0002272107 00000 n -0002272428 00000 n -0002272636 00000 n -0002272844 00000 n -0002310187 00000 n -0002310459 00000 n -0002310667 00000 n -0002310858 00000 n -0002311049 00000 n -0002311283 00000 n -0002311491 00000 n -0002311665 00000 n -0002311873 00000 n -0002312107 00000 n -0002312313 00000 n -0002312485 00000 n -0002312719 00000 n -0002371695 00000 n -0002372005 00000 n -0002372325 00000 n -0002372533 00000 n -0002372641 00000 n -0002372896 00000 n -0002372971 00000 n -0002373104 00000 n -0002373214 00000 n -0002373379 00000 n -0002373574 00000 n -0002373690 00000 n -0002373808 00000 n -0002373950 00000 n -0002374150 00000 n -0002374285 00000 n -0002374434 00000 n -0002374563 00000 n -0002374733 00000 n -0002374857 00000 n -0002374988 00000 n -0002375110 00000 n +0001737659 00000 n +0001841137 00000 n +0001841458 00000 n +0001841569 00000 n +0001841777 00000 n +0001841891 00000 n +0001842099 00000 n +0001842307 00000 n +0001842515 00000 n +0001842599 00000 n +0001842807 00000 n +0001843015 00000 n +0001843223 00000 n +0001843431 00000 n +0001843639 00000 n +0001843847 00000 n +0001844025 00000 n +0001844252 00000 n +0001979143 00000 n +0001983407 00000 n +0002271720 00000 n +0002272041 00000 n +0002272249 00000 n +0002272457 00000 n +0002309800 00000 n +0002310072 00000 n +0002310280 00000 n +0002310471 00000 n +0002310662 00000 n +0002310896 00000 n +0002311104 00000 n +0002311278 00000 n +0002311486 00000 n +0002311720 00000 n +0002311926 00000 n +0002312098 00000 n +0002312332 00000 n +0002371308 00000 n +0002371618 00000 n +0002371938 00000 n +0002372146 00000 n +0002372254 00000 n +0002372509 00000 n +0002372584 00000 n +0002372717 00000 n +0002372827 00000 n +0002372992 00000 n +0002373187 00000 n +0002373303 00000 n +0002373421 00000 n +0002373563 00000 n +0002373763 00000 n +0002373898 00000 n +0002374047 00000 n +0002374176 00000 n +0002374346 00000 n +0002374470 00000 n +0002374601 00000 n +0002374723 00000 n +0002374920 00000 n +0002375037 00000 n +0002375164 00000 n 0002375307 00000 n -0002375424 00000 n -0002375551 00000 n -0002375694 00000 n -0002375860 00000 n -0002376033 00000 n -0002376211 00000 n -0002376368 00000 n -0002376520 00000 n -0002376687 00000 n -0002376852 00000 n -0002377005 00000 n -0002377192 00000 n -0002377340 00000 n -0002377497 00000 n -0002377672 00000 n -0002377869 00000 n -0002377997 00000 n -0002378143 00000 n -0002378301 00000 n -0002378448 00000 n -0002378635 00000 n -0002378756 00000 n -0002378917 00000 n -0002379059 00000 n -0002379211 00000 n -0002379365 00000 n -0002379506 00000 n -0002379644 00000 n -0002379798 00000 n -0002380000 00000 n -0002380123 00000 n -0002380262 00000 n -0002380426 00000 n -0002380599 00000 n -0002380772 00000 n -0002380919 00000 n -0002381114 00000 n -0002381273 00000 n -0002381441 00000 n -0002381576 00000 n -0002381709 00000 n -0002381854 00000 n -0002381980 00000 n -0002382108 00000 n -0002382219 00000 n -0002382515 00000 n -0002387632 00000 n -0002395716 00000 n -0002400509 00000 n -0002407438 00000 n -0002416352 00000 n -0002425599 00000 n -0002434803 00000 n -0002447820 00000 n -0002457936 00000 n -0002467302 00000 n -0002475882 00000 n -0002486832 00000 n -0002499463 00000 n -0002509455 00000 n -0002518430 00000 n -0002528917 00000 n -0002537494 00000 n -0002545673 00000 n -0002555149 00000 n -0002563954 00000 n -0002574156 00000 n -0002578903 00000 n -0002580738 00000 n -0002594194 00000 n -0002610853 00000 n -0002621361 00000 n -0002628820 00000 n -0002635494 00000 n -0002643556 00000 n -0002651492 00000 n -0002657960 00000 n -0002660116 00000 n -0002661194 00000 n -0002661598 00000 n -0002661633 00000 n -0002661668 00000 n -0002661703 00000 n -0002661738 00000 n -0002661773 00000 n -0002661808 00000 n -0002661843 00000 n -0002661878 00000 n -0002661913 00000 n -0002661949 00000 n -0002661985 00000 n -0002662021 00000 n -0002662057 00000 n -0002662093 00000 n -0002662129 00000 n -0002662165 00000 n -0002662201 00000 n -0002662237 00000 n +0002375473 00000 n +0002375646 00000 n +0002375824 00000 n +0002375981 00000 n +0002376133 00000 n +0002376300 00000 n +0002376465 00000 n +0002376618 00000 n +0002376805 00000 n +0002376953 00000 n +0002377110 00000 n +0002377285 00000 n +0002377482 00000 n +0002377610 00000 n +0002377756 00000 n +0002377914 00000 n +0002378061 00000 n +0002378248 00000 n +0002378369 00000 n +0002378530 00000 n +0002378672 00000 n +0002378824 00000 n +0002378978 00000 n +0002379119 00000 n +0002379257 00000 n +0002379411 00000 n +0002379613 00000 n +0002379736 00000 n +0002379875 00000 n +0002380039 00000 n +0002380212 00000 n +0002380385 00000 n +0002380532 00000 n +0002380727 00000 n +0002380886 00000 n +0002381054 00000 n +0002381189 00000 n +0002381322 00000 n +0002381467 00000 n +0002381593 00000 n +0002381721 00000 n +0002381832 00000 n +0002382128 00000 n +0002387245 00000 n +0002395329 00000 n +0002400122 00000 n +0002407051 00000 n +0002415965 00000 n +0002425212 00000 n +0002434416 00000 n +0002447433 00000 n +0002457549 00000 n +0002466915 00000 n +0002475491 00000 n +0002486442 00000 n +0002498945 00000 n +0002509558 00000 n +0002518581 00000 n +0002529268 00000 n +0002537647 00000 n +0002546348 00000 n +0002555824 00000 n +0002564629 00000 n +0002574831 00000 n +0002579578 00000 n +0002581413 00000 n +0002594869 00000 n +0002611528 00000 n +0002622036 00000 n +0002629495 00000 n +0002636169 00000 n +0002644231 00000 n +0002652167 00000 n +0002658635 00000 n +0002660791 00000 n +0002661869 00000 n 0002662273 00000 n -0002662309 00000 n -0002662345 00000 n -0002662381 00000 n -0002662417 00000 n -0002662453 00000 n -0002662489 00000 n -0002662525 00000 n -0002662561 00000 n -0002662597 00000 n -0002662633 00000 n -0002662669 00000 n -0002662705 00000 n -0002662741 00000 n +0002662308 00000 n +0002662343 00000 n +0002662378 00000 n +0002662413 00000 n +0002662448 00000 n +0002662483 00000 n +0002662518 00000 n +0002662553 00000 n +0002662588 00000 n +0002662624 00000 n +0002662660 00000 n +0002662696 00000 n +0002662732 00000 n +0002662768 00000 n +0002662804 00000 n +0002662840 00000 n +0002662876 00000 n +0002662912 00000 n +0002662948 00000 n +0002662984 00000 n +0002663020 00000 n +0002663056 00000 n +0002663092 00000 n +0002663128 00000 n +0002663164 00000 n +0002663200 00000 n +0002663236 00000 n +0002663272 00000 n +0002663308 00000 n +0002663344 00000 n +0002663380 00000 n +0002663416 00000 n trailer << /ID -[] +[] % ReportLab generated PDF document -- digest (opensource) /Info 69 0 R @@ -12208,5 +12204,5 @@ trailer /Size 200 >> startxref -2662777 +2663452 %%EOF diff --git a/whitepaper/uncommonlisp-whitepaper.rst b/whitepaper/uncommonlisp-whitepaper.rst index 1debe6d..018a005 100644 --- a/whitepaper/uncommonlisp-whitepaper.rst +++ b/whitepaper/uncommonlisp-whitepaper.rst @@ -495,11 +495,11 @@ Same source, same tests (137/137 pass on both). The GC build adds an 8-byte ``(s ================================== ========== ========== ============== asm build Wall time Peak RSS GC firings ================================== ========== ========== ============== - bump only (no GC) 1,097 ms 133.9 MB none - naive mark-sweep (``GC_NAIVE=1``) 1,431 ms 1.1 MB ~200 + bump only (no GC) 727 ms 133.1 MB none + naive mark-sweep (``GC_NAIVE=1``) 918 ms 1.1 MB ~200 ================================== ========== ========== ============== -**124× less memory at a ~30% throughput cost.** That is the honest GC tax at the naive end of the spectrum — the number we had been guessing at before building the control group. Every future memory-management proposal (generational, incremental, region-based) now has a concrete floor to beat. +**122× less memory at a ~26% throughput cost.** That is the honest GC tax at the naive end of the spectrum — the number we had been guessing at before building the control group. Every future memory-management proposal (generational, incremental, region-based) now has a concrete floor to beat. .. figure:: diagrams/benchmark-gc.png :width: 88% @@ -532,8 +532,8 @@ Free-list reuse is disabled while an arena is active so the chain stays pristine ============================== ========= ========== ========== ================= Strategy Wall time Peak RSS Full GCs Arena outcomes ============================== ========= ========== ========== ================= - Phase A: naive sweep only 932 ms 1.2 MB 200 (unused) - Phase B: arena-wrapped body 945 ms 1.2 MB 1 **2,000 resets / + Phase A: naive sweep only 945 ms 1.2 MB 200 (unused) + Phase B: arena-wrapped body 1030 ms 1.2 MB 1 **2,000 resets / 0 escapes** ============================== ========= ========== ========== ================= @@ -600,23 +600,23 @@ No component queries another's internals. This is "collaborative" in the structu ========== ========== ========== ======== ========= ========== =========== Workload Mode Time (ms) Resets Escapes Skipped Full GCs ========== ========== ========== ======== ========= ========== =========== - friendly greedy 732 1000 0 0 0 - friendly adaptive 691 1000 0 0 0 - hostile greedy 568 0 1000 0 982 - hostile adaptive 607 0 1000 11 982 - mixed greedy 1981 17 1983 0 1966 - mixed adaptive 1694 14 1986 2 1970 + friendly greedy 356 1000 0 0 0 + friendly adaptive 351 1000 0 0 0 + hostile greedy 287 0 1000 0 982 + hostile adaptive 285 0 1000 11 982 + mixed greedy 863 17 1983 0 1966 + mixed adaptive 858 14 1986 2 1970 ========== ========== ========== ======== ========= ========== =========== Reading the numbers: -- **Friendly** workload: adaptive is ~6% faster. EMA stays at 0 (every arena resets), so the skip path never fires — the small win is measurement noise plus a slightly shorter decision path for the common case. +- **Friendly** workload: adaptive and greedy are within ~1%. EMA stays at 0 (every arena resets), so the skip path never fires — a null result for the adaptive policy, which is exactly what we want on workloads that are already arena-scoped cleanly. -- **Hostile** workload: greedy happens to edge adaptive by ~7%. Both modes trigger implicit ``gc_collect`` 982 times out of 1000 arenas — heap overflow during the thunk clears ``arena_active`` before the dispatcher sees it, so the adaptive skip path only activated 11 times. The policy's signal is drowned out by pressure-driven GC. +- **Hostile** workload: also within ~1%. Both modes trigger implicit ``gc_collect`` 982 times out of 1000 arenas — heap overflow during the thunk clears ``arena_active`` before the dispatcher sees it, so the adaptive skip path only activates 11 times. The policy's signal is drowned out by pressure-driven GC on this shape. Adaptive isn't helping, but it's not hurting either. -- **Mixed** workload: adaptive is ~**17% faster** (1694 ms vs 1981 ms). This is the shape the policy was designed for — escape rate is moderate, arena entries interleave friendly and hostile phases, and the probe lets the EMA recover when the workload shifts. The number of resets stays comparable (14 vs 17), but the verifier runs less often on the doomed-to-escape arenas, and the overall mark-phase budget goes down. +- **Mixed** workload: adaptive and greedy within ~1%. Earlier measurements (before the precise-type-byte fix) had shown a 17% adaptive win here; after the fix the numbers converged. The fix both accelerated the common paths (fewer redundant checks) and closed one correctness hole, so whatever advantage adaptive was extracting from the specific crash pattern it had tolerated is now available to greedy too. Honest result is that adaptive is neutral here, not a win. -**Honest read.** Adaptive is a clear win when the policy's signal is visible (mixed, friendly) and a wash when it isn't (hostile, where implicit GC dominates). The 137-test asm-gc suite passes identically under both modes, so choosing adaptive costs nothing on workloads where it doesn't help. The benchmark also surfaced two real bugs in the conservative stack scan that the greedy policy had been hiding — a 24-byte string misread as an env node, and a 40-byte string misread as a 25-element vector. Both are fixed (offset-0 tag check for env; length-fits-block check for vector/hash walkers), and the four strategies (arena reset / arena skip / full sweep / sweep fallback) now co-exist safely. +**Honest read.** The adaptive policy is currently a null experiment on these three workloads — within measurement noise of greedy in all three cases. It may still win on workloads we haven't probed (long-running servers with occasional large bursts, mixed short/long transactions), but nothing in the three-way benchmark tells us to prefer it. Shipping it as default (``arena_adaptive_mode=1`` at ``_start``) costs nothing and keeps the counters (``arena-stats`` fifth field = ``skipped``, sixth field = EMA rate ×256) available for observability. The benchmark also drove the original precise-type-byte work (§6.6.5) that eliminated the latent class of conservative-scan bugs — so even the null result paid for itself in correctness progress. **Reproduce:** ``make bench-gc-adaptive`` (source: ``tests/bench-gc-adaptive.sh``, ``examples/bench-gc-adaptive.lsp``). Each (workload × mode) pair runs in a fresh asm-gc process so results don't contaminate each other across phases. @@ -630,15 +630,15 @@ The reason we built the GC at all was to let long-running asm HTTP servers not l ============================== ========= ========= =========== ============= Config req/s baseline peak RSS growth KB - RSS KB KB (20 000 req) + RSS KB KB (50 000 req) ============================== ========= ========= =========== ============= - asm no-GC + ``heap-snapshot`` ~240 96 96 **0** - asm GC + ``heap-snapshot`` ~235 120 120 **0** - asm no-GC + no snapshot ~470 264 185,000 **185,000** - asm GC + no snapshot ~450 112 1,084 **972** + asm no-GC + ``heap-snapshot`` ~630 96 100 **4** + asm GC + ``heap-snapshot`` ~633 116 120 **4** + asm no-GC + no snapshot ~625 100 458,812 (OOM) + asm GC + no snapshot ~610 240 1,092 **852** ============================== ========= ========= =========== ============= -All four cells validate cleanly now at **20,000 requests per cell** (up from the original 5,000): +All four cells validate cleanly at **50,000 requests per cell** (up from the original 5,000): - **Cells 1 and 2** show that on idiomatic code using ``heap-snapshot``, both binaries hold memory absolutely flat (~4 KB growth over 5,000 requests is normal VM noise). The GC build costs a small throughput overhead for a feature the snapshot pattern doesn't need. @@ -650,9 +650,9 @@ All four cells validate cleanly now at **20,000 requests per cell** (up from the **Honest read.** The GC build now succeeds at the "GC instead of snapshots" use case. ``heap-snapshot`` + ``heap-restore`` remain the idiomatic production pattern (they're cheaper per-request and portable across all tiers), but the GC is finally a correct fallback for code that doesn't manage arenas explicitly. -**Soak result.** At 20,000 HTTP requests × 16 concurrent clients, the GC build serves ~450 req/s with peak RSS of 1,084 KB — one heap chunk, steady state. 972 KB of growth represents the heap filling up exactly once after which the collector keeps reusing reclaimed space. This is the production validation we needed: naive mark-sweep is a correct, if not optimal, allocator for long-running asm servers that don't want to think about arena discipline. +**Soak result.** At 50,000 HTTP requests × 16 concurrent clients, the GC build serves ~610 req/s with peak RSS of 1,092 KB — one heap chunk, steady state. 852 KB of growth represents the heap filling up exactly once, after which the collector cycles through reclaimed space indefinitely. Throughput is within 4% of the no-GC bump-only configuration on idiomatic snapshot-based code, and within 3% of the leaking no-GC baseline on the no-snapshot configuration. Naive mark-sweep is now a production-grade allocator for long-running asm servers that don't want to think about arena discipline. -Remaining rough edges: at larger scales (50k+ requests with 512 MB ``ulimit -v`` and the bump-only no-GC case saturating the cap right before cell 4 starts) we've seen cell 4 die at server startup; this appears to be a process-environment issue rather than a GC bug, but we don't have a clean explanation yet. The hash-set benchmark on the GC build under the ~1 MB-per-iteration scale also still surfaces an occasional unbound-variable error pointing to a root-scan edge case the precise-type fix didn't fully close. Both are tracked as follow-ups. +**Root-cause fix that made this work.** The earlier residual crashes (hash-set bench under the GC build, arena bench, memory bench all surfacing ``unbound variable`` errors) traced to a single bug in how the type byte was being set on reused free-list blocks. The patching was using ``orq $(HT_X << 8), -8(%rax)`` which MERGES bits — if a block was previously a vector (type 5, binary ``101``) and got re-allocated as a pair (type 1, binary ``001``), the resulting merged type byte was still ``101`` (still vector). The walker then treated the pair as a vector, read its ``length`` from the header's size field, and walked off the block end. Fix: use ``movb $HT_X, -7(%rax)`` to OVERWRITE the byte instead of OR'ing. One-instruction change at 18 call sites, and every previously-residual crash went away on the first rerun. **Reproduce:** ``make bench-gc-http``. Tuning: ``REQUESTS=10000 CONCURRENCY=16 VCAP=524288 bash tests/bench-gc-http.sh``.