--- /dev/null
+# Makefile for Borland C++ 4.5 on NT\r
+#\r
+bc= c:\bc45\r
+bcbin= $(bc)\bin\r
+bclib= $(bc)\lib\r
+bcinclude= $(bc)\include\r
+\r
+cc= $(bcbin)\bcc32\r
+rc= $(bcbin)\brc32\r
+lib= $(bcbin)\tlib\r
+link= $(bcbin)\tlink32\r
+cflags= -R -v -vi -H -H=gc.csm -I$(bcinclude);cord -L$(bclib) \\r
+ -w-pro -w-aus -w-par -w-ccc -w-rch -a4 -D__STDC__=0\r
+#defines= -DSILENT\r
+defines= -DSMALL_CONFIG -DSILENT -DALL_INTERIOR_POINTERS\r
+\r
+.c.obj:\r
+ $(cc) @&&|\r
+ $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.c\r
+|\r
+\r
+.cpp.obj:\r
+ $(cc) @&&|\r
+ $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.cpp\r
+|\r
+\r
+.rc.res:\r
+ $(rc) -i$(bcinclude) -r -fo$* $*.rc\r
+\r
+XXXOBJS= XXXalloc.obj XXXreclaim.obj XXXallchblk.obj XXXmisc.obj \\r
+ XXXmach_dep.obj XXXos_dep.obj XXXmark_rts.obj XXXheaders.obj XXXmark.obj \\r
+ XXXobj_map.obj XXXblacklst.obj XXXfinalize.obj XXXnew_hblk.obj \\r
+ XXXdbg_mlc.obj XXXmalloc.obj XXXstubborn.obj XXXdyn_load.obj \\r
+ XXXtypd_mlc.obj XXXptr_chck.obj XXXgc_cpp.obj\r
+\r
+OBJS= $(XXXOBJS:XXX=)\r
+\r
+all: gctest.exe cord\de.exe test_cpp.exe\r
+\r
+$(OBJS) test.obj: gc_priv.h gc_hdrs.h gc.h config.h MAKEFILE\r
+\r
+gc.lib: $(OBJS)\r
+ -del gc.lib\r
+ tlib $* @&&|\r
+ $(XXXOBJS:XXX=+)\r
+|\r
+\r
+gctest.exe: test.obj gc.lib\r
+ $(cc) @&&|\r
+ $(cflags) -W -e$* test.obj gc.lib\r
+|\r
+\r
+cord\de.obj cord\de_win.obj: cord\cord.h cord\cord_pos.h cord\de_win.h \\r
+ cord\de_cmds.h\r
+\r
+cord\de.exe: cord\cordbscs.obj cord\cordxtra.obj cord\de.obj cord\de_win.obj \\r
+ cord\de_win.res gc.lib\r
+ $(cc) @&&|\r
+ $(cflags) -W -e$* cord\cordbscs.obj cord\cordxtra.obj \\r
+ cord\de.obj cord\de_win.obj gc.lib\r
+|\r
+ $(rc) cord\de_win.res cord\de.exe\r
+\r
+gc_cpp.obj: gc_cpp.h gc.h\r
+\r
+gc_cpp.cpp: gc_cpp.cc\r
+ copy gc_cpp.cc gc_cpp.cpp\r
+\r
+test_cpp.cpp: test_cpp.cc\r
+ copy test_cpp.cc test_cpp.cpp\r
+\r
+test_cpp.exe: test_cpp.obj gc_cpp.h gc.h gc.lib\r
+ $(cc) @&&|\r
+ $(cflags) -WC -e$* test_cpp.obj gc.lib\r
+|\r
+\r
+scratch:\r
+ -del *.obj *.res *.exe *.csm cord\*.obj cord\*.res cord\*.exe cord\*.csm\r
+\r
+\r
+\1a
(This file must be converted with BinHex 4.0)
-:$deKBe"bEfTPBh4c,R0TG!"6594%8dP8)3#3""V-!*!%4@*6593K!!%!!"V-FNa
-KG3)!N!3@!!!J)!Y0B@03FQpUC@0dF`#3&!G[!*!$LJ(+!Si$f3#3!`-!N!q'!!!
-"B2q3"!%!U`6XdUX%l2d!N!Cc$`#3"KT'!*!+@[X0$3KRBbif1%XZZ3#3&fPF!*!
-4&J!!"lJ!N!-@rj!%68e38Ne03d-"!+X%l)@V"1bY!!!'-3!!%SJ!!!'j!!!&#Eh
--,*i!N!Dq`b0%$L)UANhN3L9rR8XNRRb5*ZE3hhmM64*pDB+1%rh3qA4mVL`Cmbe
-D[0VhjciRj-CeKVXl1`-"32ChKH0khh,pp%+LmEZ)5KURjA*%m"FLH[$AAr6`3Tp
-m-SG(2L"kb#0-p*!!ad$4Jekik%&[N!$S35rL56a!"SXHp#*&"hT$4!pk8D)([@L
-,6DK"X%%[9S!m1FZ%kHI)GH!2SIh,Zh'$B8Ukq@m!q2KrhdiNbVN`TiAr**+FIai
-BdQ('A%mLPq0#qVQ!Z%%dmd$h4AUHD"k,Mp!U,'Y05DHQ5M(YMfSme9+jii[1iC(
-H2B6BQ+K)p2QEE8lqCSGi#!9CEF6)*1SlT9KAC%0-8a0bdTIk[@HYE8Tk[[!QiA)
-26bFF!bj6(UFLFPUEDSC2NA[rffKi(YKNl9j`3chLQ#YLV$e-MV0fM$!9b*['U%D
-)cV&bR&,Nk6N26IL@0@L(b*(4H3)$i*YCbh9`YK89EKeih!`,SeF)p`%,SjF)0e0
-Jc"@f#Q,X2EC4LMAEU`%aEV+&U5`X`cC&XAal)9"XYKdFaF5K9`U-Af4KHbc-18E
-X(D)cK(9Y)iqC$,PCC8ep(`!!$2L,QD2m[+k*jr($FmT2MjqG+f[N4BiV1GC*11@
-%%DD%V9cPjeP(q8V`!H4k5M9G18"A-Sq6!58$6KJCF$,Mj"MK%NEi%8k18m)*`h0
-bR$`r`L866MMKj$Nj2L!6IS366Sk6ii56%6mbB)56!5I(#DINQ*`F!qKG!5J!1EE
-bYkIi"P*mj$KKK%BB33`(*RJIUqra!'0$NL5CISFNDG$p2NE[N[6E4Pqjlk4Ze6#
-!RM(bFH"HreQ1I1+-l*'mL[R8$NV&B!hT8UHATJ9e%p1D-953!$FXZkleBd&e2D,
-9!h3)mPDTB2f,GBimZ8030r[8,Lf65aH-QNI1U(&D80ZC3ePNUJCDJ)&$`le*3He
-J@R@SDT!!V2P$U6[IqN931jR@JJVdY!D,JGEPPrF+DKG,AN)&4kIUbAXhTQU#fZe
-61`[VJA81IrD'S2Eie2D#5S+qi&&6*lmAe#hF9j*2%cZ)Jc2qp3&"lDeS49DMS8M
-1EamY#fSIdfV#FMVXAXrr+UMp,+mi-jXZU%(`+(8k,kKE@BD`e8LVQeIV!d%GB&S
-*")D+#M@Y)kpq++L$c&I,,Q8bQ*L"Vc1cR`[U0NDejiYDSqR4P&m5e1fdQlXGaE)
-eK10k,ANVleh`pAPe%r-e"p*&JZB#VJ-'CD(eCTrDPJ0eS5led,&h"28@hk&1kT!
-!"V-eXV0bEPSiG#[,+m"Q&ZAUe1A5+d,VED`j6q*b!KCUe2-[A9S8@RHXTN(Ak!3
-3T1()m(DKGHHUV`E+0(ep8@JGmURY0LV!4SUFP6I("A@BDbA)E+4KjGc6JRUlIpI
-R64[T@T+FPCp5`YFlr'0(DVi)DeQJe0Gh$3QY#QYLKl#T)4YK1S&4f34A&C`r2Fk
-Q'DrZp)mp#A3+DJQXV8@LQYH4LN0%,6BFUP,[mSrGe#'EB#-!9kPh-iHH+5'3!0H
-)@VlQd#lrf-qT+AM+rSYFTBibkQ(60Sj"#jF)q$Z"9HSB5d-#QU8EDEL(GFURjU"
-*Tlb06RQ[Iq`k1[@XM@S4qS1kQcNdJBaQ4kP5lf0DTf"Z%U[DKYEl+eTTbQpShF2
-53)F'61D[Tb(1($U16!fAVkGKlqUdiBhQ`E3Kcc`ZZ[)$c#%,fV1&BRd#5$V[#kd
-2XZl9k#CA(AUS-QfJ('hMGDdM[mm)kX0-Dj*J+Y6Dd2S)QhTT'ZMJ#i1B1r),hiN
-d2-SG@S$TUieee5%JU2YmDPFCk#UTBprHmmQ)S1jR$K9YNJBkD1j5"&AD[%KRm`R
-hNA$lfVEZ#Sh@2bTDfcYHRZH"LYBfMpHQTSV@GSpA@e0&DpZh'Uh3d@MlakXpp#,
-D"[,U#,f)YS1m1X1N4pY#APe0&DhY)DrZTSV@0T&A6j5,F,[)DmZk&q[E4PkpS4I
-4pT&AApJ[SQdNVri`Sp&fNYI@d0(r*K@[pSH14MY2AJ1K&p%1P0GJU#,DLI,DaQr
-FU@FITFITcC!!Y#"r'fZ6,llfXhaam1$"aE1MmMHl2k@%!bj*rP)SL&8f)p+5*(r
-aBbcV*ABT"UN9ChiiF8AZ%kB##F&%`3#8#058XNjA(-SF*#Jl6aGeLUdM5bN52!Z
-"2@BTBmAR)"P6#*['imG6iVe#Vh$*9R"@d93EaK8PD8$9JNUTk0j6,C!!SmV)eVd
-(rPZLf23[%IIe(0,S$+dPS-dXS[q,p*a06KL@D-dAh1Nd1@P9''k)plRH*qQZjI*
-PH[295ET('D$rQFL5qmC0iIm0$3KRBbj38%-ZZ3#3&f''!*!4KJ!!%'i!N!-@rj!
-%68e38Ne33d-"!+VhXBZV"1br!!!'-3!!)ZJ!!!'p!!!'LI9pFkF!N!BJc50%$L)
-UANhN3L9rV@9B`f#c2p$XpAVVCc-[`k20Y5bJ+CTHPScj`Z'!lmpp6XL0k`ahGiB
-$!AM)F3b$m"((pEEqqNmZ*DTjPDLNN5GNPE-0l@Sredh,(lT2REr3kjdHcj0cZD5
--842'U'1i'FRf4U9HKG[Ni@2NLCQiC2+`20JT@CQQcPrmAUET#)6&4fJm&6R%+-#
-6HhJkX"#A+Bp6%6RGkB&kM%'jh2YHZRpqbIRhIkPrk-F16L+Aiel(A!&aJjMU352
--6)bkTU468k@BpNFl2095ZH1,cZ'4[[24@6#*b5!8h@acmMFla%-Sb'SMi%0mqNi
-TeKAC%028K*cdTAl[@@ZEXLI!PSRq1A)Gq$F!TZ2'$BBTkHDr(6"Xrr-aidGQ`E2
--8f$QkG5VX96PYa1M`VQ`A3[r5GRc`!,pedPfZXC&Hc[pA%#iD%Rr1kF8ShhLZ8N
-K)#Ek&MNb1NrJR2$0V18k10ZS+*G$Vl5mm"CQXXH#BT'f5BV"UB6H%@-@@4KVBC-
-X6'9Kbk`FqP[B24B@DQ&V,@bJ`&MlA&%+M#C'k(%,@f*T$,#`,ld6Z5'XDaYjc'6
-)c5TVk[X!N!-0q)ZCJfaN)hXl2*0l(RHbXP&Hj,JABCf%fdQBaefj*cp2rVCbI*l
-8Nakq-`E3PF`kFP`bi)54!5Fc6SjG%Nli%8k15cKKH%k1NqG(q"&1RK011(P1MJr
-)L"011$P1MK01MT2R4`D-F$,Jj$MKNQ0bFJbi#jJ#V!#%Zc+jj*MiRZ9kj$MKK"e
-K"#Pi`S%*(JJ[8)F&2##'ipL+SUM`ADiSh5r#pbcm5m#h#Eili'9FLF(ENqThX5E
-eiUZrUKFlpZ`jGDj(rAEGjq#`#liap@Y3%a&6lX8rjaAeUjpM3mSFpLp')-dc2ak
-96K!2j64#U8-eac!+P*KD-@2C4"XPe"SDXh*TcFYBVTDRcM!a[&jAkmdr4@L[4SR
-V&+K"iNF'j(X0IMN&6h1'0&2h5&c6%ME4AD)9mZ`rj%+%9G(b-[a"m*CU(T!!`&k
-2@LBaifBrmD#5+LG$QD(EYT&*f50aifVj-(cek"Q91b%"r&m,Z$V'P#9c(6`r+&f
-RBDiT@cG'E0HVj[UTG'd+A0Z0$$&'h%,@[@(V(hKiUA5G(VLfQDPd-QYADZ6hf+H
-PDc0@D-M+kECeNS39kTU9N!#Z,CKVKZJQS92e!GGPErdQA9XaekaZC*)QbBHjART
-KNh4Y3r,kGH2Ji5TjlmCd8lV1#&aEXlH!pIGrmBCdE3pFQl-k$IX#GaeiqJIT1P2
-8PBiNU4ILi1rqCTGdR6@4UqA@'SVLrr(**HNk'h20N@,bRqlec1r5G3lbkU5'NeN
-p"!pF"dHNkeaNb(&VY$*Hh3qNkcc-P4,$eUeX*GIZ9ck8VKeB9pFVT&)1cB9e26E
-mTA5GMklH@0kX06fJr,*dA3$GR(88ec-Y*jkTN!!hrYj(3Aim&Q*GddBb6kh4d0F
-h1P5Ckk,!Y5PY9"0PVRX2[50G&`F9DS8+Q@5SiZb2[ciS+l3%H6@Fh*!!PDkkALU
-m,(2Ya1EFja6l5EELHZ(ij9-bek8P'M)Q6!!K$3Hk&XKFPjAUDPZTQh9p6ZDk2("
-YpU`XU9(NMlqj@lTfL9`T$*dhFhe8ZUi)rXhQddDb3T)rrXZ!V1[+3,B-M19*K39
-`I@h0FTQVKNeXVj-c,FpbB!+$Y+P6cZ$#kGdicI"B&FMfIZX%-IXGF`U*-UrG%a@
-LHVj@SE,V2B'F!4AbU'1(aQAAe9LK*`U@-@*5[IKIKGB%FSj`(5!R[,qGbkipk,S
-rjpQ(F)0`[8aPeekNSCrN#RGT`"e)kb1M*!G6hZe1Z6D3!'d($crT@4@%VVQZ``V
-YJpA*h3UYae`2Nh5ISjZhFpd`N5Y3IMIAM8J$$!d1(EY$3a`VG-6+Q8la$JfE5Y-
-'(mh$D8-ppS$XbTZa3LlaKV2jkJ53!2$IPlPZ`Hj9kbEA+l4eBYU`dY$'UlPfrhP
--ZQl$A"28J86GflPZakNAD)$"&cCE0l,ee@HrPc6F*bTdNL5[0pC5K3cTZL0`E5X
-D'Ce@EGrHq&QhG0f*&FTl0'PNM*Zl&1QU,2a*@D!bDR%+#`ai*[9Yh98h#)e266$
-"F(DJGk0HKhS$kKl8RDJhSZj&[3Ve@Y5V8Dp"[4leBMk,`fk"E`eJdZ8c,%bKI,k
-%'CC2Tc#(SGp+2JY#2m6r5pK8$RS4f`5!AXSQCiB%fbF`)YM%b5KQI$)Z'A&3l[J
-0AKTl5K'FlJPHAVS5m!+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+
-Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`+Dm`,k,elf2kr
-fU'b+kjVX,r80VBKTN3qm4#C`SMc1l`9`kehLT,'6&X%Z$9KJIL&hM@feL1R4+0c
-jCm0qhYM2LfL1$1&N%j[P'l`!('&IU9mQL'L*61NV1p6lfG3jf9IUYaJL@L-E10R
--YM24$I-LF01XXXTh6XlAp@X8%@f4#paX+I-6mK*b%[ECUEQNF9mMJZeL)P6f$!$
-(9,pYA"D*D)mFiHA12"I1[rAE+K%cSf2kc+fV-K'c)KYifFSfiG%,h)$Qh135P6j
-6[kX6-6YbTFq%HjEk4D%)GLmFME*RH9$G`kSm15IAEbK&c)dmi'4E0%9I,['Ml&-
-HimaFkm[rAT,`f)QQ8rfpFC8UBPj86(p[h11+k)K-kHrK(V9qJ5aLIQ3)*pIf1G[
-CY9QYVc03MUrY!l8#PP[R%[YX&pqBX,6jQ0eq*ITFV`5+bUkMBJQiC,ab46b#0kV
-#hM$UrJF!!!d0$feh,fGMG'9cG#j38%-ZZ3#3%"(-!*!3"lJ!!"TF!*!$&[q3"%e
-08&*08%0$!3#UphHTU`6Xc!!!"M%!!#X-!!!"S3!!"pd+IEMl!*!'pedM4!iL+Pj
-0j%)PIdhl9fbRBC!!DR1(JAFp3hUJ2KNcZ@(k`Z'!lmqGi)cV$(GhKJ-"1#NqKM,
-$lcRBqZZ"I96dfK5LNXCFMR,r8%Ar'-lrp9!IFkbM)YTq#&@*UN"9A8$E'HSmZbF
-dRSSFHCpb$dm(&Z)bjA(i)1k4p2q[8*,a8X2K$U)b@[phXr(IIZcJ*()jlRA-&6(
-@(LE(@6X%L4F0Lir3+Nb$TU468k@BpNG62095ZH1,cZ'4[[24L6#*q5!8h@acmMF
-la%-Sb'SME1[`p*e5V#Zb)DDT#6RT5rhHXrEST22N,"2pFq3km'm!c-L0'`a6d[r
-AJI83m*Ma)l2J@HBT#M1[&UY9HM[&U(L2V&N"4dDhXQZ0LKAhfj6praE#*$XAlL3
-X`&FF*`L)'m61'[61+F9SRhKZ8JL)LEj&MSc1%cJUI$0VZ3l10LV#N5-rhX)#l,'
-J@*K0T0JTfcYLc#),BbeXNS@T,)`ZHfkkKGeMBD%@YYE#"JU-lEAdP!,$a1$YXE!
-PPXB!#r[5@0V(4@-)kpT'(M-CFV2+Q[Sq!*!$$IMVbPPfHI+*jd#@dFkVArPjQCG
-4,MN@SI`Nr!MA@VN@B4&1q*'9i22T+G1hm&QAR$$#"i3ri@6!#5HF((pbr#JRa`N
-RcmRaFq9(MT2MK(@%NqG(MK&11(P1RT2M4jk6jq6i8fi[H8jQR($#bA%**ja`#J3
-JhK@!i5QrPG0,6Xp"K#SCF#p##5I(#4)i16cK`!6BpB!k,1",['UD#8Q5C13f5GV
-b%[+lq#f#A)0m!LSX"D5f"NfaPBbY@2DA&2M[A$KZhB%KG@,2XhXIF,cQh#Bd5EU
-lfh&Vf'I%,-8bp-b#QbbGPU4GBEK*8RFGki5HdXUem8j)i9!SNY#9M"l+TQ'UKqb
-i(NTEjQ&GY80MKKfR2cMrY8)f5'$r(M8dA3YVrEU0hXL-M*UH4L@4811aa("BrE2
-BefSqRj3C3di`AlM@`G98&baRAB1mePK#8BF6'EYFkdRAYFCaE9,MZMUFb5BcmlC
-`rGTeAH'i0QLaS@Jb8HT4`E@@GfM35#N*ihlpA)IUH+eaAG&dDk%rj2U9keV2Ddd
-UDMbUkHP5VC-IZki0R,aq4EeMS%*H30&FedE(Y6kj"'b"KLE(Y6DT@-@jF,D[cD+
-[eR$8XSXi&&aAjQXe-T@"!YI[iUjV#kmeTBp&PkEA0+qV1+pQl(!dU46"qm0e0AH
-eG$@K'-Q+kr6-Zi"h+'0RBc(65T8l0%hH'Nk$VCHQ*(IpcR9GbfZeap0DCHJ9DQh
-06dTRkbL@Qr[*HYpe[C!!6f@a0Fhl`[8&er8L2SI-6'ALdF`,Z+iA-e&cAmY0q`G
-Z#r@&)j'q-"DUf9VI1$6LZPj#VNHEEdYKq4P89(h18j+1RBSqlETHbX5+$eVk$r8
-Gb+CX)kR2ehV2$aYGeh91AeYS+NG9-c9S$)AMFp2V$GGe25G[5)fQ,@2dV''Hefp
-GecE(Y@C),4VQAEpaAGZC#$jFRl%e64mX1HFLapqMAGQ*$XHeERa85@6+jHCHHI%
-Zel@68elL)0qK,l[F$S@SeVIVpjPMrAUbj(TXj1H(h&Sh1+je"mI6qQ+(RZmLERK
-FjVLZl606QQ%E*VBpS'ZCK3U12EkE0LFH'ahATRlML+leQjSqAfqK3jIR1f3Tk8U
-(#UjGMQXM1Q4ECJQqJZXQhU%lXiBkV&R+f&mGfZbiVK+Z"r8MpUac`E@EZf+q*Jl
-S'60VUA-%&Pal1!hpHLUl6--@2KYZ'G96f#M2ciBV(0H'1`EZXShbr#UiAXNlY0G
-),%k8JZY9[0B"I@LIU@MRDfA[293V+&qZp@T1!mDNDBhr6F-e[%1(M*4QM[e0`pB
-c1dTF`p['Z4eP'p9+fdE#L#eZ'j0ZVGFkVV@dGC9hQecNVAYFeqfL9XY)PEH0A15
-G2DlVGBjV(6TNQ*@piG9(D*[KX50IUfiI6UBVYHEHG&ehRQ')RP,+$*eb'EVHiE@
-T-P[2mVSVhb&M#%[0)RP2ZUihm&SMPSP#-qGVlHA[$HJVRKc`TMKIE@%fh-K%c9'
-mB0RaqCAFUIAacAfZkfjHDpUfSQTFVEcd6'qp8YX*E0RXVCGH,(R3,pl,KBJ,Z9j
-(flXTEj,CjY11LRkVahY"rGd0F4RE,KqFNVSB9G"EZ,k5kc$Ah9b(Z,kDkakZ0h*
-p"GHEZ0l-p99FYl2G([Sk0Y1JYl(T#lfG68ESDpPFKEkFqfeJ1c2d0Ich$VEP3hH
-b[4fkME%'[CAa$EfHDq,N`DNL*pkEXBLm,h'L6MLF3"-Rd-3*0(%#6Ca!%bI3a!N
-dF3*0R%!6*p$%#64a!NfF3"-Rd-3*0(%#6Ca!%bI3a!NdF3*0R%!6*p$%#64a!Nf
-F3"-Rd-5*1L&hb1cPSfeQRP4Ib88%I4mim6hJ3pV2jhH"$qmH3!5lmK$cZmbEGbN
-JBSAI#@qPrDCk%b'LeRH%MjeX,eqHfpi9L)Jkhj-j%TECLe2(c"bThVZ)U2GYi'-
-(HlhaBpJ$T9m*MdYQpZAUTBq)"Ym&AUi[F&2Na11MZRGi0dXL'Re6hP8@jUThT5@
-LbEH%%pV6PYqK[2Xd%Fhq,h0Pk5*2a%VI"NjfXEGX2iRh6Hm@885,EmTF+Ek69+m
-[4DcbIH$%ri#2(6+lp1LFfAZV0j)L,[)pi1-'hihj@ld3%E(EGf5Zr,[rHRI-)PE
-l[H`ThZ@fL!Ym6rD8i[Y!p8CGa"VINcR5HiiAlcTIa&VINreNMKF0M16[Q6J[hY@
-r#2T+!')[A@fh-PlN%Hd%rpG*H@6`He`[YMUm5+hbL,+DILGHS)NAD1)&QRL"*Pk
-JL4GSiJ@DH)%QAU#*&fML"CTiJ5CHS)NAD1)&QRL"lXcpP(d-ZLhAGq!9k+fjfpY
-ESAIQj2YkSGIRe$8bG'p1[[Fck(A`1ihq-9ld@9kmlaf)S1mM,2%#cDiefIiBBEa
-!(d&q!ZGBq*C1i'ENZj(aICd![UN6["IraIGeT12)(b*rJB`DC&aJbDK@aQ@e[!I
-j)$*14H@Mb%mK[icm$[*(b#H4Id3pZ2i)B(i'(N*q"[P9j%q3!%mKieXj3Ec+"V'
-["A(p'l`91Bhm+2*cb+rr`iYhKbU#lPEp+hJ*SJrr-I-R,h2cZ2TP$"(d*3h%IYm
-5AU6JTp1mL$[&r,fKZ#YFqUk+L&DZqCda&6$5JrTPI)@MH6+b0j(Kr`%,+hpKYmf
-4I4Rl6!%bQ*%#%Ab"B'T+r!RrN5Af(pD0r`%K)3Y0B@03FQpUC@0dF`#3'BS"bJ+
-1!pN!N!-"!!!3EJ#3"aB!N!1'!!!"B2q3"!%!U`6XdUX%l2d!N!Cc$`#3"KR@!*!
-+d@2eN!!!!!:
+
+:$deKBe"bEfTPBh4c,R0TG!"6594%8dP8)3#3"&)e!!!"4UiT8dP8)3!(!!"50A*
+
+-BA8#ZJ#3!aB"#3d0#'GM,MBi5bkjBf038%-ZZ3#3%)Zi!*!8"@`!N!6rN!4069"
+
+568e$3`%!UbqAD+X`19S!!!Ba!!!,*J!!!F%!!!-PfTmj1`#3"PET)d31)LTH6H4
+
+#*AqG5b5HI*)QjY$IIb00%ReTJSi6rG$jG(bZ,"Rc,9Umf[IRj)6FZ-j`GfGR)#!
+
+m-#qLqB#cj'G%46qffB3q8AppLXKc+P&*il4FMJMq3N32r[U,(PlSNdrQm-J(4!p
+
+jK)NHmKJSHY!,&chS$4)pk%8mL3I)B0'$AU6S3'q)k%%[5[5J&ffa#68)0ZM&#T!
+
+!*fHC-2dFZ3i83[Vr[4Xh'+DNQrm'J)rrpqe%ST`,FeVi6b,*qHH")4eQc28NFMN
+
+ZT*m,L"Y%-`pdAk6RLHDaeVV0a,,@P(4UUK66rUM'8bf91llS("lTh81)MBQ+4*q
+
+rfHENEhD)Ke#3!09'M%bL[P1+G88fa$3e)5Gpf0kARpBf*6eIH*0`ZBHR%ii"PbN
+
++D&*)688M)Sm$Bm[cCdDjh2YIjmAc`(TVpi*Vka((A*&Yl@'LTSH1M*AMP#,2[A$
+
+(FHA@S"dL4dER#3b!EfBYem(C9P5iGH"a-bb-AL(F"bb-AL,F6)%a9pJUL,(hf%B
+
+TeQb["X5ib4DQXV!-fa6&mZf&3,(C&UDd-((SpeMBEIB`8Zc,BcZR3A5'X+jYj$'
+
+6)6HVV+R[!`#3!`X!(E@*MFQ%R4d"))`m[3JM[c)bBS54Tj'M(AP+MK&f%VD5SdG
+
+SANFB@3Rqc$Am83(+)`"G(D%A'9!bBQ6!b)b4Sq3SH8D1NDGNX$)bBi54!51--$*
+
+Kj0L!M"KKK"dC--,)-h+-6#KKC-$)-F)NamL!!Z06#X!!b&%bBUHp8RcN'%%6!b,
+
+i!!kV"`"DLHFaK*!!"Ym4K,,2i2X4c[,`c5!GIPf!ZcNi'8'VfJFpSfdpq+CY$8j
+
+-V'f-DZr2[36#1(ael5hmfT@1cSU66D5pqDSA89pdTP-`Z[jj6T&!PmZBFZjal"&
+
+5iG6#blE$+&kLh#QZ118&(0T1J(hZ,9)5MJ9ic*qPI!ac'RJ96QMZjSbkMq()Ui6
+
+B+f,,#'N1icbM4N"aaBr1`3Z9U'8RY'XAiVXFKp#&k2D5Be%VCdh4%,+2QS'b"Q2
+
+%0PNT4rE#%kTUFqYDM56bVjfe!p8MqmL)1VmjVkJY`U[*$&*L3AMSpB@LCQ*U&l%
+
+T+3890rL,V9klFN*4@f0UTf8Z&&afN!"4GC6G8p3fN9$4+4[-@DAeK%lej"@eAAL
+
+eU@&4[Tm28%mqqUkS(F+VDa#lB&'rlRAllRP&l460Qc,)MHR$jMh@$8Y4Xc'e`cd
+
+ZE2AUUiH+fK96feb$epq&'RAQeLG&lCDjmP+"Kr8k9#qp'eI8RPf[6R$dS+$UcqI
+
+ELYSV[*ETFL&j[@lr803qd9I2A#bi4Vei3*d[+@Urk*!!&abe0HTVm%44"i4A6JN
+
+c(2I!kjRl6a9e813DK"A6p(LjRZZGaGH+1L5SiBT[(6ekd2*ILMSXU(l)#m3QMDB
+
+V+QTG!r*NG#RQai#DNh4,l0&!Ie`dYi98Y1%1A$5hKP4,`d9cHdKP'LkD@q4hYC*
+
+%dfdLeCCNN@i9UIBNLh5l5(8N68qhM&4R`d9cfdKP'bkD@dHU+qe&XRfNZSqc10j
+
+#8Me*&ZNfNZT0hSYd+dP&ri-FGM6G6P,p5D,rPNT0`dQLk5+6'NLb5"HDe'$L)Pe
+
+X8N2bj-Z'$r$6-$NZjLGC)1lB-"jQSff@[ak%LJ[rI#%p2ddAGREN(@"V+,S6CI!
+
+I!!!0$3KRBbj38%-ZZ@0M8&"$,VN!N"#$BJ#3%4B!!!d'!*!%rj!%68e38Ne33d-
+
+"!+X[PfqV-$P*!!!'-3!!&UB!!!(&!!!&C80(jji!N!BMM#0%$L)UANhN3L9rV@9
+
+B`f#c2p$XpAVVCc-[`k20Y5bJ+CTHPScj`Z'!lmr*#EPaRH(ZcR!J!!rqMKG"q)#
+
+cj'G%46qffB3q8Aqp4R6FA83PM6`KUjaYD&IlZ@jDrY"pk[b&AZrdH*kFbb9PM*S
+
+`4Kh$c8Lf0bVe+Y`Q$amM6mc%*C1(jF&1bFSdGIlLpc*04b#X&D8[&6R%+-#6HhJ
+
+kX"#A+Bp6%6RGkB&kM%'jh$ZLmam[1Irq,r82rGM"5H4bh1ZB+b"Z%&-pD)5CL9(
+
+AP(4UUK6$!(lkH+UPFXFARF-MIHHMXf!5Nd%SZYRQj'pfL)G3N!$94X#(q25G8U`
+
+VXL'QU3Njk8[phV2@0Q92J#d6rA2N1["[!%c(M4X-8p,0IcYJf2lRBmD2c)*RQEF
+
+68m'9jqq*MjHTji&GqDp$kh501r9fqVPJe4iQDRS)L!)ELqiX08i#@40jpP1+F@p
+
+iC&))L)Qq4Bk-cK-i*h`cDlN1cMBUbZA3+beKhX*-&UD`X%ME%F91fHB3BaCC''Y
+
+KNba-C@(,"-40Yl"l,#c8`YCDf%#"XGD%F4m3'*i'k"iah[Ddam+k"Xd3eV@02'B
+
+bj'D90I9p!!!-q)[jAU2HhQ[NiCQC&f(Ne`JR!hlN1''4Sjc`)hcL5IK+f(@8(q&
+
+(1&Nj2XreTBI[M!0dGB4'MK01#CFF2c,JK"*1MNZ1(q&(11@5ii5EKimF*ja``Np
+
+#bA(#bBL6BpQ6jq5imT-m2mQ!dq2N'H&2RT2M%Nii'6$J,PF!#N#jGS3IS9Uba%G
+
+'A-)*8[#%!j-9'#r3@EpUPQ9+NL6$ldj*kVS6INIK@`*q'q$hGRJCPb,`pUJm(fQ
+
+3!#mGrdQqe$Nm22hkJ2cerNp"i3$m4Z62S5YA40V([V`MbHF@)QPT2IN@3@$ceHm
+
+I&dT3GqF9K,'&&8[6LKMTbQ6@-*%bJE#4RM,b'FA*'VC5`0BBdTa"@aNXM#)mU'"
+
+N@d@XSIKMMiMh#RbbLSjLT49GG9"F84)Q8QfN&![N1hK"A'V5F,,dJIF@+`iNJEb
+
+H-(5Nar84j!"*Q54MH+j&08dYQc,(ipT9I+aFqIQc-XP313&803UUPPD4*+UAIlj
+
+$U+jMAP1QUSfEYV2Qp4HKfZ#TYQTCT)hEaCbp+ZXH0"m5USfHDV1HbL4cCT@41rr
+
+5+d+eL4&+'hR90)iLRp$LYcm)e5McQN@UMR#&$kKqr%eHU-DBejbUCC-k+P4N5r%
+
+Iha+Uc5aj)kVfm*'ej*8Dali5ULfHDLah-l$Zfer1#G9@6l8TTf*r,RKTZ2#Q8'h
+
+MA2&i%MYq(0aCicHKfPlfDYLeJ3*FFEG3l@"HmfJbqFrdHU&IU+jRHE95BmQFkJF
+
+29)qp)93hX!aCGLfYP0!jSEU4HF9)-e8M9rADGfC4U(BbVVC66+8XR2Hj2RAmGk'
+
+kLDNk8`@p0[6F"hrG,e3h`kmm(BhDMQjBm@`ejDH1pG)YbUXYM'Y'5aD`-H(VPZ)
+
+,*i6A,Nqe)D1Y'5@UV@HM3VAE)a3$3MT+9jAGa)HI#%*E@9ie+jmf-PA9dY#66`Z
+
+[fkMA!l&$eZ3)bP996crcal6`ZRdT$9NG0S#+V([`rRZ&eae,A%dMGB2V4H%9YPL
+
+LfZ3B194,NC[ik!QKZSYlaE"deVc1$3[9(XVeFJIG0T,9**@'AVXJZ2Db$%'!,$a
+
+e+d2+8SES`Z&RD1(C`m,VlM*Aj)cP#M@ZlJI#Djp(U28`fl)VL9dKY+IXeFM!HRJ
+
+MVc0#YCpj6@!,M0VrHYh,CMQN!FBjl1ZVEPhjaCK)``"6,6JiU@@ekMjdmEEPI@M
+
+3DpXKj3pi+f`LFFpIUPrF058)N4X)f4ZQ*P5c1[&!pGhC4i@Ue2BCE"bRL&haLRk
+
+Thb#ZUK&ZK-Kc9k4Z-[QKhdaf&1KhN!#*#IdZ-XfJhdPQ)I6l#![SYjD'HXp$hdA
+
+f$1LhNlN-r4DbV8$I8iS[RSEqj#URqY@$9b3dJG1XG))%khUHJMX,Vh896Z%"I%B
+
+PFK1MejpP2[@,$LpbTe[Q%h#[hhai0BBHF+r-MrTeL9G6k!!IKHa1rmf2qMf,9c6
+
+d)%I[5Hq$1hVVq60(`H@-9fb&cfkb$BBDc1-Ck@@#jrVH%0cXH$@cIK[C#F&2Q9X
+
+[qpl(HTpEQ9F`KqVA3&iYS3Pl6#ARpIXMVpCP6[+ma`PkbJPkbJPkbJPkbJPkbJP
+
+kbJPkbJPkbJPk1MHKTlbJTlbJpqGlF2RNe4CD`1XDTfUZEYjDHE@[F0T$,KbK"Vc
+
+mA!9AAPiGS3Qjm[HQi+l-LraVj'p1i3&mcNKce1@eZ4pFX(PY@1(66rD18)Im"eF
+
+YAJ1K#AYcK92peXpVBfM#AZAIKi*r&r$U$"h)dkhp2[JI!kp0S3GjhdZZV))A!43
+
+jH4kk(TLQKF4pTXhHI!ITRb%hcX3KfeN#**1EI54a"'@Z8(9Dm%D@b"Y#qhm!N!-
+
+0!!PRBfaTBLda,VPM8&"$,VN!N"#ah3#3%!9X!!!I``#3"2q3"&"56dT,38K-!3#
+
+TY1))Uc!eD!!!@F-!N!B563#3"2$I!*!)22J1`2KbNQaPEr+hGEX``Jk!Vpa0&eT
+
+RDl*eSGZ&%EEAc@iGG+hAYBDRapHZd6ETQH'lV2AbpMVJ4lN,ck0G4lMb)fcKAQi
+
+*AeLhm1)VRfPGM,"Zi8pBG1%a3VYZi@m,@rM#2'iAfhjHacE,K"[bJGYB,ZcNP&#
+
+"$cqJ[fRG`SmXR'aMC-H6r-)AXTaNHE+Fj"HkN!"0"R[G!H4jITB&`!(!dKX"PZ#
+
+Z+PX+S(dCS&YGZI3,cN3L+P4H)V5R@D3p,54$JD"3'!j')mhRcl%mUJ)9e2PVUaF
+
+j[6lNX)ll!4,jajb6UrZK!hSTX[caD`$ZIHl,pdeVm&EaLeKG-YjQB6AKT)84pF,
+
+kB$+55%ID`b-4QF0T19ckfSl,d['15$X-4cTr0"2!dIR5%1j[S4JQa0,J4lT!pkc
+
+"EjcQ2ZmmNDF36,1DH)X!8($N3ihbR+mcX1GC!E!0fi)+ra)rCUL`#HU&V9)ke`6
+
+IhTB!b&RK%B!&4fA8Ecr8+8IBcr)4Z8L+$bmVaA0$-Lr)$3+SMf0Xkh!%1L(hiM$
+
+H56i!P'Q(V3ZXrmCRE,f[6f'0N!"Z$E6%fl(AqCL20Ka-#kRdjh`qA&CRACe[!5i
+
++PSiKjh)6PJM4H$#5%&U%HF#GqF0F$MM6fH)T68dFSQ!hQ*["e3hGME'TS#e`Fmq
+
+Sl`'0qRTZMfEcM@b8M`(hV,a,kqB4N8iZ[4Sh5b!9ddQpT9YP#5UK!NX`BDbr,"E
+
+!TME)X#08Bm,*$)fP2Ci@G1bTGUbETe@@q%4QL60h[2d5)BQGX-U5,*6)q)99'NX
+
+bP3a1pJZTH#BC&"!P%4'5XP`!Fm82LidDE@#h&eejC#m'cSQd"k1C&S(CD`*"Va"
+
+S%C+TmmkE6aJ*6S3kTd8)4GS&PNjQ"#DY1419T&!JQT+cV-0*5@'9$$5+K-58Y"%
+
+N8Ea'&)q3!*!!UeBZ'qd'!&14D",LQVJ'$qTI1DUU3$%0cAD!e9HMkl`KaGAASBj
+
+TJ#pMhSb5Rq0c+LJ3l3LJkD2dcrJM2Q%3Kh&mZL-JR(&m+L$L-)j29b,%B4br8)j
+
+X!Y$j4ZUh`)[eI!A!R(d!4AHG`LH[d[f@re6*b2mAI`)H5F0aI+2XYq2iC)+N`6M
+
+qC$b5"Z2ij,N%KHI*24K!$k@Plm*Hm'Rd8-bci0h@*rK6m%JDM[-[aZ1Nhq+IKNH
+
+UJA&mE-V&'KM(2a129!2Mq2,5(2qIrSHmNfTSR2rTH+3D'XHRfL81irM8FE,Ep4r
+
+eTUeM[5Ra8bilkJJ6f!)lF0e(0'p*Cke+2Nq9ccEjh#UIZq6c&[RmM(3ZV*!!cL0
+
+k&5l"Jp4$Ilc)-m$9BDMqeV0m$l6LhM(EAX9A,10lG,aR)2GNb6Sm29&b0@CfmMd
+
+&Mr!pHLh'hX&p"qiPVV#h)jIcaN(YAHVY!-im,lH&lp&Fc$pX!KD$+,qKqbMQh",
+
+@BjDAX[M-KFF0&bH!le%r'GC@E`LVXP9mKXdeG)3QcED[U18Vq4jY2c-fD8XFl$a
+
+Jb0pEdXPRCYXVR!e1c(f%qF`GKAUQcPT3T6E-YjCF2GYHhq#[aqa0'*p@XJl4r*8
+
+qM(Fa(e1(MAb2DUZDVTq-SD2mJ+kFAj*ldAQmX-KFQf"C5i,E1fA&P2jHj`!8*c4
+
+Cbq,eU+LUqmriLrQ-H$8"RJ(GXC,YKXYCKk(M!EcN!3MV-HG3b@DB@MEAd"P5,9[
+
+2CjDYplkH1ckr$1D5aNf'jH[,p0ehXaPCKe@(eI0#11SC',UQT)X9K3qD(G8hK#c
+
+C@GQUfADhU*AQPE#2X"A&i-9KaAUdDe$"bpQU)@mfJNfL,U61YQ4RBFiKFac+[hC
+
+Y@49Fi(Ye4UjKII9Fl[b`UM[(Ca+6ZhF[@mq`0Seer)R3*#Y$$IcK`pPc%EI6FKZ
+
+I`IV"'%bLZK'Mdl!5jqQ+3J!feU'k*f(FZf(EGY@@N!!CGAmMqd9@CrDD68d'jf(
+
+3TlQV6AYhAEJlGh4$epjV3bSqBiDXKA!BPjeTVUYp1pI,DPfESAK1"2eSD[B-elh
+
+H#"KCEIFl0K-Um0E-CFr[,$HC6Hhc`fDr-eb-HmN5*`iSE-8)!#TL+mfKpUV"jrc
+
+$X6fMXIlRYZ5'5$I94YXX-&C(`""L$Dkf)VmVe*%)GZr'mh(#3i3EqlYKNKblRf*
+
+'9fi`h"aV43`ejERI0DPfA"MDB``XX)HHa#bYS3h1c!hCcPlQ0+mDh0Yr`mEU8Hk
+
+YrAmUXCIMj8SFBkA%6iNVCjRI%C(IMj&E3@l3G[C&a#hGId-rBQbXrT)c0e6q'2p
+
+eC)89`[fJmPd62,qrh"5fBCA-$%rb1d1R5hbj`ddQ1G,60%Q1l'T#EqB1)110@)h
+
+%i!95M+ekEiM0HfqSHM1k9UQY&%V$jTQPB&VZFVm*4FmG"[Acbff$#qbZ,a3IKUr
+
+B"VZ2A1J-[B%elK$paa&k8Z63JaakNVNdL$c1fP%+A`QGIJ'bm6iH0ZklkX(0S"E
+
+8jP*3Mb,[3pbE@&fLD'2RS@ZY1`pG"kj1X1j#2R9*X*QX*TAMbYcVef*YX2)T6FA
+
+Q@D$Hf'AE5@VBGSP+2*elSqN#9T4Gc"`I)"SMr!P3K8hPL)Se--@E+!*#j8qBAdA
+
+F)f`H'*JMT!TSH@V*`'V2IZI1K@DpeEljYRXA2YJ9eU,IcfjLaVQJjXS%LTUELM'
+
+UNU1Q*M@HTVX(FV[-AA`QqadqFr3i9[JU81PlSB$r%d$A3iqhZfXV+KG!GjBeeU(
+
+[-cfI+9deX0(XqqDqeeCrEqGcqm6iUPf$i$#AQd`B@p0rSjJ6NR2d'hX'fX5-"MQ
+
+MU,pRS%(-F-NCDZeUk[$*BA*h$2XG9RaZHj-D6bq3!1YJC6AD61@QEFZ@lXi09,[
+
+#3r`40LMRE"V0'C!!FecYKJh1Q(D[`hN%90BLbX@@Y!c8C8j3QmY!ApD)[GhVGTJ
+
+**CcApF6MTA!ZjkemqUrh9AKG,PI[cVeVI+q#h6`$QIm$kKcXmZ"@c&ph+[pbaRf
+
++-2[6I1-)JqV1YQR9UpZ-&Cd9Uc'6i5P6JCdV6"8c-TKV%$1eQ*@af2(L22GJCe"
+
+VaTDFcfaEffcXh1Pef-$Pm$Vic)0VQmqbL$(+mRVQJpGcr8kVcZZakIJ-9F5"VJ2
+
+A)XVacTfpDfd&ZhSY"9l2XleH6rpD3Epa6E1D10FlQJjH!G34SPGS&qM3*fC3Pe2
+
+L`2L%lVY,CV!*T39qcpXH[fHHVQRU'%UAhk2&Qk`VKaD[,i2ZHk`cX2[6K&iQRrQ
+
+lbPXmS@QX)1Y!&RH`da"Y"8BfPYDc4GPC#3lV4AhlG+E(2&HTGaMM!VD)&65CaPL
+
+Dr4lQB&J09`k9kE(,mhf[0f[T[[2#[mfpH2-6*6k4bk,U5Z`kcd%Ia$UcfEZ2Z!G
+
+1&'%PEF2B1aKl$'0hBH`R',X1BjX`pP1-h6AD-aHa8TJD0Z"T@[KdIJ$5L*0!R+1
+
+)NmCi#mDEj(J5i`fS4KaV[49[Y[ASjjGJCfSIkdaR)f+)e-#cLpMMH4iTJQFE+B$
+
+RFiN4RXfXNFpBZGXAc[3QM,G2Yh*CMh@3!(q8lFE6#ID-P'YZ"AefKT9M99N2Re%
+
+Z5UJ[cKd0UjR$Y@%N5eQr[bVdDANH1X3[2[#XjcJ0%Se1!jKa'U#f[M%BE`p&`TC
+
+@-mfEF*1J""c`J'Sc4b0!`0Q1cH9X!e(3aCl!)H`k4qIhpfYS1)*',+EMMLJR'JM
+
+*XAVRp4,L3*6EFHJLENI+bThcfZ@BBX$BV8U1Sr-@+@iljX&F'M+D6*J-'5#(%1k
+
+[1&EhlT'("@L3!%(&RA-a6V0,2#9X9%3D8*&8fT'k`V(k5V),NCZX$kh*MY@GDYV
+
+4Y-8%c[bAlh!l-U6&69c*e@N4Mj-C)C2d+XbiMLZjUSJ3--Aq8HQ-$[R0RcMaPa8
+
+e&lLqlpUj[TGS[iMVqri'VZr9AUl[KhZi[J-YA0r"GUl[d&eFhq'YA0rr0h*pEml
+
+RqYlHa2Ap"212)[Ba!pGh2-6e$Gc+p3dqbr80[FMe`hbZAjA&I4IA2aN0'##DQ-I
+
+F0B%8$M1bX*!!6V&dUi!$KD&N2-DNDAZFBic&F2BrKF2r6-!j%"D+4)8c'q,aD,f
+
+3!-3j51B9SJP@RdlLA(j+(8X++A@L25E3BD9ki@,HV9l@i1F0$6KDbP$RC(bL'2*
+
+%ikP8)(QCZL15MXe30%"dDAVbI)DMURqBCV&i5b4dfDrbrk!LN!!@@#SGL#9B+*j
+
+N3JH#Y3HLV#@5r"fhhq@IS5Jp9LM&BLQF6+PSMTk2cbS%9c)KQ@5a90K#Sf4N5PN
+
+S5M[3da4hiQK)k+XiA(ND$YpSYSe-m)LIZ,6N5rL%!p$M"e)Z2G@JJJ8FXU,((EM
+
+pQ)@$C4*&(*ZN6`SqKSGP)q02Q+F@[iqA@RaFJFBHbCM4qfMF%h!%89`D('LN6e`
+
+k'KDkIh4i5)XM8r4*4)JcM9hKZ+)%Kcj2Rl4%aj+pAcSALTmN,qQmF&6[3Z`$k*0
+
+%H%M18RJEF-b22R&0qM&+6,@P[&-a!BIik*1U!BGKe64B611lY)`iBNHI9"S+Ab9
+
+l)JjKd5HT3V25,H+!P%`9Z`rkT%9kNCS1THY!pHQ6Q&%@$8)T99L%Sfhd5H*hI$J
+
+64C28Y,C`Djl#m$6b!XGfTmrR*X8$d@L`Y6QkdK+%4i(E8[b59GP&,"cqQPC3ih4
+
+MlA''N6k&X1iVfl4IfC%6%hNG3kaD8[4Nmd+LGcpXR+[Xb-XNFZZYEkLS`Q4G+Yd
+
+5L413!'S-T`$1NR'U9P55`+R)+U%aM8!K9-"b-+[Xk$GR5FTkh)hN*rJB5@-L'EP
+
+%j(6IK+GdbSlH-e9"XT!!TkM$335*3-%BFqd`miD+#P4)M`VKJ,5STAS-5DFJ,A9
+
+lRF6mdQ"V)#Q+K-c,[YUNl&M9XNEZ@PkXmY(k8'eCj+P3G[5T%69*)e+cY5@CqV"
+
+#$%SP0969B)9`fR3N*L#-jAfF#50kqURL8%pU-)M3+FmipZBILqkTH!E9YJip)aj
+
+%`mKhi"GMeDhkeqSZq1IU*VIi[,SeRcM3"dM$M['C$j!!BhcZ!m11mCN2&2k,$aK
+
+qi32[Hr5%Rh[d,hX-I&T(k6&F2UIBBc4(!m'9d93k(d+2NBr*-djj`D*SpBJAZ,f
+
+9j!86F'3iZ$+9LDAqShqJf[jh,cLPbr2V[SPKZ8BUA*j'UT'@jR"M,2UIAFerUC*
+
+hbU&Hqqk24KaUB492qKV`$C4!&+Z"V#$rQ"GJ24rmKPrCa6X4KAZ0c$d@5+lmTal
+
+hVejS(qNI[*91V#iSP&p#b,2@2paR1A6E52mJe6FBBMJ1dGJL*2+9p3qIhj!![Bp
+
+M('C8fB"h)XK)5,I&%TpfThIZ`BHa&(9Vm2+9kL#QA,kQIZdYiIaLYrARRVV2f2q
+
+YNG[k'UGr%8DeBN-EK0EmEAlarTd(p5,rIHIa&j&hIpETLXk#R@jbC@-b,9jkj$[
+
+SG20dc3jaep#MG,*Rm*9,kClGd#jFfLM2Qq@TmibVrRcNcU2@95h1CX5Efl"&%5r
+
+8mURGV@U5ZdHGS,k4EYRemG4[EPCrFjZ4PqYQYFV$Li`LB4cI%5Ak4CIabTc4cV5
+
+Z`5pfTSPdXM(B'Xb,d*RQlCVl-6rbfNK(iUpddhemB9))4J14@"k%hM42efh'efl
+
+%*i192U1qBE',qSa81Y2F(%qfjbIV-mbRlM2Dk!QiiGN-X@CeBXhQjHJG2R%#l)P
+
+%*m$r!"'46R)DGS+2k[XNTp(qiGGq@r81$FI)IYZ`[)lZM!cTba)YbQKh2VHq(T'
+
+iYATPahXMf583L9i#-b!5'SA3JP$LMk5FV"eL5P&e,)!2AM(fqq[&rAqqJEX3ZJ0
+
+4GUAcq1#I[$MlrpXrj3jb$ZiY+2BkkdRM@qKR3r"mcb,mia%m2lM89dZ[Vqh!-,f
+
+QqNbpVjjZ29qJCq04M`2d!b+N'UT5MqGLqX832%q[Aej$mA2Gr%)2D,J,T!VQVUK
+
+`%6jhAB9V+HAI4,rjJHFl+Pb,m4eQEZZ5@KrPp5aF@N9GqC2+ql1S&YkPdTmG6Gr
+
+!qEV`09U+&4c&223NLQNk-DpALZNdR1mDqVXNM'QAB`crlBKL%mp(M*G"*FCZ`&J
+
+DZ&cZG*Ki-f,J@mmLMhX`*R29E-FB[Qe,XDNr4DlPFZc[1GrDKlkqQYkKeBBaYUl
+
+YEqK(@E3aM+N[HKM14ThU%2X*Hb(-`McNHXhpB"3j2BDaPJB6I!Ne%&qEaD`r`V`
+
+YU-G"k"3ar)MaKKaEKl'$NQC6hd1-Lq4B$Q0G-XB+e-BRajCJ,+'*V3bd4NrqAp,
+
+B[bJT[kddmXG*R(e#AIa5)9RRT[cr!`!!$3!*Cf0XD@)Y-LkjBe"33bkj!*!3qL)
+
+!N"!0"J!!,h3!N!6rN!438Np+5d&)6!%!UE6L#+X`0A!!!#*k!*!'$d%!N!43[J#
+
+3#1j"$F$iCXbcEQ9ffFS2dS@*jbZl63NYVcACZY$0##1XPDZ$V[@ke[$dmVQ6K5h
+
+FYGEmE+(Rmc@246PGf0D9hF)@VNAi`VhS`KGM(GQA+lmmdfiI)f`c`Tq`63P23V[
+
+Y`VEH`KHqX)9f(@(E*!Zrf-)@IZi)AhKXi3[E,M3j*432"&!HrHaD@&$M#f(,qq3
+
+@XL1hN!$"3Rk6AcKCb%+1%di@J&@""TeG+a&(42abSQ*m9@@VL(4[%29TUPEGj%S
+
+NfN09'd1a&"q0T8,*F(-`0#85E)pZZ-eZrEB+Z[80G6A,A6ir2'5jYd$i*mlPdrI
+
+-@8-1XA6I6r6dUG[h&cAjUSAPI(dbhQEPDb0*+mqX6fN-*U1*9$3@'8GN$c0%(%0
+
+GelfTH&Fd4Q0)jLrR%MNc2aM&pcf8d``Y,Ak!B(cHb*GQH1E2Phb'JLQq0Yi5)P*
+
+IZ&DMccNrDX`mDiN1BLbSE&MC!)B+3p!!(FM4Z3"pmf##5,64Fd39&fA9Eck6N4(
+
+q-Kr+TK`qGQ`-&dGPAb51%'Q'J"dB3bK$iZYMHPIm%$'QJ`j8f2l6cq5j@TmTYD&
+
+8Dh0,2)CCjkGqG*&J+Y5CqU@IDmIQUUrh9q!`X*4GG$59b(1#DBYLrXT3Hc`B6B4
+
+D3NZ)Zr'(SNLFq4ETPX+0#01J@-c9Mci&E"ETe"lZK'B2D682F5pVpcl#6cM0`cF
+
+VIh2RdI%LA6N'$6l@jXi1I@kfp+LX3395@i-*Bq1p(FdBDS-m*N)0#&FB@QXXRJV
+
+TqHr&d$F[UDca!YiDjchaf-C3%T1`bTUFNM26%1V@@T1GbH#dKP"R2*d-KU#5L)D
+
+5FVQ)&NXr0"XEY)Prh,6j`NN!Fk+aB(Zk*F3lDTZ$[P"c5bMC1Arq8UD4i#5T15f
+
+KF$3@iP2*G)M2RB8&#LRFh0iTXfaMT'5S@aDD8))aK6DZ*"9[2BV(P+51c4hG,L+
+
+c53S*k44Xa8Acmd49U9R$Xk-p6,4P'e,Rh4bZH3"e6"(G$Pjab5Ikh&MNk*3JKBH
+
+am`[rd,p4KJ)IdrpGAkQ!SYrdArSB+K6p(4q-kaYR%DeiK@MHTTrT+airpFpf(!c
+
+C6D6hMrH[fSGq[SpSi@NLdj2ApC8!q05rrM0pH5A%p,FGr*AqP!RpYPrTjl,kIr)
+
+Mrc0p)kiXJcl9Cb(1%'6hP`BRQ0MP'EU4U`lF@CCrSLp0(%#3!"HAp98B52*lSGq
+
+&ZrfkrM3CD5@kEp'%2R+m!*ldPFM#f(9p0R-`C#rdT5&)cLr`#Kk#rMULrlIXZ[j
+
+d'6P$Y0N+!(Y!54rDdc&h'$"brDYqB3l4$[hhr$0$4PE$2eXNb2ieb2fErJLM)1T
+
+RZCa*(rQIH68r2Xk[*I+#iKreEj!!r52r-kc1XRmYjSpI3ai@B(RaKIqI,BSqG$#
+
+E'MkH69X[ckB'iJEe$Qi`RhhAFB-&cq&lKKZFKRc"-D9m50)#'Z6Fp%2+jFLffS0
+
+N5Tj%4@C5"GI&cC(ZFcD,h$e838lFZmM*m-eX'F$dP%A,,mqff[SF8$&N-KPiM91
+
+9NF2XSa0J@f1fH(J8"hGPCVYkTSRLJ,V55r6R486P'%J,"U5PdFrVi(p*UM20Z#1
+
+AjGIGE[0r"EdLeqdcjp[mNSplX,Y)hCYJ5aj0I@@G*jb-Gm65lHf-'iiR1d+aG!I
+
+M4Q-YACfKpTEfZ,40CpQLY-XkZ5B+lNFp6BS(cVppFXHLm)JE3biI%jRZ4TD29iR
+
+SY!R1P$QEBbjeBD*lqi'1GccMbIje'bEC1H@a56dI1a@*I@9pEqBF-qYcdaaAM`b
+
+5FjP9B(QLVT*e4Aa$'kXN*T*FX[j[jrbLXcJ8Me@X&Eh%AL-JTT!!Gd4B3#S&rjI
+
+6(0UBDSje*M'BT4+G-9BhC9*@-5jcH$[1@!XpJKl'$ZGDCHXmRb03ICB4reapCC!
+
+!(Mqj("6&rGSNfp+B@FQGKfZV'cfXb6ZLR8&V%2h"l5[mJ8hjJPR%eT0&kPUA"r-
+
+MPcHq*D-)FI[,GTp4[[$$5jiqJ&BGP+G#UkjaI6!H#dFM9NbNa28pDebXI1(,,(N
+
+ED'bUV!CChjPULFDCN!"U8NG00mXke@ZV@1Ge4VY$ke-3#PpeT"PAmJT`"+9)V,N
+
+pTl6IHLkVI,'RZ6PAIkpR2HXM[+GCRdK'0dVZpqGr6kpmXC'CT5KCd3'NL33K%LA
+
+eT(2pQ21Q5[3dR+GDX116UUkC9$)S5UXm2KGcINq`Y6NTP421bhiMS(ba5j&Vj+N
+
+6f#aTQ1JNeElPhNVPLj`GVbDV%DYQDdZbmeS[j5Xpee4GLelLG+PS4`JbeUXka[&
+
+k0V$H4$f6H2FMHFHjNP0bI"Sd(Fh4'2DERk5`R-%10TmaEFjrI`$I68b$mrG)kq6
+
+aHBBP*&LlQC0%8Xl9HQQfr9b!L@&XcMHPT*eJ*QI3,1Ibj`$iNqZ&q@YbPJ1Ha&!
+
+Tc3P+,rc(E-IjIaGE%9QEH@4l"'92bccba&FiN!#)&l6[jHikPAbI*GrYmVe9[[I
+
+)phhbr86Z2U8bGeIk!)'b%TGV)mAiNDCMGeGHc9GI%IUT&GqZ"BjUSA+ed+mA[-2
+
+LXC)(FAZaC"ZB'D&IrCc3Ep!"HarI&r!YF8GmAD,SLj2'YmVA4CaPLEK2k0IH*6a
+
+V*Vk$fS9GI4I"H5aL!-[(@%*ka9$HA3N5qMA()VUDA4&9YPT)mi[cZX*6&cM@eJP
+
+93VpZN!!h"R3P6RiqmI$[+mN)k3@15PH6#pcRH,qPD`T@&9NVUY3'[UeNf`)(%Um
+
+4l0h!LdSHK&T$P4pi$qrR04'Md+mkS'(0E3aI&)EejF*+mAAAd"56T5l"Ckd*lZ6
+
+dYG-("ec$9*M3CUehlN4&9Aer+0`PT+AR#H3GeRp3FMK[%pq9er8Y223JLKM!HEY
+
+N,mdU@jbA#DY@la65UhIkhK'(PTE4BPEM30kDR@@'[UIiiUc6TNIh["CTp`k2hPr
+
+5`jXLjbc1QSI$eZbmE28#KdHUPIB[)RkQV95-AKqV@,pZ+bUiLHmHp@@M''(eB8f
+
+f*6X2R,FYF5Vrc4ePeE6)rfDaf,5cCM&h@d69*`VTa,5qikYhmZK0Ble`+6c9aU-
+
+'$C(cf9ZKQl&q68LMIi$490Bh%PU%6PbL0f'aB1Hl9(X5aT1l$Kj@l3YE82GhXer
+
+JkbdqLcQ3!1Fk6iB8YmemmZL+iq,&A6dRGi493YT#@5[6iERXA%YphBr&!El1[CF
+
++&dD44l1b0lLIpNA*b0Ie[@mhS`,[c9hpkT&bXm8F@aUa0,JLKIL@V(3KLJm!)8*
+
+&l+8LDUmD1G8`KVdmJ3fHfLH1XVUTHZhcb&J6TE``hq4Z-c@i`ef*B0pah)HB(K3
+
+H'HbMU6,f$BBChH*)C%0(+c3dM1IjL9Re`SV`bmEQ#NIi'&Lk[$Dk84behl,DCHN
+
+H16RiF'r0K2I@`Gr,ZCIaFJ8(9XVm+EKbPreGN!$mr6@mUF84qbhVQ,I8i-1$d1L
+
+YqD*,(#erAVJEVY!Kh&Y92c(6UfI+c4%lZQ4ZC'U$+c`cjjFl(c$,5(pJUS`F$5#
+
+EZE0`h)YZC!jHBaAMZcmFjCGm1&U$M9+Ne&j+T4(,h&)bVh&lrSC-Tmk6jY8epT%
+
++KrZQ`[0dKhfNlm)+9rKGp,K6bKpRq*MNS4mHqT0LLL3I0lp35RH%Cbk#'pph)mE
+
+6[h0S,fP#'NXTD5D86d2hbhap`Y5EHAZ(lFME$j!!1d1fSr"6Rb5lf@C@BB2jcJl
+
+d"Pmq29"SQ8HDhKll%9B0qe'T%Lq*l`B@mDEXREcc)d9M9,K%USLj(+VSJHQqK)Q
+
+BUR$*mLCd,r",+)phKPA01S'YCFRQb(lRkmXX"TYMlpHHARDS*k*$hLm)m'`$`C@
+
+&''S*&!*9bDJjS-&YYQGB2'VT%G,Cl`MTLd2Sm'j5'3C),I`f)I@3!2%1,)HU+UJ
+
+[bkq[4qlc"L&GfMhFDr(rrZQrf[,p)kG15hMhd4&b@XV0CQ"E"aq41''CBqMY(fk
+
+6'%db`c6B2p`N-G`b3k2E`LC4PM$L%f0jKiiA$`FdZ,h'8JHGYGjZ,MFIA,hUZ$K
+
+Fiik-#KIi%CQcHi)c,(2FXEaGVJlG5DIV!UPX*XE&5&T'QM)AD5aPC#KEMpRZ(3F
+
+@d#@FcrhLGd[T9XjApG)IRkldZGhZJ5-RYrVI*)HP'-lr3A8KTMck#[J2AZG[`VV
+
+Jha3@r)a[((G3NfNVUYR5CUc-9'i"NmFYABR*P@C*M$5iH4*6"eEDLVfl+"l+"(8
+
+@M14#qZ$f$FE-%Cr66QkRcbQN$fhIF,09`KM,jee+2Zp$4fakRpHZ&p+X)mlfR0d
+
+"PD(-NB(YG[A4!D[DjheP`1FGh"ibp'lGS''H'jf"FrF4Q`L4&ES+2A+LQ%dj*8l
+
+JqAe2P46cqDAU"Zq2[3hH*IV!V%Q9RJD[$Y[IcD0hlLbM[MffBNarf[!E,'IqV1S
+
+aElL)9fHGF2%%2`0UDi(dPMEbbl2c%Kck4I2iE0i!RV[80kDaL&r1U`2Q5CH@"Lr
+
+[j0%0QdI,$*Mbr0mIb&Vl[VlL6mAA(hfaa#pj@9j6KDPc$R)3I@Chp&h`$&mbSC-
+
+1!RXIf22!RJ6fYm!H!,BEf0m"Hh*LCMEaT63VNSGE8@5Q-%`Tk#5JFa%k+H!Y`!-
+
+bRJ6HK'V%dHZYf,SBN!$R'c'C1LBRd`93$,0Ui1jQlR&I`LU#Zje9!2GEQ52F,Ia
+
+k)@hM(PmfejF`2MlEaQ@pYK(Kfraah#la*h*F5bXCXX8fMUr1HS@dXLKKFl&i-D,
+
+KRHjGikbVar'Y9la$l2RB6pmR,LdS'+0CVLaC,H`"dT@r%Z!F2cScr3P3LVMhU0$
+
+RDQ6lXmIBIJ6h2FZaT-(pd#Tr(GX$[`!BEfIS4+1rNEepHBe0*1LCXfaR!QFkYKh
+
+"[C!!E89`RpfiTTEKYhU%C9l5FSYb1eVZ[NShdqFHU(5[B[`[Xmd%lNp8ZZr%``V
+
+Z`-Sk2q2e,eY9c6DeamCH2MPq""hf),AJ0Z`'mAk4BHU,`2"fN@(D$$6B3eKJHLe
+
+ijh+BEJhfCmrNX"X@BR0iMP35pJI3b"!RLM2TKUm#`jj4mR%B@%X1Qrhh`&k8X3q
+
+"I82'4(M5h,f&[F[64H#l[1e2f"XKA3FdhPMh,0f#,XX(PR*-SARJ23cXC6*+rTj
+
+($GBeQHQ,U+Ad,JkXA`G[(hJpP*%d'S#PC1a"B'rNDPDX"RC'a[6!hT)eeX&I3XE
+
+f-%rDMYpUEQfrmLafmJQYmYTfr+%XjmL[Mpm65YCl'2rr!!d!#'GMG'9cG#kjZ@0
+
+38%-ZZ3#3%%0D!*!3(m-!!%+&!*!%rj!%8&*25NY"5%`"!+QdiJLV-$9B!!"5l3#
+
+3"K+K!*!%$I3!N!Me"!i!pCQCc1abX2*Ef-,&mj8EA@KjV4fRQfkf--,fZP@[Eld
+
+Z$dq2VmN'A5Bp-hbAY9lHAJFXfQdl+AG,Z2)ME*&GEJRrA-libQIDl@-,fic`*fc
+
+6K5HKhAEKE`YIq-)mEQiRK(pXXmb@iapGq-+kKCfFELT3q1c,IZ&ZXPf1@pl#b%)
+
+ffjdZC,)F@FK#&m,)B+r,!D4[CPq-FBbaqZ@-eH&@A,@%-I9,M(@V+THFE3i'I@,
+
+PFV%p`R[E)f,)lA5*'SmV)SBMaKm`"H(DkkSAQQdeb1%*lP8%I"Kcj(3rX&H6m0M
+
+IZTkaqjrj`UCT$PZ9X*!!V`m&fSamV5GNj#ReR!CAb"Z-H0XpDBqF`ePa(%eGaiT
+
+)S-2EcP+HcTr1B+bXmm9Kh'q$6Mf`X[$"KF4R$RhYV2*CXk3m49H%V`fdL)`T"cl
+
+J+-2j13Fpcq@-E8&E8'&IE%H%!Ne3,pZF#1HDf2Hf""Q,&l1('*Yr8%EphJ1GXSF
+
+r%JrNr)3rGBV*(aq@mf,a)FC8Kq$ER2+`6KCr)B9h0"r'+0,%0Xm[rQdqSqFB2cQ
+
+eBU69f4*S4krcbhc8LClZG$iIR'*cIAh0I"abUXM3iXkAEq$(ilQ,49r!j3f+,H)
+
+maNhp56c112ejNK@"P6JkPXIB&fjK8aKcR!drZX6iG+jqq&li[TdQiqM4U(!CR@&
+
+rGU+(,&FBA8QAdZJ+kKT@q*eSAPdm1Mm9!Sj'C"RE!a%aQhqm(IAaK-)B'-FE!ha
+
+jS(fj'%,(Uc#'FK,*f-@9@FC3113DEaI$J@M)*3)Pk"9$i'!+Qm`pccf[0,(*#J2
+
+h%ZcNS8*JE#k(6ij38,[0q$[cVaRB"FIjhRDA,pSLmUCDTmXQ1P[%8(M@V%X))mK
+
+*81HhL'j[ZmK(3P'46jb,ab@$h%jI@)iU6J@&a*8bd!J5%NZ'TC%NDKY",5%K9lA
+
+%%1kQ%f8Z9IE(4kQ5X*9Mq!UPK%dirih2+53-k[E(m!QELQ!-Rl#ccq$6B)6Z-I`
+
+FQ(52iC0Hd6f'2a&QlKPm`YDG`5GX%V)aI-*'%r+rq)3prJ`qB9260)C2f"21i"-
+
+feI!B2QRI@@I`#A[5'Ic*-1NH`dIV+GeMrFY8Q(52j8mG(mdXar#TGUKe(X1R`pq
+
+T1G'EYSlfTT4IFZ446jL-RfpLA2G!eYX*@kf3!1dTXPdLfkfbh5AE'fAlbB5G8j'
+
+`4rJkCZFXKT(SUhpj-0jKc0+KVIl1dd)2DmAG-GY8*93X&AUb"HYJr,'#0E!H,EJ
+
+1NCe#Mr)KS8HMKZmGh)rJ,V"iE"haZ#h!9,BPYJl''HE&0`Sp@9F+$qSClfFqB9h
+
+h3F6FlY%JbNC43[653pSVJdcS86hQ89H[mbKL98+8Rk[YF1I00PeH*e3+2HTqAYH
+
+N,LMMCc%HqGX+1SASE&1&f@&'l%0mMD%M4m1VBND`e)EiiS,VCTXD(2B'40m'rl5
+
+#08#c9pE!hmAAm#U26ZK4E&E48%VR2LJ-CTF+Lq-[Q!rPj"[UJRc-'14f6EKm3Rq
+
+[HC!!63aQaBb,eS*44IHY`T9#9"TN-1YJpRX&fl4AmahDMZpMp-1B4i1Br38Ef*5
+
+LZGT1Yf,T@L'kG+hYpILK5iVBA1+i5A[CfL*0plhmp&KCF6DUCir(CadF[VkJLmr
+
+hl$189GrN0XCQaUTQQmSPVV*HpY33GT)apN++X4le+M"i0Epbf"EcSZR0GUYL,E'
+
+CL0P[#,$5,pp39-AQe,`b2HjB@cfAZmLMk)i,dH$ilTe,er+S69fpF0LG9mb$!l[
+
+R31a#i(BDla#LU"ri@"l9MH5GKNUFPjh[CUb%le$F&p6Y@VGPQf+Mf`$HhiaG`0F
+
+EE!CpNpCmJ'NLh(AkA6XZh4NrZ+jVe`eZK4!eX*L4F(JZ0X03ArHcH#pICpR!*Pl
+
+XK4j0L8ffh'rc-KeIere1L4i-[$eMkE2E5r8'IIXP(S2Gl*Q)Zf#a'@X,Qq&K$)b
+
+8&-E"[@,S'A[+pp5)VrqCMI&KiNfa[Q3Qde9lQGE01baYqAD,Zb2SkYi*qa$K!H(
+
+QrQk@*rZq5ckG*6lNDIDh!N0&FHA[kK@2A1Tq5ZHFEh)rKLLeYSe0M3qAR,I8E&J
+
+jY+[rT[A9)lQhp[p4)R[CAjVd`eG)q5Ap59[1Ed$+lfq3!*Xb2P4bhK@8@k6rTRj
+
+JV+rq[$NqA2U`m"9NK3VKAUem9mqHIDj8lbP"PFc`j0R0lNQ*I,N$6AVCdp18*hY
+
+f0%'EZEh)H$fUN6,B3ica+pmIjZHp2ebp!DT9@&,)#Mf''B9-IjQPr#f@rm`"TRV
+
+fXT+Kq5E,f4-2X#q@$(82A'Tf[iND,j2dTmcpQ*4$$h,S#F8M6-VMR%F+f4IGNqB
+
+J'pZ22,VGhpLkJDP%PD'3!+P'N!"h!rF@[MkB[ljcr`h&frIIb#bGV(J(mUN2X4*
+
+pX9j4GNhmp4Y3'hcTK+D*KTP-YEkVC$Za8E*$BZ+*q*Y0FrMmf#+ql$LLcLXFCJU
+
+2[K5SU)%*YQ!q)e6KX1%9i!l`mjL@,h-VR'U"@M4@E)Vpm1i&"NfaDF-GpbrBfZ9
+
+43qpR0r'kZ8c&&BRN0640K&FKHr90+PMRPJr'GaLkK'MXKd,di#&8q%UQd23bTI"
+
+9"Y@$aT[+kbSUjl2Z'0pB$phR08+dF1AJHN20YhDrGZhcfjrC,IPAlKKLCBC5[4k
+
+q9Idh5c&Z18Dc[QH`6BT`b"(jr6f$$LR#)NHSe0H#a(a5Q2KG+Ee$aFHh0DPJl5(
+
+93@8ePZK,p9Z@,YNC(kbfH)D&!Aj)MVPY*'C3MV'dDpHCrHTGCHB"TLM1TeLdU%9
+
+-9@4Q+N-4da3eSVGlhF4QX!,1CRRd4iAX3Xj@qF4Il+k`@5b@hZfl9Y@m`Nb'kFM
+
+m(e%[4TI(rJ6aDdl'AmecRb,-rM4HPmkJZV0Y@[@eEEU+cSTV%FR$LPDJFf96T)J
+
+SBV95T"T4851Qcr(ieNkAfS!@ABKZ@GfXkpaZ+bYKPM*EQ4$GZVVj(+2NSbLEp4*
+
+QXhjcHh'fc9U5,85T)[CflEd"+)FkYrHZ,P(Zk$8UEGDRHfh@rY@LC[fUCKAPh&$
+
+@Y1rVM$T#D)9kIMCdBMTe139Pm1GfheX`RFmY90UY2l2DVI1bQkD-SR6CVHVV',Y
+
+QH0(D)YCpAr&dG(pClTG)CrkkmRDVHaU[M*8KLl[iXi"f16cV#a[iKE'C33leSVV
+
+cA&k$1%ZK,B8aKer)+j[dSeNDl&DqM%FeA$0FT%'A9r0mEmcBIIHPIa9riGZ2&Y4
+
+)Z5bXVN6AH6jd%(9@BZSH+"mmR)p+fJ,I1r!p$0mpm2dGI$I#GaYmI`rI25-pFcj
+
+Ib+CiY,#QH5B*Jb`#R#"`$J)R!Rm,r%fb2`5r!f`%81ZYQ*CVS1I,dCQD4M[6f8"
+
+d%aZ`,C3pl(R%#1`5BJ$fKC34E!2I+%5,Z6XAc,!&GAHH@mc&V-9$`JriRE!1mdm
+
+QBJfY6"1EAXca96'V%%d15UJ[MKrdU2JbblTde+I(r2fRV)GU*0F[GKFZ'6FZ&@C
+
+!@&e$S`1V*BfZ3,[Ekc'f'QM#1TGaI6mfFAd[dRd&lTYa2mhe[DcQqPkGarAYVFD
+
+pRq[EGj!!kh[Gb2@pdFVerHebVZqYjlLqJ6bZladIehI`(Ul[(a4Fhf(J[@rMqRk
+
+qJHZ,jh2ph!,FAqIkPGrNqY@YA,rQDG`$A2piD5R$)dE#I+49a0+%1a6`miQp3Qa
+
+bq2hBFJaMcC%A-H[Lh9kI1084#2JDa"!f3ALEk![b$C%30K$$+Rp)$+Z#lAk4M'@
+
+U"BZ%FY95Keh3%Y-m5!m&aNNZUbm3$MY$+e3GhSKrHRQY-ib9%UaRb2XM&r&Bb[Q
+
+$#1m2Y(MG+riPr[FUR"'4$dHFrL$[$S4iX30Jl8iIhq)0r5khhm926M)p@LJ6T9)
+
+i'P,4l,[)jI1kP[&L+-6l`aiMMHaaP!k@(kR(!$5jIF64)2HV9c"fkm2Bb8M[NA,
+
+5*ahe$KKB9T9'TSPBKI4**`H4UR2Kk*+M&9J[`FHC*Q&NUD#pVUA83F[45Jadk'0
+
+F3Yf1$dpTM65,Hfl&AGM3!#1U'a&eQabGKF82I&eA%c-D$%HjjT%"U4TMFAb*[&A
+
+h)@)HETXFRBf&$h`V0NVHj1U3!,`K#cY(qL511H*j`3MI14L%iN0H')LU%pY@kEb
+
+e@+I!ap@!&jDr$K6[395bNR+a,%&ISM6!LST@Uj*V5MUX3Y#A)"$4+kM@NKY`il$
+
+S30pF$R`T#q@S*(BHeKMSieHp#Flf)`,0AQTaDcb@&2)PHQQ)5fb5Xdb1cXF+!Vj
+
+N8DB2,Ic5f4Kjid'T!M!XRlE0,$48%8&NcjVeLhiPLG[pfVbedR#BF'qX0CFl+(-
+
+SP#2N$)DCki1*FLTMEYAMF%qMfLlECUkT+5IZR$kIUlACYmcS)YhC12(&iZ3YB9'
+
+@5Q5*+ZHdkID)X$BCAmp+hXKTKT6AHm#U3r4C*hSQB(BrU*ZE[*&EJ[hH"NF&f1H
+
+b`j%@Ei"`&+-i5TRYhSDUbbZ*lE"hTGJB!9#%@0JA5pj3Yh-5l&V,'fQFRq0a03C
+
+$hZ956TYb(mp1hP#k+8NN)bQBbZ-#L*FT4c0ATc*h9&5!)3dB`XSCTF08SdMC5D3
+
+Pj6BcCAk9Up8CNNK#jN9IDNVH8!QCSr)k39+0G(N`aFD&eSVN$99-XdNF%CZY,D(
+
+`"a@L69D5SkS@&F+T)ekr#"MM-CcF0*pfUMM`5Hd-*A450pjlk`mPT8VU"Y9h0R3
+
+Mi#,4b)#J'D-9V[Mh#PIqZX**-8jAH0BrUp"aT*4UR0)#8Sh6@T!!8Se6@T!!maX
+
+Yd(kN"FGd1[HIG2TA[3DH,8Mf'TBDXp4V02ZFVQ8q2,U3!#'KemM%T"XRp@#KVcU
+
+Y"q@f5Y+$A#aMZCD&Srj`4S3qiL3hckljPY445pa8@+b09#FYcCj'[bpc@BGcr'Q
+
+!%69iq@)m[C*8URU(RG4!'ib%'PfYVS`*8j,-6"h[aReIXbG[D8k5c,e@cYh[$#h
+
+lT)pilFFr65[(JLU"+N',p`QF2Y40KM[Pq2-plHN1e&CT4R@a((P61@0C"rU4'Q`
+
+blVmMh8FNDTaTr9MRD@`4JjR-qSM6-pGM1,T84T8160L3!*%BDI-(2jh'hIh8YR5
+
+r8BZ42Y@"2cR5GhfQ,m$+0,B(FZ(*qFCchdR[JG5Dl3[K98[0EFBhc6Jf!k'Hj$p
+
+R)(rUIIG)ebZT#lVHd,,'8%3DJQ5UfdlEP"@LKiU5A8P9!ff@U2hH-(@biF`FQ[(
+
+KV+6++NJeiI9JS(a#A@K@FPTGe,p@Pj4QR&)AdSc6kT,5M&2U3T15dqU5QT4mULl
+
+T5FPrl#eaeipXJ`L95k4YN!"fmDV'M(FlXp`hrMJpBDZc9%XlCB(Q0M6#dJJhdpT
+
+%2bZdFd30'KTT[d-6#2rA22prCQFCZHEjar[pNj2C69PYp)K@DM)V+8'fT!3C%RU
+
+0$!Sc%%F&0K8NII&jQb@NScQPp1@%DKc0DD4,rDbV-ccd@PV(lCAPY$H4%a*G2UI
+
+ARl'MdM)(c3+5MpDF8)f1Rr4*kNc)faB*9I4DMcVDlZfJPej1UXfAEck8RMde1"C
+
+Ci0@')p(QjN#S(A*Mr%a[J*8"E)T3G!%pL5YhHBl+"RVj4bhpa)5,Y@G#d)*M[FH
+
+rp@3IGap(N9*kF+TlbrUSQrlA5IIaD[aidXeYj&CVNMH83&CM+!&9RaC+%&Q"[`%
+
+!PM5C'9(,)ph(*fUTr9!YMqT9DV2iP&iGfErj4+r'r8D[mMkHFibb02iMPNjf1PA
+
+[d("$VLh(CI8d(p1LX&VN*cJbP(8k[pfF2kE#ZPqTX(51-%LC%ZXU[a22)[*i8[E
+
+rZJ[cIcUGL4G#pHMBk,e2kCF0VX,2PP#E5Iik[#T1$qmHrqXJc[6'Fa2`XLUETTM
+
+$*YV-$D3cYp12%m#qEb(qhJ$feL8eGE5PqJMF0!YqXU&'QZAY39+9b(8[r8`"-MX
+
+Ah$6![T!!ITF!pTb'bfV*EbNA&PMaKL[H#UA+i@kTX"!qGeH&C3R&EkCI&X"$k6d
+
+9PN9@f#m[VUY"R%+aB%N90%@4PhahPUZj([c3IkY-$A%eUr''+[Q8"m(LQS3[kcE
+
+1G+!PiF[1j8b6mBiYqG4I![EZK'rFji"Ab"55leDmdYV+9*,[$[MHa&2kj,XIH(K
+
+90KkIa-Ep'I$!Tj5(&h&2b4cN`,G2pSf$$kqZ5Vi*m(hh+pHLCV(B#pqMEAp*2`L
+
+K$S-ce482X[1!F4&mDd`jE#EL`-(e-DD6q,X(FCd12IXm1+#IdU#-2SFi1q)HB*d
+
+54KI`ANVie'C`8jVJFZTNa%85A%ip'ebqP1"bkZr$jj-acJ0'8-Di!,i@'@-Q-2E
+
+*q68KTiMXZ`ja[9RqCFj@hp%rG"RpQjINMlqNrpQ&-qA@"ki53rAP&2rr!!!0$3p
+
+YGbpRBh4PFh3Z0MK,,VN!N""453#3%#pd!!"+8`#3"2q3"%e08&*0680$!3#V,jH
+
+ZUc!jB!!!"M%!!"R%!!!"V3!!"E(*MaZS!*!'[VXM4!iL+Pj0j%)PIdhl9fbRBC!
+
+!DR1(JAFp3hUJ2KNcZ@(k&LeHlIYc*cMM1X2GRCf"!*`N(81C&iAQNTm4&Ifii1"
+
+EpGII4h6#PiP+'R-jb[e$&IeM12rA3hh-XBk+D2XK9#@U!P9e!@eRU22XRT!!%ar
+
+%6jaP3[FjFKhiIjQ@hidE$&25cAm$`-IrIXai*1U*jZd88q%pXX1%F$M`RNJbAQS
+
+ih%%N0J*@A""6p[pE#%1,cL9X%K8j[Z%i38$F)*'R%8!QpTQQT&06TCMf4amme9+
+
+jii[1iC(HE43E%aa#QlrCjZ4[GSL(8*!!e8D-E"#r6LR@&GN3aF6F'028K*cdTGk
+
+aT$fkUhhK6F,P(Tj11!CFTLJ+QQSXDINp,M$RL-+Cm9q6j"VK+Hr'rhrjXB16b1@
+
+iec&AC&Z,)bAP)A[QZNkT`brFF9bj0@L(b*(4H3)$i*YCbh9`YK90aj%$0a!Gm&!
+
+,de[B3!XlC'%$"-Eme,D0'(Z229-8DlB`9Q$FC!Y6@9L'KA%@PQm[")V0YM#PKBP
+
+$[mI#m!L#i#MfjAH50i4eE512Q3bj@@90I4m!N!--!'XcXfpJlh2Ij$4lRaZHF-P
+
+a`Tr-D)4&@%FjIAiV9hi5rZ3i@3NqRhV5`hI'm8m[3MNjENHi%AjN`!NMR"`rbB$
+
+bTrc)FA,m$%r*F51Fm*03FTa`FTa`-Q#%%hlN'4R`Pa`RA(+FF+mMamRa)mq2m$2
+
+#bB!#GjN8B'@Y6-+0iUpN*rl)-F)*2m)*8[#%!j-9H"9SN!!()1QkKK#+`Hm@K$S
+
+HJ&m,rN[#E`hmIJLEJ,q0bk)PQTCS@&q4J@q@4d"9U,FU)md-(0Yrf-'kLSC3Ech
+
+QTZ6PDfM!,6kXTJh48"8c3%-B$Af2ZR8CG9Ip2$-35k-p#&9[4Zd)$4`EE%%G46!
+
+,R0"9-23T99CN34j4,-#2%@HJ4P(6T'aDQa#N[iMDX5G2a3J5j8hqU`G8AI)J-HU
+
+[2pc+8DXTel3Q5K1DDDe`rC'MeMLS#5QV5"2QC-jFKV@(Y,XiDUf$'TI6Q941+fY
+
+NIrEXmabeMLSdTZC&6Ae8m48krm8h(,@HFXdUSU`BRMk!q[lRHBlD3,RQ4#QENT@
+
+#"cXRI2X+4ie6jif)dMfM+mkEUadrc9%E(G5'h+TKlGFqRHHS#3He,LFDrPe`h($
+
+QCBlDa(3e*P+'jG["RP9riDM0,PI9V"`8d09SikJYP'YH1C5kHVfHlZ'SDkKIpI4
+
+i+LIkaJ28)bpbe,88e9!N694cCG6ZNqFjkMUUN!"T6DE6ZT(h&AViKGmikRVU"NX
+
+TAdR(H9q1FY4@bY@D,XL9SfF2rY6286HiPp,*+'9G,aJIFG50p#Uce14Gj3Y'd81
+
+Ek"h5cFV&)blrQ+1f8B8b8UTJU&0#eN-9cVh+8GXGe*U-j!-kU)P6p4b9*UB'dj*
+
+PCDb-E#IIrF$K4qBkCkfIRK)eFi@ZrFEXr4ae-h@$T1I(e%`C&K,!AUi3T&L#1U`
+
+I'P&bCG3h(rRp#Fje+d8&50fBrKHeFp&j@4Q5M3GV$pea1eGSfk+(0$9pa80R1GF
+
+ZCkfce*a5FDbGI1mKMRSpifUSq482fFRj!BlD6Id+#UPkaDr(MfcMU0YGVSSeRLY
+
+8Z0V[F05H43q4)19lk0aM"lL(GMKViS"LkT1'T(MH+rPeTkZ3!*U"!([&H8FjkLl
+
++0@RS306mKfX[64ZJ+`31D"5@fGUaCaUiVRd8Y@!C+5NVP42Ef6h&a0E[S,D5e*Z
+
+k$e*4k[,4R"1qUq@S0cKV-k$Hk86c@fiEqT2V*rYSlLHcfePEppip1YM9Hl2Del9
+
+2!&`"@TQ,U#F1&[Z''jdelZ4b1(ZHmdimH"0(45eR)(&!*q9f)f6q6PCX0VTUBad
+
+IAd$pf!@`[ik1Br'KUlR)+fakrN"cHF(H36)2h%jb&H(+NrX0&jMF9VMIj$*$&L)
+
+T"p)0cLf`Yq1%"AXR6JQ`Yq'FKMf0GB,GdbRXPYLiZ+lq4#IBL8k`%jeJ*cV"6R5
+
+#RHJ%1p%*GU)6l%3Rf)P1h%qc#+[@Y15RS-eL8qhT&"fJcd&k4dVkK,dC'pb'AVi
+
+MRZjKXmB'HccD3(IrcJ8G(KYmfk)&p1R"5Hkrqa'fKQc`$Bdfm0&Ek'dF5*Cm&25
+
+6E"T+qQc(16M5i"iI4FpKHCCb3p#-XSR6I3[1YF$(e@dVrAm(hAhGA,f#1a4fVQ`
+
+D)a0bM1IcX19PNiJXd-QrQrjp$rTP0Nh4$ljDEE6C0*GdfSPEQNJ$[AaI"9dkQjE
+
+)"&rjZ5PSlpQXL6c)65I42'&jkHi((6HE659pGY(F%GhJrk#CBp-AQC!!QcfG`RF
+
+BE0C'2GbTm18(Qh@4"hI+cbI"'a-fkb-2I05,Qq*VI86`ZS90Dq6"IEUNPpZrZ6d
+
+IkmP@hp@`f9$5UmK,"LjZ2dGjKIdd'pTRSrf,Re6[[[HdcbYXX0R3aK[KcVI)#mr
+
+A-dm"R8jJFcLjAc2T0r!1Xr%Ph(NRKdhm"Y1PM9qd9#9(PFc#![X)[SNKr!e@jAm
+
+!N!-0$3pYGbpRBh4PFh3Z8&"$,VN!N"!4c!#3%%+&!*!)rj!%68e38Ne33d-"!+X
+
+[PkkV-$P&!!!'-3!!'Z!!!!'T!!!&bE5F%03!N!B"fL0%$L)UANhN3L9r6IYAE+G
+
+KN!"UFiH"Gce$HU!q'61jBIV#iB$[cjhJM1X-GhH'!`%ib6Q'-Lm+c58r)bVkFF(
+
+"YqU[[irS4$#9MENFjIkKL[iaR2rVS6lQ@%G&Y2d3UK*9JDUkJ,Bce(Pf6fJm&6R
+
+b2Z8HRJiXa'A+ir""h#2TreqK*11PKX-G4'@dI[MrP@fl(cXiL9b1Haec4BbeKmP
+
+aeJj"iNA$iL1d#Y1J+HR89#QQrG%86l98l[LLFhLNlhad)NaL2JK&0pZFr-d1m4!
+
++XYS)fcSm[diTeKAC%-A8h"M6e)5Fp+AHXD3p1ZNm1FY%rabj$[`E!$0bi`E$P26
+
+rG@!p"$aQr-JXH*CjLX,-Um9UPGj1-5VH)fY@`*(4VHaDSf,&r6CPrlq&--R1K6X
+
+*#r!9a`Q#"HZ@0$hdcLR&Z$Fm-LN%a%6I)NG'j`NF&EkCY9`(CaX9iFL4(fpK!IC
+
+B8#c-*P,XP1dG-@D4KE%@0XR#9"C'PcdhhF,ZXE"3#eYVB3-&a[CDHNU"FB-@YXI
+
+#PPJD!bcX5f0T(aH0)DaV'hR-C-M0+Q[Uq``!Da0l'f3fmMSr"jhCCQZ%N3NRNdf
+
+14LJRP"rPR[a@3Sqr%8D1NjAJmk5Hp2#G-Ic6Le"1MJm)Pachb(2###I(6c*J%8k
+
+j%8k1RiHRj,J46[K*+$P11$P11"P3`JNrmS`-q)!-Z'6!D6eKj2L4C`f-F$+J`(8
+
+Q"D$m9QE4e,T1r"&qK,q%%k6J#3FQ+c!qS%%HJ+LU#N)S",rE%'S`i2Fjq"D$ha,
+
+iI4qf+2P[K53BJQi)Q['&0I#IjBQL)Y4CP"42pjcUHm,'ZSf'8'HBF--Ck@qdLS0
+
+b3K-d'HXH'L*+S#ZS9C93Dp(hThY##E32SH*'Y!@KRP2p0@MV!TJ"6QM*DZUi,'%
+
+T+JeJ!r"$PM03TD!SBLUKM%E&Qd60d0-c)3Z*mVDqK3&9&I13!!6eTfr[iUM&P'Y
+
+#%F4446G@Z(l(88YXe)LB`Z+S2TE@Pf(0!mTp(,A84Uf3!",*H&STD'4qmZcc(,@
+
+-+M3XC`4&IJbl#Phql%Z1'UCF8eL3!,#@e`G3hrdd`e(,+GHd)+EL%XlQBDHLAlh
+
+-85ZSm`B%mB'K&HG0PBjFj+L90QTjHXf`jUXI6h28L)eDPKBdpblBE[Mm*BjDaA6
+
+94Z1DiGV"R*4rj+M9$PGCAcdSS+ZfQD2@8+iCI$4qqhSpdmj4DkPIeF4)2#fiaJ2
+
+8Bbpbe(889F1L)XMT!QVVKFXFYBiUT"YMLB5UC9b&(RhKCikkRVV"`)8VDEQKZf-
+
+V4kfRA)f*V,4kp-cqUedFGB0c+Hf-8Y$eQ[B"4pe)Vc*,6IQVI%eEm0!QHSG8IIA
+
+L@5lrN!#MEUCQhhrr8(p,Ec3@kie#4,V"pIbK)a`9-T!!GBlk-`E@KJ84,f%LG'i
+
+f[T!!!'KLUKNie$XiPM(N0&lQH[KU'dGYS"j+L['X*Sp(8hPGSl0R1'UMM9U5&&e
+
+!'c8b%qDSN!"L,3rTKL6Ki3+b'A[l2CZI0G[Y06`a,LMk#PhcpFQ(1'S6pDZSCSE
+
+PC!&fUR[r&Uj3-eASS(Td!+F,U1H1r2)8jpT#83&5e5EZS1kBGej+JZb9Kc82h(-
+
+h9kKehN1+R,MPS8ZFDjZpPPPABF@aCZbG`abeRA(9j-b+KmcBG!p(lD"q"B9NGG@
+
+[CimeFp5G$PGXM+5cUec0YcMUVRN2@9(2pG$Xii2F3jhf'KR%ZMUQL6M[[CaIGcX
+
++b8Q)f,HFGj+MGP'Z-8d&S[SrA2I32!5k3L5#cQ1CV4NkAXjer4pehS"JT*BMJmh
+
+eq+jHMVUAFXdD@Pa-LB8NHQRI3K)PI3p-0D6jHqhb!-,0lkJIrAq#kpTYIkZh1S$
+
+iJj!!%H0,"hSUqR8TjiTU6d$LH!3qd"l'QVp5(*Z0MQj%N5IR8$IK#2YVk#b4%AU
+
+KAhRjVG*[D*cA0T*HB1mJp`hf9R+*B@mR9a,f0R*MBGp1mJVX655"`0j)XK,X1mL
+
+pKlf"*+irG2*l,$B1E[#"6T2S$,#X@[56ejba+FlV&"bJcm2dMZ6dm6Xk0U4jAES
+
+MHGhp&Sp0DH#"lZkGmrT#0Q@"!rVX)TRXhr[K0j4X`S%(2RS$[3RXDKCpj(@KE-T
+
+cqZ`NL6E3i"kI4160319LE["D@$B9G'mQ#4Ai1,Ued1qGG(GeFr6blT!!hqqbU3a
+
+-b$&jRrZ0-TY)B)&1lYedll[ACE1T#Rl`e9TlcUBkTp0ZdVF%-H4Z[lGR8a1Bi#X
+
+h0hN["GM8"KlNTJYSfQ*jrHjlI6UE66PpZQMZ#'l`[pH@XGNEQ*!!Qr-kq@mqf+`
+
+,HVK6rLX60R@""hI+c5IHHaBfk`-2I,5(G,jrpK(H5aSfpB%(pqQkANlrj[4mV#G
+
+EHm2$CN01V`9H%R"aqMR+bhpj`iDqe%&p8bAIR!qTj%[4$kpFY(MK'lcmYcPXk&Z
+
+H1lcmlTi0lIT[mPVbJIFUL!elGjRM4BM8c8"+#$@"@kr%qK5GrJGH8d5JeDSp%6Z
+
+S`aY94TZmpLQ+$H(Nh"cl%r`RK-KrL#Vr!3#3!aq$!!!"!*!$!43!N!-8!*!$-Tr
+
+lRLe!rr#`!,K[$#eZd!6rm2rdd"lm`FAKdkSV8FY+$deKBe"bEfTPBh4c,R0TG!)
+
+!N!06594%8dP8)3#3"P0*9%46593K!*!BUc!jI3!!8M8!!!&'"1"2l'mDG@6JrHc
+
+K@5U#NI*HN@GK!Z"2kQ`FG&2UN!"S!!,L@5[48(adA`CdC!EJ6qj[8hJS!!EJEHl
+
+LEe5!)D$!FJC1ANl!*IrX51FI-#D`jL63G!*&0K!+1Li!&Ri!)VX-S"lbUKQJ(Z`
+
+3!+SDI!$!#3ZT8,aIE!!!Q$!'8!6"aG!!N!-3!#X!"3%B!J#3"`-!N!-"!*!$!43
+
+!N!-8!*!$-J$j(l!@#J#3!a`!-J!!8f9dC`#3!`S!!2rr!*!&q@G%'@B:
+
--- /dev/null
+/*
+ MacOS_Test_config.h
+
+ Configuration flags for Macintosh development systems.
+
+ Test version.
+
+ by Patrick C. Beard.
+ */
+
+#ifdef __MWERKS__
+#if defined(__powerc)
+#include <MacHeadersPPC>
+#else
+#include <MacHeaders68K>
+#endif
+#endif
+
+// these are defined again in gc_priv.h.
+#undef TRUE
+#undef FALSE
+
+#define ALL_INTERIOR_POINTERS // follows interior pointers.
+//#define SILENT // no collection messages.
+//#define DONT_ADD_BYTE_AT_END // no padding.
+//#define SMALL_CONFIG // use a smaller heap.
+#define USE_TEMPORARY_MEMORY // use Macintosh temporary memory.
+
+// CFLAGS= -O -DALL_INTERIOR_POINTERS -DSILENT
+// Setjmp_test may yield overly optimistic results when compiled
+// without optimization.
+// -DSILENT disables statistics printing, and improves performance.
+// -DCHECKSUMS reports on erroneously clear dirty bits, and unexpectedly
+// altered stubborn objects, at substantial performance cost.
+// -DFIND_LEAK causes the collector to assume that all inaccessible
+// objects should have been explicitly deallocated, and reports exceptions
+// -DSOLARIS_THREADS enables support for Solaris (thr_) threads.
+// (Clients should also define SOLARIS_THREADS and then include
+// gc.h before performing thr_ or GC_ operations.)
+// -DALL_INTERIOR_POINTERS allows all pointers to the interior
+// of objects to be recognized. (See gc_private.h for consequences.)
+// -DSMALL_CONFIG tries to tune the collector for small heap sizes,
+// usually causing it to use less space in such situations.
+// Incremental collection no longer works in this case.
+// -DDONT_ADD_BYTE_AT_END is meaningful only with
+// -DALL_INTERIOR_POINTERS. Normally -DALL_INTERIOR_POINTERS
+// causes all objects to be padded so that pointers just past the end of
+// an object can be recognized. This can be expensive. (The padding
+// is normally more than one byte due to alignment constraints.)
+// -DDONT_ADD_BYTE_AT_END disables the padding.
--- /dev/null
+/*
+ MacOS_config.h
+
+ Configuration flags for Macintosh development systems.
+
+ by Patrick C. Beard.
+ */
+
+#ifdef __MWERKS__
+#if defined(__powerc)
+#include <MacHeadersPPC>
+#else
+#include <MacHeaders68K>
+#endif
+#endif
+
+// these are defined again in gc_priv.h.
+#undef TRUE
+#undef FALSE
+
+#define ALL_INTERIOR_POINTERS // follows interior pointers.
+#define SILENT // no collection messages.
+//#define DONT_ADD_BYTE_AT_END // no padding.
+//#define SMALL_CONFIG // use a smaller heap.
+#define USE_TEMPORARY_MEMORY // use Macintosh temporary memory.
+
+// CFLAGS= -O -DALL_INTERIOR_POINTERS -DSILENT
+// Setjmp_test may yield overly optimistic results when compiled
+// without optimization.
+// -DSILENT disables statistics printing, and improves performance.
+// -DCHECKSUMS reports on erroneously clear dirty bits, and unexpectedly
+// altered stubborn objects, at substantial performance cost.
+// -DFIND_LEAK causes the collector to assume that all inaccessible
+// objects should have been explicitly deallocated, and reports exceptions
+// -DSOLARIS_THREADS enables support for Solaris (thr_) threads.
+// (Clients should also define SOLARIS_THREADS and then include
+// gc.h before performing thr_ or GC_ operations.)
+// -DALL_INTERIOR_POINTERS allows all pointers to the interior
+// of objects to be recognized. (See gc_private.h for consequences.)
+// -DSMALL_CONFIG tries to tune the collector for small heap sizes,
+// usually causing it to use less space in such situations.
+// Incremental collection no longer works in this case.
+// -DDONT_ADD_BYTE_AT_END is meaningful only with
+// -DALL_INTERIOR_POINTERS. Normally -DALL_INTERIOR_POINTERS
+// causes all objects to be padded so that pointers just past the end of
+// an object can be recognized. This can be expensive. (The padding
+// is normally more than one byte due to alignment constraints.)
+// -DDONT_ADD_BYTE_AT_END disables the padding.
--- /dev/null
+/*
+ dataend.c
+
+ A hack to get the extent of global data for the Macintosh.
+
+ by Patrick C. Beard.
+ */
+
+long __dataend;
--- /dev/null
+/*
+ datastart.c
+
+ A hack to get the extent of global data for the Macintosh.
+
+ by Patrick C. Beard.
+ */
+
+long __datastart;
# Primary targets:
# gc.a - builds basic library
-# c++ - adds C++ interface to library and include directory
-# cords - adds cords (heavyweight strings) to library and include directory
-# test - prints porting information, then builds basic version of gc.a, and runs
-# some tests of collector and cords. Does not add cords or c++ interface to gc.a
+# c++ - adds C++ interface to library
+# cords - adds cords (heavyweight strings) to library
+# test - prints porting information, then builds basic version of gc.a,
+# and runs some tests of collector and cords. Does not add cords or
+# c++ interface to gc.a
# cord/de - builds dumb editor based on cords.
-CC= cc
+CC= gcc
CXX=g++ -ansi
# Needed only for "make c++", which adds the c++ interface
AS=as
-CFLAGS= -O -DSILENT -DALL_INTERIOR_POINTERS -DNO_SIGNALS
+CFLAGS= -O -DALL_INTERIOR_POINTERS -DNO_SIGNALS -DSILENT
# Setjmp_test may yield overly optimistic results when compiled
# without optimization.
# -DSILENT disables statistics printing, and improves performance.
# -DCHECKSUMS reports on erroneously clear dirty bits, and unexpectedly
# altered stubborn objects, at substantial performance cost.
+# Use only for incremental collector debugging.
# -DFIND_LEAK causes the collector to assume that all inaccessible
-# objects should have been explicitly deallocated, and reports exceptions
+# objects should have been explicitly deallocated, and reports exceptions.
+# Finalization and the test program are not usable in this mode.
# -DSOLARIS_THREADS enables support for Solaris (thr_) threads.
# (Clients should also define SOLARIS_THREADS and then include
# gc.h before performing thr_ or dl* or GC_ operations.)
# -DOPERATOR_NEW_ARRAY declares that the C++ compiler supports the
# new syntax "operator new[]" for allocating and deleting arrays.
# See gc_cpp.h for details. No effect on the C part of the collector.
-
+# This is defined implicitly in a few environments.
+# -DREDIRECT_MALLOC=X causes malloc, realloc, and free to be defined
+# as aliases for X, GC_realloc, and GC_free, respectively.
+# Calloc is redefined in terms of the new malloc. X should
+# be either GC_malloc or GC_malloc_uncollectable.
+# The former is occasionally useful for working around leaks in code
+# you don't want to (or can't) look at. It may not work for
+# existing code, but it often does. Neither works on all platforms,
+# since some ports use malloc or calloc to obtain system memory.
+# (Probably works for UNIX, and win32.)
+
+CXXFLAGS= $(CFLAGS)
AR= ar
RANLIB= ranlib
SRCS= $(CSRCS) mips_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s sparc_mach_dep.s gc.h gc_typed.h gc_hdrs.h gc_priv.h gc_private.h config.h gc_mark.h include/gc_inl.h include/gc_inline.h gc.man if_mach.c if_not_there.c gc_cpp.cc gc_cpp.h $(CORD_SRCS)
-OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE \
+OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \
README test.c test_cpp.cc setjmp_t.c SMakefile.amiga \
SCoptions.amiga README.amiga README.win32 cord/README \
cord/gc.h include/gc.h include/gc_typed.h include/cord.h \
README.QUICK callprocs pc_excludes barrett_diagram \
README.OS2 README.Mac MacProjects.sit.hqx MacOS.c \
EMX_MAKEFILE makefile.depend README.debugging \
- include/gc_cpp.h
+ include/gc_cpp.h Mac_files/datastart.c Mac_files/dataend.c \
+ Mac_files/MacOS_config.h Mac_files/MacOS_Test_config.h
CORD_INCLUDE_FILES= $(srcdir)/gc.h $(srcdir)/cord/cord.h $(srcdir)/cord/ec.h \
$(srcdir)/cord/cord_pos.h
./if_not_there on_sparc_sunos5 $(RANLIB) gc.a || cat /dev/null
gc_cpp.o: $(srcdir)/gc_cpp.cc $(srcdir)/gc_cpp.h $(srcdir)/gc.h Makefile
- $(CXX) -c -O $(srcdir)/gc_cpp.cc
+ $(CXX) -c $(CXXFLAGS) $(srcdir)/gc_cpp.cc
-test_gc_c++: $(srcdir)/test_cpp.cc $(srcdir)/gc_cpp.h gc_cpp.o $(srcdir)/gc.h gc.a
- $(CXX) -O -o test_gc_c++ $(srcdir)/test_cpp.cc gc_cpp.o gc.a
+test_cpp: $(srcdir)/test_cpp.cc $(srcdir)/gc_cpp.h gc_cpp.o $(srcdir)/gc.h gc.a
+ $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/test_cpp.cc gc_cpp.o gc.a
-c++: gc_cpp.o $(srcdir)/gc_cpp.h test_gc_c++
+c++: gc_cpp.o $(srcdir)/gc_cpp.h test_cpp
rm -f on_sparc_sunos5
./if_mach SPARC SUNOS5 touch on_sparc_sunos5
./if_mach SPARC SUNOS5 $(AR) rus gc.a gc_cpp.o
./if_not_there on_sparc_sunos5 $(AR) ru gc.a gc_cpp.o
./if_not_there on_sparc_sunos5 $(RANLIB) gc.a || cat /dev/null
- ./test_gc_c++ 1
+ ./test_cpp 1
dyn_load_sunos53.o: dyn_load.c
$(CC) $(CFLAGS) -DSUNOS53_SHARED_LIB -c dyn_load.c -o $@
$(CC) $(CFLAGS) -o if_not_there $(srcdir)/if_not_there.c
clean:
- rm -f gc.a test.o gctest $(OBJS) dyn_load.o dyn_load_sunos53.o \
- gctest_dyn_link \
+ rm -f gc.a *.o gctest gctest_dyn_link test_cpp \
setjmp_test mon.out gmon.out a.out core if_not_there if_mach \
$(CORD_OBJS) cord/cordtest cord/de
-rm -f *~
./if_mach ALPHA "" $(CC) $(CFLAGS) -o setjmp_test $(ALPHACFLAGS) $(srcdir)/setjmp_t.c
./if_not_there setjmp_test $(CC) $(CFLAGS) -o setjmp_test $(srcdir)/setjmp_t.c
-test: setjmp_test gctest
+test: KandRtest cord/cordtest
+ cord/cordtest
+
+# Those tests that work even with a K&R C compiler:
+KandRtest: setjmp_test gctest
./setjmp_test
./gctest
- make cord/cordtest
- cord/cordtest
gc.tar: $(SRCS) $(OTHER_FILES)
tar cvf gc.tar $(SRCS) $(OTHER_FILES)
all: gctest.exe cord\de.exe test_cpp.exe
.c.obj:
- $(cc) $(cdebug) $(cflags) $(cvars) -DSMALL_CONFIG -DSILENT -DALL_INTERIOR_POINTERS $*.c /Fo$*.obj
+ $(cc) $(cdebug) $(cflags) $(cvars) -DSMALL_CONFIG -DSILENT -DALL_INTERIOR_POINTERS -D__STDC__ $*.c /Fo$*.obj
.cpp.obj:
$(cc) $(cdebug) $(cflags) $(cvars) -DSMALL_CONFIG -DSILENT -DALL_INTERIOR_POINTERS $*.CPP /Fo$*.obj
# Adding thread support may be nontrivial, since we haven't yet figured out how to
# look at another thread's registers.
-# We also haven't figured out how to do partial links or build static libraries. Hence a
-# client currently needs to link against all of the following:
+# Significantly revised for GC version 4.4 by Mark Boulter (Jan 1994).
OBJS= alloc.obj reclaim.obj allchblk.obj misc.obj mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj obj_map.obj blacklst.obj finalize.obj new_hblk.obj dbg_mlc.obj malloc.obj stubborn.obj typd_mlc.obj ptr_chck.obj
$(OBJS) test.obj: gc_priv.h gc_hdrs.h gc.h
+## ERASE THE LIB FIRST - if it is already there then this command will fail
+## (make sure its there or erase will fail!)
+gc.lib: $(OBJS)
+ echo . > gc.lib
+ erase gc.lib
+ LIB gc.lib $(OBJS), gc.lst
+
mach_dep.obj: mach_dep.c
- $(CC) $(CFLAGS) /C mach_dep.c
+ $(CC) $(CFLAGS) /C mach_dep.c
-gctest.exe: test.obj $(OBJS)
- $(CC) $(CFLAGS) /B"/STACK:524288" /Fegctest test.obj $(OBJS)
+gctest.exe: test.obj gc.lib
+ $(CC) $(CFLAGS) /B"/STACK:524288" /Fegctest test.obj gc.lib
cord\cordbscs.obj: cord\cordbscs.c cord\cord.h cord\cord_pos.h
- $(CC) $(CFLAGS) /C /Focord\cordbscs cord\cordbscs.c
+ $(CC) $(CFLAGS) /C /Focord\cordbscs cord\cordbscs.c
cord\cordxtra.obj: cord\cordxtra.c cord\cord.h cord\cord_pos.h cord\ec.h
- $(CC) $(CFLAGS) /C /Focord\cordxtra cord\cordxtra.c
+ $(CC) $(CFLAGS) /C /Focord\cordxtra cord\cordxtra.c
cord\cordprnt.obj: cord\cordprnt.c cord\cord.h cord\cord_pos.h cord\ec.h
- $(CC) $(CFLAGS) /C /Focord\cordprnt cord\cordprnt.c
+ $(CC) $(CFLAGS) /C /Focord\cordprnt cord\cordprnt.c
-cord\cordtest.exe: cord\cordtest.c cord\cord.h cord\cord_pos.h cord\ec.h $(CORDOBJS)
- $(CC) $(CFLAGS) /B"/STACK:65536" /Fecord\cordtest cord\cordtest.c $(OBJS) $(CORDOBJS)
\ No newline at end of file
+cord\cordtest.exe: cord\cordtest.c cord\cord.h cord\cord_pos.h cord\ec.h $(CORDOBJS) gc.lib
+ $(CC) $(CFLAGS) /B"/STACK:65536" /Fecord\cordtest cord\cordtest.c gc.lib $(CORDOBJS)
\ No newline at end of file
Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
-Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
+Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved.
THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
provided the above notices are retained, and a notice that the code was
modified is included with the above copyright notice.
-This is version 4.3 of a conservative garbage collector for C and C++.
+This is version 4.4 of a conservative garbage collector for C and C++.
HISTORY -
The most important routine here is one to mark from registers.
The distributed file includes a generic hack (based on setjmp) that
happens to work on many machines, and may work on yours. Try
- compiling and running setjmp_test.c to see whether it has a chance of
+ compiling and running setjmp_t.c to see whether it has a chance of
working. (This is not correct C, so don't blame your compiler if it
doesn't work. Based on limited experience, register window machines
are likely to cause trouble. If your version of setjmp claims that
all accessible variables, including registers, have the value they
had at the time of the longjmp, it also will not work. Vanilla 4.2 BSD
- makes such a claim. SunOS does not.)
+ on Vaxen makes such a claim. SunOS does not.)
If your compiler does not allow in-line assembly code, or if you prefer
not to use such a facility, mach_dep.c may be replaced by a .s file
(as we did for the MIPS machine and the PC/RT).
be desirable to set GC_stacktop to a good approximation of the stack base.
(This enhances code portability on HP PA machines, since there is no
good way for the collector to compute this value.) Client code may include
-"gc.h", which defines all of the following, plus a few others.
+"gc.h", which defines all of the following, plus many others.
1) GC_malloc(nbytes)
- allocate an object of size nbytes. Unlike malloc, the object is
if a garbage collection failed to GC_reclaim enough memory. Explicit
calls to GC_expand_hp may prevent unnecessarily frequent collections at
program startup.)
-
-6) GC_clear_roots()
- - Reset the collectors idea of where static variables containing pointers
- may be located to the empty set of locations. No statically allocated
- variables will be traced from after this call, unless there are
- intervening GC_add_roots calls. The collector will still trace from
- registers and the program stack.
-
-7) GC_add_roots(low_address, high_address_plus_1)
- - Add [low_address, high_address) as an area that may contain root pointers
- and should be traced by the collector. The static data and bss segments
- are considered by default, and should not be added unless GC_clear_roots
- has been called. The number of root areas is currently limited to 50.
- This is intended as a way to register data areas for dynamic libraries,
- or to replace the entire data ans bss segments by smaller areas that are
- known to contain all the roots.
+
+6) GC_malloc_ignore_off_page(bytes)
+ - identical to GC_malloc, but the client promises to keep a pointer to
+ the somewhere within the first 256 bytes of the object while it is
+ live. (This pointer should nortmally be declared volatile to prevent
+ interference from compiler optimizations.) This is the recommended
+ way to allocate anything that is likely to be larger than 100Kbytes
+ or so. (GC_malloc may result in failure to reclaim such objects.)
+
+7) GC_set_warn_proc(proc)
+ - Can be used to redirect warnings from the collector. Such warnings
+ should be rare, and should not be ignored during code development.
8) GC_enable_incremental()
- Enables generational and incremental collection. Useful for large
The Ellis-Hull C++ interface to the collector is included in
the collector distribution. If you intend to use this, type
"make c++" after the initial build of the collector is complete.
-See gc_c++.h for the difinition of the interface. This interface
+See gc_cpp.h for the difinition of the interface. This interface
tries to approximate the Ellis-Detlefs C++ garbage collection
proposal without compiler changes.
3. If your compiler supports an overloaded new[] operator,
then gc_c++.cc and gc_c++.h should be suitably modified.
+4. Many current C++ compilers have deficiencies that
+break some of the functionality. See the comments in gc_cpp.h
+for suggested workarounds.
USE AS LEAK DETECTOR:
The collector may be used to track down leaks in C programs that are
intended to run with malloc/free (e.g. code with extreme real-time or
-portability constraints). To do so define FIND_LEAK somewhere in
-gc_priv.h. This will cause the collector to invoke the report_leak
+portability constraints). To do so define FIND_LEAK in Makefile
+This will cause the collector to invoke the report_leak
routine defined near the top of reclaim.c whenever an inaccessible
object is found that has not been explicitly freed.
Productive use of this facility normally involves redefining report_leak
Note that the debugging facilities described in the next section can
sometimes be slightly LESS effective in leak finding mode, since in
leak finding mode, GC_debug_free actually results in reuse of the object.
-(Otherwise the object is simply marked invalid.)
+(Otherwise the object is simply marked invalid.) Also note that the test
+program is not designed to run meaningfully in FIND_LEAK mode.
+Use "make gc.a" to build the collector.
DEBUGGING FACILITIES:
file system. (Charles Fiterman's suggestion.)
- Changed Windoes NT Makefile to include C++ support in
gc.lib. Added C++ test as Makefile target.
-
\ No newline at end of file
+
+Since version 4.3:
+ - ASM_CLEAR_CODE was erroneously defined for HP
+ PA machines, resulting in a compile error.
+ - Fixed OS/2 Makefile to create a library. (Thanks to
+ Mark Boulter (mboulter@vnet.ibm.com)).
+ - Gc_cleanup objects didn't work if they were created on
+ the stack. Fixed.
+ - One copy of Gc_cpp.h in the distribution was out of
+ synch, and failed to document some known compiler
+ problems with explicit destructor invocation. Partially
+ fixed. There are probably other compilers on which
+ gc_cleanup is miscompiled.
+ - Fixed Makefile to pass C compiler flags to C++ compiler.
+ - Added Mac fixes.
+ - Fixed os_dep.c to work around what appears to be
+ a new and different VirtualQuery bug under newer
+ versions of win32S.
+ - GC_non_gc_bytes was not correctly maintained by
+ GC_free. Fixed. Thanks to James Clark (jjc@jclark.com).
+ - Added GC_set_max_heap_size.
+ - Changed allocation code to ignore blacklisting if it is preventing
+ use of a very large block of memory. This has the advantage
+ that naive code allocating very large objects is much more
+ likely to work. The downside is you might no
+ longer find out that such code should really use
+ GC_malloc_ignore_off_page.
+ - Changed GC_printf under win32 to close and reopen the file
+ between calls. FAT file systems otherwise make the log file
+ useless for debugging.
+ - Added GC_try_to_collect and GC_get_bytes_since_gc. These
+ allow starting an abortable collection during idle times.
+ This facility does not require special OS support. (Thanks to
+ Michael Spertus of Geodesic Systems for suggesting this. It was
+ actually an easy addition. Kumar Srikantan previously added a similar
+ facility to a now ancient version of the collector. At the time
+ this was much harder, and the result was less convincing.)
+ - Added some support for the Borland development environment. (Thanks
+ to John Ellis and Michael Spertus.)
+ - Removed a misfeature from checksums.c that caused unexpected
+ heap growth. (Thanks to Scott Schwartz.)
+ - Changed finalize.c to call WARN if it encounters a finalization cycle.
+ WARN is defined in gc_priv.h to write a message, usually to stdout.
+ In many environments, this may be inappropriate.
+ - Renamed NO_PARAMS in gc.h to GC_NO_PARAMS, thus adhering to my own
+ naming convention.
+ - Added GC_set_warn_proc to intercept warnings.
+ - Fixed Amiga port. (Thanks to Michel Schinz (schinz@alphanet.ch).)
+ - Fixed a bug in mark.c that could result in an access to unmapped
+ memory from GC_mark_from_mark_stack on machines with unaligned
+ pointers.
+ - Fixed a win32 specific performance bug that could result in scanning of
+ objects allocated with the system malloc.
+ - Added REDIRECT_MALLOC.
README.Mac
----------
-This is a preliminary version of my port of the collector to the Macintosh.
-It passes all tests in the file test.c, but there might be more bugs lurking.
-
-Mac Specific Files
-------------------
-
-Since I built the collector under Symantec C++ 7, and it doesn't use Makefile's
-in the standard sense, I'm including the file mac_proj.sit.hqx, which contains
-a binhexed (similar to uuencoding) copy of the compressed project files you'll
-need to build this on the Macintosh. This contains projects for building
-the test program, gctest.pi, a project containing just the library sources,
-gc.lib.pi, for testing the cord library, cord.pi, and finally a hacked up
-version of the cord text editor, de, that runs under the console emulation
-library, ANSI++, under Symantec. It has a pretty weak emulation of curses
-and only really works if you hack console.c a little bit in ANSI++. However
-it works well enough to page through a file and move around editing, etc.
-
-Changes
+v4.3 of the collector now runs under Symantec C++/THINK C v7.0.4, and
+Metrowerks C/C++ v4.5 both 68K and PowerPC. Project files are provided
+to build and test the collector under both development systems.
+
+Configuration
+-------------
+
+To configure the collector, under both development systems, a prefix file
+is used to set preprocessor directives. This file is called "MacOS_config.h".
+Also to test the collector, "MacOS_Test_config.h" is provided.
+
+Testing
-------
-The biggest changes made to the source was providing a target for MACINTOSH.
-Some care had to be taken to fit it in with the rest of the #ifdefs, as usual.
-The most most major change was converting the GC_arrays structure from static
-data to dynamically allocated, because no file can contain more than 32k of
-global data under Symantec C/C++. However; on the non-Macintosh platforms
-I still leave it as global data, I just take a pointer to it rather than
-dynamically allocating it.
+To test the collector (always a good idea), build one of the gctest projects,
+gctest.¹ (Symantec C++/THINK C), mw/gctest.68K.¹, or mw/gctest.PPC.¹. The
+test will ask you how many times to run; 1 should be sufficient.
+
+Building
+--------
+
+For your convenience project files for the major Macintosh development
+systems are provided.
-One thing this affects is that it is really a good idea to call GC_init
-before using the collector. I don't trust the collector to be able to
-do this automatically with these new changes.
+For Symantec C++/THINK C, you must build the two projects gclib-1.¹ and
+gclib-2.¹. It has to be split up because the collector has more than 32k
+of static data and no library can have more than this in the Symantec
+environment. (Future versions will probably fix this.)
-Also, since GC_arrays is no longer at a constant location, the static
-initialization of the array GC_obj_kinds won't work. So, I added a new
-function to mark.c, called C_init_mark() which does the rest of the
-initializations of GC_obj_kinds.
+For Metrowerks C/C++ 4.5 you build gc.68K.¹/gc.PPC.¹ and the result will
+be a library called gc.68K.lib/gc.PPC.lib.
-Happy garbage collecting!
+Using
+-----
-Patrick Beard, June 6, 1994.
+Under Symantec C++/THINK C, you can just add the gclib-1.¹ and gclib-2.¹
+projects to your own project. Under Metrowerks, you add gc.68K.lib or
+gc.PPC.lib and two additional files. You add the files called datastart.c
+and dataend.c to your project, bracketing all files that use the collector.
+See mw/gctest.¹ for an example.
-I undid some of Patrick's changes, to keep things as consistent as
-possible across platforms. GC_arrays is statically allocated. A few
-of its former components are now dynamically allocated separately.
-It should not be necessary to call GC_init explicitly.
+Include the projects/libraries you built above into your own project,
+#include "gc.h", and call GC_malloc. You don't have to call GC_free.
-I replaced the macro MACINTOSH with MACOS, both for consistency with
-other platforms, and to better distinguish it from AUX (which is
-admittedly less interesting, but was already supported).
-Hans-J. Boehm, June 9, 1994
+Patrick C. Beard
+January 4, 1995
-[Note: The original Amiga port was made by Jesper Peterson. I (Michel
-Schinz) modified it slightly to reflect the changes made in the new
-official distribution, and to take advantage of the new SAS/C 6.x
-features. I also created a makefile to compile the "cord" package (see
-the cord subdirectory).
+===========================================================================
+ Michel Schinz's notes
+===========================================================================
+WHO DID WHAT
+
+The original Amiga port was made by Jesper Peterson. I (Michel Schinz)
+modified it slightly to reflect the changes made in the new official
+distributions, and to take advantage of the new SAS/C 6.x features. I also
+created a makefile to compile the "cord" package (see the cord
+subdirectory).
+
+TECHNICAL NOTES
+
+In addition to Jesper's notes, I have the following to say:
+
+- Starting with version 4.3, gctest checks to see if the code segment is
+ added to the root set or not, and complains if it is. Previous versions
+ of this Amiga port added the code segment to the root set, so I tried to
+ fix that. The only problem is that, as far as I know, it is impossible to
+ know which segments are code segments and which are data segments (there
+ are indeed solutions to this problem, like scanning the program on disk
+ or patch the LoadSeg functions, but they are rather complicated). The
+ solution I have chosen (see os_dep.c) is to test whether the program
+ counter is in the segment we are about to add to the root set, and if it
+ is, to skip the segment. The problems are that this solution is rather
+ awkward and that it works only for one code segment. This means that if
+ your program has more than one code segment, all of them but one will be
+ added to the root set. This isn't a big problem in fact, since the
+ collector will continue to work correctly, but it may be slower.
+
+ Anyway, the code which decides whether to skip a segment or not can be
+ removed simply by not defining AMIGA_SKIP_SEG. But notice that if you do
+ so, gctest will complain (it will say that "GC_is_visible produced wrong
+ failure indication"). However, it may be useful if you happen to have
+ pointers stored in a code segment (you really shouldn't).
+
+ If anyone has a good solution to the problem of finding, when a program
+ is loaded in memory, whether a segment is a code or a data segment,
+ please let me know.
+
+PROBLEMS
If you have any problem with this version, please contact me at
schinz@alphanet.ch (but do *not* send long files, since we pay for
every mail!).
-Following is Jesper's original README.amiga. Please read it
-carefully.]
-
+===========================================================================
+ Jesper Peterson's notes
+===========================================================================
ADDITIONAL NOTES FOR AMIGA PORT
NT threads.)
The collector has only been compiled under Windows NT, with the
-original Microsoft SDK and Visual C++ 2.0.
+original Microsoft SDK, with Visual C++ 2.0, and with Borland 4.5.
It runs under both win32s and win32, but with different semantics.
Under win32, all writable pages outside of the heaps and stack are
scanned for roots. Thus the collector sees pointers in DLL data
segments. Under win32s, only the main data segment is scanned.
+(The main data segment should always be scanned. Under some
+versions of win32s, other regions may also be scanned.)
Thus all accessible objects should be excessible from local variables
or variables in the main data segment. Alternatively, other data
segments (e.g. in DLLs) may be registered with the collector by
(There are two reasons for this. We didn't want to see many 16:16
pointers. And the VirtualQuery call has different semantics under
-the two systems.)
+the two systems, and under different versions of win32s.)
The collector test program "gctest" is linked as a GUI application,
but does not open any windows. Its output appears in the file
This may be suboptimal for some tastes and/or sets of default
window colors.)
+For Microsoft development tools, rename NT_MAKEFILE as
+MAKEFILE. For Borland tools, use BCC_MAKEFILE. Note that
+Borland's compiler defaults to 1 byte alignment in structures (-a1),
+whereas Visual C++ appears to default to 8 byte alignment (/Zp8).
+The garbage collector in its default configuration EXPECTS AT
+LEAST 4 BYTE ALIGNMENT. Thus the BORLAND DEFAULT MUST
+BE OVERRIDDEN. (In my opinion, it should usually be anyway.
+I expect that -a1 introduces major performance penalties on a
+486 or Pentium.) Note that this changes structure layouts. (As a last
+resort, config.h can be changed to allow 1 byte alignment. But
+this has significant negative performance implications.)
+
CPU=68030
NOSTACKCHECK
-ERRORREXX
OPTIMIZE
VERBOSE
MAPHUNK
NOICONS
OPTIMIZERTIME
DEFINE SILENT
+DEFINE AMIGA_SKIP_SEG
+IGNORE=85
+IGNORE=154
IGNORE=161
IGNORE=100
+OPTIMIZERCOMPLEXITY=4
+OPTIMIZERDEPTH=3
-OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o real_malloc.o dyn_load.o dbg_mlc.o malloc.o stubborn.o checksums.o typd_mlc.o
+OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o real_malloc.o dyn_load.o dbg_mlc.o malloc.o stubborn.o checksums.o typd_mlc.o ptr_chck.o
INC= gc_private.h gc_hdrs.h gc.h config.h
checksums.o : checksums.c $(INC)
typd_mlc.o: typd_mlc.c $(INC)
mach_dep.o : mach_dep.c $(INC)
+ptr_chck.o: ptr_chck.c $(INC)
test.o : test.c $(INC)
gc.lib: $(OBJS)
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, May 19, 1994 1:55 pm PDT */
+/* Boehm, January 31, 1995 3:01 pm PST */
#define DEBUG
#undef DEBUG
GC_allochblk(sz, kind, flags)
word sz;
int kind;
-unsigned char flags;
+unsigned char flags; /* IGNORE_OFF_PAGE or 0 */
{
register struct hblk *thishbp;
register hdr * thishdr; /* Header corr. to thishbp */
(kind != PTRFREE || size_needed > MAX_BLACK_LIST_ALLOC)) {
struct hblk * lasthbp = hbp;
ptr_t search_end = (ptr_t)hbp + size_avail - size_needed;
+ word orig_avail = size_avail;
signed_word eff_size_needed = ((flags & IGNORE_OFF_PAGE)?
HBLKSIZE
: size_needed);
}
size_avail -= (ptr_t)lasthbp - (ptr_t)hbp;
thishbp = lasthbp;
- if (size_avail >= size_needed && thishbp != hbp
- && GC_install_header(thishbp)) {
+ if (size_avail >= size_needed) {
+ if (thishbp != hbp && GC_install_header(thishbp)) {
/* Split the block at thishbp */
thishdr = HDR(thishbp);
/* GC_invalidate_map not needed, since we will */
phdr = hhdr;
hbp = thishbp;
hhdr = thishdr;
+ }
+ } else if (size_needed > BL_LIMIT
+ && orig_avail - size_needed > BL_LIMIT) {
+ /* Punt, since anything else risks unreasonable heap growth. */
+ WARN("Need to allocated blacklisted block at %ld\n", (word)hbp);
+ thishbp = hbp;
+ size_avail = orig_avail;
} else if (size_avail == 0
&& size_needed == HBLKSIZE
&& prevhbp != 0) {
* modified is included with the above copyright notice.
*
*/
-/* Boehm, November 21, 1994 4:35 pm PST */
+/* Boehm, February 10, 1995 1:18 pm PST */
# include "gc_priv.h"
char * GC_copyright[] =
{"Copyright 1988,1989 Hans-J. Boehm and Alan J. Demers",
-"Copyright (c) 1991-1993 by Xerox Corporation. All rights reserved.",
+"Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved.",
"THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY",
" EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK."};
word GC_free_space_divisor = 4;
+int GC_never_stop_func(NO_PARAMS) { return(0); }
+
+CLOCK_TYPE GC_start_time;
+
+int GC_timeout_stop_func(NO_PARAMS)
+{
+ CLOCK_TYPE current_time;
+ static unsigned count = 0;
+ unsigned long time_diff;
+
+ if ((count++ & 3) != 0) return(0);
+ GET_TIME(current_time);
+ time_diff = MS_TIME_DIFF(current_time,GC_start_time);
+ if (time_diff >= TIME_LIMIT) {
+# ifdef PRINTSTATS
+ GC_printf0("Abandoning stopped marking after ");
+ GC_printf1("%lu msecs\n", (unsigned long)time_diff);
+# endif
+ return(1);
+ }
+ return(0);
+}
+
/* Return the minimum number of words that must be allocated between */
/* collections to amortize the collection cost. */
static word min_words_allocd()
/* We try to mark with the world stopped. */
/* If we run out of time, this turns into */
/* incremental marking. */
- if (GC_stopped_mark(FALSE)) {
+ GET_TIME(GC_start_time);
+ if (GC_stopped_mark(GC_timeout_stop_func)) {
# ifdef SAVE_CALL_CHAIN
GC_save_callers(GC_last_stack);
# endif
}
}
+
/*
* Stop the world garbage collection. Assumes lock held, signals disabled.
+ * If stop_func is not GC_never_stop_func, then abort if stop_func returns TRUE.
*/
-void GC_gcollect_inner()
+bool GC_try_to_collect_inner(stop_func)
+GC_stop_func stop_func;
{
# ifdef PRINTSTATS
GC_printf2(
(long)WORDS_TO_BYTES(GC_words_allocd));
# endif
GC_promote_black_lists();
- /* GC_reclaim_or_delete_all(); -- not needed: no intervening allocation */
+ /* Make sure all blocks have been reclaimed, so sweep routines */
+ /* don't see cleared mark bits. */
+ /* If we're guaranteed to finish, then this is unnecessary. */
+ if (stop_func != GC_never_stop_func && !GC_reclaim_all(stop_func)) {
+ /* Aborted. So far everything is still consistent. */
+ return(FALSE);
+ }
+ GC_invalidate_mark_state(); /* Flush mark stack. */
GC_clear_marks();
# ifdef SAVE_CALL_CHAIN
GC_save_callers(GC_last_stack);
# endif
- (void) GC_stopped_mark(TRUE);
+ if (!GC_stopped_mark(stop_func)) {
+ /* We're partially done and have no way to complete or use */
+ /* current work. Reestablish invariants as cheaply as */
+ /* possible. */
+ GC_invalidate_mark_state();
+ GC_unpromote_black_lists();
+ if (GC_incremental) {
+ /* Unlikely. But just invalidating mark state could be */
+ /* expensive. */
+ GC_clear_marks();
+ }
+ return(FALSE);
+ }
GC_finish_collection();
+ return(TRUE);
}
+
+
/*
* Perform n units of garbage collection work. A unit is intended to touch
* roughly a GC_RATE pages. Every once in a while, we do more than that.
# ifdef SAVE_CALL_CHAIN
GC_save_callers(GC_last_stack);
# endif
- (void) GC_stopped_mark(TRUE);
+ (void) GC_stopped_mark(GC_never_stop_func);
GC_finish_collection();
break;
}
* Otherwise we may fail and return FALSE if this takes too long.
* Increment GC_gc_no if we succeed.
*/
-bool GC_stopped_mark(final)
-bool final;
+bool GC_stopped_mark(stop_func)
+GC_stop_func stop_func;
{
- CLOCK_TYPE start_time;
- CLOCK_TYPE current_time;
- unsigned long time_diff;
register int i;
+# ifdef PRINTSTATS
+ CLOCK_TYPE start_time, current_time;
+# endif
- GET_TIME(start_time);
STOP_WORLD();
# ifdef PRINTSTATS
+ GET_TIME(start_time);
GC_printf1("--> Marking for collection %lu ",
(unsigned long) GC_gc_no + 1);
GC_printf2("after %lu allocd bytes + %lu wasted bytes\n",
GC_noop(0,0,0,0,0,0);
GC_initiate_partial();
for(i = 0;;i++) {
- if (GC_mark_some()) break;
- if (final) continue;
- if ((i & 3) == 0) {
- GET_TIME(current_time);
- time_diff = MS_TIME_DIFF(current_time,start_time);
- if (time_diff >= TIME_LIMIT) {
- START_WORLD();
+ if ((*stop_func)()) {
# ifdef PRINTSTATS
- GC_printf0("Abandoning stopped marking after ");
- GC_printf2("%lu iterations and %lu msecs\n",
- (unsigned long)i,
- (unsigned long)time_diff);
+ GC_printf0("Abandoned stopped marking after ");
+ GC_printf1("%lu iterations\n",
+ (unsigned long)i);
# endif
- GC_deficit = i; /* Give the mutator a chance. */
+ GC_deficit = i; /* Give the mutator a chance. */
+ START_WORLD();
return(FALSE);
- }
}
+ if (GC_mark_some()) break;
}
GC_gc_no++;
}
/* Externally callable routine to invoke full, stop-world collection */
-void GC_gcollect(NO_PARAMS)
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_try_to_collect(GC_stop_func stop_func)
+# else
+ int GC_try_to_collect(stop_func)
+ GC_stop_func stop_func;
+# endif
{
+ int result;
DCL_LOCK_STATE;
GC_invoke_finalizers();
if (!GC_is_initialized) GC_init_inner();
/* Minimize junk left in my registers */
GC_noop(0,0,0,0,0,0);
- GC_gcollect_inner();
+ result = (int)GC_try_to_collect_inner(stop_func);
UNLOCK();
ENABLE_SIGNALS();
- GC_invoke_finalizers();
+ if(result) GC_invoke_finalizers();
+ return(result);
+}
+
+void GC_gcollect(NO_PARAMS)
+{
+ (void)GC_try_to_collect(GC_never_stop_func);
}
word GC_n_heap_sects = 0; /* Number of sections currently in heap. */
return(x < y? x : y);
}
+void GC_set_max_heap_size(n)
+word n;
+{
+ GC_max_heapsize = n;
+}
+
/*
* this explicitly increases the size of the heap. It is used
* internally, but may also be invoked from GC_expand_hp by the user.
if (n < MINHINCR) n = MINHINCR;
bytes = n * HBLKSIZE;
+
+ if (GC_max_heapsize != 0 && GC_heapsize + bytes > GC_max_heapsize) {
+ /* Exceeded self-imposed limit */
+ return(FALSE);
+ }
space = GET_MEM(bytes);
if( space == 0 ) {
return(FALSE);
static int count = 0; /* How many failures? */
if (!GC_incremental && !GC_dont_gc && GC_should_collect()) {
-# ifdef SAVE_CALL_CHAIN
- GC_save_callers(GC_last_stack);
-# endif
GC_gcollect_inner();
} else {
word blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor)
if (!GC_expand_hp_inner(blocks_to_get)
&& !GC_expand_hp_inner(needed_blocks)) {
if (count++ < 10) {
- WARN("Out of Memory! Trying to continue ...\n");
+ WARN("Out of Memory! Trying to continue ...\n", 0);
GC_gcollect_inner();
} else {
- WARN("Out of Memory! Returning NIL!\n");
+ WARN("Out of Memory! Returning NIL!\n", 0);
return(FALSE);
}
} else if (count) {
- WARN("Memory available again! Continue ...\n");
+# ifdef PRINTSTATS
+ GC_printf0("Memory available again ...\n");
+# endif
count = 0;
}
}
BZERO(doomed, sizeof(page_hash_table));
}
+void GC_copy_bl(old, new)
+word *new, *old;
+{
+ BCOPY(old, new, sizeof(page_hash_table));
+}
+
/* Signal the completion of a collection. Turn the incomplete black */
/* lists into new black lists, etc. */
void GC_promote_black_lists()
GC_incomplete_stack_bl = very_old_stack_bl;
}
+void GC_unpromote_black_lists()
+{
+# ifndef ALL_INTERIOR_POINTERS
+ GC_copy_bl(GC_old_normal_bl, GC_incomplete_normal_bl);
+# endif
+ GC_copy_bl(GC_old_stack_bl, GC_incomplete_stack_bl);
+}
+
# ifndef ALL_INTERIOR_POINTERS
/* P is not a valid pointer reference, but it falls inside */
/* the plausible heap bounds. */
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, July 14, 1994 3:27 pm PDT */
+/* Boehm, January 31, 1995 12:36 pm PST */
# ifdef CHECKSUMS
# include "gc_priv.h"
/* safe under other conditions.) */
# define NSUMS 2000
-# define OFFSET 100000
+# define OFFSET 0x10000
typedef struct {
bool new_valid;
while (p < lim) {
result += *p++;
}
- return(result);
+ return(result | 0x80000000 /* doesn't look like pointer */);
}
# ifdef STUBBORN_ALLOC
pe -> block = h + OFFSET;
}
+word GC_bytes_in_used_blocks;
+
+void GC_add_block(h, dummy)
+struct hblk *h;
+word dummy;
+{
+ register hdr * hhdr = HDR(h);
+ register bytes = WORDS_TO_BYTES(hhdr -> hb_sz);
+
+ bytes += HDR_BYTES + HBLKSIZE-1;
+ bytes &= ~(HBLKSIZE-1);
+ GC_bytes_in_used_blocks += bytes;
+}
+
+GC_check_blocks()
+{
+ word bytes_in_free_blocks = 0;
+ struct hblk * h = GC_hblkfreelist;
+ hdr * hhdr = HDR(h);
+ word sz;
+
+ GC_bytes_in_used_blocks = 0;
+ GC_apply_to_all_blocks(GC_add_block, (word)0);
+ while (h != 0) {
+ sz = hhdr -> hb_sz;
+ bytes_in_free_blocks += sz;
+ h = hhdr -> hb_next;
+ hhdr = HDR(h);
+ }
+ GC_printf2("GC_bytes_in_used_blocks = %ld, bytes_in_free_blocks = %ld ",
+ GC_bytes_in_used_blocks, bytes_in_free_blocks);
+ GC_printf("GC_heapsize = %ld\n", GC_heapsize);
+ if (GC_bytes_in_used_blocks + bytes_in_free_blocks != GC_heapsize) {
+ GC_printf("LOST SOME BLOCKS!!\n");
+ }
+}
+
/* Should be called immediately after GC_read_dirty and GC_read_changed. */
void GC_check_dirty()
{
register struct hblk *h;
register ptr_t start;
+ GC_check_blocks();
+
GC_n_dirty_errors = 0;
GC_n_changed_errors = 0;
GC_n_clean = 0;
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, November 22, 1994 11:55 am PST */
+/* Boehm, February 6, 1995 5:24 pm PST */
#ifndef CONFIG_H
# if defined(__MWERKS__) && defined(__powerc)
# define POWERPC
# define MACOS
+# define mach_type_known
# endif
# if defined(NeXT) && defined(mc68000)
# define M68K
# define MSWIN32 /* or Win32s */
# define mach_type_known
# endif
+# if defined(__BORLANDC__)
+# define I386
+# define MSWIN32
+# define mach_type_known
+# endif
/* Feel free to add more clauses here */
# endif
# endif
+# ifdef POWERPC
+# define MACH_TYPE "POWERPC"
+# define ALIGNMENT 2
+# ifdef MACOS
+# ifndef __LOWMEM__
+# include <LowMem.h>
+# endif
+# define OS_TYPE "MACOS"
+ /* see os_dep.c for details of global data segments. */
+# define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
+# endif
+# endif
+
# ifdef VAX
# define MACH_TYPE "VAX"
# define ALIGNMENT 4 /* Pointers are longword aligned by 4.2 C compiler */
# ifdef I386
# define MACH_TYPE "I386"
-# define ALIGNMENT 4 /* Appears to hold for all "32 bit" compilers */
+# define ALIGNMENT 4 /* Appears to hold for all "32 bit" compilers */
+ /* except Borland. The -a4 option fixes */
+ /* Borland. */
# ifdef SEQUENT
# define OS_TYPE "SEQUENT"
extern int etext;
typedef <OPAQUE but fairly big> CORD_pos[1];
- /* Extract the cord from a position:
+ * Extract the cord from a position:
CORD CORD_pos_to_cord(CORD_pos p);
- /* Extract the current index from a position:
+ * Extract the current index from a position:
size_t CORD_pos_to_index(CORD_pos p);
- /* Fetch the character located at the given position:
+ * Fetch the character located at the given position:
char CORD_pos_fetch(CORD_pos p);
- /* Initialize the position to refer to the given cord and index.
- /* Note that this is the most expensive function on positions:
+ * Initialize the position to refer to the given cord and index.
+ * Note that this is the most expensive function on positions:
void CORD_set_pos(CORD_pos p, CORD x, size_t i);
- /* Advance the position to the next character.
- /* P must be initialized and valid.
- /* Invalidates p if past end:
+ * Advance the position to the next character.
+ * P must be initialized and valid.
+ * Invalidates p if past end:
void CORD_next(CORD_pos p);
- /* Move the position to the preceding character.
- /* P must be initialized and valid.
- /* Invalidates p if past beginning:
+ * Move the position to the preceding character.
+ * P must be initialized and valid.
+ * Invalidates p if past beginning:
void CORD_prev(CORD_pos p);
- /* Is the position valid, i.e. inside the cord?
+ * Is the position valid, i.e. inside the cord?
int CORD_pos_valid(CORD_pos p);
*/
# define CORD_FOR(pos, cord) \
* The redisplay algorithm doesn't let curses do the scrolling.
* The rule for moving the window over the file is suboptimal.
*/
-/* Boehm, June 13, 1994 2:35 pm PDT */
+/* Boehm, February 6, 1995 12:27 pm PST */
/* Boehm, May 19, 1994 2:20 pm PDT */
#include <stdio.h>
#include <ctype.h>
#endif
+#if defined(__BORLANDC__) && !defined(WIN32)
+ /* If this is DOS or win16, we'll fail anyway. */
+ /* Might as well assume win32. */
+# define WIN32
+#endif
+
#if defined(WIN32)
# include <windows.h>
# include "de_win.h"
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, May 19, 1994 2:21 pm PDT */
+/* Boehm, February 6, 1995 12:29 pm PST */
/*
* The MS Windows specific part of de.
hwnd = CreateWindow (szAppName,
FullAppName,
WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */
- CW_USEDEFAULT, 0, /* default pos. */,
- CW_USEDEFAULT, 0, /* default width, height */,
+ CW_USEDEFAULT, 0, /* default pos. */
+ CW_USEDEFAULT, 0, /* default width, height */
NULL, /* No parent */
NULL, /* Window class menu */
hInstance, NULL);
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, December 7, 1994 12:09 pm PST */
+/* Boehm, January 28, 1995 3:59 pm PST */
/*
* Note that this defines a large number of tuning hooks, which can
/* at the expense of space. */
/* GC_free_space_divisor = 1 will effectively */
/* disable collections. */
-
+
/* Public procedures */
/*
/* Returns 0 on failure, 1 on success. */
extern int GC_expand_hp(/* number_of_bytes */);
+/* Limit the heap size to n bytes. Useful when you're debugging, */
+/* especially on systems that don't handle running out of memory well. */
+/* n == 0 ==> unbounded. This is the default. */
+extern void GC_set_max_heap_size(/* n */);
+
/* Clear the set of root segments. Wizards only. */
extern void GC_clear_roots(NO_PARAMS);
/* Explicitly trigger a full, world-stop collection. */
void GC_gcollect(NO_PARAMS);
+/* Trigger a full world-stopped collection. Abort the collection if */
+/* and when stop_func returns a nonzero value. Stop_func will be */
+/* called frequently, and should be reasonably fast. This works even */
+/* if virtual dirty bits, and hence incremental collection is not */
+/* available for this architecture. Collections can be aborted faster */
+/* than normal pause times for incremental collection. However, */
+/* aborted collections do no useful work; the next collection needs */
+/* to start from the beginning. */
+typedef int (* GC_stop_func)(NO_PARAMS);
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_try_to_collect(GC_stop_func stop_func);
+# else
+ int GC_try_to_collect(/* GC_stop_func stop_func */);
+# endif
+
/* Return the number of bytes in the heap. Excludes collector private */
/* data structures. Includes empty blocks and fragmentation loss. */
/* Includes some pages that were allocated but never written. */
size_t GC_get_heap_size(NO_PARAMS);
+/* Return the number of bytes allocated since the last collection. */
+size_t GC_get_bytes_since_gc(NO_PARAMS);
+
/* Enable incremental/generational collection. */
/* Not advisable unless dirty bits are */
/* available or most heap objects are */
/* use involves calling GC_register_disappearing_link(&p), */
/* where p is a pointer that is not followed by finalization */
/* code, and should not be considered in determining */
-/* finalization order. */
-int GC_register_disappearing_link(/* void ** link */);
+/* finalization order. */
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_register_disappearing_link(void ** link);
+# else
+ int GC_register_disappearing_link(/* void ** link */);
+# endif
+
/* Link should point to a field of a heap allocated */
/* object obj. *link will be cleared when obj is */
/* found to be inaccessible. This happens BEFORE any */
/* Returns 1 if link was already registered, 0 */
/* otherwise. */
/* Only exists for backward compatibility. See below: */
-int GC_general_register_disappearing_link(/* void ** link, void * obj */);
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_general_register_disappearing_link(void ** link, void * obj);
+# else
+ int GC_general_register_disappearing_link(/* void ** link, void * obj */);
+# endif
/* A slight generalization of the above. *link is */
/* cleared when obj first becomes inaccessible. This */
/* can be used to implement weak pointers easily and */
/* the object containing link. Explicitly deallocating */
/* obj may or may not cause link to eventually be */
/* cleared. */
-int GC_unregister_disappearing_link(/* void ** link */);
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_unregister_disappearing_link(void ** link);
+# else
+ int GC_unregister_disappearing_link(/* void ** link */);
+# endif
/* Returns 0 if link was not actually registered. */
/* Undoes a registration by either of the above two */
/* routines. */
void GC_debug_invoke_finalizer(/* void * obj, void * data */);
# endif
+/* GC_set_warn_proc can be used to redirect or filter warning messages. */
+# if defined(__STDC__) || defined(__cplusplus)
+ typedef void (*GC_warn_proc)(char *msg, GC_word arg);
+ GC_warn_proc GC_set_warn_proc(GC_warn_proc p);
+ /* Returns old warning procedure. */
+# else
+ typedef void (*GC_warn_proc)(/* char *msg, GC_word arg */);
+ GC_warn_proc GC_set_warn_proc(/* GC_warn_proc p */);
+# endif
/* The following is intended to be used by a higher level */
/* (e.g. cedar-like) finalization facility. It is expected */
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, November 8, 1994 5:35 pm PST */
+/* Boehm, January 28, 1995 4:26 pm PST */
# define I_HIDE_POINTERS
# include "gc_priv.h"
# include "gc_mark.h"
*table = new_table;
}
-
-int GC_register_disappearing_link(link)
-extern_ptr_t * link;
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_register_disappearing_link(extern_ptr_t * link)
+# else
+ int GC_register_disappearing_link(link)
+ extern_ptr_t * link;
+# endif
{
ptr_t base;
return(GC_general_register_disappearing_link(link, base));
}
-int GC_general_register_disappearing_link(link, obj)
-extern_ptr_t * link;
-extern_ptr_t obj;
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_general_register_disappearing_link(extern_ptr_t * link,
+ extern_ptr_t obj)
+# else
+ int GC_general_register_disappearing_link(link, obj)
+ extern_ptr_t * link;
+ extern_ptr_t obj;
+# endif
+
{
struct disappearing_link *curr_dl;
int index;
return(0);
}
-int GC_unregister_disappearing_link(link)
-extern_ptr_t * link;
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_unregister_disappearing_link(extern_ptr_t * link)
+# else
+ int GC_unregister_disappearing_link(link)
+ extern_ptr_t * link;
+# endif
{
struct disappearing_link *curr_dl, *prev_dl;
int index;
GC_set_mark_bit(real_ptr);
while (!GC_mark_some());
}
- /*
if (GC_is_marked(real_ptr)) {
- --> Report finalization cycle here, if desired
+ WARN("Finalization cycle involving %ld\n", real_ptr);
}
- */
}
}
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, December 7, 1994 12:09 pm PST */
+/* Boehm, January 28, 1995 3:59 pm PST */
/*
* Note that this defines a large number of tuning hooks, which can
/* at the expense of space. */
/* GC_free_space_divisor = 1 will effectively */
/* disable collections. */
-
+
/* Public procedures */
/*
/* Returns 0 on failure, 1 on success. */
extern int GC_expand_hp(/* number_of_bytes */);
+/* Limit the heap size to n bytes. Useful when you're debugging, */
+/* especially on systems that don't handle running out of memory well. */
+/* n == 0 ==> unbounded. This is the default. */
+extern void GC_set_max_heap_size(/* n */);
+
/* Clear the set of root segments. Wizards only. */
extern void GC_clear_roots(NO_PARAMS);
/* Explicitly trigger a full, world-stop collection. */
void GC_gcollect(NO_PARAMS);
+/* Trigger a full world-stopped collection. Abort the collection if */
+/* and when stop_func returns a nonzero value. Stop_func will be */
+/* called frequently, and should be reasonably fast. This works even */
+/* if virtual dirty bits, and hence incremental collection is not */
+/* available for this architecture. Collections can be aborted faster */
+/* than normal pause times for incremental collection. However, */
+/* aborted collections do no useful work; the next collection needs */
+/* to start from the beginning. */
+typedef int (* GC_stop_func)(NO_PARAMS);
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_try_to_collect(GC_stop_func stop_func);
+# else
+ int GC_try_to_collect(/* GC_stop_func stop_func */);
+# endif
+
/* Return the number of bytes in the heap. Excludes collector private */
/* data structures. Includes empty blocks and fragmentation loss. */
/* Includes some pages that were allocated but never written. */
size_t GC_get_heap_size(NO_PARAMS);
+/* Return the number of bytes allocated since the last collection. */
+size_t GC_get_bytes_since_gc(NO_PARAMS);
+
/* Enable incremental/generational collection. */
/* Not advisable unless dirty bits are */
/* available or most heap objects are */
/* use involves calling GC_register_disappearing_link(&p), */
/* where p is a pointer that is not followed by finalization */
/* code, and should not be considered in determining */
-/* finalization order. */
-int GC_register_disappearing_link(/* void ** link */);
+/* finalization order. */
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_register_disappearing_link(void ** link);
+# else
+ int GC_register_disappearing_link(/* void ** link */);
+# endif
+
/* Link should point to a field of a heap allocated */
/* object obj. *link will be cleared when obj is */
/* found to be inaccessible. This happens BEFORE any */
/* Returns 1 if link was already registered, 0 */
/* otherwise. */
/* Only exists for backward compatibility. See below: */
-int GC_general_register_disappearing_link(/* void ** link, void * obj */);
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_general_register_disappearing_link(void ** link, void * obj);
+# else
+ int GC_general_register_disappearing_link(/* void ** link, void * obj */);
+# endif
/* A slight generalization of the above. *link is */
/* cleared when obj first becomes inaccessible. This */
/* can be used to implement weak pointers easily and */
/* the object containing link. Explicitly deallocating */
/* obj may or may not cause link to eventually be */
/* cleared. */
-int GC_unregister_disappearing_link(/* void ** link */);
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_unregister_disappearing_link(void ** link);
+# else
+ int GC_unregister_disappearing_link(/* void ** link */);
+# endif
/* Returns 0 if link was not actually registered. */
/* Undoes a registration by either of the above two */
/* routines. */
void GC_debug_invoke_finalizer(/* void * obj, void * data */);
# endif
+/* GC_set_warn_proc can be used to redirect or filter warning messages. */
+# if defined(__STDC__) || defined(__cplusplus)
+ typedef void (*GC_warn_proc)(char *msg, GC_word arg);
+ GC_warn_proc GC_set_warn_proc(GC_warn_proc p);
+ /* Returns old warning procedure. */
+# else
+ typedef void (*GC_warn_proc)(/* char *msg, GC_word arg */);
+ GC_warn_proc GC_set_warn_proc(/* GC_warn_proc p */);
+# endif
/* The following is intended to be used by a higher level */
/* (e.g. cedar-like) finalization facility. It is expected */
C++ Interface to the Boehm Collector
John R. Ellis and Jesse Hull
- Last modified on Thu Dec 8 12:41:07 PST 1994 by ellis
+ Last modified on Wed Jan 4 16:30:20 PST 1995 by ellis
This interface provides access to the Boehm collector. It provides
basic facilities similar to those described in "Safe, Efficient
#define _cdecl
#endif
+#if __BORLANDC__ >= 0x450 && !defined(OPERATOR_NEW_ARRAY)
+# define OPERATOR_NEW_ARRAY
+#endif
+
enum GCPlacement {GC, NoGC};
class gc {public:
((gc_cleanup*) ((char*) obj + (ptrdiff_t) displ))->~gc_cleanup();}
inline gc_cleanup::gc_cleanup() {
- register void *base = GC_base( (void *) this );
- GC_REGISTER_FINALIZER_IGNORE_SELF(
- base, cleanup, (void*) ((char*) this - (char*) base), 0, 0 );}
+ void* base = GC_base( (void *) this );
+ if (0 != base) {
+ GC_REGISTER_FINALIZER_IGNORE_SELF(
+ base, cleanup, (void*) ((char*) this - (char*) base), 0, 0 );}}
inline void* operator new(
size_t size,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, November 8, 1994 5:49 pm PST */
+/* Boehm, January 30, 1995 4:01 pm PST */
# ifndef GC_PRIVATE_H
# define THREADS
# endif
-#if defined(SPARC) || defined(HP_PA)
+#if defined(SPARC)
# define ALIGN_DOUBLE /* Align objects of size > 1 word on 2 word */
/* boundaries. Wasteful of memory, but */
/* apparently required by SPARC architecture. */
# define TIME_LIMIT 50 /* We try to keep pause times from exceeding */
/* this by much. In milliseconds. */
+# define BL_LIMIT (25*HBLKSIZE)
+ /* If we need a block of N bytes, and we have */
+ /* a block of N + BL_LIMIT bytes available, */
+ /* and N > BL_LIMIT, */
+ /* but all possible positions in it are */
+ /* blacklisted, we just use it anyway (and */
+ /* print a warning, if warnings are enabled). */
+ /* This risks subsequently leaking the block */
+ /* due to a false reference. But not using */
+ /* the block risks unreasonable immediate */
+ /* heap growth. */
+
/*********************************/
/* */
/* Stack saving for debugging */
# endif
/* Print warning message, e.g. almost out of memory. */
-# define WARN(s) GC_printf0(s)
+# define WARN(msg,arg) (*GC_current_warn_proc)(msg, (GC_word)(arg))
+extern GC_warn_proc GC_current_warn_proc;
/*********************************/
/* */
struct _GC_arrays {
word _heapsize;
+ word _max_heapsize;
ptr_t _last_heap_addr;
ptr_t _prev_heap_addr;
word _words_allocd_before_gc;
# define GC_non_gc_bytes_at_gc GC_arrays._non_gc_bytes_at_gc
# define GC_mem_freed GC_arrays._mem_freed
# define GC_heapsize GC_arrays._heapsize
+# define GC_max_heapsize GC_arrays._max_heapsize
# define GC_words_allocd_before_gc GC_arrays._words_allocd_before_gc
# define GC_heap_sects GC_arrays._heap_sects
# define GC_last_stack GC_arrays._last_stack
struct hblk * GC_next_block(/* struct hblk * h */);
void GC_mark_init();
void GC_clear_marks(); /* Clear mark bits for all heap objects. */
+void GC_invalidate_mark_state(); /* Tell the marker that marked */
+ /* objects may point to unmarked */
+ /* ones, and roots may point to */
+ /* unmarked objects. */
+ /* Reset mark stack. */
void GC_mark_from_mark_stack(); /* Mark from everything on the mark stack. */
/* Return after about one pages worth of */
/* work. */
/* these false references. */
void GC_promote_black_lists();
/* Declare an end to a black listing phase. */
+void GC_unpromote_black_lists();
+ /* Approximately undo the effect of the above. */
+ /* This actually loses some information, but */
+ /* only in a reasonably safe way. */
ptr_t GC_scratch_alloc(/*bytes*/);
/* GC internal memory allocation for */
/* Arrange for all reclaim lists to be */
/* empty. Judiciously choose between */
/* sweeping and discarding each page. */
+bool GC_reclaim_all(/* GC_stop_func f*/);
+ /* Reclaim all blocks. Abort (in a */
+ /* consistent state) if f returns TRUE. */
bool GC_block_empty(/* hhdr */); /* Block completely unmarked? */
-void GC_gcollect_inner();
+bool GC_never_stop_func(); /* Returns FALSE. */
+bool GC_try_to_collect_inner(/* GC_stop_func f */);
/* Collect; caller must have acquired */
/* lock and disabled signals. */
- /* FALSE return indicates nothing was */
- /* done due to insufficient allocation. */
+ /* Collection is aborted if f returns */
+ /* TRUE. Returns TRUE if it completes */
+ /* successfully. */
+# define GC_gcollect_inner() \
+ (void) GC_try_to_collect_inner(GC_never_stop_func)
void GC_finish_collection(); /* Finish collection. Mark bits are */
/* consistent and lock is still held. */
bool GC_collect_or_expand(/* needed_blocks */);
/* Collect or expand heap in an attempt */
/* make the indicated number of free */
/* blocks available. Should be called */
+ /* until the blocks are available or */
/* until it fails by returning FALSE. */
void GC_init(); /* Initialize collector. */
void GC_collect_a_little_inner(/* int n */);
typedef <OPAQUE but fairly big> CORD_pos[1];
- /* Extract the cord from a position:
+ * Extract the cord from a position:
CORD CORD_pos_to_cord(CORD_pos p);
- /* Extract the current index from a position:
+ * Extract the current index from a position:
size_t CORD_pos_to_index(CORD_pos p);
- /* Fetch the character located at the given position:
+ * Fetch the character located at the given position:
char CORD_pos_fetch(CORD_pos p);
- /* Initialize the position to refer to the given cord and index.
- /* Note that this is the most expensive function on positions:
+ * Initialize the position to refer to the given cord and index.
+ * Note that this is the most expensive function on positions:
void CORD_set_pos(CORD_pos p, CORD x, size_t i);
- /* Advance the position to the next character.
- /* P must be initialized and valid.
- /* Invalidates p if past end:
+ * Advance the position to the next character.
+ * P must be initialized and valid.
+ * Invalidates p if past end:
void CORD_next(CORD_pos p);
- /* Move the position to the preceding character.
- /* P must be initialized and valid.
- /* Invalidates p if past beginning:
+ * Move the position to the preceding character.
+ * P must be initialized and valid.
+ * Invalidates p if past beginning:
void CORD_prev(CORD_pos p);
- /* Is the position valid, i.e. inside the cord?
+ * Is the position valid, i.e. inside the cord?
int CORD_pos_valid(CORD_pos p);
*/
# define CORD_FOR(pos, cord) \
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, December 7, 1994 12:09 pm PST */
+/* Boehm, January 28, 1995 3:59 pm PST */
/*
* Note that this defines a large number of tuning hooks, which can
/* at the expense of space. */
/* GC_free_space_divisor = 1 will effectively */
/* disable collections. */
-
+
/* Public procedures */
/*
/* Returns 0 on failure, 1 on success. */
extern int GC_expand_hp(/* number_of_bytes */);
+/* Limit the heap size to n bytes. Useful when you're debugging, */
+/* especially on systems that don't handle running out of memory well. */
+/* n == 0 ==> unbounded. This is the default. */
+extern void GC_set_max_heap_size(/* n */);
+
/* Clear the set of root segments. Wizards only. */
extern void GC_clear_roots(NO_PARAMS);
/* Explicitly trigger a full, world-stop collection. */
void GC_gcollect(NO_PARAMS);
+/* Trigger a full world-stopped collection. Abort the collection if */
+/* and when stop_func returns a nonzero value. Stop_func will be */
+/* called frequently, and should be reasonably fast. This works even */
+/* if virtual dirty bits, and hence incremental collection is not */
+/* available for this architecture. Collections can be aborted faster */
+/* than normal pause times for incremental collection. However, */
+/* aborted collections do no useful work; the next collection needs */
+/* to start from the beginning. */
+typedef int (* GC_stop_func)(NO_PARAMS);
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_try_to_collect(GC_stop_func stop_func);
+# else
+ int GC_try_to_collect(/* GC_stop_func stop_func */);
+# endif
+
/* Return the number of bytes in the heap. Excludes collector private */
/* data structures. Includes empty blocks and fragmentation loss. */
/* Includes some pages that were allocated but never written. */
size_t GC_get_heap_size(NO_PARAMS);
+/* Return the number of bytes allocated since the last collection. */
+size_t GC_get_bytes_since_gc(NO_PARAMS);
+
/* Enable incremental/generational collection. */
/* Not advisable unless dirty bits are */
/* available or most heap objects are */
/* use involves calling GC_register_disappearing_link(&p), */
/* where p is a pointer that is not followed by finalization */
/* code, and should not be considered in determining */
-/* finalization order. */
-int GC_register_disappearing_link(/* void ** link */);
+/* finalization order. */
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_register_disappearing_link(void ** link);
+# else
+ int GC_register_disappearing_link(/* void ** link */);
+# endif
+
/* Link should point to a field of a heap allocated */
/* object obj. *link will be cleared when obj is */
/* found to be inaccessible. This happens BEFORE any */
/* Returns 1 if link was already registered, 0 */
/* otherwise. */
/* Only exists for backward compatibility. See below: */
-int GC_general_register_disappearing_link(/* void ** link, void * obj */);
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_general_register_disappearing_link(void ** link, void * obj);
+# else
+ int GC_general_register_disappearing_link(/* void ** link, void * obj */);
+# endif
/* A slight generalization of the above. *link is */
/* cleared when obj first becomes inaccessible. This */
/* can be used to implement weak pointers easily and */
/* the object containing link. Explicitly deallocating */
/* obj may or may not cause link to eventually be */
/* cleared. */
-int GC_unregister_disappearing_link(/* void ** link */);
+# if defined(__STDC__) || defined(__cplusplus)
+ int GC_unregister_disappearing_link(void ** link);
+# else
+ int GC_unregister_disappearing_link(/* void ** link */);
+# endif
/* Returns 0 if link was not actually registered. */
/* Undoes a registration by either of the above two */
/* routines. */
void GC_debug_invoke_finalizer(/* void * obj, void * data */);
# endif
+/* GC_set_warn_proc can be used to redirect or filter warning messages. */
+# if defined(__STDC__) || defined(__cplusplus)
+ typedef void (*GC_warn_proc)(char *msg, GC_word arg);
+ GC_warn_proc GC_set_warn_proc(GC_warn_proc p);
+ /* Returns old warning procedure. */
+# else
+ typedef void (*GC_warn_proc)(/* char *msg, GC_word arg */);
+ GC_warn_proc GC_set_warn_proc(/* GC_warn_proc p */);
+# endif
/* The following is intended to be used by a higher level */
/* (e.g. cedar-like) finalization facility. It is expected */
C++ Interface to the Boehm Collector
John R. Ellis and Jesse Hull
- Last modified on Sun Nov 20 17:37:45 PST 1994 by ellis
+ Last modified on Wed Jan 4 16:30:20 PST 1995 by ellis
This interface provides access to the Boehm collector. It provides
basic facilities similar to those described in "Safe, Efficient
collector frees "a". You must supply an explicit clean-up function
for that to occur.
-3. Evidently cfront 3.0 does not allow destructors to be explicitly
-invoked using the ANSI-conforming syntax t->~T(). If you're using
-cfront 3.0, you'll have to comment out the class gc_cleanup, which
-uses explicit invocation.
+4. Compiler bugs:
+
+ Solaris 2's CC (SC3.0) doesn't implement t->~T() correctly, so the
+ destructors of classes derived from gc_cleanup won't be invoked.
+ You'll have to explicitly register a clean-up function with
+ new-placement syntax.
+
+ Evidently cfront 3.0 does not allow destructors to be explicitly
+ invoked using the ANSI-conforming syntax t->~T(). If you're using
+ cfront 3.0, you'll have to comment out the class gc_cleanup, which
+ uses explicit invocation.
****************************************************************************/
#define _cdecl
#endif
+#if __BORLANDC__ >= 0x450 && !defined(OPERATOR_NEW_ARRAY)
+# define OPERATOR_NEW_ARRAY
+#endif
+
enum GCPlacement {GC, NoGC};
class gc {public:
inline void* operator new[]( size_t size );
inline void* operator new[]( size_t size, GCPlacement gcp );
inline void operator delete[]( void* obj );
-#endif OPERATOR_NEW_ARRAY
+#endif /* OPERATOR_NEW_ARRAY */
};
/*
Instances of classes derived from "gc" will be allocated in the
((gc_cleanup*) ((char*) obj + (ptrdiff_t) displ))->~gc_cleanup();}
inline gc_cleanup::gc_cleanup() {
- register void *base = GC_base( (void *) this );
- GC_REGISTER_FINALIZER_IGNORE_SELF(
- base, cleanup, (void*) ((char*) this - (char*) base), 0, 0 );}
+ void* base = GC_base( (void *) this );
+ if (0 != base) {
+ GC_REGISTER_FINALIZER_IGNORE_SELF(
+ base, cleanup, (void*) ((char*) this - (char*) base), 0, 0 );}}
inline void* operator new(
size_t size,
{
return ::operator new( size, gcp, cleanup, clientData );}
-#endif OPERATOR_NEW_ARRAY
+#endif /* OPERATOR_NEW_ARRAY */
#endif /* GC_CPP_H */
# ifdef AMIGA
/* AMIGA - could be replaced by generic code */
- /* SAS/C optimizer mangles this so compile with "noopt" */
/* a0, a1, d0 and d1 are caller save */
GC_push_one(getreg(REG_A2));
GC_push_one(getreg(REG_A3));
/* other machines... */
# if !(defined M68K) && !(defined VAX) && !(defined RT)
# if !(defined SPARC) && !(defined I386) && !(defined NS32K)
-# if !defined(HP_PA) && !defined(M88K)
+# if !defined(HP_PA) && !defined(M88K) && !defined(POWERPC)
--> bad news <--
# endif
# endif
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, September 19, 1994 4:18 pm PDT */
+/* Boehm, February 10, 1995 12:55 pm PST */
#include <stdio.h>
#include "gc_priv.h"
}
}
+# ifdef REDIRECT_MALLOC
+# ifdef __STDC__
+ extern_ptr_t malloc(size_t lb)
+# else
+ extern_ptr_t malloc(lb)
+ size_t lb;
+# endif
+ {
+ /* It might help to manually inline the GC_malloc call here. */
+ /* But any decent compiler should reduce the extra procedure call */
+ /* to at most a jump instruction in this case. */
+ return(REDIRECT_MALLOC(lb));
+ }
+
+# ifdef __STDC__
+ extern_ptr_t calloc(size_t n, size_t lb)
+# else
+ extern_ptr_t calloc(n, lb)
+ size_t n, lb;
+# endif
+ {
+ return(REDIRECT_MALLOC(n*lb));
+ }
+# endif /* REDIRECT_MALLOC */
+
/* Allocate lb bytes of pointerful, traced, but not collectable data */
# ifdef __STDC__
extern_ptr_t GC_malloc_uncollectable(size_t lb)
}
}
+# ifdef REDIRECT_MALLOC
+# ifdef __STDC__
+ extern_ptr_t realloc(extern_ptr_t p, size_t lb)
+# else
+ extern_ptr_t realloc(p,lb)
+ extern_ptr_t p;
+ size_t lb;
+# endif
+ {
+ return(GC_realloc(p, lb));
+ }
+# endif /* REDIRECT_MALLOC */
+
/* Explicitly deallocate an object p. */
# ifdef __STDC__
void GC_free(extern_ptr_t p)
GC_mem_freed += sz;
/* A signal here can make GC_mem_freed and GC_non_gc_bytes */
/* inconsistent. We claim this is benign. */
- if (knd == UNCOLLECTABLE) GC_non_gc_bytes -= sz;
+ if (knd == UNCOLLECTABLE) GC_non_gc_bytes -= WORDS_TO_BYTES(sz);
if (ok -> ok_init) {
BZERO((word *)p + 1, WORDS_TO_BYTES(sz-1));
}
DISABLE_SIGNALS();
LOCK();
GC_mem_freed += sz;
- if (knd == UNCOLLECTABLE) GC_non_gc_bytes -= sz;
+ if (knd == UNCOLLECTABLE) GC_non_gc_bytes -= WORDS_TO_BYTES(sz);
GC_freehblk(h);
UNLOCK();
ENABLE_SIGNALS();
}
}
+# ifdef REDIRECT_MALLOC
+# ifdef __STDC__
+ void free(extern_ptr_t p)
+# else
+ void free(p)
+ extern_ptr_t p;
+# endif
+ {
+ GC_free(p);
+ }
+# endif /* REDIRECT_MALLOC */
/*
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
- * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
+ * Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved.
*
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
# endif
}
+void GC_invalidate_mark_state()
+{
+ GC_mark_state = MS_INVALID;
+ GC_mark_stack_top = GC_mark_stack-1;
+}
+
mse * GC_signal_mark_stack_overflow(msp)
mse * msp;
{
WORDS_TO_BYTES(SPLIT_RANGE_WORDS-1);
/* Make sure that pointers overlapping the two ranges are */
/* considered. */
- limit += sizeof(word) - ALIGNMENT;
+ limit = (word *)((char *)limit + sizeof(word) - ALIGNMENT);
break;
case DS_BITMAP:
GC_mark_stack_top_reg--;
# undef GC_least_plausible_heap_addr
}
-#endif UNALIGNED
+#endif /* UNALIGNED */
#endif /* SMALL_CONFIG */
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, November 8, 1994 5:53 pm PST */
+/* Boehm, February 10, 1995 12:37 pm PST */
#include <stdio.h>
return ((size_t) GC_heapsize);
}
+size_t GC_get_bytes_since_gc(NO_PARAMS)
+{
+ return ((size_t) WORDS_TO_BYTES(GC_words_allocd));
+}
+
bool GC_is_initialized = FALSE;
void GC_init()
# endif
}
-#if defined(OS2) || defined(MSWIN32) || defined(MACOS)
- FILE * GC_stdout = NULL;
- FILE * GC_stderr = NULL;
-#else
-# if !defined(AMIGA)
-# include <unistd.h>
-# endif
-#endif
-
#ifdef MSWIN32
+# define LOG_FILE "gc.log"
+# include <windows.h>
+
+ HANDLE GC_stdout = 0, GC_stderr;
+ int GC_tmp;
+ DWORD GC_junk;
+
void GC_set_files()
{
- if (GC_stdout == NULL) {
- GC_stdout = fopen("gc.log", "wt");
+ if (!GC_stdout) {
+ GC_stdout = CreateFile(LOG_FILE, GENERIC_WRITE, FILE_SHARE_READ,
+ NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH,
+ NULL);
+ if (INVALID_HANDLE_VALUE == GC_stdout) ABORT("Open of log file failed");
}
- if (GC_stderr == NULL) {
+ if (GC_stderr == 0) {
GC_stderr = GC_stdout;
}
}
+
#endif
#if defined(OS2) || defined(MACOS)
+FILE * GC_stdout = NULL;
+FILE * GC_stderr = NULL;
+int GC_tmp; /* Should really be local ... */
+
void GC_set_files()
{
if (GC_stdout == NULL) {
}
#endif
+#if !defined(OS2) && !defined(MACOS) && !defined(MSWIN32)
+ int GC_stdout = 1;
+ int GC_stderr = 2;
+# if !defined(AMIGA)
+# include <unistd.h>
+# endif
+#endif
+
#ifdef SOLARIS_THREADS
# define WRITE(f, buf, len) syscall(SYS_write, (f), (buf), (len))
#else
-# define WRITE(f, buf, len) write((f), (buf), (len))
+# ifdef MSWIN32
+# define WRITE(f, buf, len) (GC_set_files(), \
+ GC_tmp = WriteFile((f), (buf), \
+ (len), &GC_junk, NULL),\
+ (GC_tmp? 1 : -1))
+# else
+# if defined(OS2) || defined(MACOS)
+# define WRITE(f, buf, len) (GC_set_files(), \
+ GC_tmp = fwrite((buf), 1, (len), (f)), \
+ fflush(f), GC_tmp)
+# else
+# define WRITE(f, buf, len) write((f), (buf), (len))
+# endif
+# endif
#endif
/* A version of printf that is unlikely to call malloc, and is thus safer */
buf[1024] = 0x15;
(void) sprintf(buf, format, a, b, c, d, e, f);
if (buf[1024] != 0x15) ABORT("GC_printf clobbered stack");
-# if defined(OS2) || defined(MSWIN32) || defined(MACOS)
- GC_set_files();
- /* We hope this doesn't allocate */
- if (fwrite(buf, 1, strlen(buf), GC_stdout) != strlen(buf))
- ABORT("write to stdout failed");
- fflush(GC_stdout);
-# else
- if (WRITE(1, buf, strlen(buf)) < 0) ABORT("write to stdout failed");
-# endif
+ if (WRITE(GC_stdout, buf, strlen(buf)) < 0) ABORT("write to stdout failed");
}
void GC_err_printf(format, a, b, c, d, e, f)
buf[1024] = 0x15;
(void) sprintf(buf, format, a, b, c, d, e, f);
if (buf[1024] != 0x15) ABORT("GC_err_printf clobbered stack");
-# if defined(OS2) || defined(MSWIN32) || defined(MACOS)
- GC_set_files();
- /* We hope this doesn't allocate */
- if (fwrite(buf, 1, strlen(buf), GC_stderr) != strlen(buf))
- ABORT("write to stderr failed");
- fflush(GC_stderr);
-# else
- if (WRITE(2, buf, strlen(buf)) < 0) ABORT("write to stderr failed");
-# endif
+ if (WRITE(GC_stderr, buf, strlen(buf)) < 0) ABORT("write to stderr failed");
}
void GC_err_puts(s)
char *s;
{
-# if defined(OS2) || defined(MSWIN32) || defined(MACOS)
- GC_set_files();
- /* We hope this doesn't allocate */
- if (fwrite(s, 1, strlen(s), GC_stderr) != strlen(s))
- ABORT("write to stderr failed");
- fflush(GC_stderr);
-# else
- if (WRITE(2, s, strlen(s)) < 0) ABORT("write to stderr failed");
-# endif
+ if (WRITE(GC_stderr, s, strlen(s)) < 0) ABORT("write to stderr failed");
+}
+
+# if defined(__STDC__) || defined(__cplusplus)
+ void GC_default_warn_proc(char *msg, GC_word arg)
+# else
+ void GC_default_warn_proc(msg, arg)
+ char *msg;
+ GC_word arg;
+# endif
+{
+ GC_err_printf1(msg, (unsigned long)arg);
}
+GC_warn_proc GC_current_warn_proc = GC_default_warn_proc;
+
+# if defined(__STDC__) || defined(__cplusplus)
+ GC_warn_proc GC_set_warn_proc(GC_warn_proc p)
+# else
+ GC_warn_proc GC_set_warn_proc(p)
+ GC_warn_proc p;
+# endif
+{
+ GC_warn_proc result;
+
+ LOCK();
+ result = GC_current_warn_proc;
+ GC_current_warn_proc = p;
+ UNLOCK();
+ return(result);
+}
+
+
#ifndef PCR
void GC_abort(msg)
char * msg;
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, November 4, 1994 4:23 pm PST */
+/* Boehm, February 10, 1995 1:14 pm PST */
# include "gc_priv.h"
# if !defined(OS2) && !defined(PCR) && !defined(AMIGA) && !defined(MACOS)
q = (LPVOID)(p - GC_get_page_size());
if ((ptr_t)q > (ptr_t)p /* underflow */ || q < limit) break;
result = VirtualQuery(q, &buf, sizeof(buf));
- if (result != sizeof(buf)) break;
+ if (result != sizeof(buf) || buf.AllocationBase == 0) break;
p = (ptr_t)(buf.AllocationBase);
}
return(p);
/* heap sections? */
bool GC_is_heap_base (ptr_t p)
{
- static ptr_t malloc_heap_pointer = 0;
+
register unsigned i;
- register DWORD result;
- if (malloc_heap_pointer = 0) {
- MEMORY_BASIC_INFORMATION buf;
- result = VirtualQuery(malloc(1), &buf, sizeof(buf));
- if (result != sizeof(buf)) {
- ABORT("Weird VirtualQuery result");
- }
- malloc_heap_pointer = (ptr_t)(buf.AllocationBase);
- }
- if (p == malloc_heap_pointer) return(TRUE);
+# ifndef REDIRECT_MALLOC
+ static ptr_t malloc_heap_pointer = 0;
+
+ if (0 == malloc_heap_pointer) {
+ MEMORY_BASIC_INFORMATION buf;
+ register DWORD result = VirtualQuery(malloc(1), &buf, sizeof(buf));
+
+ if (result != sizeof(buf)) {
+ ABORT("Weird VirtualQuery result");
+ }
+ malloc_heap_pointer = (ptr_t)(buf.AllocationBase);
+ }
+ if (p == malloc_heap_pointer) return(TRUE);
+# endif
for (i = 0; i < GC_n_heap_bases; i++) {
if (GC_heap_bases[i] == p) return(TRUE);
}
GetSystemInfo(&sysinfo);
while (p < sysinfo.lpMaximumApplicationAddress) {
result = VirtualQuery(p, &buf, sizeof(buf));
- if (result != sizeof(buf) || GC_is_heap_base(buf.AllocationBase)) break;
+ if (result != sizeof(buf) || buf.AllocationBase == 0
+ || GC_is_heap_base(buf.AllocationBase)) break;
new_limit = (char *)p + buf.RegionSize;
protect = buf.Protect;
if (buf.State == MEM_COMMIT
for (data = (ULONG *)BADDR(myseglist); data != 0;
data = (ULONG *)BADDR(data[0])) {
- GC_add_roots_inner((char *)&data[1], ((char *)&data[1]) + data[-1]);
+# ifdef AMIGA_SKIP_SEG
+ if (((ULONG) GC_register_data_segments < (ULONG) &data[1]) ||
+ ((ULONG) GC_register_data_segments > (ULONG) &data[1] + data[-1])) {
+# else
+ {
+# endif /* AMIGA_SKIP_SEG */
+ GC_add_roots_inner((char *)&data[1], ((char *)&data[1]) + data[-1]);
+ }
}
}
GC_proc_buf_size = new_size;
}
if (syscall(SYS_read, GC_proc_fd, bufp, GC_proc_buf_size) <= 0) {
- WARN("Insufficient space for /proc read\n");
+ WARN("Insufficient space for /proc read\n", 0);
/* Punt: */
memset(GC_grungy_pages, 0xff, sizeof (page_hash_table));
# ifdef SOLARIS_THREADS
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, September 20, 1994 11:51 am PDT */
+/* Boehm, January 30, 1995 4:05 pm PST */
#include "gc_priv.h"
#include "gc_mark.h"
retry:
switch(descr & DS_TAGS) {
case DS_LENGTH:
- if ((ptr_t)p - (ptr_t)base > (word)descr) goto fail;
+ if ((word)((ptr_t)p - (ptr_t)base) > (word)descr) goto fail;
break;
case DS_BITMAP:
if ((ptr_t)p - (ptr_t)base
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, June 13, 1994 6:22 pm PDT */
+/* Boehm, January 19, 1995 5:39 pm PST */
#include <stdio.h>
#include "gc_priv.h"
* Clear lists of blocks waiting to be reclaimed.
* Must be done before clearing mark bits with the world running,
* since otherwise a subsequent reclamation of block would see
- * the wrong mark bits.
+ * the wrong mark bits. (Alternatively, GC_reclaim_all
+ * may be used.)
* SHOULD PROBABLY BE INCREMENTAL
*/
void GC_reclaim_or_delete_all()
MS_TIME_DIFF(done_time,start_time));
# endif
}
+
+/*
+ * Reclaim all small blocks waiting to be reclaimed.
+ * Abort and return FALSE when/if (*stop_func)() returns TRUE.
+ * If this returns TRUE, then it's safe to restart the world
+ * with incorrectly cleared mark bits.
+ */
+bool GC_reclaim_all(stop_func)
+GC_stop_func stop_func;
+{
+ register word sz;
+ register int kind;
+ register hdr * hhdr;
+ register struct hblk * hbp;
+ register struct obj_kind * ok;
+ struct hblk ** rlp;
+ struct hblk ** rlh;
+# ifdef PRINTTIMES
+ CLOCK_TYPE start_time;
+ CLOCK_TYPE done_time;
+
+ GET_TIME(start_time);
+# endif
+
+ for (kind = 0; kind < GC_n_kinds; kind++) {
+ ok = &(GC_obj_kinds[kind]);
+ rlp = ok -> ok_reclaim_list;
+ if (rlp == 0) continue;
+ for (sz = 1; sz <= MAXOBJSZ; sz++) {
+ rlh = rlp + sz;
+ while ((hbp = *rlh) != 0) {
+ if ((*stop_func)()) return(FALSE);
+ hhdr = HDR(hbp);
+ *rlh = hhdr -> hb_next;
+ GC_reclaim_small_nonempty_block(hbp, FALSE);
+ }
+ }
+ }
+# ifdef PRINTTIMES
+ GET_TIME(done_time);
+ GC_printf1("Disposing of reclaim lists took %lu msecs\n",
+ MS_TIME_DIFF(done_time,start_time));
+# endif
+ return(TRUE);
+}
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, November 8, 1994 5:50 pm PST */
+/* Boehm, January 27, 1995 12:58 pm PST */
/* An incomplete test for the garbage collector. */
/* Some more obscure entry points are not tested at all. */
# endif
DCL_LOCK_STATE;
+# ifdef FIND_LEAK
+ (void)GC_printf0(
+ "This test program is not designed for leak detection mode\n");
+ (void)GC_printf0("Expect lots of problems.\n");
+# endif
if (GC_size(GC_malloc(7)) != 8
|| GC_size(GC_malloc(15)) != 16) {
(void)GC_printf0("GC_size produced unexpected results\n");
#endif
+#ifdef __STDC__
+ void warn_proc(char *msg, GC_word p)
+#else
+ void warn_proc(msg, p)
+ char *msg;
+ GC_word p;
+#endif
+{
+ GC_printf1(msg, (unsigned long)p);
+ FAIL;
+}
+
+
#if !defined(PCR) && !defined(SOLARIS_THREADS) || defined(LINT)
#ifdef MSWIN32
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int n)
printf("Testing GC Macintosh port.\n");
# endif
GC_INIT(); /* Only needed if gc is dynamic library. */
+ (void) GC_set_warn_proc(warn_proc);
# if defined(MPROTECT_VDB) || defined(PROC_VDB)
GC_enable_incremental();
(void) GC_printf0("Switched to incremental mode\n");
GC_debug_free, GC_debug_realloc, GC_generic_malloc_words_small,
GC_init, GC_make_closure, GC_debug_invoke_finalizer,
GC_page_was_ever_dirty, GC_is_fresh,
- GC_malloc_ignore_off_page, GC_malloc_atomic_ignore_off_page);
+ GC_malloc_ignore_off_page, GC_malloc_atomic_ignore_off_page,
+ GC_set_max_heap_size, GC_get_bytes_since_gc);
# endif
return(0);
}
n_tests = 0;
GC_enable_incremental();
+ (void) GC_set_warn_proc(warn_proc);
th1 = PCR_Th_Fork(run_one_test, 0);
th2 = PCR_Th_Fork(run_one_test, 0);
run_one_test();
n_tests = 0;
GC_INIT(); /* Only needed if gc is dynamic library. */
GC_enable_incremental();
+ (void) GC_set_warn_proc(warn_proc);
if (thr_keycreate(&fl_key, GC_free) != 0) {
(void)GC_printf1("Key creation failed %lu\n", (unsigned long)code);
FAIL;
granted, provided the above notices are retained, and a notice that
the code was modified is included with the above copyright notice.
****************************************************************************
+Last modified on Wed Jan 4 16:35:11 PST 1995 by ellis
+ modified on December 20, 1994 7:27 pm PST by boehm
-usage: test_gc_c++ number-of-iterations
+usage: test_cpp number-of-iterations
This program tries to test the specific C++ functionality provided by
gc_c++.h that isn't tested by the more general test routines of the
few minutes to complete.
***************************************************************************/
-/* Boehm, December 20, 1994 7:27 pm PST */
#include "gc_cpp.h"
#include <assert.h>
int i, iters, n;
if (argc != 2 || (0 >= (n = atoi( argv[ 1 ] )))) {
- fprintf( stderr, "usage: test_gc_c++ number-of-iterations\n" );
+ fprintf( stderr, "usage: test_cpp number-of-iterations\n" );
exit( 1 );}
for (iters = 1; iters <= n; iters++) {
check to make sure they've gone away. */
for (i = 0; i < 1000; i++) {
C* c = new C( 2 );
+ C c1( 2 ); /* stack allocation should work too */
D* d = ::new (GC, D::CleanUp, (void*) i) D( i );
if (0 == i % 10) delete c;}