From 33fc0db6afb99d1a15092aa3c1faef764ebb752d Mon Sep 17 00:00:00 2001 From: Ralf Treinen Date: Mon, 12 May 2008 19:46:34 +0000 Subject: [PATCH] Imported Upstream version 3.10.2 --- Changes | 21 ++++- VERSION | 4 +- asmrun/.depend | 6 +- asmrun/arm.S | 13 ++- asmrun/roots.c | 6 +- boot/ocamlc | Bin 1016576 -> 1018891 bytes boot/ocamldep | Bin 284516 -> 284531 bytes boot/ocamllex | Bin 160693 -> 160708 bytes bytecomp/typeopt.ml | 4 +- byterun/.depend | 4 +- byterun/compatibility.h | 5 +- byterun/finalise.c | 5 +- byterun/freelist.c | 49 +++++----- byterun/freelist.h | 4 +- byterun/gc_ctrl.c | 6 +- byterun/main.c | 23 ++++- byterun/major_gc.c | 20 ++-- byterun/major_gc.h | 7 +- byterun/memory.c | 59 +++++++++--- byterun/memory.h | 10 +- byterun/minor_gc.c | 101 +++++++++++++------- byterun/minor_gc.h | 17 +++- byterun/misc.c | 12 ++- byterun/misc.h | 4 +- byterun/obj.c | 2 +- byterun/weak.c | 68 ++++++++++++-- debugger/.depend | 4 +- man/ocamldep.m | 2 +- otherlibs/graph/.depend | 12 +++ otherlibs/str/Makefile.nt | 4 +- otherlibs/threads/.depend | 18 ++-- stdlib/gc.mli | 4 +- stdlib/lazy.ml | 2 +- stdlib/obj.ml | 2 +- stdlib/obj.mli | 2 +- stdlib/weak.ml | 191 +++++++++++++++++++++++++------------- tools/make-package-macosx | 24 ++--- typing/ctype.ml | 61 ++++++------ typing/typeclass.ml | 10 +- typing/typetexp.ml | 8 +- 40 files changed, 529 insertions(+), 265 deletions(-) diff --git a/Changes b/Changes index 7eee8820..0ed6e5cd 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,20 @@ +Objective Caml 3.10.2: +---------------------- + +Bug fixes: +- PR#1217 (partial) Typo in ocamldep man page +- PR#3952 (partial) ocamlopt: allocation problems on ARM +- PR#4339 (continued) ocamlopt: problems on HPPA +- PR#4455 str.mli not installed under Windows +- PR#4473 crash when accessing float array with polymorphic method +- PR#4480 runtime would not compile without gcc extensions +- PR#4481 wrong typing of exceptions with object arguments +- PR#4490 typo in error message +- Random crash on 32-bit when major_heap_increment >= 2^22 +- Big performance bug in Weak hashtables +- Small bugs in the make-package-macosx script +- Bug in typing of polymorphic variants (reported on caml-list) + Objective Caml 3.10.1: ---------------------- @@ -82,7 +99,7 @@ New features: - made configure script work on PlayStation 3 - ARM port: brought up-to-date for Debian 4.0 (Etch) - many other small changes and bugfixes in camlp4, ocamlbuild, labltk, - emacs files, + emacs files Objective Caml 3.10.0: ---------------------- @@ -2236,4 +2253,4 @@ Caml Special Light 1.06: * First public release. -$Id: Changes,v 1.168.2.7 2008/01/04 13:27:04 doligez Exp $ +$Id: Changes,v 1.168.2.13 2008/02/29 12:17:26 doligez Exp $ diff --git a/VERSION b/VERSION index e02a2ee7..0c28df08 100644 --- a/VERSION +++ b/VERSION @@ -1,6 +1,6 @@ -3.10.1 +3.10.2 # The version string is the first line of this file. # It must be in the format described in stdlib/sys.mli -# $Id: VERSION,v 1.2.2.11 2008/01/11 11:17:21 doligez Exp $ +# $Id: VERSION,v 1.2.2.17 2008/02/29 12:17:26 doligez Exp $ diff --git a/asmrun/.depend b/asmrun/.depend index 3176dd55..ec447ee7 100644 --- a/asmrun/.depend +++ b/asmrun/.depend @@ -252,7 +252,7 @@ minor_gc.o: minor_gc.c ../byterun/config.h ../byterun/../config/m.h \ ../byterun/misc.h ../byterun/minor_gc.h ../byterun/misc.h \ ../byterun/misc.h ../byterun/mlvalues.h ../byterun/gc_ctrl.h \ ../byterun/misc.h ../byterun/signals.h ../byterun/misc.h \ - ../byterun/mlvalues.h + ../byterun/mlvalues.h ../byterun/weak.h ../byterun/mlvalues.h misc.o: misc.c ../byterun/config.h ../byterun/../config/m.h \ ../byterun/../config/s.h ../byterun/misc.h ../byterun/config.h \ ../byterun/memory.h ../byterun/config.h ../byterun/gc.h \ @@ -620,7 +620,7 @@ minor_gc.d.o: minor_gc.c ../byterun/config.h ../byterun/../config/m.h \ ../byterun/misc.h ../byterun/minor_gc.h ../byterun/misc.h \ ../byterun/misc.h ../byterun/mlvalues.h ../byterun/gc_ctrl.h \ ../byterun/misc.h ../byterun/signals.h ../byterun/misc.h \ - ../byterun/mlvalues.h + ../byterun/mlvalues.h ../byterun/weak.h ../byterun/mlvalues.h misc.d.o: misc.c ../byterun/config.h ../byterun/../config/m.h \ ../byterun/../config/s.h ../byterun/misc.h ../byterun/config.h \ ../byterun/memory.h ../byterun/config.h ../byterun/gc.h \ @@ -988,7 +988,7 @@ minor_gc.p.o: minor_gc.c ../byterun/config.h ../byterun/../config/m.h \ ../byterun/misc.h ../byterun/minor_gc.h ../byterun/misc.h \ ../byterun/misc.h ../byterun/mlvalues.h ../byterun/gc_ctrl.h \ ../byterun/misc.h ../byterun/signals.h ../byterun/misc.h \ - ../byterun/mlvalues.h + ../byterun/mlvalues.h ../byterun/weak.h ../byterun/mlvalues.h misc.p.o: misc.c ../byterun/config.h ../byterun/../config/m.h \ ../byterun/../config/s.h ../byterun/misc.h ../byterun/config.h \ ../byterun/memory.h ../byterun/config.h ../byterun/gc.h \ diff --git a/asmrun/arm.S b/asmrun/arm.S index 109e930c..da036506 100644 --- a/asmrun/arm.S +++ b/asmrun/arm.S @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: arm.S,v 1.15 2004/01/03 12:51:18 doligez Exp $ */ +/* $Id: arm.S,v 1.15.18.1 2008/02/20 12:25:17 xleroy Exp $ */ /* Asm part of the runtime system, ARM processor */ @@ -91,11 +91,13 @@ caml_allocN: /* Record return address and desired size */ ldr alloc_limit, .Lcaml_last_return_address str lr, [alloc_limit, #0] - str r10, .Lcaml_requested_size + ldr alloc_limit, .LLcaml_requested_size + str r10, [alloc_limit, #0] /* Invoke GC */ bl .Linvoke_gc /* Try again */ - ldr r10, .Lcaml_requested_size + ldr r10, .LLcaml_requested_size + ldr r10, [r10, #0] b caml_allocN /* Shared code to invoke the GC */ @@ -323,9 +325,12 @@ caml_ml_array_bound_error: .LLtrap_handler: .word .Ltrap_handler .Lcaml_apply2: .word caml_apply2 .Lcaml_apply3: .word caml_apply3 -.Lcaml_requested_size: .word 0 +.LLcaml_requested_size: .word .Lcaml_requested_size .Lcaml_array_bound_error: .word caml_array_bound_error +.data +.Lcaml_requested_size: .word 0 + /* GC roots for callback */ .data diff --git a/asmrun/roots.c b/asmrun/roots.c index a0c61618..d35e7634 100644 --- a/asmrun/roots.c +++ b/asmrun/roots.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: roots.c,v 1.41.2.1 2007/10/25 09:08:20 xleroy Exp $ */ +/* $Id: roots.c,v 1.41.2.2 2008/02/20 12:18:13 xleroy Exp $ */ /* To walk the memory roots for garbage collection */ @@ -233,7 +233,11 @@ void caml_do_local_roots(scanning_action f, char * bottom_of_stack, frame_descr * d; uintnat h; int i, j, n, ofs; +#ifdef Stack_grows_upwards + short * p; /* PR#4339: stack offsets are negative in this case */ +#else unsigned short * p; +#endif value * root; struct caml__roots_block *lr; diff --git a/boot/ocamlc b/boot/ocamlc index 63b5acdcd61c10313f29daed263d940785f2416d..29b8cdeb46e48a6defb1a6bf55af3f1af74b7eb4 100755 GIT binary patch delta 56934 zcmcG%4Omsh_CMa9{c;ZPpvX}`4lfES%282KF)>jwDe)~eEvYCiF|aJHD34c7OG`@9 zRa)YeZkm)>TDvPMq@^VWUac%GEv+mqtgI|G&+oJ5>`lb2@ALmZzwhrn4zp)w&6+i9 z)>^Y>_Uv)qqJc}F9yo8SBBm-oQP_dN7&C6F^85g?)}ZdMC{c7|o$@TjWrsLv;JUzY z{pKsKxZ;Phus2BEL9i8K5Jw|OVDeq3xV@=J3WP?V&liH2 z!xRJ+ArK)JfvY4U1R>mx5Q@P0jIINMj=-?|%SOmU;B*{9073!+*X8gK!gz#k2>5v= zkONN)#Ff$!xFREE;+T*_AdVYl1YG7sV1g6`ZZHhtYAZd&N{_J8L#=eKl^$lLuaW7( zKPYA-IS3lU-3Xk%)=GCm%mig1aE}cH<`g3>u$~zq!!g0_5SZyq@LUA$aXFoRNr_S7 z$nmn062RnhSAuE5^NQz2W-)Vs*~=BDAaIW*2x89X207+D=G4syKOndfxXf;pVVHOu zHmJl`;>?DUCr{iS(_Z@pG^+eVNvObz@&7t(ugF!K&twe z;_1d!SPB^2)(P%$5(1-Q_Sxk@RQkCQLvask&Ir!SMwo)Y=)=nLX1bJU%A4bKtyrma z2z(BLq_Vi;78oo>#)@!i!4V z&dgjJClkkvvilT|XZ~@%L9I6`*@{6EHYy(aagNfKrmRw(bSz5wU!b3gx)@HHazP93 z*1Q)yvg?|U2-4i~&Inx)lrnd55^WkB;DmwqR4OjIoCm^wT&KiFxKYkbV*%qhw(R&P zt~RHEjay*W#UpTcU6eP52co^R%@-(UR&ijk6a<|-&nqs)NqL{EE+v`D|E0JRcnFv+ zjNN8eH$3yt&#s0_B|CtJVG2Scon4{2%GQi=Qva8f0e|qXY+3dH9sA14?{rhBM+r`7 z$+#z5FfNe7uF_(dIq?bHeJOB=S#<3FvayiT#>@)%5*XMD#?tW#s>{oA<+6b1B4)AY zsfK@ykURQ40_XF{F+3x)Ely87vkWrNxU6LzRG|Dfpz55inDCW zqrnOL&%*SmHuU6^IT<{=69etrwDJu zQox<#PTL*5h6*+-1)aIC9GDoMxcejUU^1Z`GauxDQ^Qi&p3pk1Y39_77U`}n(%)V7!*{jd zxz5N7J|Cj-O-MEZh@s2{=wv*LB-lu#~~(o6=fQ zey8keWwLUa%BvNh@LfS`w<}`==Ks%LiK4(A$~*Mqb}-;rjN&vKcPQHxAryL|Mu{?a z)hG)!MWr)7C6(@eOX)zv-cq{KE!Y!BxD{e&v?*X>8A2!nTy@xeUL>sF#%8FfPYJ(D_^k|DTiw>*#dkEtZ?nLN~ z(C#nF`cv)!B_@!CoRc?yUFdMpkzb5h8u^LR2`$a} zM46yL@ESf-mP!;XzljKJz*tKCE##iSaIE@V*$hxTPeaWuCzNyrtG;qwxXJiJi4|_8 zY*b{F+5ZdWF`>kpd%seqX-Wcl&L|5+qCy828*xcCv<}Q#RRf8^Wb)FmdB0| z=XGh8*Vf8QZI;KH%rhgyc5RW*vl!=hYmpB_?3D#+Eed!Lxq_!fK93XUcW;r;s?GU5 zTIBP1a(>Si`8*1opRQmcwtLS#;AbxA)uIAhV9xK|BA?AE=l5xm&+|X$XSB#?M~CzK z+WG7VaKmgwxS*e1VCA!&=KTIG^4ZpNerAh&HmsaKpjp1{OtAgovMZaF(WG-qaJzxc za+n%>(6h*UPDyVw2*u3$>k(}Ix{CIm!^FDh9L!PlPs&7*t1NuI(|_uD#~r7{;GHaZbLEtT``EfUkAH7kH;g+DML<0eka6S%uKRDrGlCz zzba!DF-@V`->{fI{hQLO9RsjIu=~e=oTpRyugV;A(*@;Q5qAeN`lFy9!gM?{t>Lf% z++v|Z;m=}6uKstWQ%ANREN}@3O?IJK9&>L7#axE!##7d1%nNtY>dQ)%QbY}^aEW4= zxELi$XSkW<^(lqQU2M*?l-pLMiX3q_rj1omE0&1x2quzcI2(b9j$ctJCijT9a+v`B z$$mE@!0w(sShFZY5vj^OOj8WaRYWA1T&4(*xL2W3xmuLCO`)~l1Vz!0iilTcQ)?ko zlsQxtEL{EEXnvKU z#%57-j9!|c!7|6v98Ki5n+N<%!aoqR?Athl$bCYOpLR@zQym2mrg}UA zTLUI(feDMBqbLi_Q-(ODC=Z(rPINhNQ4{Ga1I0lWm8K3qMP~y=jIx3nf<%m1iK!qc zB+6i9geh)?8ckDzL?`jIQg$FGst42e43G^%%s)=ALYiqEj=&0$jKGGPajceTv1xpU zu|KEK=623FgKMpkiWn!#{Vld<=(QG^Hpl;oG{deVZ?Nzv6+Hei5zix+HQgSvfAL7V zsj-_gKmv&MKpiaNlnpYeyhz>!?cZiydyy`b&E#{7EJRuHB2(E$Rq>#G zRXjALnx9Q&J55V~(Cnba2_SAKxqAt$)e=NsrG_#RMV6>V_g4l)QQRS?lU62*UgAyU zEHo13sP0mzd$AVPpM`))+l}_wKW1*ShqNDIJOYm-m%oK_HazTeaQbb3eVUYnu9)Vm zBmoP#hl)FjBxSEz){*=04kumau@rHQLVHp~EDh@{IwwsVotyT5FvSM`nrq7iujLGws}Wf*^x29 z^lDErPCv**Qr1ADJ#|VKX{a_K9Rkxpi_?W$98xI$Z8eJ4ypQd-J?SDcv;pw;R1bHK z*_9BF&T*$v)a1T3hx>pz?fFyH4`GB)IuaueqfT?l_=rk-Vemetx?W;+;t`Zy1*A@d zK?wX~J7RPAD9BR<$m=a05uYeD?`J(K&@TK`p_^{f;%M$;s?#j$gK}{UogWiLD;J8k zH1ZJraMG;8aPx0Q_)EAAac))gt#}Dsd?gz2tCsb!?y|rKP5)ez`-J%(q^FA zs;5M7=y%OP8vlyyv&{g$r?4qv0o9j@aC7Ha(LqInC&!BtMEMi!D3y$fVnzTDwsg|T z`%93EmQNJ70_^-m3Ff<5WYfTLAfj=ia3cTg^`Z(<`6P(f59Gc9HuOg-oh(X~bND(@an?X(og&^hF-}`^6Bm=q|BVQLdn{St8dAoh5=*bLwm`N(rXC`@owJS~>?& zC{^tcu7EIDc$Us^az7+esnr}zZ4rLJRuWLO7PR)3AeYkuY$E~9gZBY2Bnp|fe7nrd z2jCinv~8Bxj*3elQ;@zA;R%UpRuW5RN?=vm%ckhWgCa77$#7e(#B(dfAqhy@I*>@K z9};8n4ny{$gP;747JRZFKBXCaCx*|Vxr4!{HM2!0it~yNA)T8+bfG*i8c9W#-HEPL z=N0Qix;4v6Bkw%n!i$64GLc2omy26Nx;HEC!AMeR?otsiy|$i2{}2~L(wl+w@?+@D z7*goie6e5j5j5x-zn1r<`b`+X`djel@+1%&`ih7x+h_*M$vH#N_p^gwb^3_`RJ0Hi zXVG}{CHi6UkyI0&-tp?C5^7Qu<_xB}*FXaQz{NUlZd)Xtaw`2OuM`S6vXtAIhd(>B zLlG%*f0d#aZ=7hP+#i)=go8=GW{9>#R(2LxVLCs38VitI4O$oFiZJ3A; z8QiQen}VJat3!q~%NojW2zV?seHaz{J_)vq4_(CCd~ zh(j4;=D#9TA;t>0l9&MFoPKuUSPViWX{O znxN0#0K+c-8`O>5206P!P;fPxW~}DOYPcq%P|!_7uwGfSovGh0BB^Kxo?hUmHFNN^ z3r_*|YPZ<0XEVWa*3Y}BVTVYkkvl}NxEuW0?}%1rNjpKacfd0Wr=>eYj8x^>R+Twi zB~#pILEle7Z^BJV-f3xki3Rqc-vBM!DZ<4=82A}_6uk~0cXThgMama z9!`sv;Ln&EagUhqZ-n;L*qu3nr>4$4?8mXl!m*edYT+C_V$omgr@z*sf2jram>=qK zNw>1hkD}Bne8Nx0-EU%T^rYXGEq~MMS(yd%6g9jF*K7sV?GovbNZ&5u>djM})Lk%@ zcNKZM;~)E0AES(agXG^Uu9%FN*Rmf|?r!*YcTn+e81R*}bhlWokeTw9C=&@!qcyvN z9kW%lw?CetqkF_^u?nmWhRiS93rSyXvFnAsVAqFx#TUwRRQ(PX0u40zU8qk}RQax? z{P?>fLzj~?RbA5Ev}~VnwoIc^@jhAi{~~gSOatjj=+cdde<~}y1Lt4%iy>z$$YMx4HUjhm~k3R*Y9Gn zs%(C(T!kmmVAd(BgWEYIR1&X1jlY8$&sWv9$Xl(dhsCRc4n#W>Y1tk}B+Y%!8BhB( zbvxayscp?Qx_Y~4-<%@m8GFJ_RGCRmb&C*N#mY47L4Fvh4xoV<4!rgaQX{cQ$_r9c zXk?H&!#okBJ`4ZN^oFTpMM5=(q`A+%9cjkB!s=B#or_S}&ns@FlD-3_fs_}njio8A z)qC3SM4DGM?<4SL6mJ2rGB7`O(%IJPEU{Bi_fx@%v?x-&70awMk!lv_4f>7cxKt0O zk!{rO0X0D6XJSbdUQexSqqY?v!-ubTL`ASQ<0Vt=pJ6VyQTsB?6Hy`2otX%JVFr+< zL251>Z#J)+p-UyD(*Bx@>Z8=BuB_yG_%SzGo|qKQ!%)kyZl1@WJmyV#RPItU0(T*w zsVI-2QM>e>VmF4kJfI5=Y^yrOTY|#BawO99w&>T};K+70ju%c+aQ9$_+2@R=J#E#S zl)aSFPMwCOUuiovMR}LZc50HckB+ue3+YHZwF6C$R{JXZDKAD%qCL@SSLHn}OrjCF zYA|h!Q6p(dG=!?2AxbfB$79rdHs#}!*_^U;=SBEGEX>xltPdP-D?bR&heLB-# z%~n1jPn=q;d`RVSYKndsT?(VBWDH3C2sJohh(+*6loyW{k5I8&ova+? z23&N)t~ z1oZI)r6#IokCPyRcgmRMaR{RkQV>}9`Ns=x&L4rmX5b6TNmAX^GYQCAC8_Z=HA#(C zz9L^oD8R-f^#`BDLq+yT#DQ$sQc-jo8uc6Pv@`5i#XEgewrLoO!)bwZ27I;lhGawjzyhe{+_QOGX)OTB?Y zdqW{2DW$i%RB1z7dIL)oUF;39b&!Z4Kwm^6dl>zYfWM%+7jt*yl5;tY_h0erNRbO>1-UVg$gP?Wk2eL&!jPWh~)cdGE zKaETPGo$*e1Mn^out_w#zdB0kNJsmrnY3&;q$M;HgeFr;rn;VzGlAh)rn*+?#Qj-H za|b{&M_j31LxES~Y3Be~_(fN$qc|^?<_<*Fu0#XDlx~!sh0#o-(kyhxLl?8qo$h~h zC(G(i51KXz-RVi@Aap044i7?idQsL@uo%6m{3KYbPO=TgCN@ZlQH%A=jb!L^ZBtG6p7$-G*f#jAm9p}pfrsGXEi zM@je4f+MU+FcpT`ID7#bQs0Tbrf_BIzFBOCMXm9b&gzv7AMk0 z)KRV{_qCvG5(A{rvTNB2U5nn0?1r5)uq4?0>RR+oxq*`MFhVy{X`V{T6iOMTt`_;~ z$~z345gr9~xrs7Ht8=K&X!LpKX!Q9OQpbSw0-7@h_UBf*I0p4^qiJJ7{8XwN3zI*M zCXa(4-cD8Hka-8Sz7DDBH0?SJZXq>XrzVLRDy?lF5>27w(a$@{Jst{NM7iVD3{h+q ztr@RAq0A)D1WXQhQSk)Tqufp96VUrv3>ZU=6QI5KP|!p*Q@NLFCPL$;OoSi~n+RH$ zOvF&n;oKP7IT2<6MNYaf5o&xtrCblk;{lcZ6j7qCOb$wD)MQ#VS^a`m z-GH_pQ&+yDcA;Z8s2#-PDs7I(GAr&z6f9GzwjR6n4_vE6N}VsI!W-30@q|kAK2Z~C z-;FSaPa;w8>_SmfAg#;Evt4zYlcuP(LMbz2ZdS8`l&8$eGt{F(Sz%@rLq;N2Li>1o z*mfE=Q~6BQ6+y`69pOK+_s)d!J#D7k1p$MTR(Ln$2=SI#YPuTu48YmPcw3Z>!U+Il zj@n%pt5o(S)6A(4V&b4a55iqs@{p=2$+w$F)FWyJ-buJ0Rb!Nml=&#QT*)aHZG2RnsJuk#64fJK zR%!b?BAF&FQD@?PMBNf~G2TavT?(#lrqxR!_pi|2rD{sRtDua%zIZy%gkt@`1spkra`svPkusLO= zIz)&!GHER9l(jf5N&r z^f}CD+iAgbu<94cy$0%cfyS;uUoV)IYt(Fk4O3Wsr2IJC2k24>5S?%Qjo~o^CjZkW-*i>`Ho9fE_kn&@u8Yy-` zYmAU&xiPlebiV<+gKhC9M>af^-7fn*`P=@Azx-QWh}Re;+b}A7iMFXp0q=mb?3lev z?zb`ZpV+3(jNXSle)rf5fgQO-1cs?osr!B%YoKbhzh9;J?#?tiSPe_~9&6bIQLnDd z(0KbpeIlX(NLU*XN%@A8y8{Ph|3js3K?;g?s9nWDrYf0s?Etz%AiZxu7x6v@g&p&> zooaCO2Q6@Xh%^&&*dk>1PIX?pk1QZQT)=L?$5uLsj_*`m!;ZATaTIC$3{p10$0OM9 zAwFpV`zg}g-Z7P5Ek)D72E1%qRs*wqoXTs|GVvJ-Rt7-6YGJ89hoxGIxnW5y1m*-) z)T(*yPPV}Kg@y4;)?#ecys5^DuVB==8gcppv~&e!yb0|tdK1QR)0>#vzM+o-MorO4msHV~K-7v1-L!!QQB-50`YIxbUjNmx#`VTqUx0&goo5*<6u+wU{UQTfXQyhRa>c0F6HT z94K48t8R!0Y|(BI)xE2_+Xc7C4zb9=%Y}WAkS_bw0TE#>V8Z=XBU)s)vZ}V`syQN3 zqXVZg&T(}x1x;9>;nV&o2NW2G2Jn%hC28mSlo;r;-y~nKF z&wg1wCby`1BuAdXx?=VOqpfrRI#NwN=ugG~Y=>hI+JLQ?6phx_s9j`vCp!Ki6m3_7 zI$Y_DwE~X1PdNa5X$P<%>(Z1FEK*UaD|CF(0jP3UuqYL(yy@`(93LDU7-^n90MiNI zz4)LyHZcudV)M#pYB;uyByT)1Lp&BYFC2ua=*}FDq3AXaY~hzfefu9$J4N?s!Ihp! zbJcX&k)E{a5CpB4=C>$u@2j0eZ!oE&h@+|R!^i0Zk+RO_dXnwzT6uZTVE&L z@&R@$`jPJgw&@>$tGhm6PJW1|%bXnlA-uBzl26f8RIfY5l^VZrmA>3S`AF+NNs(g)?^vFD}$-@Ft9E=tU4p?p&nvUKh#gcvBNNH!$9xokT@&^FaoJk?uYxc#MPjl z=Z;k$srO+`(E4L|<+-dYIKc2RsO$4Fh+Y0MobYR@;bXM|Yl2xv0Fy@zh-ljpxSuPJ zs2$of$3~-VcATal@cA!(=KL`XoYHRW-xQDY7hm@`#p9{;C_I@76m(pT5fe2zJ7MYI z{Y1?dlfV!5SdV?8K2M>?VLNYMZrHA%k*+0j(q)frPZ5+~{#gCT_LPO59gz1qrI z4)~d0sKH{k>A2WTKGxTI5IH!v^oy%5uJv=S!*_&X1B1G(!W)6qH7_YtfB0_ z^LE}41n#j_)eM}YO;jkb5sa;+q(;bBE#)+-C&h!H>;ur8cE1*kys>BD^w-jsvzXXw zsr-Ho@0`EK)Lcu)d+SM5^u4+n&+Z>oFBks+->TNE{sG=1{OYW8((gu;K?l!aJtDKx zsmKU&QqP|-gfatfy&?jGY0*#WBj{z=&+5{Ehrm$3%bRy8&_&yR#_FuXJoU5cP|?iU zU$I*vqZA6fgzbxczp0P;GvHiZP(OpOnRik3F*EXh$0AU|;`sFMvbWX0LtG>~y#aHZ z8Zs|q5!#X5KJ>RE&Kt?-xDQIyk;Mo>Ag7=XWz0-9RH!QuabkVomFrX`6bR!ea@S{k8i-6NXnTNFQLf?^yGs-?va ztq@~>&Y{gxbOsYtgSQPdKR_FR;+g=B$Dvu&TLJ-(z2ahpdfXZhUXAh3=FBoXpGpHk zcgx}@nu=@ws(5)*@!7vBeyXY19rPE-S2h*r{Z;YPO~u~7Dqhu8T!mst@$n!G6%p8&L|{Xljle`)qN+G;wZCdMEpuxVBiNEK zXp#luHP5@XAhx7xf_6A!1Gc#(AQWc@ zG$EzD{zeRqNYrpJBtZ-QYjl}-_W%L&Qbq?G-O@JA8@9=>pv;b7l9!Hmgvr@J7dvW6 zY(A575#?f)NjK2W`82tk=J|i$jCrOTBu3|P z3&S~ONN7)wwjIKI)}s|lCh@5AG~gHcs_x+9!0uY?Uze>%%?UlUbBJ<#YO~s~iD2%q zJlL{OL5F&33m7mRbCQ?J(zSG?_NHr#5#{xg(P4j--&<=CFZn%Q@iIL4Zya5uH@^wb zGq8@IYlH-2+YXBlw>;py*%H7ZR)efBJhi{VASFY2&Pzg)J5+$co#MW;gUNaPv-6ri z1Eh%wUaHB!)Nvb~&Csgg7MJ&h5q*`+zS;!PAJz{kFQxR;%9Jfs-A~KH`=5*bv>1I0 z7-5v1UFV{n{b97WPp+I6~}l_mx&osGT$GN*)HY>Pjt0U^1xA(lSJ6 zW(xoK4LfgGFduEk2s|?rWtw6JYp0}N!r9D2&aR}^+0bCy#c0YlE3z?vpeyHwfQ8l! zFk+}Z19(w#d?-2q>l}l*Vc;+rLuu}}pac_37F}NMaO&IyL?uV|u`ox=XH?NxUVoLN z#s9s@H{HWE96qn0i&sPBWb2vs)H8pCHbmJGHFpkZ{(tLTIHblG*_n*IdJD8_+p!z(`Dc*pje`O@o$Whut;5#%*%Rv+~8lA47 zlF?eG_um*R`=EyH+OmD-1*zoJ|HJ2j*fs1uM!Og1=qtx)sn{JqJVwhh;4!$a*LEvP zwRv=smSO1e;7}mtFH&7*+Rd0S1Gj@{_BPgzrp+&_1I<;pXutAavoAx(KK*Ula6F&8 z4SlVptPfyw#!Q8f)Y7!6+GIq#r(ytWDgU2N7llsKdUaz-v;7U8=6hOw=Y0NlgAEY> zm>+P^r$H@iscM?UBJp3C=6CFF(Nn1B?b>GP9yiCxhprf_Ez5t6*>#7O3(O7oq8AU` zq0Qsx$8}dbuE}S;xEB9-&h^t$RR|}dz8ev0PHDCCRmmWB_^k=;;(UQ|knE0bP=l%f2wk( zRxEZvl-nDLQdup^C*7sRH&N4q1sm_u9>EtF>33^~fhcGetf_n%0zS^twj#@O4=-WN z!h1k0lJ41nsHHixHFrDastau3v0*dRH2PFEoBL!Qo(*#h=)(K3Ji^-fJ}q7B{PRjX z^L}_-a*55Nar}O{Uc$mUh5`p+`6a*AAM=3r4hmyRG_R<^KFTVb76|Pjf@x=o_AClO zVv;%cL2V*S^6FlC5?z=phcC>_?V1a`P!Ysc^UxMRTF(a^wVFKfWlou|ZC7DYiWk9< z^;x9Fw&!lK0ZvA6BJj^XG$`S)?Lg}nX?wZWVi*Lld9ijJsj5e$7+!n?3Umi$KZ;?# zgBCx^;%-(ys^Ne(xf-Tx~GDkMW#POG}r5eYK{$RKthQ8z}t= zxM8(a_XIS&)+~Ke8>=Ed`4ndLe*EE-Jz=opKL!C=e!OUt`@+L?9YQVw|NL#1uhdF_ zHHM@lWsuZ;FR^%;6{O*a+y=AqY4k*Slg>V)d68YbN;}W=O?wV9fw5boxgyw${c~rs z*GQXzQdZ3~YqT6G%iRHpt==`5XKpFiW}v8{T$^K|F{iB6zD2Jn_j#!lv!2&7+Az;- zPvH+<)jY420x<7iT2>T8FkbGZfxv6(U2tFO1LMqH|I#)vv4tD7Vnjzb$W>*|i(01C z_f+!Tg*y>8{o6?!--1uD?7l#pj($<&4Wjamnmb@9aQQhEwo%fA$X&MSyI|UwjT7QU z8{xT1P*&o-8>Kj;RQh{Vsbvgg+H8Z?WC@z(HR&Vr*o5*Z{gJn_l^$0XdZW|q{}RkM zc%T2WcAgnD;T1`Y_Z97^WDxV7tFqww$t`|WTMEF7uVV6rDsEvR!Z>Wj{D>Wi*Q6S| zUe{{4@O7<3NZCw7b=zpS!gCYFRQzx4EGp)2({kizdd;PcjR5m}H`Q$89U1fZHcZBV zc5Rn(l(`);faKyG+EH=6piz%&iC5i*3fvsW9Ik5iZ0FfAGmy#Q-Bgw|{scFX95q_L zv}>uHMBtgtO>=6{S}^Udf%0#l{2v@HoeRFEv9%C^eYCq)%M#m^vhQz*h7aq0Q_CBg zg7W2x--0d1^Lm8;ApB_Mb6G2dbOh!!`y@;cbNdf^PQ5ATx0GGldgy(_E~!yxWMn#a zLrtMdOW)F3JN{mzGw5`kc3+dC;Dhv2FiTw?)^L)4zjlK(x%N=Alng~^8txR@^IA}- zIp{rYw$hHR0J94e%TXNG1ldrpjg`gBMYh}An?H&(8?>r6T$|g0P&Ttqz6PG7%!&gT z)vKBdHVcC!qlI7(K|b?`-P!~MCb=n(!rsFcj!k1Wif%`^AAwtEJ!aY&HKVZI36@BP z#k%P~AS0YwAA}}^QRYGHe=snU%}BXNjEI$r^PIH$Alx<Y1&6?cWvay6R@dq|KaJz=I;)}{RSF(oj;HY!;~&J=nk zvK5+kzm6~SDW(7i-$$<2+g{BL@M&d!^UQQHSGYFwk7IVLTgJVR_bXm~$0O$caleA7 z<{%u`E|0PIuvc^HEPF%C@;1Au@qM^eYbfXg+y7*f?PJ$-*$41~V6HyYOhgSIYAI4h z?GCa`_1B%QB>0=E0w|k2tgPR}|`U2a3GE;-uyjg7+ME z3G?4uly?amm2YeG**7>^@WLg`RsJ=FdE%0GyCU{rOC29bQ(9NN1F4^&$C}G7YvB&` zv0T@2hrnLHGe&_9{UiF((A(0n-?VTu(5c_ViG1>JZ%n`*S8l$Hzt|96CP2 z3D<98@2#q}&W>=MjLcK5^=f8dMH{^Yiz0Hz>Zw4J8>_qZKQWEni9bvzm=h^WF4Y*1SD(RtDNYbNFjTX)L+jBWMO|jN!gEY0d)3DJy(G-a66tt*LH>k z`!^x5{>jwS{jgcIEmL3n_mDIIV~?fl01VAm+I^+uU)VtIiOWZLMVBiZJ4egj#qD0J2J7*Xk!=|Wfqxbw2ZMPMHdi{Bab;Pa7;}EM z4*LMVYp8Cb;W@+fOjQ<#Qo|2{G3{6o`ykX~OxXh3X11EnT&-84r+5)HSu|Li63b$7 zC~4RpJ<{xxtM_G1ExuMy(GQ^VASyqHeU4@CV`e;^%?dhR4~O=8#_JBnf9==KOY$A3 zZ=~d`D^K5xBU;Dv^vR&_>;yf7?jEJb2W*8b;@=fRDQ~Fm4zUS5DBCFQW#BXTQF*C=Ro=*M8(U(r>=`hkX7urnv>DJ`0YD|hrd zwzEqD!)e<@NE5_vqMi*lCS9+`{2c`Z3NlS`gFcZ*cyhiDzm!VyrRD|QB!yAE85B!o zF*N38+*X98&CPn4@?>JMcq47XA`&JD1RyubpI#@v&w?Q+un)$cs zUNFf#J{4jMAZa;T-7ZlBCrt6}x>Jf%I3z(yqGkTF-M34ezT5QzSt_Kkl^xp=ZZ5w= z@2X?rUsD9Vs5NVf^$M0xiTQ!MS=`NvyCJK{n|u$bmXNrn?jHSnWMSf4(3!23R1$P| z5(2XW(jnbRsS9>F`L-!8bNOt&JEPk@M=EyKeR_FBHQ?D-v&9{9aGzd>#;Whvi^T_0 z+!JZ!1GsbxbUX+tnEil0kqLMJU&`UDm=bADP%=mAY!~24D9bY4bm2k$DZrIJBze5$ zA$>h2fXQ=pxdsees(r2C?8^~Qr;<~s`Y^WouY|3p;dSISD2wbS1r)MY< zxzu&a;;r~i7uDePar1Qr+nMeKa#G4$pl{JIa_S@cZZy35Q4otQjBxtp5owS!AC<$5 z{0YslmA1!bQ}la*k>bF|n$MiBe>9Nzs290BuV}Eh#<5E-dAJ=1= zHj-G<{iRDEXKmyiH@37FAJ_esuN{T8!qJ_gWl~NnmPs}pTBcWt5PP4S>wBs6N!+>n zr!0ttlZrQD``+Jz+;MDtQhy2fS1*^ADsLs^KD10SEv8J)BZX!9WXTe~`HnlmPLG9v z=Z{Tg&=P;zSElFw36ur536!@RRLfh+WP@O)^6RHv|&QkhXQ2bpqaI<`_u z=&6;Gv}}^I?G|Ei^DM#UFv4dbNEpRuAbTHC*cv^ZR<6>ok;`tL^mz=K3SLNmj0dJB zo_wqHa!IHS!hK?pBa8x{alMQa&W)?}QS>UjXd3^lejg2d7Ed_!98bn``ZZGXQ>nNM zI#To;zVEB&;^oij57GnA;pu@@aK{F((Z}iHxV2~UdWAk*fmh{w9+N!Y8~+O~^2!Q$ zGt2)42c|t=Mkc=`wMh9K)Y?1YeQ5Q1J^;snl^y{AIeYQcn(u-sJOfZ@;1SmC)oNR96X;e;Q}ATH!F2 zcu9{`o*~yudZzeg6ODUGPgBm&f|v9K;*(9d6I36M!;bkc!+edTy)UD!+2q~?6M8#k zZqf_I{>`*ulRiRxzL|d7q)&zNPOid`Z6&ILtd5|)Rgn4;+{Ot6t8mpOY{)tadId8r z+pR0)<%A<&(Kq1G=lNIk_2RcJwDwg!T6}Af_u;G1+hkI==z03mt+*+h@6x5BE&A|) z0$ioZnz+@h*`lk8@|d}ME8@grY!%Z|9Pt*|aQ+`AD4T@l!Z$dP)}=X+_l&)4=XpKm(CPjCBt++{|0Rm$06_4YA34mlt!~uK#H*#_X&O7&wzXGrL z?7UBrCwquIMrN-N*IO`5@I0&DVk?hv-DK6{Ivo*OvB#AnAN)H~T)=1GIL;!^x?q=g ziIrqJIr~W~F0J^CjdecXWBYx4NLk|QV#Uj>coSmo zBh$b8YkBdqR|0Y-2j=|CC}4;2J3!gG$IM{jxIvDY0FG^NbC$8>pt_Z)J{B!!0 zm9`s1%_}}^@XI%&ViDQ>7ck!ehGCf)9&U!^k(dft&KvE|GbDoRsG(ZV@b*L=mkqSy zu~vM86;H9^0xKpfe%^{-wqjeXY#zU1<-cpi2N2u+iNbUF0ZA)8yj_pD(g^}*Ad?lF zi77|OMo6&I{jGQhV!KmkPT1C?^b&@6G*$gG*rnhywROQM-j}Qjo2=NT>fctn0Wnj< z0?du-AKk9@xI2z`$D1>YXlbd)nugROX|6~Ac3d#!jMVkQpq>Ahk;sN+g6ScS|U zyZbyOXV3^DiFkt*zlxX++TkXo*9qb*cLq7FclUIm)W>kG$M|AeLmKbd<3ps zX~j0Bbx1Q3?!DJS!VU?;uD4>lLFS;1oZ(+T>L;A*b7Nsv{af(N^(Du>c(4V48*7f> z=}-QQ;NWNe>xFq37%6k-$Z@|?+KoJfG@B0AHX9ei9sJafi_M8$_uMg`@7f?_@c7x8 z8Wg&3f+@3I^5hzC_;kj2&B5m8M5UQ@#-Thi4o2#z2Vtdk9XQk~?wBcCD8Gbr> zTI1WIs3d&-_G67ceDrv$;0`Ok-ijw%v8{2pSm~Rs_~91uBUXATRc*t9_8AJ=p}QmO zajUdSU#75%U>EhN2yW}OrGK|o_O=y&WW`6U_){w$YsDw6_)9B3WyRlE@fj=r&WgXc z;&WE~vp*L2*2eREu*a)|#mpMMr&QZ-3rbm_}XR*5f07 zh7xr`b1Zee5q_b`Z)0h2o+{slQ~9e__WhU960+5AEg&ywRNEcLiwEw(p^1xT{vI9I zc3#4U=3M^7A}LG^T(^n6j}#lPOGG-PVXcF zbU%l-)#-yopj8sL9~(MBzpXJ5snwT>223ZH`@t+=vYtZ}3WewAs zfWY>kF9J>)G=O8cz2VRSteYCC;6HM0x8*-rH%Eg)28zc^AAOpv??CcT^{Mor+^$SN zq_0M64Tt>Oaqq*ikHPl5+X1v0i|vQ*}Mt zb!=^#AN*9`$_X5{fao8`CU_(Hj_WnZs`*Tx9N=!kob-vs~`HMegpQ63cr*)zEz~-oImV%# zujHCmo=Z9Ll|Bkun0|_RYL=YB9tD;$i$>Al%cQ69}_QnEFL!;cD z23G95oRynDt%HYc{~2ZGS!gXjpgE^M@?QsJ zu}%1seijD==ll$@#?=$WUm2-1{Umlp$DG&OVl)cRV?U@f9Y$nyL94B>hgG9SnNxn% zH!DgigA9%S5?I<-{EpstBgbV#X;gR_n^PV-exs2jZ+@p=F5|Vu z20G~j2fMEbGY%^oR-7_YSA-hfX|Q5ECHIPK-QzK}RRTMBiecgk3)m3s*b8Gg?y;y^ zisv}hh{RgKm0OBY` zpusz~DM3cQG({m6#2+HQItbJ^Qgx7#DhBG!KIaV$Hrk3T9akQtg|IY~K*%w4S7ehr z*znN6k@%EqXB+UV1XukU={lFIRNfkFyc}%s1ep|KWcy2Ty8R>$qAUwBI-xBy#7Koy zXN|+8c_GALg9~HiqO?$B6pFo}2EQqSg7Zs?^Pz^jGbM)}i6f{JDn#6FUmrceb1DD*+4aa!4Y-enQQR1&rg3Cp6TNxANt1dJwTjdrPBJhv7 zz%%z?+TF^SgPTV(TO0XkVRdWttC9A$mZNgEwUGo$T1Og7xr31gzauguA*Ms9w2jRf zcK~B#{^IOu8)K}ph4P{#wyG%fzk<$3*`P6Ho62zt&}9s0H54SU51}A1CBq9=E0X%|?F}p15AP)FNV{CKCj5geH zT&wxq!(+gZJQWYu`Kv=XATh?XA#&3RnT!?#9Rr3~^TmZ2qbr-jl=j91MBerWiL3o{ za$20x7g;zW=c2iBhO^ZOt9!PKlnYgvszsTb;taf~yoMT5;i+tkH)e=yb$Jzq{62J~ z?*DwTOCY{>o}FL}YQ=`l9zZ5F&m#3if)O7u3XMppNVAM>;Ev(PvjJDa z2b-zJYB5&2330TfE7&p)pASoADrjE*wQ~bTfw0qHYFu zKLb@Ku559q89A-Ep+q1~vKp9zKAd)RN#uNPl!qr9fr+#8n2>yUEw};<7b6*6BU&Q4 ziQFC|7mMI9kC8#^JW#;VROo@C?mXiN76r2B$+&;hc$$_y6C5sXhu_9G8{A=)T<&fR zq3Jy^5;Lfxhmj6JKHLKm*huc4(8or~>uD?qywhS*8;!pI0fYWaPoq0tTBM{KRXn(d zdl}hHpRe$mOfr~KdrOTN+uNwbdlO%8!`%eLo%I8G`WUmCvTgfRL0kGj{;TPHAH&yF z`bVY0zA&(feT}~VU1p+efztGeOmm+IpY8NVSv4*055jP@d4HoIfJN5@YLcjYdr$_Y zWg57VBNL_=aOMD`6j9EVP;|<(@wB>rhdMRs?QQ(i#X=k2>??WdUA0cD+WQd@b z&P)bkd|h+{Qq@#)gG`;g0a7Xt?8MOg8$lI5Fu4%|GK;;SGjIm$rWiilr&N~@;yTj$ zn=t8lagQ~$*GsuKW9s*si*JU^0;TU3@TjAiT3}SGN|AYLs!<@sy)c<&fyq>Kui*r2 z$sGpXJ>q58bctd2bXb(x6jq2Pai=R=!TT&Lc)Ac%_5HlEN{V3iu{p9Qga@d2hLNFj zRyc*-X}F}t<3(Kp0$Z{Yi6xEJ%s{iFDd;DqLy_IES2mnTMGP~KyhZ5eo#ZLTsEwvNyGC5I z8vnr5!~Wi~Vk2B0FyMtM_t;-el8yf*sK{_xk7tUEj3$;qs3d6%sH&JpgU%F7&bntB z>B5Wa7zSyHG<&Ae=})$ynkr`+RS`vCAgeRa6WpTLEW8Uc#7@fHMg}6sEE#3_qdESl z${(HbNA7!!9Qh_Fa77g^U|xBTagFuSPuOg9`cCrQW6Y5`p=9Nh-3x*7QqXK82GW}{ zTS{W-Y|wo-?VfG$XGoqokfpn6@*E>Z+|4@!4qVGQ2Xyg;ZBk#ymO2Oq*x810F@Uxx4XHIuACnk%InV z!~`s9%JuxiSSprUbNv!$U~qqi=Bb`{c-Tt;sQeAV-{xiZ6wnj-EHICOblxo)I3Kg# z<5WH$1kIjr{M3p!9&BHl0ay6_6nTZkqJP4>IJm$Vg6nu)3&AR)(uGEP^wVgyc|C57 z>pmj|D3LBNH2Tt!g~pH&#>^$FQ6ro@229SHhmBt1SwQmT8K)nHa6U&DA2y1`nr1C8 zS!4u9mA7by5v^?ov~LmY{XgmKBICHS&TLqWff5yxglLL-)YvSZ_X8h$)L1C~Woh&L zCB{tU1uUUrD0Hc@R$0%hp&VEq^eo0~^_cOQfb~DO3~thkXx~3NzGnm7w5Qa#DPW_W zXL_D6b_WDhHl;5@<{Y2drYx8ilI6XgwH`;2RF;f@hYoAwzKX*oY7 z)?v|V)ZuAro$-#c4O?(f<7)D}XJm@)aP{5@#C=h#)L`i`@6c(jj@9bE{rIZj)&1~O zf81~2B98r7B=tugCQMoJO<6G+|HC0ZMw|K`fH%HpbQim^>R^1Q`vu^Caj7@r6`ZmJ z`AIaa!FUjr^`^I{)AA<3S8f_MRU_=TU^8paAI&3^b^ABU4J@6xA zvmzRR^kbtxbvXjrIYbpl;3>UN=Q#R+vX3JAkjjq2vBQG=6QiWX+NJUnSe?TbnH6Tk zCq|f}d}JQ~)F>CQSl-VJceju2Uhr7s*Ac;xPyVlQ*l9Up!%(?^w{ZG1<0f&`Zwbv? zJ~!~)#|8@e!l?USmrBa`Qm&)%g-8r-d=Q5!mVJrkw>2vDUqa76F)>;m5%6gfjqAUb zzLRupjy@${eMl60`9q${+vv%a>Tq{WB<9{_j%Krr^H38{URxFTqZaCB(TD+%V4Jr^;*zP2f2F-Z9@|G1IDT#$~qDXipEaEV`96?&GY zI)VefX{uQ>KRCvmqB;ifX~EToV;c50ftvE4#p|Uwha<9u2xmDQu7p3W$UzmGChqlV z3vC6>aX7Nu{TuCdei_6>PC~HX z)JPGfs#VS;ni}UA2Ly7^Ka6t>f_Zhh9ehkO)9v6ThlKjd?bs@Q(5beYBRZe}nEV)O z;vF&KN66LzyqGvW!Wl_Mf}^cC2Xi(Acl-2D0KP^lNpR$~;R^#;TbOUzO$d%BI0^uf zo#^1}E=m#|ivxIl#A<{~$EM<=#3|EoxOrJRMxlPJGg$IBl=5$Mq+_w_O>$tSYNVwd z97#8_Uh|J9vZe-rD-vl|(IE);Bk-WHS>r+DwwOOW;=FZb=W*{i55@jG3hL;Xg_gV> z9VwEA3_9D{;o_WnEHmS}I0jL4vV->nvy&aX#9y53$i=*WDA}=I{Dc{Yz>k$Fj!5w{ z+>}zVYgdY+ZNM*0>TogzOs_T_og9<7O9h=B#ZuOIYGW=MpYNE z5}#V8I(VU1nJUMyA=NP_s)?gO!Q5aCJ`a-cu^v6p)p6gSJ|u6>I&5Vx!R5|fx;X~O zPUEh#)A-+Rtxm7%=6D4A+U|QDF>SaBdvm$~=>6hh4eQc0NA6$L5A;Ct?x1{+BSvoS zIZ=-XimiaG51c72^UMklx(N~-Js<)Q(jMUUujK9Fm?haIB?pz*Kly`@pq`G^l194? zlv*@a_mpgNr(3$s6`2a=H$(e-l9%pC#SVB?s~~LtE;NDzxE&5XD2qSj-kI*`n%11p zTvbJwV8#5*lF7#cnE$_l|8YUly_;x6XSwN)2rQkP&nq{`M^oOdc=nT%)r+k}vsr3x zFUL4(hHYtQIO}lngjLJz&o0z1ek!qDp(hVmpx?o3KlL;Z4f0E3D@g-vkzd zx|_nPC}xU+vkB?4Fdj0RE^FiQnl3NIE7=AOis_FuaEL642aVEY*;H_Fx@?<@j!Bm> z)0B$qD4#`nt9L1mM2^Y|wAh*jOPB4_l$7C=Y%vsaaJ$pZl)pl6^UXK!wY-H!CZV#d|Z%+NxxEekgo8xAbvJ1A!$Y8qj7i$ zvjD%zirH*ap!o9uFCm%QX%-|aa13!T*&HQjH1V^ATqMdS;~^fVIBMNE8GH*$b;x)G zK^@pT{vq_*_VBcflI^T6QCW?w+LAE<30_$ zeEu%w@qP-F`kA>8{pZGSA{@BG&yk61FuQs8-O85$l9@ zPUH2U>+I#q8l=`P2OD(Aj1@`>k47yba1+eh6@Vyjjl{6)qa0;R2y$kwfiNAEZEKWc zpk{3@)8lw9cT4s$v@U3^Les>awd@-~S;Es@t3-n4m1~s}q`2~+oX~4|)Y-Bm5Br7XXc=BVEKwF^NTPg(_o}{z7qR>y zIA7maynn!VCq=H@1eWQ?Apvdxhj>tmI3&O|vT>v0W_FD6Cs~Gw0S{!r=?`KQf$8f9 zSOOeNos@tlxK>x|I$CYh9g;I>f(qAZ5zPAGT{1eKYf6ODel;H#F+(j3Dkc&W8kj4-b@Z{jJ_*mdK$r1foah7cLjkEZR zdYJQ>P32_1I?OZAKt0d|%1%~NWjk4YHSO$GE4UPjh8Ug-rRx%+#XPH2_?>Y;YIzpT zM#fetoGMM*`TEfHJRo|_tmhRhj5Nps$vUQ1GS_n6UZziY!Ka5_@Y@7}K*pq3O;o-> z3d?MG0i21tlwHvEmvQG&=F0StRduRc9@?eQT3h=rC5k;Fa;%AzmZe7zRkD!AS8^RC z^oD(HxNu1Bt5intXTfL+h9m~v#07hsa;B0Mxc+PQ!Psyf__cBm$;eAQSOOEmg?~xe zf~dsZ%4*X%fwn{7CnJyd>tW^dcYs0pkTE)ZTf0mJo z#1CM~-%y5u$((NhSFmpCKZDKj-ntJS1uEyMlSlR|Q<-lpy7qSc@%`vVuZ(?@MXBIT z7NxQ`q2zL9%bT#uIE;EYBu36WfY}#p@i+h$$(1Sf%qgep!EM+Rcu=Wl-5n!i(=e~I zc@Q@LTs)|Z=kM>KJ$*VV{lsrWWISsKD(b#V0? z!X@)fG#mFQndCUaulyZ6S`Iw;IHvLzk{S*xdE`WRjzIUrS2?28@VPUaEIE&X-o#+| zF}vr{Hl;@88T4<|Q4)Ii%D-2XAa?C7MMT{~!o!RL#+i=aZt0i!oUxX7K)7H7Yy92e}x!MK3Z; z0i?~=<4Rr-yGS&)CN1FOdY;wVhhy9F#JiY=Jo0X+eI#)p$%hjm>0r|5lpD8yz2`S6 z0Uc*5O-fcU3nxSsy8$Y2+sMHBh(sOK}OLS!4@H4&qpvWa2a^*^?hZV|ZoUDJA2&z8`-i zEk$&+XiA;gpQdyfkQ}uO4L*4aEbWzTr??&Z#~j3dtdz6pQomYbRDu>zFP$G_fR!uL zK4JRheZsCfJC`RuVV4EI5N_)HltypnsZWW?VM$sr9SW!MFD&*Ye_?TUd{4j$N`tWHz&yz_B9b9=~2e-GWgPB0-WEP6)? z6E7$gA)%zTekRLr(%j~cT}pHaTt(MUv9Yk-65V)(>Om&K0cMB>819UGwsIgnY;(5eK5e*#UM~XBAr6WZdf}vN5ECdBt zi8ch8E%`-MC3K=9@MSk-kH3F#Z^?Dy0yFvy z*}5IO>rYM+bkUMCR>ZLhvK$(Vztgdn1m;aQi({c6a5Zt`WYKl`l?2&zy~v){*A`kG zM{&S_rK4{g**lB2uwXX`vZ!pBzq>(@VfMZ++;>>i{eOmx+NmZ|{Q<6*<#82?-wM5!ZpOt!8u8jVRnSFGQPV^jA3*v8 z?qc4tECe4-pC<0Hyw#;}^cGGRBe?f1_mW6J0(H{gE75Y>bb!WKZ8|6rSkcJN6{+&{ z-LP)2BnbGsW@Cb=Ay2GzmWYu%XNW)HclJzH1IK5I)WP+{==igwFITz~#c`Rxoz`-~l;*$H)1SUPqGigwfkea4+k!Q2+40=Gtsm49nKCmo9_-;wY zS56*=pSybz_ADLFV2#_7A(8ZSh zHYE!N5!Zv=1G2z#xCchGL$1CDtOYxG532%wsh|-}&sppbShiGP3Bxb*O9c(aE0&U} zu;g7{SSD)mR+Y_OXk#`&;2cvn!*$#%wlRNAlCk$;?0n!}Rv59%MKP+YSjy@0!R-=ct9 znt+|2%UtVQfHT3aQNd_Q$vS8(q&BS=XKbs?x_mO~9kTj<=nve(e!uYWMtZWA zx}`xj7l9jK@iz+R0Fyo*Wi5A+H-mWOu8rU&;IR>8MGrp+Yu#WTdr%w;X5zbL>`Vyv z<`OZ?PnCv8xc56BVUHqqlfb1{GINvgt<$?@`A=BrUbc&D{Ny0a#BUNS8B&;Rd<4>W zYb{QH-}jIT^Sg_<6#rH1ZpAHaKNstOfbyt_VhWIE9*xH*UGa}X3*oMpM@2m{rEUiM z!rp9VUTfSe;xzK&$Uvt2OdegS;se01;odaNK9w+**(D+YZ%hB8rcZ1?NNE^28SLPT*#;h#z`PB;h1u*JF@#pwh5SR3J!uT*UXA!Xu6M zm0#n5vmY06oScB@Xgp-9EYAsp&By%~lUhkEYFSLnEFXD5e?mOOe&Z0|y4uWA*gT$^aLQe!tTDW$=w6<|Avq!P=J+9!140VWNAA2QL7EO( z@gzJs93Xg7qz&gCR>)vE5$p=ewDb7()y(PW=e66#%>xcZR^uKlh&E=?eL>fDrhIal z@U6jHv$bmiHJ6lemCa?M8O~$PQxFTxJRN&l(C1m{+B&SkKZCX$G^?HgOZaDxfTU|D zn87!Pd?n@ooWR9qJH-+k&%Rj>962k2DFf%T%ppA2vf)|SiA!cD&BW*6uK*M8^KjmA zFhxQ)V4x?N%`gw%!r9VpdVc%NCS_-#f;eKPM-9C6FlKLv4 zqcZ1ZXl+c-zRaq;?qzfiW*z^DJ$u{;mNAahYhNj#tpHR*V5*uhklCj(ci8byV(bLU zZ_O<+7I^Qc6!1=?!O^mAK8Wy2JCTAHvNWeR^qF0$qq`-d8~cs z55)r7edn?J?fX~B`H@3wF#3U8T*C#+YnW4dH}Bz~Kn-{(SH|rX8CU-Vq{z4td1x;h z33abmRJ|9Va4>2wte96ey(Ut*4=neL`2N2W>bqZOr2Olg<*$pl>-!D?sa|@gKT;+n z&U5gPXjwiE&OW@3p*POx){17{HAE~%xh+k?^VYF&Gs@opVUY8}KZ|m9XK)5y;QMU5 z_lY%#R_Z_#Y=NkQmxp2Eet3jlbJKp25cJ_r?`jb)hBL1>Akt~Og)3HGkHnCpp zhtf(t2ur{4jm3Y(FYoBQ5$?GvaU{m|dmcNK{2rod^ll;dmG<;KcaT79%7d*)lKS=(kyHYTgF1{=b1?s|F1upk=U% zcTBttYNWj*Tr;RCMjy7(pr{(2?hKv7D}mNZhJ*}o0Hw0sj^cwa2sJnklj4}uGkVZqwoA2fgzgp z9Wny1KpYL^$c-iXaz3;2kK#;_Z`??;ygYH6E?fU39}M*qwJm6x>8Ps50U^OByK7nya;trFU!o36rv3s2Jb)RlZlDVhHCI zA0ndoeGDu(KAA_#7GxVr_l0CB39F{QV^>UJe}EROmt`MtC2b$TmS86OBsZ)0Bs{uw zS$`7lHpZ+cxjr6K=Qs118U(^ea+<}jAvY->igvbsmOZh^Pu*r6asz6N8^!grGiKiZ z5t%{r`zksT9pVCNOW$~E&*kE2R2PVs`o|*ce>kcv`xv8etYLlv%K?Tj`;^T>?We2< zFvxPrj!y+`;Vo(5l&TgUCo6vuUE{1_5g|#x2?=6h>ONwAif@qa&xCtGR?1>!weW6` zd7lYa;Hy^_R3e3yH3h#(>V1&wkUcOqyHa-G<;#vA!}uVsIpj2kis)2NtBCTSB}~hK zBXeIXTsKSwwz8guH-xFc&*9=?tg{Avz3g)_8NbUvXF}9{&Kjc4_r@7U{X5SaCjPs~ zVe?KpirBsHQUvxS{JSW{Sl3McQdHSy5i?lKi>!<)#aa5YFC&p7L-5GOBC1f6G0jkd zPMUd^tA+`QXB|bNO+>T!|4JYS@TP1&%Y$QdeGK(F?I54s<}=c5Jnn01WAbpy#Wosr z%c193j~Aa4zC98Hke9XRgokNjwSf>MA@H@K{ao*$e&$!bgZgD(am|~)Vs@*Qf{9fAS0 zpw8kN&Gt@67=UH`O=R*w)$*u)q-yvZXx)GX91Iiig|_eThN~|wV2uFxnO_jq&_-BK zaLeug;h#N&%Ue9i34nFOz|a%_6Rr+yxo@*?-G8$5Cwvd`BQ~!K8W7WGU6ugg+euyU zR6v~{0yH;I{~-3*uC}ZmiDX~fMOb2G<42L%?|>l50x4&UZ-H|+dI74ln?@TluNw*$ zE$D`GL(Ce3yu|B7L2Jq?u+?VuPweN?=@0YbPhtU$mr^fc1koVnMKq;B9=`}qXpo&3 z*%?Ud5!(Wz?OQ5J3bCW6!;Xy-JtA`8T)=ZNY6d%T!%;UGv_!OzniWvQGVyG%>$iv0 zXM=cGHQ80dmGbO0vx3#3!Kk}nkeW4Myo&XbL24ILmHBFpoFdef`0bsqrpmKIEy8K> zELANI;$r=~{fw?w@Ys8l^oFTXa+h5_$M0Ct^}mP9Lx%cuOs>R*shBy!B9ud|K%g&F zv56#Hy|&-c=Mq^QuI3@Re4*+xFNUjogZfUtVh3O@)_N|!g-iRlhwCHc=2@6l8P$%P zh9ZWkb5KjxFg2F+SXqRMd0bqtFhZp{($*2G7jJbV)zZ)>LO~H(o{v?%CuC!!%7;5u>{4TF{wmU3RE3Eu93hw- z^G2&ZK*c*+jT=ZxbLbe=V}m1`;8x?Yt+CLp7WgS!HBL=7CyrI`C+by>Q;(sU+1IEE zw5V3;Q8Q@TvU7skidXMMH81!Qf~HI&f|~V{RE*$r&E&~yly6`1LRnIvI?c`3tAduX zN^ekU;Yx{9vusQU8X=Mbu!Mscjf91m%F^J~vg}4QxI~&ag3g%UzX{lwJ*RIKk$RU3v!qyCY86f7GQDa)rC za0sTVzLR$zq!ZdCBTFG8mfIF7W2dPuJ|ai0pkB?FnbSaZuPm8{I-r85shKmVndFdB zGwILje)>&z!qSQKWk-^RWIR?K(fE`v$mf-{(*YNglG9Z;2+%bhEx{^mf|`k-JVC8R z4=3CVdBCUFZblaD0l?evz96mfIfIOmQ)Z}>hfsQ7HwH&)!+)XNKwIL4YUv|x4b~+l z;yfU+utg_~NN1>V)EzU`LZ&=1bTl6DHn$R=D4D6I0K=}CK&?b3C#sqKSec|HMt+f~ z?%^u~f@JwUa8O=NQkS4mPZFA3Ej_bTiL#Be)S5{oHRKo($p~)?MT#fVQM|=T`8Z5G z3}=yFpRLkoc3Wnv85o4dCWAWpG9y_{2;A^um8h0gNWGe_Ng!2EGDu0pu2w}5{A9HT za7yQ>FvVuq9B>wp%$W<0#3z}3LGxU-84ajOQCFib$2?0FLUEYTf+T2CPlaB=szj21 zAt+qt>+0BwNe9i57*Hcr}>Nd8IaR zhVyn6%M@nT?W7U#!TJoSs9ovm8~B~F2-4eNu3iLA@+Gw*s9Fr+^JmV~t z7E}lEf>qZO^2{AzNq>>)cdC1UY3rS8z3rr|$V7{uklsvC13bF~;@u!~mVm9HEh%V_ zuDjGiP^$bcP?MFa%Z#{NofiuAk)5q#XKu7?T!~$(yY5xD7$i@Y8jY5o<O_jzb!xm^wj6`8 zxog#T{BUX}<*EL}9A6%6on5DXh~%>MXjrsqu2;=Lcr7Smj;JY8%Yz_R?_Xt$Fc)q_ zP84$&t0rn{DOL+LglSueC92J`ZEE2lggsBHWx>c+_B0p=H^uKj@8P4xJJez%CYGyJ z1f%sCN;FUXO3fs!W1j^fsmyZ_xN5WcIkk>JZj);EpfI8s^%iNc5B#f3D(YE zbVY}m_s@_U-W5y!hLsm5V@jv zuR6InS(iXG`hosPO;K?wVil(eORtx%*9ZJk8hKhoQ^qH`SGL zdja-h%srq+^Ufx#R|w`@JWSTh^^C8N_Z?7gW-9cjS@!|e#nJs~=BZc7{lu{@e4M0S z{qTQTBXzFtczak3Hio`?Pz?`d(#o_IHmCU=zC|=IlqUDWW#5}PHizJo~n#%k}3BwWZOSZr=}6x_mbS_Slq8RgNk za4`yQwyePIB0I1eXYL-aZ3(5MNm>&vKtEp@I?B{;(6Ij8VIG^J!Ekh#u~W51(o3Dw zG|YjT`gE;_#272)nDd&ijg<@Yu(>8|zBXR&JBRDHw%)8A^|!0;C|$4e`$587J45>x zHA%X1m2T;>%dN@U7AxZPY~1#7cP^M?$2+(KfY0?To1-nD@y;9#3xHqGdEwZh=^?VWuC2Ffza+%<1zL%KhACUDVf_SmnBAdacG^t7Q_F$w zGHdSA^r1XKI}CIqhVP}>@pW1|>Am`5?N}JFD1Jgq0kVxxXgOS6sC2xoJI$G;+Tviu zgMJwKm!T17pVnw15zF?0~NOa0R+0ZL!-@4 zQRP~(MW+Mh+BaxO)iWBtfnpB*m6k~D%GjyZAn4wy(K2&Xg+}{7sw%WnAI7+jI2xGc zKMVH4xu0jXc3*Oo-1(d~9(i!*kXxR9PWuV*EzfH?V2DJCfLL|%z3@*K&JuR>-4`@m zev4`NU7FKJb3YOGRchE-7H#5k9CQ)a?8G-@L5FAwIIfB@j!2pRBxvzzm4=01Gv#G1 z1q>$3_h^-PjronXEf}wLd$lOMdiSEknIf9(c{((zV)IVx)=?CISMVGi0efA03RQN! zuB8MI7~0`m==;#q5S)D=-C$ymfRe{=T+lU0i83GAuZ0trl)b5SQn;yJ+eTRRnA#?K z{TGx~S;C1sWYl2|7XPre5_xe6k5-2u<}EFO-u_jKHEu$#y_i2DCB~x4Y(7lBZeVzO z`YnxSB@+LY@|(z?Of@zh0ha6$pbXB*I*#cs^S-0nQA+f@t*s_0EPt1zFxu=suC-XK zp7twTQS|*EwTB3of+o!wN^S+lcTUw+apVQNJkX@Q%(#`rq`r*;nwe#p(*vOYv6X z(CORt*v=UPU2w*s*CVeii2%@jr5KZAy%i@72kTpqnleOhCU?d)OwS1dMC8JU)~e0M z5qcLXA#=2j$%tyRX{=sIdubD|(Osw_>l%HVU!U=o+EKE69y;r=M@Q#k?Qeokqo~3O zdckPgVNR}NGM+o}MBt%6%XBu#;E8$z3N=pDiR7&lbuSR9i_!J4fE&NN(I(7Kr|G;e zxO;}~;aVLym=2DZIa43O?}L5sug}Cn>*kqyIPfi>smF8LNMG8hL_K^sY!#nDibfdl z5(4Sb(9nsAdM4Q}c?)oY>v@abL;j<=K<^G7(0?kLNAd$I-L4k~V=f8z<;Eg=!D79M z$dPcTPWw&KttD6&cVy~ibbD0gJ$ef;bsVHK zyMC!3r%rF&u4j`?jCx9!2-?fh*lL_7)P3uNL4ZN_g*bV-)kc}~w7zWs32qJ~_dKoV z0Cdg{eKmn@^1&p~*Iz0fv#mmxNKLX8FB6{86X+)8du4Ehx#JoAeFB-iQ-_e4#XI$6 z8pdGUHk4$*`w~U>ksWQf{?hOKm#aVy5CbTG?2c~qZ@nI}_!8={RZknzWK&mg>K z|51-2e9D@1Pf#e)dARKP5jT71|6sQRVCSE84{wbg0|vEg2Yc4z=cnA4;6vJ zls9~;Cn2TqQymvPn`b_Sl;gGPFU%mppXp5shNRvvp@3jT>3+_)|Eka7J<4<;1930u z45B2?0-S|v<2g~MJbV^Zz#Pe0NL7QG(x$^rV&5u39y+K0JaCT^dDg_cFQ8MC5JC|# zG*;`Wa`#vIjXqS}znX-Z%CB@WaN@#revPhUHlpIxwQKO?`ayx@-$1mO~tM=aJ(I4#!V*nYy{2m zb`OGX1bpNgC3rixikmb;oaWrA_HV}_J${+J8v3nenf-#D8%aK;2M;j{R|8%eDhuwk zMO7Sbv71BI+4p1fv3YF0JzfX#;1@fedk-rlqaL2|1eKg+K-KbIjcNur|+OA zH`wdZ`CScY=20{AEqm2aRMF+NT%zJoWTW%g(cc29h7ztQiL@!d$*blHC$O7?rCtos21eY(po&;@N> z_G1WYf3U~dB4z6jb~+;4^MgGRLE?WQEm{WuXwN_mnLpZ{giXOkv@O?k^w=c?;JF&3 z5|PO^BMm`?4Lvl@G;Kx(ghJ{HUUOxvVw7^#HW@1n*I>ee$Ti>Ja$unt9*(AQb#HW( zFk(15s9$uJFya8VTo@kUYziX^!6{)hUQdwegG$MGh_*Bdr{E#FQ;!n((RfHAI8Gi{ zjZ~iBwvq@jUy?^Nq6Sm1Sfa|khkNod?S10!So_$l8S^lA=3Al|Ej!PL#DZKsDAo@m zb+!*;oNn|WM`DB#B^TL^$bQ*~vwYdM*^NB#d8gf2y^2~ys8Ne3m8zo_jrPA2e$*P$ zjn9LXtUMN<(mU}cQNk)?(LVqaU(YsNxJCAqVMI-!)C7O-zLS>&pvb5&BL<~X!wmOe zN`>nis3Vf-1a}MPj*M8kpcYhPVp^nUBxLp)!!?B3L`1UigD}3lC=?&uaTp_p_f536 z!Q{$3hmrWdz_i)HnD#gf(^hYq;f5Ik)Cz_h8Q>%EKE7T%+!)LF^(A(+92$Xw++z|s zz2mXRrX#`#$M2p9qhfG9FvmZ}oMadu&u|*J5J5MqW_8 zO@8af$q3x4Bjgmfu>{4+-A3JI8jv>D*alwGC!_Q#**(^v(L~%h<2bPE9%q^ zPu#Es56KNFa$kGUWDnsso|EHRc8G42Cb{f z<2Qi4fZq+qDFog)?yl}QqXZgj(~X9-spLU%AIZir%`In6F&=_pGN+(H)$+m=qvXN!9A4Qn&nN(fsq?{*Ub%WcIvbNQ z^ai<@&jRd!Ynu7k4}nWQaU1y0|NDzRzh^EqhVfcjh>ZFOdwug4LU^B$B?}GO;n=va7s8aZUI;sT zf14d?5HH+;oRV&wL5pJ+8Cl#(BY@UuJibmU$OKuilDUZK-oD7lG%EajM;R~yodF9+ z%G&8K^ETNu+4&-!mB}#P0==^q1F2kDxtOh+cd@bQ>KBPh__HeN4|DY$hKC)V08CkV zhfzz&-id}q%j!FghJT1GuGq*lMlg&BR70q~El*`~Ba|g*QiY6J0?Q7$T>`A|t;Z!s z{NVj)hNZ8m>mYth3|hcUyvy)8h1NpuT}UND`Eu3WWjH5TCma_e+H!rYIO6ip{YDIn z>vw@3(K7aK!^JmrkWxy z`ZDWlxMve#^N<}ytDz%$))+agBCnE(YYit7N^%W1#|*|70SxDGvXo@L37?gId~#*8 zl?zj6$i>Exv_rpKC`s;6zc`t&76hf{)9{0m#^WJU_y}5nWMEN-fU72Nqd$O#wSFx> zhW)wg2*EM_T>W4np17RIZfOAYXCBlF1R~FH&Zm-=!KEBYc<7I1#-BC-L&W3X<)M1> z{8&dJ2bH8hh9-ORKxk_AI9az2y^VpyI%sW*!L;Q%BT+`IHzIrAJ#rb|k!{m@BO59& zt-x>^>AQf|LNR)JYbuM7Ul&6YmFW zQ4>b@jlLpoCHEVyTiCO^0(5Fl0Q!}{ARc=hKyJ{a>wcyQ=!H3m2aI9UEa=oUOO6R= z(j80CJ47gozl=lr0J}0Z55RilO3wzSdDaFam0^+{BABEfh-3j52-pPs( zs&xb0h-e(BGrCw<$OWeMjSl4S6dB2=F0Y8It19AFnMKf-@F9I~&W(&%;zq;CnvCR< zTmwR(7f=C`QKobwEH5TlQHC?S{F!NGv^R5)1&d%1ESiPsO^$t#VWm81B+MXfPJfh| zi-#K4H;x;MJQ0Yu9F|^4jex{>jPoZ`*qhvGC42nI6b6#bsA6ODFtvEq^1SR7>vD^v zEHj!6v?P2izD0Z+KA`L}3!XA?qvH)`ak;Tu(L9;RJL$INd8=f!G{%-Ll!m!bhRs=U z^`P|qID@DC@z(tzhE4nPhW#O7Hr+FKe~81T{~+tmghdS=Gkbr?5SwA2J=(oLWSC7W zm#t^QMg(2ELKYZ~k>-#u!y<;7W4ppmjJWEiq^vvgR}^f_Um2aVZh2v0QuMgxNlVqq zNm+7GxZ~Q50l(f|RdAQ?&7~46sBf;_cV8^7Kfgtynh;j`#cT zC+$xfmrPa7vW0Xc&Dx(de$MiuHiUDqgVap;f3S=m-vy zI@ZpJu76atB$x07Zk?@zjhU#YHIsTMitmXL8pj`(qV3FL&^H{`C*Ey{fm z`Gf13Oyd!iU$ndswFg(o$BG>D;HQ*<0k z&$(qT$hdgbhV{Am_Z0yBwesIKI$p%4z!eWVVlh#?^Fhbh=ofu>XD;86pPRqB5ZU%q syT=kk&a(aNNAsfx9q06*t&hv2TOCey|D0KiXZ_6fm2P&mtL1q=YtG(y^yc^dz0dP|pZ7eDvu9?_ znzh!fS+i#L>|w!68MB|sn7vUE6P2?Sr@xLiVOI50>ft`6e5Hm1R?Z5 z;I@(&OyJ>buh+{+xWRY?{xK0;;YNg(2ns?c1QnqTf)jy}&q82gZbe8#;KmFDCIDz9 zUWVl~*X@na!FrCnj>2A748=+A*Oe403+91&@gOjIyQ#@|4n^RYNp&Ew+}b1P2n@$@ zCIbIh4$Nx-!aouC$Mu*rj+uXEk;|Dp)Gw6}T&Wnr1{#d#seb7Zcy5irmAR8_I2QVY zerc{}cN7!Gb-2SiB5>oK5Lh1kV;qj_=%zQ6{b~p4uR2exPejil}x$H~x(Jwm2Cg5rKP!wU_a;=w~7DfZ}|ArD1vUPxd5* zu2ZsH48o#6L*>gBr0lQAR%_;x=yVe+yWdkvMZS$PcLS zPH|&cpWmXSv}2WIK-Po|20-9nCxliNHRaJax@FpjhKDShXJ&z|C0o8*5Lh})-aG{U zvBbDJZrZLBN^`aFM7TH z>9niTU9L*EMVbZ2ZTQyNDk8B|H!+*b8I^S#dC>9Z(9D5UM<&q=`_4K6pWi(itL*&K^)Ugoj&zEv&dD znO~qngs(y?Uxigu4=PG{qy^%(;?`#AAtg{z+R%c-FfrQ?D-i*Gfw?C_v_ikP3XW3R znvI8*6>2~`)ER^P3u?uHrz6ef4a!U*VifxMbt8^)zErTDN7OJ{|BEt4#4B{{6E)I|IjbyIsMk5AwYle4<$gu!NZ{CQ=A7f6PN2}=U{9y~ zrnIL^86rYTz7rMwrVQ)Z8EBb@ID|+9?vyTmc|2-4FUc>jHFkN_V%ue9BgJCL@GE2XZ4qW(m2Zo2 z03EoXr0N4v?4s<8=#}J)N>?R|@-HeywC|#_xDBHnhjO00Z1^PW-(#g2 z8>jCz^Z!sTD#}C}=T%Y=&GRZr?Ir<=tvVv9`4jQL&vKBM^N__0gvJe|B=Wd^;wPVcZJS#&aUgm_iNOaU|xX0~}ncxGzDFd;B?_hZPstVB{y z797Q7U9|1UW0Q3`7J*rn6#3<`)E=N>UBv6L$PS^D3OHKh4JU2WMK@(CHR+;8DW+;e zxW$7C4Tx4ELFU-6iLd%OlUNH?i3Md?37cah({D!c+44zWQt3qL0W)t z(=3+=Q)W`ROC)yomjHA7C`e-bEXQ=jOoL2QBV(9Cxvhge%45u)JDh<$0ATvLatRd# zi1cQuvIEO=G0XmOfZ961=_lCwC&8$l4glI&Qi4h;r3Z@qRyP0s^=H$XK-j!?v^P*> zw|WxTxWT6ov(`%qQBsg7QRYx)OYpcYNVJV&`XW)x^o>Q}d7c}e>$9C^KrlK{dD=`5 z5vLU888bc%w9u4r@kt*BTkJ-BLu0moN{#6A)E# zGAn{Y7Qu(y*Fpq|zhY7y7I_0RunedMAm$&ZE0Jbqh9j`^oq)i8JEMNthx!#}Fj`ch zYYja{YFjmxwuEqAm5oOI%_7?t{c@xk_X>r&l|%i1Y$;lcl?uH&M2T$0h+hK$^J918 z>)gAEVwDd>XOK6j1|3doqZFrj)0a>CB18vSxP}WoRQ9YI;j(eO?XhCO@ zDe557FF@Y$&Z3{PojhGcqOyaAbwQ<_Gzn4ohiH~<5PP{y-!7sqB1L)6+}%aMQ10eB zZaUIc1Subxr@DeNn$=CTHG8Fq;fk_{O1pu`y=HAUaY9i(p%vZ5IOS9GVt0|RihbZU znU1zmgJ@ANfY(z)FLB(OGdOgwYRum5uYm+>)wx{ z3w^`{)oIa!DYExt#mi-;=<4#72g z!H8=ESgB6jrhmo5RFf{^TYQOf|8D*YM)B)Nx{xk9C`ZWCPgE)mw51=!_%${36V=K$ zRMH;=9aU)ED{73nxxe^UQ5wzaOfgIgJ_c;}S(N>QYDS4t3MdqOCP#EK zl>Mgr7H9y(mpK;Qw%;rrD^81$pZwtesnCQXze(xtk2vl zerH}!PZFhwiYALmhz?AaDM=~_=#8v`*F-$Uj1e=bsz}U*SPoAS*<2ISDyEEqpmO#7 zVkIqq0E2Mq1EL4TO~uo)BK)^@49K6F3-YlPp9(^ky@>Lu14WRue7{rf1B`qSaLj)I ztN%k&#a8_fP&|-A9|U;J04zw>l4x)KSS*56<&t@RnlLr$J`**z4F>Y4rvNc)hUg}) z6SQuIh@=d%<(82rg3PL!Vy9xReGJtpqy!uVnX8_F9w@=&*@ZZS8fPI2rQDsu?P6zx zhe$Y;K8@a*I7{52wD1A8^Z`cr09#prkrL2Mm<_;SH!^KiZf%x732h2#7XT->mE`Ehc5a$rky6+h=IJhecY{sr9 z&pffJW3pdX3Z8k%-T{G~J=?+TM%BwiCT;txxF_TWKlttz?vO>Iy;Ou$3f%|i$9PU0 z>)68&u;(=p_hQ6}H2!^61qL?1(ENf1XiId)T=dxAWum*6A4~ma6dm9 z`%}s?F^)2x6*mQE_~mDEez7uuNzD!!=vOkxVxQH3rapzXqyl95fefaCN|?DJepy2q zUlOgI53NsrMf5P2zAQcxJV2|338HA>0+C>5yed9XDQcx?Yw(0MLT1O&rCUYVs_`oY z#;u6~Ev=kykXK+}hg3iUn~Q+>kyUVcB}%t>WR-YNDA|;`2IFHS)vOlf$|zqdhf`SD zu0_4F38;sm7Dh+cpmMI6^p`4|I)mM4Efv z6F&iVvv^CATVRpP7K)Z{0pf{Ufq2;hv~y;Qc$^;FD!NL@Nj`olr&fH+W+H+vZ4ndX zlbO6tbW&-49RxeIPPA3-qXl*11kKtGv%^9uGE29^YZ3PgnlM<2#A+;bC$uklHyZ7} z6R3{v6i!hrXn&6Y--6&l-&pz!x`Wkc8Wr!v3^AQ*xZX*-3W*OfUU}<{fgbVInPJtL z$#qhjOCR;sUCK3h5y3S|d^H}oYCIuLOE?dvLIfLX7T0uBz%IBurM{s)+gI^PtKw6# zB0aN9ET&$&!H?u@G(Snsp7!JH8DG_TR@G;zd^a4blQt|t#V)h7zz6)i1^j{pR?4X0 zBWOsuuW+GN_@a-9T_0f>ijV#5ScMO6u?4q;;Zi849@I_zSiGk!CC?s_+J+}b_MKx9 z?0q-sk5JJb5#8npiupG{{(s$d`G|S3euS#`i1>EAc3^jh9on%7{LD32%tVcQ;G(=_ zmh2T3LisD(9*?q&QuYaqIUzl3dhEe~AUd-TlS?F1#u8LsA$PqvuT)X!emFJzsb)V0 zQgh_pkM3=znyNnwbW_M6ASioYICYEk&#-F3WQ$1bhc|Q&=BqRNMcDs~1Z@5R_^oFv zitdXxryUT3MN~EVfJ3TJd!409Bn=%5_*|aNA zZB2&))Yiyt3Q!NzksxFo4OD*@8wDLZtVEi>1gVo*0QsS6G;quaRW}H+35CmD9x7^~ zMoWukLi1jCCA47AnpM^2^gRIfF%syP7V2Qy)krj&ct7#C_v728c-4`lTbm9$qU zDIe2`_G%*5bb+yIyt0>4V$~un=@7-!wpj4=DR~m16d`eV-sj7&8jZ!>o>;Xj7I$`G z5bcUn@25raYI_>nU4`cn4?X>iD&o}*%I7|?@g3Bgu%@f&pyn!HkhcTme2_9bs#(e* zn$uA&Ru0qIjv(esicU~dm9Ho_0gy0#2_UV3ni7391<}M#Y8V}f#mau9#nji_!W^u~ zP$izGCaV#2BoY7h>ZEp{7X061{2w@ywIh^c(x7yGqk0 z1{J>04eA8tH_p$coEx$IliXc(D*xfObqWU6`(l|icFI+fb@P{%6@mG)4FDS~$QfbmkPuqRkL-V-FR?}^rX^#V&5 zdcyuq>jf$mpluLCJ%mFSnn+Q+<|u=$V;cHo7DEw*Gr_5LFy{J+ltRpYiRsn z=v>ZFAdTUtANjwk!RknQWQbouH#!12;4K+MkWZfvfi1h9P7i^|l4;&hH6Oe3Cx(Kl zZj?I=Ox-{<3`}*WEyKW6Dg_P)Q#~kYIGE~56~i$^dePb807)bFji}I@3T{-#DSgPi z5o5kD6^&45DCtz1t)^0BHd^jSo>3TcIoZ&I&$HDYv_2bMlHr30=?sWWA4JATXz&0k z9*KqrQte16W6UT>%jgW{nK%l9S~dpEE*qu#)|-QU)yhV}Mh&6eqhL{nQeY1Bb{J*n zKv9NMbq*-Jkxu16dqz-pF38TN;#_2oBr_NCxcep+RW}fk!}*CmgK+yGwQWU4iIaBS zqz+bcDez`>x^feh-i%r4W~+mKyjdNI_mlOb!RM6GK#<4fI3O_^T#VuTeB~BO%7aN8 zO9go#Zk!KbR~|;wt-gxMV<3v#D0d79yWLm3bPQM)x8T2{cv9}*+$1yk77TplPMR?m zT{WIgj8#b~pptQFrI?`72fejOO1>4^eHSgb74pBE)Z5fN+H)IJY~pR|J<2___cmC{ zdnxyJAecy7ZihrBktZKxW-`^}19;*c0B&)IItDxIlkR}{ifGFn==J+4{!TSsJfPC6 z8Cn!?6-Y=_D2d}ksjju(X=fGCTc_h?DE4@Pyn0z2&GJ5KZvttPNe zrz9Lryc_1J>X452>32aK&mbwGp7zy0lO_yWw;xEh-Hjd!C{(}oc`?tc&0b7v@q$Xn zB8)E7{T{W0C{t;FqKKkt_h96eb1TvG*eE4JqFqR}_h1HpQRNvtj$-bGIxM2hdocnk z%<_BHMxiV=izlm@fyxrIX1dxSl%?i^N91^e;OvtH>=V2L#{vJO-*5|Jp845ky#zSk z@r^~0a1=cggZQsz$xP@Ze689?F&q#(O4L+US!SlsQge0MH5Y>puVY)Ao9AHW6EA}& zcK?pfRW&8y6(D8*3XyE23J>ha@Um_&0{3h+YIMdXbRFIK3&mjPX##q@dUJuFq$4hjx3*FLMxRh5;L`aDL`O0)cVc2-vsy`auR z{5sTO5GcnDqJ%k;gbCv2s?8nMJp{keFpXppR z0O!AkvOQ<@AamO*YHvX;UR7I5e|)pL^!|W2v)8NYRt2n{{Tn99UMr#N%a­$LF= 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 eZ(bJf3p1~s4{>;M_RQ;NUgY{@m^@wXiT)qT@ + Tvar | Tunivar -> Pgenarray | Tconstr(p, args, abbrev) -> if Path.same p Predef.path_int || Path.same p Predef.path_char then diff --git a/byterun/.depend b/byterun/.depend index 43277c13..3ce28b10 100644 --- a/byterun/.depend +++ b/byterun/.depend @@ -87,7 +87,7 @@ meta.o: meta.c alloc.h compatibility.h misc.h config.h ../config/m.h \ major_gc.h freelist.h memory.h gc.h minor_gc.h prims.h stacks.h minor_gc.o: minor_gc.c config.h ../config/m.h ../config/s.h \ compatibility.h fail.h misc.h mlvalues.h finalise.h roots.h memory.h \ - gc.h major_gc.h freelist.h minor_gc.h gc_ctrl.h signals.h + gc.h major_gc.h freelist.h minor_gc.h gc_ctrl.h signals.h weak.h misc.o: misc.c config.h ../config/m.h ../config/s.h compatibility.h \ misc.h memory.h gc.h mlvalues.h major_gc.h freelist.h minor_gc.h obj.o: obj.c alloc.h compatibility.h misc.h config.h ../config/m.h \ @@ -224,7 +224,7 @@ meta.d.o: meta.c alloc.h compatibility.h misc.h config.h ../config/m.h \ major_gc.h freelist.h memory.h gc.h minor_gc.h prims.h stacks.h minor_gc.d.o: minor_gc.c config.h ../config/m.h ../config/s.h \ compatibility.h fail.h misc.h mlvalues.h finalise.h roots.h memory.h \ - gc.h major_gc.h freelist.h minor_gc.h gc_ctrl.h signals.h + gc.h major_gc.h freelist.h minor_gc.h gc_ctrl.h signals.h weak.h misc.d.o: misc.c config.h ../config/m.h ../config/s.h compatibility.h \ misc.h memory.h gc.h mlvalues.h major_gc.h freelist.h minor_gc.h obj.d.o: obj.c alloc.h compatibility.h misc.h config.h ../config/m.h \ diff --git a/byterun/compatibility.h b/byterun/compatibility.h index 0eca2794..f005bfd0 100644 --- a/byterun/compatibility.h +++ b/byterun/compatibility.h @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: compatibility.h,v 1.15 2006/01/27 14:33:42 doligez Exp $ */ +/* $Id: compatibility.h,v 1.15.6.1 2008/01/21 14:09:05 doligez Exp $ */ /* definitions for compatibility with old identifiers */ @@ -237,8 +237,7 @@ #define young_end caml_young_end #define young_ptr caml_young_ptr #define young_limit caml_young_limit -#define ref_table_ptr caml_ref_table_ptr -#define ref_table_limit caml_ref_table_limit +#define ref_table caml_ref_table #define minor_collection caml_minor_collection #define check_urgent_gc caml_check_urgent_gc diff --git a/byterun/finalise.c b/byterun/finalise.c index ed1e91bc..9408c9eb 100644 --- a/byterun/finalise.c +++ b/byterun/finalise.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: finalise.c,v 1.19.10.1 2007/11/19 17:15:53 doligez Exp $ */ +/* $Id: finalise.c,v 1.19.10.2 2008/01/17 15:57:23 doligez Exp $ */ /* Handling of finalised values. */ @@ -85,8 +85,9 @@ void caml_final_update (void) Assert (Is_in_heap (final_table[i].val)); if (Is_white_val (final_table[i].val)){ if (Tag_val (final_table[i].val) == Forward_tag){ + value fv; Assert (final_table[i].offset == 0); - value fv = Forward_val (final_table[i].val); + fv = Forward_val (final_table[i].val); if (Is_block (fv) && (Is_young (fv) || Is_in_heap (fv)) && (Tag_val (fv) == Forward_tag || Tag_val (fv) == Lazy_tag || Tag_val (fv) == Double_tag)){ diff --git a/byterun/freelist.c b/byterun/freelist.c index de775503..91c9d7cd 100644 --- a/byterun/freelist.c +++ b/byterun/freelist.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: freelist.c,v 1.17 2005/09/22 14:21:50 xleroy Exp $ */ +/* $Id: freelist.c,v 1.17.10.3 2008/02/19 13:36:49 doligez Exp $ */ #include "config.h" #include "freelist.h" @@ -63,7 +63,11 @@ static void fl_check (void) size_found += Whsize_bp (cur); Assert (Is_in_heap (cur)); if (cur == fl_prev) prev_found = 1; - if (cur == caml_fl_merge) merge_found = 1; + if (cur == caml_fl_merge){ + merge_found = 1; + Assert (cur <= caml_gc_sweep_hp); + Assert (Next (cur) == NULL || Next (cur) > caml_gc_sweep_hp); + } prev = cur; cur = Next (prev); } @@ -71,6 +75,7 @@ static void fl_check (void) Assert (merge_found || caml_fl_merge == Fl_head); Assert (size_found == caml_fl_cur_size); } + #endif /* [allocate_block] is called by [caml_fl_allocate]. Given a suitable free @@ -109,7 +114,7 @@ static char *allocate_block (mlsize_t wh_sz, char *prev, char *cur) } fl_prev = prev; return cur + Bosize_hd (h) - Bsize_wsize (wh_sz); -} +} /* [caml_fl_allocate] does not set the header of the newly allocated block. The calling function must do it before any GC function gets called. @@ -175,14 +180,9 @@ char *caml_fl_merge_block (char *bp) mlsize_t prev_wosz; caml_fl_cur_size += Whsize_hd (hd); - + #ifdef DEBUG - { - mlsize_t i; - for (i = 0; i < Wosize_hd (hd); i++){ - Field (Val_bp (bp), i) = Debug_free_major; - } - } + caml_set_fields (bp, 0, Debug_free_major); #endif prev = caml_fl_merge; cur = Next (prev); @@ -249,29 +249,26 @@ char *caml_fl_merge_block (char *bp) /* This is a heap extension. We have to insert it in the right place in the free-list. - [caml_fl_add_block] can only be called right after a call to + [caml_fl_add_blocks] can only be called right after a call to [caml_fl_allocate] that returned NULL. Most of the heap extensions are expected to be at the end of the free list. (This depends on the implementation of [malloc].) + + [bp] must point to a list of blocks chained by their field 0, + terminated by NULL, and field 1 of the first block must point to + the last block. */ -void caml_fl_add_block (char *bp) +void caml_fl_add_blocks (char *bp) { Assert (fl_last != NULL); Assert (Next (fl_last) == NULL); -#ifdef DEBUG - { - mlsize_t i; - for (i = 0; i < Wosize_bp (bp); i++){ - Field (Val_bp (bp), i) = Debug_free_major; - } - } -#endif - caml_fl_cur_size += Whsize_bp (bp); if (bp > fl_last){ Next (fl_last) = bp; - Next (bp) = NULL; + if (fl_last == caml_fl_merge && bp < caml_gc_sweep_hp){ + caml_fl_merge = (char *) Field (bp, 1); + } }else{ char *cur, *prev; @@ -282,12 +279,14 @@ void caml_fl_add_block (char *bp) cur = Next (prev); } Assert (prev < bp || prev == Fl_head); Assert (cur > bp || cur == NULL); - Next (bp) = cur; + Next (Field (bp, 1)) = cur; Next (prev) = bp; - /* When inserting a block between [caml_fl_merge] and [caml_gc_sweep_hp], + /* When inserting blocks between [caml_fl_merge] and [caml_gc_sweep_hp], we must advance [caml_fl_merge] to the new block, so that [caml_fl_merge] is always the last free-list block before [caml_gc_sweep_hp]. */ - if (prev == caml_fl_merge && bp <= caml_gc_sweep_hp) caml_fl_merge = bp; + if (prev == caml_fl_merge && bp < caml_gc_sweep_hp){ + caml_fl_merge = (char *) Field (bp, 1); + } } } diff --git a/byterun/freelist.h b/byterun/freelist.h index 518e768c..ad745b07 100644 --- a/byterun/freelist.h +++ b/byterun/freelist.h @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: freelist.h,v 1.12 2004/01/02 19:23:21 doligez Exp $ */ +/* $Id: freelist.h,v 1.12.20.1 2008/02/12 21:26:29 doligez Exp $ */ /* Free lists of heap blocks. */ @@ -28,7 +28,7 @@ char *caml_fl_allocate (mlsize_t); void caml_fl_init_merge (void); void caml_fl_reset (void); char *caml_fl_merge_block (char *); -void caml_fl_add_block (char *); +void caml_fl_add_blocks (char *); void caml_make_free_blocks (value *, mlsize_t, int); diff --git a/byterun/gc_ctrl.c b/byterun/gc_ctrl.c index fa5c7034..7f0a04d0 100644 --- a/byterun/gc_ctrl.c +++ b/byterun/gc_ctrl.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: gc_ctrl.c,v 1.50.10.1 2007/11/20 18:27:06 doligez Exp $ */ +/* $Id: gc_ctrl.c,v 1.50.10.2 2008/02/12 13:30:16 doligez Exp $ */ #include "alloc.h" #include "compact.h" @@ -457,10 +457,6 @@ void caml_init_gc (uintnat minor_size, uintnat major_size, { uintnat major_heap_size = Bsize_wsize (norm_heapincr (major_size)); -#ifdef DEBUG - caml_gc_message (-1, "### O'Caml runtime: debug mode ###\n", 0); -#endif - caml_set_minor_heap_size (Bsize_wsize (norm_minsize (minor_size))); caml_major_heap_increment = Bsize_wsize (norm_heapincr (major_incr)); caml_percent_free = norm_pfree (percent_fr); diff --git a/byterun/main.c b/byterun/main.c index 6ede2d3f..71b989d3 100644 --- a/byterun/main.c +++ b/byterun/main.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: main.c,v 1.36 2004/01/08 22:28:48 doligez Exp $ */ +/* $Id: main.c,v 1.36.20.1 2008/02/12 13:30:16 doligez Exp $ */ /* Main entry point (can be overridden by a user-provided main() function that calls caml_main() later). */ @@ -28,6 +28,27 @@ CAMLextern void caml_expand_command_line (int *, char ***); int main(int argc, char **argv) { +#ifdef DEBUG + { + char *ocp; + char *cp; + int i; + + caml_gc_message (-1, "### OCaml runtime: debug mode ###\n", 0); +#if 0 + caml_gc_message (-1, "### command line:", 0); + for (i = 0; i < argc; i++){ + caml_gc_message (-1, " %s", argv[i]); + } + caml_gc_message (-1, "\n", 0); + ocp = getenv ("OCAMLRUNPARAM"); + caml_gc_message (-1, "### OCAMLRUNPARAM=%s\n", ocp == NULL ? "" : ocp); + cp = getenv ("CAMLRUNPARAM"); + caml_gc_message (-1, "### CAMLRUNPARAM=%s\n", cp == NULL ? "" : cp); + caml_gc_message (-1, "### working dir: %s\n", getcwd (NULL, 0)); +#endif + } +#endif #ifdef _WIN32 /* Expand wildcards and diversions in command line */ caml_expand_command_line(&argc, &argv); diff --git a/byterun/major_gc.c b/byterun/major_gc.c index 1f3ce458..c97e493a 100644 --- a/byterun/major_gc.c +++ b/byterun/major_gc.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: major_gc.c,v 1.58.10.2 2007/11/26 16:11:49 doligez Exp $ */ +/* $Id: major_gc.c,v 1.58.10.3 2008/01/21 14:09:05 doligez Exp $ */ #include @@ -50,11 +50,7 @@ extern char *caml_fl_merge; /* Defined in freelist.c. */ static char *markhp, *chunk, *limit; -static int gc_subphase; /* Subphase_main Subphase_weak[12] Subphase_final */ -#define Subphase_main 10 -#define Subphase_weak1 11 -#define Subphase_weak2 12 -#define Subphase_final 13 +int caml_gc_subphase; /* Subphase_{main,weak1,weak2,final} */ static value *weak_prev; #ifdef DEBUG @@ -118,7 +114,7 @@ static void start_cycle (void) caml_gc_message (0x01, "Starting new major GC cycle\n", 0); caml_darken_all_roots(); caml_gc_phase = Phase_mark; - gc_subphase = Subphase_main; + caml_gc_subphase = Subphase_main; markhp = NULL; #ifdef DEBUG ++ major_gc_counter; @@ -134,7 +130,7 @@ static void mark_slice (intnat work) mlsize_t size, i; caml_gc_message (0x40, "Marking %ld words\n", work); - caml_gc_message (0x40, "Subphase = %ld\n", gc_subphase); + caml_gc_message (0x40, "Subphase = %ld\n", caml_gc_subphase); gray_vals_ptr = gray_vals_cur; while (work > 0){ if (gray_vals_ptr > gray_vals){ @@ -197,11 +193,11 @@ static void mark_slice (intnat work) markhp = chunk; limit = chunk + Chunk_size (chunk); }else{ - switch (gc_subphase){ + switch (caml_gc_subphase){ case Subphase_main: { /* The main marking phase is over. Start removing weak pointers to dead values. */ - gc_subphase = Subphase_weak1; + caml_gc_subphase = Subphase_weak1; weak_prev = &caml_weak_list_head; } break; @@ -240,7 +236,7 @@ static void mark_slice (intnat work) work -= Whsize_hd (hd); }else{ /* Subphase_weak1 is done. Start removing dead weak arrays. */ - gc_subphase = Subphase_weak2; + caml_gc_subphase = Subphase_weak2; weak_prev = &caml_weak_list_head; } } @@ -264,7 +260,7 @@ static void mark_slice (intnat work) gray_vals_cur = gray_vals_ptr; caml_final_update (); gray_vals_ptr = gray_vals_cur; - gc_subphase = Subphase_final; + caml_gc_subphase = Subphase_final; } } break; diff --git a/byterun/major_gc.h b/byterun/major_gc.h index 7c493090..1bcf45f6 100644 --- a/byterun/major_gc.h +++ b/byterun/major_gc.h @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: major_gc.h,v 1.21 2005/09/22 14:21:50 xleroy Exp $ */ +/* $Id: major_gc.h,v 1.21.10.1 2008/01/21 14:09:05 doligez Exp $ */ #ifndef CAML_MAJOR_GC_H #define CAML_MAJOR_GC_H @@ -33,6 +33,7 @@ typedef struct { #define Chunk_block(c) (((heap_chunk_head *) (c)) [-1]).block extern int caml_gc_phase; +extern int caml_gc_subphase; extern uintnat caml_allocated_words; extern double caml_extra_heap_resources; extern uintnat caml_dependent_size, caml_dependent_allocated; @@ -41,6 +42,10 @@ extern uintnat caml_fl_size_at_phase_change; #define Phase_mark 0 #define Phase_sweep 1 #define Phase_idle 2 +#define Subphase_main 10 +#define Subphase_weak1 11 +#define Subphase_weak2 12 +#define Subphase_final 13 #ifdef __alpha typedef int page_table_entry; diff --git a/byterun/memory.c b/byterun/memory.c index c3f4fa8b..5337b637 100644 --- a/byterun/memory.c +++ b/byterun/memory.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: memory.c,v 1.43 2005/09/22 14:21:50 xleroy Exp $ */ +/* $Id: memory.c,v 1.43.10.3 2008/02/12 21:26:29 doligez Exp $ */ #include #include @@ -27,6 +27,8 @@ #include "mlvalues.h" #include "signals.h" +extern uintnat caml_percent_free; /* major_gc.c */ + #ifdef USE_MMAP_INSTEAD_OF_MALLOC extern char * caml_aligned_mmap (asize_t size, int modulo, void ** block); extern void caml_aligned_munmap (char * addr, asize_t size); @@ -96,7 +98,7 @@ int caml_add_to_heap (char *m) page_table_entry *block, *new_page_table; asize_t new_page_low = Page (m); asize_t new_size = caml_page_high - new_page_low; - + caml_gc_message (0x08, "Growing page table to %lu entries\n", new_size); block = malloc (new_size * sizeof (page_table_entry)); if (block == NULL){ @@ -118,7 +120,7 @@ int caml_add_to_heap (char *m) page_table_entry *block, *new_page_table; asize_t new_page_high = Page (m + Chunk_size (m)); asize_t new_size = new_page_high - caml_page_low; - + caml_gc_message (0x08, "Growing page table to %lu entries\n", new_size); block = malloc (new_size * sizeof (page_table_entry)); if (block == NULL){ @@ -169,25 +171,52 @@ int caml_add_to_heap (char *m) } /* Allocate more memory from malloc for the heap. - Return a blue block of at least the requested size (in words). - The caller must insert the block into the free list. + Return a blue block of at least the requested size. + The blue block is chained to a sequence of blue blocks (through their + field 0); the last block of the chain is pointed by field 1 of the + first. There may be a fragment after the last block. + The caller must insert the blocks into the free list. The request must be less than or equal to Max_wosize. Return NULL when out of memory. */ static char *expand_heap (mlsize_t request) { - char *mem; - asize_t malloc_request; + char *mem, *hp, *prev; + asize_t over_request, malloc_request, remain; - malloc_request = caml_round_heap_chunk_size (Bhsize_wosize (request)); + Assert (request <= Max_wosize); + over_request = request + request / 100 * caml_percent_free; + malloc_request = caml_round_heap_chunk_size (Bhsize_wosize (over_request)); mem = caml_alloc_for_heap (malloc_request); if (mem == NULL){ caml_gc_message (0x04, "No room for growing heap\n", 0); return NULL; } - Assert (Wosize_bhsize (malloc_request) >= request); - Hd_hp (mem) = Make_header (Wosize_bhsize (malloc_request), 0, Caml_blue); - + remain = malloc_request; + prev = hp = mem; + /* XXX find a way to do this with a call to caml_make_free_blocks */ + while (Wosize_bhsize (remain) > Max_wosize){ + Hd_hp (hp) = Make_header (Max_wosize, 0, Caml_blue); +#ifdef DEBUG + caml_set_fields (Bp_hp (hp), 0, Debug_free_major); +#endif + hp += Bhsize_wosize (Max_wosize); + remain -= Bhsize_wosize (Max_wosize); + Field (Op_hp (mem), 1) = Field (Op_hp (prev), 0) = (value) Op_hp (hp); + prev = hp; + } + if (remain > 1){ + Hd_hp (hp) = Make_header (Wosize_bhsize (remain), 0, Caml_blue); +#ifdef DEBUG + caml_set_fields (Bp_hp (hp), 0, Debug_free_major); +#endif + Field (Op_hp (mem), 1) = Field (Op_hp (prev), 0) = (value) Op_hp (hp); + Field (Op_hp (hp), 0) = (value) NULL; + }else{ + Field (Op_hp (prev), 0) = (value) NULL; + if (remain == 1) Hd_hp (hp) = Make_header (0, 0, Caml_white); + } + Assert (Wosize_hp (mem) >= request); if (caml_add_to_heap (mem) != 0){ caml_free_for_heap (mem); return NULL; @@ -267,7 +296,7 @@ CAMLexport value caml_alloc_shr (mlsize_t wosize, tag_t tag) else caml_raise_out_of_memory (); } - caml_fl_add_block (new_block); + caml_fl_add_blocks (new_block); hp = caml_fl_allocate (wosize); } @@ -358,10 +387,10 @@ void caml_initialize (value *fp, value val) { *fp = val; if (Is_block (val) && Is_young (val) && Is_in_heap (fp)){ - *caml_ref_table_ptr++ = fp; - if (caml_ref_table_ptr >= caml_ref_table_limit){ - caml_realloc_ref_table (); + if (caml_ref_table.ptr >= caml_ref_table.limit){ + caml_realloc_ref_table (&caml_ref_table); } + *caml_ref_table.ptr++ = fp; } } diff --git a/byterun/memory.h b/byterun/memory.h index 3723d04f..b830ba5b 100644 --- a/byterun/memory.h +++ b/byterun/memory.h @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: memory.h,v 1.56 2007/02/09 13:31:15 doligez Exp $ */ +/* $Id: memory.h,v 1.56.4.1 2008/01/21 14:09:05 doligez Exp $ */ /* Allocation macros and functions */ @@ -94,11 +94,11 @@ color_t caml_allocation_color (void *hp); if (caml_gc_phase == Phase_mark) caml_darken (_old_, NULL); \ if (Is_block (val) && Is_young (val) \ && ! (Is_block (_old_) && Is_young (_old_))){ \ - *caml_ref_table_ptr++ = (fp); \ - if (caml_ref_table_ptr >= caml_ref_table_limit){ \ - CAMLassert (caml_ref_table_ptr == caml_ref_table_limit); \ - caml_realloc_ref_table (); \ + if (caml_ref_table.ptr >= caml_ref_table.limit){ \ + CAMLassert (caml_ref_table.ptr == caml_ref_table.limit); \ + caml_realloc_ref_table (&caml_ref_table); \ } \ + *caml_ref_table.ptr++ = (fp); \ } \ } \ }while(0) diff --git a/byterun/minor_gc.c b/byterun/minor_gc.c index 96904671..b262830e 100644 --- a/byterun/minor_gc.c +++ b/byterun/minor_gc.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: minor_gc.c,v 1.43.10.1 2007/11/20 18:27:06 doligez Exp $ */ +/* $Id: minor_gc.c,v 1.43.10.2 2008/01/21 14:09:05 doligez Exp $ */ #include #include "config.h" @@ -26,23 +26,55 @@ #include "mlvalues.h" #include "roots.h" #include "signals.h" +#include "weak.h" asize_t caml_minor_heap_size; CAMLexport char *caml_young_start = NULL, *caml_young_end = NULL; CAMLexport char *caml_young_ptr = NULL, *caml_young_limit = NULL; -static value **ref_table = NULL, **ref_table_end, **ref_table_threshold; -CAMLexport value **caml_ref_table_ptr = NULL, **caml_ref_table_limit; -static asize_t ref_table_size, ref_table_reserve; + +CAMLexport struct caml_ref_table + caml_ref_table = { NULL, NULL, NULL, NULL, NULL, 0, 0}, + caml_weak_ref_table = { NULL, NULL, NULL, NULL, NULL, 0, 0}; + int caml_in_minor_collection = 0; #ifdef DEBUG static unsigned long minor_gc_counter = 0; #endif +void caml_alloc_table (struct caml_ref_table *tbl, asize_t sz, asize_t rsv) +{ + value **new_table; + + tbl->size = sz; + tbl->reserve = rsv; + new_table = (value **) caml_stat_alloc ((tbl->size + tbl->reserve) + * sizeof (value *)); + if (tbl->base != NULL) caml_stat_free (tbl->base); + tbl->base = new_table; + tbl->ptr = tbl->base; + tbl->threshold = tbl->base + tbl->size; + tbl->limit = tbl->threshold; + tbl->end = tbl->base + tbl->size + tbl->reserve; +} + +static void reset_table (struct caml_ref_table *tbl) +{ + tbl->size = 0; + tbl->reserve = 0; + if (tbl->base != NULL) caml_stat_free (tbl->base); + tbl->base = tbl->ptr = tbl->threshold = tbl->limit = tbl->end = NULL; +} + +static void clear_table (struct caml_ref_table *tbl) +{ + tbl->ptr = tbl->base; + tbl->limit = tbl->threshold; +} + void caml_set_minor_heap_size (asize_t size) { char *new_heap; - value **new_table; Assert (size >= Minor_heap_min); Assert (size <= Minor_heap_max); @@ -59,16 +91,8 @@ void caml_set_minor_heap_size (asize_t size) caml_young_ptr = caml_young_end; caml_minor_heap_size = size; - ref_table_size = caml_minor_heap_size / sizeof (value) / 8; - ref_table_reserve = 256; - new_table = (value **) caml_stat_alloc ((ref_table_size + ref_table_reserve) - * sizeof (value *)); - if (ref_table != NULL) caml_stat_free (ref_table); - ref_table = new_table; - caml_ref_table_ptr = ref_table; - ref_table_threshold = ref_table + ref_table_size; - caml_ref_table_limit = ref_table_threshold; - ref_table_end = ref_table + ref_table_size + ref_table_reserve; + reset_table (&caml_ref_table); + reset_table (&caml_weak_ref_table); } static value oldify_todo_list = 0; @@ -191,16 +215,25 @@ void caml_empty_minor_heap (void) caml_in_minor_collection = 1; caml_gc_message (0x02, "<", 0); caml_oldify_local_roots(); - for (r = ref_table; r < caml_ref_table_ptr; r++){ + for (r = caml_ref_table.base; r < caml_ref_table.ptr; r++){ caml_oldify_one (**r, *r); } caml_oldify_mopup (); + for (r = caml_weak_ref_table.base; r < caml_weak_ref_table.ptr; r++){ + if (Is_block (**r) && Is_young (**r)){ + if (Hd_val (**r) == 0){ + **r = Field (**r, 0); + }else{ + **r = caml_weak_none; + } + } + } if (caml_young_ptr < caml_young_start) caml_young_ptr = caml_young_start; caml_stat_minor_words += Wsize_bsize (caml_young_end - caml_young_ptr); caml_young_ptr = caml_young_end; caml_young_limit = caml_young_start; - caml_ref_table_ptr = ref_table; - caml_ref_table_limit = ref_table_threshold; + clear_table (&caml_ref_table); + clear_table (&caml_weak_ref_table); caml_gc_message (0x02, ">", 0); caml_in_minor_collection = 0; } @@ -243,32 +276,34 @@ CAMLexport value caml_check_urgent_gc (value extra_root) CAMLreturn (extra_root); } -void caml_realloc_ref_table (void) -{ Assert (caml_ref_table_ptr == caml_ref_table_limit); - Assert (caml_ref_table_limit <= ref_table_end); - Assert (caml_ref_table_limit >= ref_table_threshold); +void caml_realloc_ref_table (struct caml_ref_table *tbl) +{ Assert (tbl->ptr == tbl->limit); + Assert (tbl->limit <= tbl->end); + Assert (tbl->limit >= tbl->threshold); - if (caml_ref_table_limit == ref_table_threshold){ + if (tbl->base == NULL){ + caml_alloc_table (tbl, caml_minor_heap_size / sizeof (value) / 8, 256); + }else if (tbl->limit == tbl->threshold){ caml_gc_message (0x08, "ref_table threshold crossed\n", 0); - caml_ref_table_limit = ref_table_end; + tbl->limit = tbl->end; caml_urge_major_slice (); }else{ /* This will almost never happen with the bytecode interpreter. */ asize_t sz; - asize_t cur_ptr = caml_ref_table_ptr - ref_table; + asize_t cur_ptr = tbl->ptr - tbl->base; Assert (caml_force_major_slice); - ref_table_size *= 2; - sz = (ref_table_size + ref_table_reserve) * sizeof (value *); + tbl->size *= 2; + sz = (tbl->size + tbl->reserve) * sizeof (value *); caml_gc_message (0x08, "Growing ref_table to %" ARCH_INTNAT_PRINTF_FORMAT "dk bytes\n", (intnat) sz/1024); - ref_table = (value **) realloc ((char *) ref_table, sz); - if (ref_table == NULL){ + tbl->base = (value **) realloc ((char *) tbl->base, sz); + if (tbl->base == NULL){ caml_fatal_error ("Fatal error: ref_table overflow\n"); } - ref_table_end = ref_table + ref_table_size + ref_table_reserve; - ref_table_threshold = ref_table + ref_table_size; - caml_ref_table_ptr = ref_table + cur_ptr; - caml_ref_table_limit = ref_table_end; + tbl->end = tbl->base + tbl->size + tbl->reserve; + tbl->threshold = tbl->base + tbl->size; + tbl->ptr = tbl->base + cur_ptr; + tbl->limit = tbl->end; } } diff --git a/byterun/minor_gc.h b/byterun/minor_gc.h index 380b38ef..dc1f12bb 100644 --- a/byterun/minor_gc.h +++ b/byterun/minor_gc.h @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: minor_gc.h,v 1.17 2003/12/31 14:20:37 doligez Exp $ */ +/* $Id: minor_gc.h,v 1.17.20.1 2008/01/21 14:09:05 doligez Exp $ */ #ifndef CAML_MINOR_GC_H #define CAML_MINOR_GC_H @@ -21,10 +21,20 @@ CAMLextern char *caml_young_start, *caml_young_ptr; CAMLextern char *caml_young_end, *caml_young_limit; -CAMLextern value **caml_ref_table_ptr, **caml_ref_table_limit; extern asize_t caml_minor_heap_size; extern int caml_in_minor_collection; +struct caml_ref_table { + value **base; + value **end; + value **threshold; + value **ptr; + value **limit; + asize_t size; + asize_t reserve; +}; +CAMLextern struct caml_ref_table caml_ref_table, caml_weak_ref_table; + #define Is_young(val) \ (Assert (Is_block (val)), \ (addr)(val) < (addr)caml_young_end && (addr)(val) > (addr)caml_young_start) @@ -33,7 +43,8 @@ extern void caml_set_minor_heap_size (asize_t); extern void caml_empty_minor_heap (void); CAMLextern void caml_minor_collection (void); CAMLextern void garbage_collection (void); /* def in asmrun/signals.c */ -extern void caml_realloc_ref_table (void); +extern void caml_realloc_ref_table (struct caml_ref_table *); +extern void caml_alloc_table (struct caml_ref_table *, asize_t, asize_t); extern void caml_oldify_one (value, value *); extern void caml_oldify_mopup (void); diff --git a/byterun/misc.c b/byterun/misc.c index 68c96068..8e937a2a 100644 --- a/byterun/misc.c +++ b/byterun/misc.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: misc.c,v 1.28 2005/10/18 14:03:43 xleroy Exp $ */ +/* $Id: misc.c,v 1.28.10.1 2008/02/12 13:30:16 doligez Exp $ */ #include #include "config.h" @@ -29,6 +29,14 @@ int caml_failed_assert (char * expr, char * file, int line) return 1; /* not reached */ } +void caml_set_fields (char *bp, unsigned long start, unsigned long filler) +{ + mlsize_t i; + for (i = start; i < Wosize_bp (bp); i++){ + Field (Val_bp (bp), i) = (value) filler; + } +} + #endif /* DEBUG */ uintnat caml_verb_gc = 0; @@ -54,7 +62,7 @@ CAMLexport void caml_fatal_error_arg (char *fmt, char *arg) } CAMLexport void caml_fatal_error_arg2 (char *fmt1, char *arg1, - char *fmt2, char *arg2) + char *fmt2, char *arg2) { fprintf (stderr, fmt1, arg1); fprintf (stderr, fmt2, arg2); diff --git a/byterun/misc.h b/byterun/misc.h index 2248deac..aeb7b3b1 100644 --- a/byterun/misc.h +++ b/byterun/misc.h @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: misc.h,v 1.31 2005/09/22 14:21:50 xleroy Exp $ */ +/* $Id: misc.h,v 1.31.10.1 2008/02/12 13:30:16 doligez Exp $ */ /* Miscellaneous macros and variables. */ @@ -132,6 +132,8 @@ char *caml_aligned_malloc (asize_t, int, void **); #define Debug_filler_align Debug_tag (0x85) #define Debug_uninit_stat 0xD7 + +extern void caml_set_fields (char *, unsigned long, unsigned long); #endif /* DEBUG */ diff --git a/byterun/obj.c b/byterun/obj.c index 2af63fea..f846363a 100644 --- a/byterun/obj.c +++ b/byterun/obj.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: obj.c,v 1.39 2005/01/04 16:29:33 doligez Exp $ */ +/* $Id: obj.c,v 1.39.12.2 2008/01/29 13:14:57 doligez Exp $ */ /* Operations on objects */ diff --git a/byterun/weak.c b/byterun/weak.c index 8f4377a9..19252300 100644 --- a/byterun/weak.c +++ b/byterun/weak.c @@ -11,7 +11,7 @@ /* */ /***********************************************************************/ -/* $Id: weak.c,v 1.25 2006/01/04 16:55:49 doligez Exp $ */ +/* $Id: weak.c,v 1.25.6.1 2008/01/21 14:09:05 doligez Exp $ */ /* Operations on weak arrays */ @@ -45,6 +45,24 @@ CAMLprim value caml_weak_create (value len) #define None_val (Val_int(0)) #define Some_tag 0 +static void do_set (value ar, mlsize_t offset, value v) +{ + if (Is_block (v) && Is_young (v)){ + /* modified version of Modify */ + value old = Field (ar, offset); + Field (ar, offset) = v; + if (!(Is_block (old) && Is_young (old))){ + if (caml_weak_ref_table.ptr >= caml_weak_ref_table.limit){ + CAMLassert (caml_weak_ref_table.ptr == caml_weak_ref_table.limit); + caml_realloc_ref_table (&caml_weak_ref_table); + } + *caml_weak_ref_table.ptr++ = &Field (ar, offset); + } + }else{ + Field (ar, offset) = v; + } +} + CAMLprim value caml_weak_set (value ar, value n, value el) { mlsize_t offset = Long_val (n) + 1; @@ -52,15 +70,11 @@ CAMLprim value caml_weak_set (value ar, value n, value el) if (offset < 1 || offset >= Wosize_val (ar)){ caml_invalid_argument ("Weak.set"); } - Field (ar, offset) = caml_weak_none; if (el != None_val){ - value v; Assert (Wosize_val (el) == 1); - v = Field (el, 0); - if (Is_block (v) && (Is_young (v) || Is_in_heap (v))){ - Modify (&Field (ar, offset), v); - }else{ - Field (ar, offset) = v; - } + Assert (Wosize_val (el) == 1); + do_set (ar, offset, Field (el, 0)); + }else{ + Field (ar, offset) = caml_weak_none; } return Val_unit; } @@ -141,3 +155,39 @@ CAMLprim value caml_weak_check (value ar, value n) } return Val_bool (Field (ar, offset) != caml_weak_none); } + +CAMLprim value caml_weak_blit (value ars, value ofs, + value ard, value ofd, value len) +{ + mlsize_t offset_s = Long_val (ofs) + 1; + mlsize_t offset_d = Long_val (ofd) + 1; + mlsize_t length = Long_val (len); + long i; + Assert (Is_in_heap (ars)); + Assert (Is_in_heap (ard)); + if (offset_s < 1 || offset_s + length > Wosize_val (ars)){ + caml_invalid_argument ("Weak.blit"); + } + if (offset_d < 1 || offset_d + length > Wosize_val (ard)){ + caml_invalid_argument ("Weak.blit"); + } + if (caml_gc_phase == Phase_mark && caml_gc_subphase == Subphase_weak1){ + for (i = 0; i < length; i++){ + value v = Field (ars, offset_s + i); + if (v != caml_weak_none && Is_block (v) && Is_in_heap (v) + && Is_white_val (v)){ + Field (ars, offset_s + i) = caml_weak_none; + } + } + } + if (offset_d < offset_s){ + for (i = 0; i < length; i++){ + do_set (ard, offset_d + i, Field (ars, offset_s + i)); + } + }else{ + for (i = length - 1; i >= 0; i--){ + do_set (ard, offset_d + i, Field (ars, offset_s + i)); + } + } + return Val_unit; +} diff --git a/debugger/.depend b/debugger/.depend index 328b77bd..f56903a3 100644 --- a/debugger/.depend +++ b/debugger/.depend @@ -119,12 +119,12 @@ main.cmo: unix_tools.cmi ../otherlibs/unix/unix.cmi time_travel.cmi \ show_information.cmi question.cmi program_management.cmi primitives.cmi \ parameters.cmi ../utils/misc.cmi input_handling.cmi frames.cmi exec.cmi \ ../typing/env.cmi debugger_config.cmi ../utils/config.cmi \ - command_line.cmi checkpoints.cmi + command_line.cmi ../utils/clflags.cmi checkpoints.cmi main.cmx: unix_tools.cmx ../otherlibs/unix/unix.cmx time_travel.cmx \ show_information.cmx question.cmx program_management.cmx primitives.cmx \ parameters.cmx ../utils/misc.cmx input_handling.cmx frames.cmx exec.cmx \ ../typing/env.cmx debugger_config.cmx ../utils/config.cmx \ - command_line.cmx checkpoints.cmx + command_line.cmx ../utils/clflags.cmx checkpoints.cmx parameters.cmo: primitives.cmi ../utils/misc.cmi envaux.cmi \ ../utils/config.cmi parameters.cmi parameters.cmx: primitives.cmx ../utils/misc.cmx envaux.cmx \ diff --git a/man/ocamldep.m b/man/ocamldep.m index 4fa557bd..7b24082a 100644 --- a/man/ocamldep.m +++ b/man/ocamldep.m @@ -50,7 +50,7 @@ compilation unit Bar, a dependency on that unit's interface bar.cmi is generated only if the source for bar is found in the current directory or in one of the directories specified with .BR -I . -Otherwise, Bar is assumed to be a module form the standard library, +Otherwise, Bar is assumed to be a module from the standard library, and no dependencies are generated. For programs that span multiple directories, it is recommended to pass .BR ocamldep (1) diff --git a/otherlibs/graph/.depend b/otherlibs/graph/.depend index 97fd3415..32bfc323 100644 --- a/otherlibs/graph/.depend +++ b/otherlibs/graph/.depend @@ -1,4 +1,5 @@ color.o: color.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -7,6 +8,7 @@ color.o: color.c libgraph.h \ ../../byterun/misc.h ../../byterun/compatibility.h \ ../../byterun/config.h draw.o: draw.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -17,6 +19,7 @@ draw.o: draw.c libgraph.h \ ../../byterun/compatibility.h ../../byterun/misc.h \ ../../byterun/mlvalues.h dump_img.o: dump_img.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -32,6 +35,7 @@ dump_img.o: dump_img.c libgraph.h \ ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \ ../../byterun/misc.h ../../byterun/mlvalues.h events.o: events.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -44,6 +48,7 @@ events.o: events.c libgraph.h \ ../../byterun/compatibility.h ../../byterun/misc.h \ ../../byterun/mlvalues.h fill.o: fill.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -57,6 +62,7 @@ fill.o: fill.c libgraph.h \ ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \ ../../byterun/misc.h ../../byterun/mlvalues.h image.o: image.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -68,6 +74,7 @@ image.o: image.c libgraph.h \ ../../byterun/mlvalues.h ../../byterun/custom.h \ ../../byterun/compatibility.h ../../byterun/mlvalues.h make_img.o: make_img.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -81,6 +88,7 @@ make_img.o: make_img.c libgraph.h \ ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \ ../../byterun/misc.h ../../byterun/mlvalues.h open.o: open.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -99,6 +107,7 @@ open.o: open.c libgraph.h \ ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \ ../../byterun/misc.h ../../byterun/mlvalues.h point_col.o: point_col.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -107,6 +116,7 @@ point_col.o: point_col.c libgraph.h \ ../../byterun/misc.h ../../byterun/compatibility.h \ ../../byterun/config.h sound.o: sound.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -115,6 +125,7 @@ sound.o: sound.c libgraph.h \ ../../byterun/misc.h ../../byterun/compatibility.h \ ../../byterun/config.h subwindow.o: subwindow.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ @@ -123,6 +134,7 @@ subwindow.o: subwindow.c libgraph.h \ ../../byterun/misc.h ../../byterun/compatibility.h \ ../../byterun/config.h text.o: text.c libgraph.h \ + \ \ \ ../../byterun/mlvalues.h ../../byterun/compatibility.h \ diff --git a/otherlibs/str/Makefile.nt b/otherlibs/str/Makefile.nt index 1fce47ca..f3eec32d 100644 --- a/otherlibs/str/Makefile.nt +++ b/otherlibs/str/Makefile.nt @@ -11,7 +11,7 @@ # # ######################################################################### -# $Id: Makefile.nt,v 1.15 2007/01/29 12:11:16 xleroy Exp $ +# $Id: Makefile.nt,v 1.15.4.1 2008/01/18 15:27:36 doligez Exp $ # Makefile for the str library @@ -54,7 +54,7 @@ clean: partialclean install: cp dllstr.dll $(STUBLIBDIR)/dllstr.dll cp libstr.$(A) $(LIBDIR)/libstr.$(A) - cp str.cma str.cmi $(LIBDIR) + cp str.cma str.cmi str.mli $(LIBDIR) installopt: cp str.cmx str.cmxa str.$(A) $(LIBDIR) diff --git a/otherlibs/threads/.depend b/otherlibs/threads/.depend index 37a41092..e1a829fa 100644 --- a/otherlibs/threads/.depend +++ b/otherlibs/threads/.depend @@ -22,21 +22,19 @@ scheduler.o: scheduler.c ../../byterun/alloc.h \ ../../byterun/mlvalues.h ../../byterun/memory.h ../../byterun/sys.h \ ../../byterun/misc.h condition.cmi: mutex.cmi -thread.cmi: unix.cmi -threadUnix.cmi: unix.cmi +thread.cmi: unix.cmo +threadUnix.cmi: unix.cmo condition.cmo: thread.cmi mutex.cmi condition.cmi condition.cmx: thread.cmx mutex.cmx condition.cmi event.cmo: mutex.cmi condition.cmi event.cmi event.cmx: mutex.cmx condition.cmx event.cmi -marshal.cmo: pervasives.cmi marshal.cmi -marshal.cmx: pervasives.cmx marshal.cmi +marshal.cmo: pervasives.cmo +marshal.cmx: pervasives.cmx mutex.cmo: thread.cmi mutex.cmi mutex.cmx: thread.cmx mutex.cmi -pervasives.cmo: unix.cmi pervasives.cmi -pervasives.cmx: unix.cmx pervasives.cmi -thread.cmo: unix.cmi thread.cmi +pervasives.cmo: unix.cmo +pervasives.cmx: unix.cmx +thread.cmo: unix.cmo thread.cmi thread.cmx: unix.cmx thread.cmi -threadUnix.cmo: unix.cmi thread.cmi threadUnix.cmi +threadUnix.cmo: unix.cmo thread.cmi threadUnix.cmi threadUnix.cmx: unix.cmx thread.cmx threadUnix.cmi -unix.cmo: unix.cmi -unix.cmx: unix.cmi diff --git a/stdlib/gc.mli b/stdlib/gc.mli index 373f8ac0..7dfbac1f 100644 --- a/stdlib/gc.mli +++ b/stdlib/gc.mli @@ -11,7 +11,7 @@ (* *) (***********************************************************************) -(* $Id: gc.mli,v 1.42 2005/10/25 18:34:07 doligez Exp $ *) +(* $Id: gc.mli,v 1.42.10.1 2008/02/12 13:30:16 doligez Exp $ *) (** Memory management control and statistics; finalised values. *) @@ -86,7 +86,7 @@ type control = mutable major_heap_increment : int; (** The minimum number of words to add to the - major heap when increasing it. Default: 62k. *) + major heap when increasing it. Default: 60k. *) mutable space_overhead : int; (** The major GC speed is computed from this parameter. diff --git a/stdlib/lazy.ml b/stdlib/lazy.ml index 8425db7f..96566771 100644 --- a/stdlib/lazy.ml +++ b/stdlib/lazy.ml @@ -11,7 +11,7 @@ (* *) (***********************************************************************) -(* $Id: lazy.ml,v 1.11 2004/01/01 16:42:40 doligez Exp $ *) +(* $Id: lazy.ml,v 1.11.20.2 2008/01/29 13:14:57 doligez Exp $ *) (* Module [Lazy]: deferred computations *) diff --git a/stdlib/obj.ml b/stdlib/obj.ml index 465642e2..c654c197 100644 --- a/stdlib/obj.ml +++ b/stdlib/obj.ml @@ -11,7 +11,7 @@ (* *) (***********************************************************************) -(* $Id: obj.ml,v 1.23 2004/01/01 16:42:40 doligez Exp $ *) +(* $Id: obj.ml,v 1.23.20.2 2008/01/29 13:14:57 doligez Exp $ *) (* Operations on internal representations of values *) diff --git a/stdlib/obj.mli b/stdlib/obj.mli index 57425f13..d372c97d 100644 --- a/stdlib/obj.mli +++ b/stdlib/obj.mli @@ -11,7 +11,7 @@ (* *) (***********************************************************************) -(* $Id: obj.mli,v 1.29 2005/10/25 18:34:07 doligez Exp $ *) +(* $Id: obj.mli,v 1.29.10.2 2008/01/29 13:14:57 doligez Exp $ *) (** Operations on internal representations of values. diff --git a/stdlib/weak.ml b/stdlib/weak.ml index 0ad9a022..1661fe62 100644 --- a/stdlib/weak.ml +++ b/stdlib/weak.ml @@ -11,7 +11,7 @@ (* *) (***********************************************************************) -(* $Id: weak.ml,v 1.14 2007/02/16 16:05:36 doligez Exp $ *) +(* $Id: weak.ml,v 1.14.2.2 2008/01/29 13:14:33 doligez Exp $ *) (** Weak array operations *) @@ -26,6 +26,8 @@ external set : 'a t -> int -> 'a option -> unit = "caml_weak_set";; external get: 'a t -> int -> 'a option = "caml_weak_get";; external get_copy: 'a t -> int -> 'a option = "caml_weak_get_copy";; external check: 'a t -> int -> bool = "caml_weak_check";; +external blit: 'a t -> int -> 'a t -> int -> int -> unit = "caml_weak_blit";; +(* blit: src srcoff dst dstoff len *) let fill ar ofs len x = if ofs < 0 || len < 0 || ofs + len > length ar @@ -37,23 +39,6 @@ let fill ar ofs len x = end ;; -let blit ar1 of1 ar2 of2 len = - if of1 < 0 || of1 + len > length ar1 || of2 < 0 || of2 + len > length ar2 - then raise (Invalid_argument "Weak.blit") - else begin - if of2 > of1 then begin - for i = 0 to len - 1 do - set ar2 (of2 + i) (get ar1 (of1 + i)) - done - end else begin - for i = len - 1 downto 0 do - set ar2 (of2 + i) (get ar1 (of1 + i)) - done - end - end -;; - - (** Weak hash tables *) module type S = sig @@ -83,27 +68,35 @@ module Make (H : Hashtbl.HashedType) : (S with type data = H.t) = struct type t = { mutable table : data weak_t array; - mutable totsize : int; (* sum of the bucket sizes *) - mutable limit : int; (* max ratio totsize/table length *) + mutable hashes : int array array; + mutable limit : int; (* bucket size limit *) + mutable oversize : int; (* number of oversize buckets *) + mutable rover : int; (* for internal bookkeeping *) };; - let get_index t d = (H.hash d land max_int) mod (Array.length t.table);; + let get_index t h = (h land max_int) mod (Array.length t.table);; + + let limit = 7;; + let over_limit = 2;; let create sz = let sz = if sz < 7 then 7 else sz in let sz = if sz > Sys.max_array_length then Sys.max_array_length else sz in { table = Array.create sz emptybucket; - totsize = 0; - limit = 3; + hashes = Array.create sz [| |]; + limit = limit; + oversize = 0; + rover = 0; };; let clear t = for i = 0 to Array.length t.table - 1 do t.table.(i) <- emptybucket; + t.hashes.(i) <- [| |]; done; - t.totsize <- 0; - t.limit <- 3; + t.limit <- limit; + t.oversize <- 0; ;; let fold f t init = @@ -126,85 +119,155 @@ module Make (H : Hashtbl.HashedType) : (S with type data = H.t) = struct Array.iter (iter_bucket 0) t.table ;; - let count t = - let rec count_bucket i b accu = - if i >= length b then accu else - count_bucket (i+1) b (accu + (if check b i then 1 else 0)) + let iter_weak f t = + let rec iter_bucket i j b = + if i >= length b then () else + match check b i with + | true -> f b t.hashes.(j) i; iter_bucket (i+1) j b + | false -> iter_bucket (i+1) j b in + Array.iteri (iter_bucket 0) t.table + ;; + + let rec count_bucket i b accu = + if i >= length b then accu else + count_bucket (i+1) b (accu + (if check b i then 1 else 0)) + ;; + + let count t = Array.fold_right (count_bucket 0) t.table 0 ;; - let next_sz n = min (3*n/2 + 3) (Sys.max_array_length - 1);; + let next_sz n = min (3 * n / 2 + 3) Sys.max_array_length;; + let prev_sz n = ((n - 3) * 2 + 2) / 3;; + + let test_shrink_bucket t = + let bucket = t.table.(t.rover) in + let hbucket = t.hashes.(t.rover) in + let len = length bucket in + let prev_len = prev_sz len in + let live = count_bucket 0 bucket 0 in + if live <= prev_len then begin + let rec loop i j = + if j >= prev_len then begin + if check bucket i then loop (i + 1) j + else if check bucket j then begin + blit bucket j bucket i 1; + hbucket.(i) <- hbucket.(j); + loop (i + 1) (j - 1); + end else loop i (j - 1); + end; + in + loop 0 (length bucket - 1); + if prev_len = 0 then begin + t.table.(t.rover) <- emptybucket; + t.hashes.(t.rover) <- [| |]; + end else begin + Obj.truncate (Obj.repr bucket) (prev_len + 1); + Obj.truncate (Obj.repr hbucket) prev_len; + end; + if len > t.limit && prev_len <= t.limit then t.oversize <- t.oversize - 1; + end; + t.rover <- (t.rover + 1) mod (Array.length t.table); + ;; let rec resize t = let oldlen = Array.length t.table in let newlen = next_sz oldlen in if newlen > oldlen then begin let newt = create newlen in - newt.limit <- t.limit + 100; (* prevent resizing of newt *) - fold (fun d () -> add newt d) t (); - (* assert Array.length newt.table = newlen; *) + let add_weak ob oh oi = + let setter nb ni _ = blit ob oi nb ni 1 in + let h = oh.(oi) in + add_aux newt setter None h (get_index newt h); + in + iter_weak add_weak t; t.table <- newt.table; - (* t.limit <- t.limit + 2; -- performance bug *) + t.hashes <- newt.hashes; + t.limit <- newt.limit; + t.oversize <- newt.oversize; + t.rover <- t.rover mod Array.length newt.table; + end else begin + t.limit <- max_int; (* maximum size already reached *) + t.oversize <- 0; end - and add_aux t d index = + and add_aux t setter d h index = let bucket = t.table.(index) in + let hashes = t.hashes.(index) in let sz = length bucket in let rec loop i = if i >= sz then begin - let newsz = min (sz + 3) (Sys.max_array_length - 1) in - if newsz <= sz then failwith "Weak.Make : hash bucket cannot grow more"; + let newsz = min (3 * sz / 2 + 3) (Sys.max_array_length - 1) in + if newsz <= sz then failwith "Weak.Make: hash bucket cannot grow more"; let newbucket = weak_create newsz in + let newhashes = Array.make newsz 0 in blit bucket 0 newbucket 0 sz; - set newbucket i (Some d); + Array.blit hashes 0 newhashes 0 sz; + setter newbucket sz d; + newhashes.(sz) <- h; t.table.(index) <- newbucket; - t.totsize <- t.totsize + (newsz - sz); - if t.totsize > t.limit * Array.length t.table then resize t; + t.hashes.(index) <- newhashes; + if sz <= t.limit && newsz > t.limit then begin + t.oversize <- t.oversize + 1; + for i = 0 to over_limit do test_shrink_bucket t done; + end; + if t.oversize > Array.length t.table / over_limit then resize t; + end else if check bucket i then begin + loop (i + 1) end else begin - if check bucket i - then loop (i+1) - else set bucket i (Some d) - end + setter bucket i d; + hashes.(i) <- h; + end; in loop 0; + ;; - and add t d = add_aux t d (get_index t d) + let add t d = + let h = H.hash d in + add_aux t set (Some d) h (get_index t h); ;; let find_or t d ifnotfound = - let index = get_index t d in + let h = H.hash d in + let index = get_index t h in let bucket = t.table.(index) in + let hashes = t.hashes.(index) in let sz = length bucket in let rec loop i = - if i >= sz then ifnotfound index - else begin + if i >= sz then ifnotfound h index + else if h = hashes.(i) then begin match get_copy bucket i with | Some v when H.equal v d -> begin match get bucket i with | Some v -> v - | None -> loop (i+1) + | None -> loop (i + 1) end - | _ -> loop (i+1) - end + | _ -> loop (i + 1) + end else loop (i + 1) in loop 0 ;; - let merge t d = find_or t d (fun index -> add_aux t d index; d);; + let merge t d = + find_or t d (fun h index -> add_aux t set (Some d) h index; d) + ;; - let find t d = find_or t d (fun index -> raise Not_found);; + let find t d = find_or t d (fun h index -> raise Not_found);; let find_shadow t d iffound ifnotfound = - let index = get_index t d in + let h = H.hash d in + let index = get_index t h in let bucket = t.table.(index) in + let hashes = t.hashes.(index) in let sz = length bucket in let rec loop i = - if i >= sz then ifnotfound else begin + if i >= sz then ifnotfound + else if h = hashes.(i) then begin match get_copy bucket i with | Some v when H.equal v d -> iffound bucket i - | _ -> loop (i+1) - end + | _ -> loop (i + 1) + end else loop (i + 1) in loop 0 ;; @@ -214,20 +277,22 @@ module Make (H : Hashtbl.HashedType) : (S with type data = H.t) = struct let mem t d = find_shadow t d (fun w i -> true) false;; let find_all t d = - let index = get_index t d in + let h = H.hash d in + let index = get_index t h in let bucket = t.table.(index) in + let hashes = t.hashes.(index) in let sz = length bucket in let rec loop i accu = if i >= sz then accu - else begin + else if h = hashes.(i) then begin match get_copy bucket i with | Some v when H.equal v d -> begin match get bucket i with - | Some v -> loop (i+1) (v::accu) - | None -> loop (i+1) accu + | Some v -> loop (i + 1) (v :: accu) + | None -> loop (i + 1) accu end - | _ -> loop (i+1) accu - end + | _ -> loop (i + 1) accu + end else loop (i + 1) accu in loop 0 [] ;; diff --git a/tools/make-package-macosx b/tools/make-package-macosx index 29672d85..80a0bb89 100755 --- a/tools/make-package-macosx +++ b/tools/make-package-macosx @@ -12,14 +12,14 @@ # # ######################################################################### -# $Id: make-package-macosx,v 1.13.4.1 2007/12/19 14:14:06 doligez Exp $ +# $Id: make-package-macosx,v 1.13.4.3 2008/01/25 14:00:21 doligez Exp $ cd package-macosx rm -rf ocaml.pkg ocaml-rw.dmg VERSION=`head -1 ../VERSION` -VERSION_MAJOR=`sed -n -e '1s/^\([0-9]*\)\..*/\1/p' ../VERSION -VERSION_MINOR=`sed -n -e '1s/^[0-9]*\.\([0-9]*\)[.+].*/\1/p' ../VERSION +VERSION_MAJOR=`sed -n -e '1s/^\([0-9]*\)\..*/\1/p' ../VERSION` +VERSION_MINOR=`sed -n -e '1s/^[0-9]*\.\([0-9]*\)[.+].*/\1/p' ../VERSION` # Worked in 10.2: @@ -101,7 +101,7 @@ mkdir -p resources # stop here -> | cat >resources/ReadMe.txt <&2 + echo "Unable to mount the disk image as \"/Volumes/$volname\"" >&2 exit 3 fi -open "/Volumes/Objective Caml" +open "/Volumes/$volname" +sleep 2 hdiutil detach $name rm -rf "ocaml-${VERSION}.dmg" diff --git a/typing/ctype.ml b/typing/ctype.ml index 5c210f2f..ed96e6db 100644 --- a/typing/ctype.ml +++ b/typing/ctype.ml @@ -10,7 +10,7 @@ (* *) (***********************************************************************) -(* $Id: ctype.ml,v 1.205.2.3 2007/06/08 08:03:15 garrigue Exp $ *) +(* $Id: ctype.ml,v 1.205.2.5 2008/02/12 04:49:25 garrigue Exp $ *) (* Operations on core types *) @@ -1958,6 +1958,10 @@ let moregen_occur env level ty = occur_univar env ty; update_level env level ty +let may_instantiate inst_nongen t1 = + if inst_nongen then t1.level <> generic_level - 1 + else t1.level = generic_level + let rec moregen inst_nongen type_pairs env t1 t2 = if t1 == t2 then () else let t1 = repr t1 in @@ -1968,8 +1972,7 @@ let rec moregen inst_nongen type_pairs env t1 t2 = match (t1.desc, t2.desc) with (Tunivar, Tunivar) -> unify_univar t1 t2 !univar_pairs - | (Tvar, _) when if inst_nongen then t1.level <> generic_level - 1 - else t1.level = generic_level -> + | (Tvar, _) when may_instantiate inst_nongen t1 -> moregen_occur env t1.level t2; occur env t1 t2; link_type t1 t2 @@ -1986,8 +1989,7 @@ let rec moregen inst_nongen type_pairs env t1 t2 = with Not_found -> TypePairs.add type_pairs (t1', t2') (); match (t1'.desc, t2'.desc) with - (Tvar, _) when if inst_nongen then t1'.level <> generic_level - 1 - else t1'.level = generic_level -> + (Tvar, _) when may_instantiate inst_nongen t1 -> moregen_occur env t1'.level t2; link_type t1' t2 | (Tarrow (l1, t1, u1, _), Tarrow (l2, t2, u2, _)) when l1 = l2 @@ -2049,33 +2051,36 @@ and moregen_kind k1 k2 = and moregen_row inst_nongen type_pairs env row1 row2 = let row1 = row_repr row1 and row2 = row_repr row2 in + let rm1 = repr row1.row_more and rm2 = repr row2.row_more in + if rm1 == rm2 then () else + let may_inst = rm1.desc = Tvar && may_instantiate inst_nongen rm1 in let r1, r2, pairs = merge_row_fields row1.row_fields row2.row_fields in let r1, r2 = if row2.row_closed then - filter_row_fields true r1, filter_row_fields false r2 + filter_row_fields may_inst r1, filter_row_fields false r2 else r1, r2 in if r1 <> [] || row1.row_closed && (not row2.row_closed || r2 <> []) then raise (Unify []); - let rm1 = repr row1.row_more and rm2 = repr row2.row_more in - let univ = - match rm1.desc, rm2.desc with - Tunivar, Tunivar -> - unify_univar rm1 rm2 !univar_pairs; - true - | Tunivar, _ | _, Tunivar -> - raise (Unify []) - | _ -> - if not (static_row row2) then moregen_occur env rm1.level rm2; - let ext = - if r2 = [] then rm2 else - let row_ext = {row2 with row_fields = r2} in - iter_row (moregen_occur env rm1.level) row_ext; - newty2 rm1.level (Tvariant row_ext) - in - if ext != rm1 then link_type rm1 ext; - false - in + begin match rm1.desc, rm2.desc with + Tunivar, Tunivar -> + unify_univar rm1 rm2 !univar_pairs + | Tunivar, _ | _, Tunivar -> + raise (Unify []) + | _ when static_row row1 -> () + | _ when may_inst -> + if not (static_row row2) then moregen_occur env rm1.level rm2; + let ext = + if r2 = [] then rm2 else + let row_ext = {row2 with row_fields = r2} in + iter_row (moregen_occur env rm1.level) row_ext; + newty2 rm1.level (Tvariant row_ext) + in + link_type rm1 ext + | Tconstr _, Tconstr _ -> + moregen inst_nongen type_pairs env rm1 rm2 + | _ -> raise (Unify []) + end; List.iter (fun (l,f1,f2) -> let f1 = row_field_repr f1 and f2 = row_field_repr f2 in @@ -2084,7 +2089,7 @@ and moregen_row inst_nongen type_pairs env row1 row2 = Rpresent(Some t1), Rpresent(Some t2) -> moregen inst_nongen type_pairs env t1 t2 | Rpresent None, Rpresent None -> () - | Reither(false, tl1, _, e1), Rpresent(Some t2) when not univ -> + | Reither(false, tl1, _, e1), Rpresent(Some t2) when may_inst -> set_row_field e1 f2; List.iter (fun t1 -> moregen inst_nongen type_pairs env t1 t2) tl1 | Reither(c1, tl1, _, e1), Reither(c2, tl2, m2, e2) -> @@ -2100,9 +2105,9 @@ and moregen_row inst_nongen type_pairs env row1 row2 = | [] -> if tl1 <> [] then raise (Unify []) end - | Reither(true, [], _, e1), Rpresent None when not univ -> + | Reither(true, [], _, e1), Rpresent None when may_inst -> set_row_field e1 f2 - | Reither(_, _, _, e1), Rabsent when not univ -> + | Reither(_, _, _, e1), Rabsent when may_inst -> set_row_field e1 f2 | Rabsent, Rabsent -> () | _ -> raise (Unify [])) diff --git a/typing/typeclass.ml b/typing/typeclass.ml index 06bb7f2d..6c39fc8b 100644 --- a/typing/typeclass.ml +++ b/typing/typeclass.ml @@ -10,7 +10,7 @@ (* *) (***********************************************************************) -(* $Id: typeclass.ml,v 1.89.6.2 2007/10/29 06:56:27 garrigue Exp $ *) +(* $Id: typeclass.ml,v 1.89.6.3 2008/01/28 13:26:48 doligez Exp $ *) open Misc open Parsetree @@ -1476,16 +1476,16 @@ let report_error ppf = function "This pattern cannot match self: it only matches values of type" Printtyp.type_expr ty | Unbound_class cl -> - fprintf ppf "Unbound class@ %a" + fprintf ppf "@[Unbound class@ %a@]" Printtyp.longident cl | Unbound_class_2 cl -> - fprintf ppf "The class@ %a@ is not yet completely defined" + fprintf ppf "@[The class@ %a@ is not yet completely defined@]" Printtyp.longident cl | Unbound_class_type cl -> - fprintf ppf "Unbound class type@ %a" + fprintf ppf "@[Unbound class type@ %a@]" Printtyp.longident cl | Unbound_class_type_2 cl -> - fprintf ppf "The class type@ %a@ is not yet completely defined" + fprintf ppf "@[The class type@ %a@ is not yet completely defined@]" Printtyp.longident cl | Abbrev_type_clash (abbrev, actual, expected) -> (* XXX Afficher une trace ? *) diff --git a/typing/typetexp.ml b/typing/typetexp.ml index 33583af5..0e4072b9 100644 --- a/typing/typetexp.ml +++ b/typing/typetexp.ml @@ -386,8 +386,12 @@ and transl_fields env policy = function [] -> newty Tnil - | {pfield_desc = Pfield_var}::_ -> - if policy = Univars then new_pre_univar () else newvar () + | ({pfield_desc = Pfield_var} as pf)::_ -> + begin match policy with + Fixed -> raise (Error (pf.pfield_loc, Unbound_type_variable "..")) + | Extensible -> newvar () + | Univars -> new_pre_univar () + end | {pfield_desc = Pfield(s, e)}::l -> let ty1 = transl_type env policy e in let ty2 = transl_fields env policy l in -- 2.30.2