gc4.4 tarball import gc4_4
authorHans Boehm <boehm@acm.org>
Sat, 18 Feb 1995 00:00:00 +0000 (00:00 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Sat, 17 May 2014 13:13:22 +0000 (17:13 +0400)
40 files changed:
BCC_MAKEFILE [new file with mode: 0644]
MacProjects.sit.hqx
Mac_files/MacOS_Test_config.h [new file with mode: 0644]
Mac_files/MacOS_config.h [new file with mode: 0644]
Mac_files/dataend.c [new file with mode: 0644]
Mac_files/datastart.c [new file with mode: 0644]
Makefile
NT_MAKEFILE
OS2_MAKEFILE
README
README.Mac
README.amiga
README.win32
SCoptions.amiga
SMakefile.amiga
allchblk.c
alloc.c
blacklst.c
checksums.c
config.h
cord/cord.h
cord/de.c
cord/de_win.c
cord/gc.h
finalize.c
gc.h
gc_cpp.h
gc_priv.h
include/cord.h
include/gc.h
include/gc_cpp.h
mach_dep.c
malloc.c
mark.c
misc.c
os_dep.c
ptr_chck.c
reclaim.c
test.c
test_cpp.cc

diff --git a/BCC_MAKEFILE b/BCC_MAKEFILE
new file mode 100644 (file)
index 0000000..63f0707
--- /dev/null
@@ -0,0 +1,81 @@
+# 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
index 65fc5a1..99dff88 100644 (file)
 (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:
+
diff --git a/Mac_files/MacOS_Test_config.h b/Mac_files/MacOS_Test_config.h
new file mode 100644 (file)
index 0000000..db24e0b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+       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.
diff --git a/Mac_files/MacOS_config.h b/Mac_files/MacOS_config.h
new file mode 100644 (file)
index 0000000..dd88516
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+       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.
diff --git a/Mac_files/dataend.c b/Mac_files/dataend.c
new file mode 100644 (file)
index 0000000..a3e3fe8
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+       dataend.c
+       
+       A hack to get the extent of global data for the Macintosh.
+       
+       by Patrick C. Beard.
+ */
+
+long __dataend;
diff --git a/Mac_files/datastart.c b/Mac_files/datastart.c
new file mode 100644 (file)
index 0000000..a9e0dd5
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+       datastart.c
+       
+       A hack to get the extent of global data for the Macintosh.
+       
+       by Patrick C. Beard.
+ */
+
+long __datastart;
index 5694728..aee1b11 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,23 +1,26 @@
 # 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.)
@@ -41,7 +44,18 @@ CFLAGS= -O -DSILENT -DALL_INTERIOR_POINTERS -DNO_SIGNALS
 # -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
 
@@ -62,7 +76,7 @@ CORD_OBJS=  cord/cordbscs.o cord/cordxtra.o cord/cordprnt.o
 
 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 \
@@ -70,7 +84,8 @@ OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE \
            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
@@ -122,18 +137,18 @@ cords: $(CORD_OBJS) cord/cordtest
        ./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 $@
@@ -193,8 +208,7 @@ if_not_there: $(srcdir)/if_not_there.c
        $(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 *~
@@ -214,11 +228,13 @@ setjmp_test: $(srcdir)/setjmp_t.c $(srcdir)/gc.h if_mach if_not_there
        ./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)
index cf01084..7c732c5 100644 (file)
@@ -9,7 +9,7 @@ OBJS= alloc.obj reclaim.obj allchblk.obj misc.obj mach_dep.obj os_dep.obj mark_r
 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
index ba6025d..a019c3e 100644 (file)
@@ -3,8 +3,7 @@
 # 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
 
@@ -20,20 +19,27 @@ all: $(OBJS) gctest.exe cord\cordtest.exe
 
 $(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
diff --git a/README b/README
index 4402054..16eab21 100644 (file)
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
 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.
@@ -10,7 +10,7 @@ Permission to modify the code and to distribute modified code is granted,
 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 -
 
@@ -273,13 +273,13 @@ following are likely to require change:
       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).
@@ -328,7 +328,7 @@ collector doesn't already understand them.)  On some machines, it may
 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
@@ -373,22 +373,18 @@ good way for the collector to compute this value.)  Client code may include
       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
@@ -439,7 +435,7 @@ THE C++ INTERFACE TO THE ALLOCATOR:
   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.
 
@@ -455,13 +451,16 @@ This is likely to result in disaster without linker warnings.
 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
@@ -480,7 +479,9 @@ to symbolic addresses.  It was largely supplied by Scott Schwartz.)
   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:
 
@@ -989,4 +990,57 @@ functionality not tested by the other programs.
   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.
index 612d234..180de7e 100644 (file)
@@ -1,54 +1,50 @@
 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
index e8345d4..865642b 100644 (file)
@@ -1,17 +1,53 @@
 
-[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
 
index 53d378e..7963aca 100644 (file)
@@ -3,12 +3,14 @@ is good reason to believe this is fixable.  (SRC M3 works with
 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
@@ -18,7 +20,7 @@ registrations are ignored, but not terribly quickly.)
 
 (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
@@ -37,3 +39,15 @@ characters are displayed explicitly, but in this case as red text.
 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.)
+
index 26fef04..a61e0cb 100644 (file)
@@ -1,6 +1,5 @@
 CPU=68030
 NOSTACKCHECK
-ERRORREXX
 OPTIMIZE
 VERBOSE
 MAPHUNK
@@ -8,5 +7,10 @@ NOVERSION
 NOICONS
 OPTIMIZERTIME
 DEFINE SILENT
+DEFINE AMIGA_SKIP_SEG
+IGNORE=85
+IGNORE=154
 IGNORE=161
 IGNORE=100
+OPTIMIZERCOMPLEXITY=4
+OPTIMIZERDEPTH=3
index 97c9b8e..40ca781 100644 (file)
@@ -1,4 +1,4 @@
-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
 
@@ -26,6 +26,7 @@ stubborn.o : stubborn.c $(INC)
 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)
index b8b9f89..ab0ccf7 100644 (file)
@@ -11,7 +11,7 @@
  * 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
@@ -110,7 +110,7 @@ struct hblk *
 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 */
@@ -164,6 +164,7 @@ unsigned char flags;
                 (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);
@@ -176,8 +177,8 @@ unsigned char flags;
              }
              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    */
@@ -191,6 +192,13 @@ unsigned char flags;
                      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) {
diff --git a/alloc.c b/alloc.c
index 1b7c4af..e58590a 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -12,7 +12,7 @@
  * 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"
@@ -65,7 +65,7 @@ int GC_full_freq = 4;    /* Every 5th collection is a full    */
 
 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."};
 
@@ -79,6 +79,29 @@ bool GC_dont_expand = 0;
 
 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()
@@ -179,7 +202,8 @@ void GC_maybe_gc()
             /* 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
@@ -190,10 +214,13 @@ void GC_maybe_gc()
     }
 }
 
+
 /*
  * 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(
@@ -202,15 +229,37 @@ void GC_gcollect_inner()
           (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.
@@ -234,7 +283,7 @@ int n;
 #              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;
            }
@@ -267,17 +316,17 @@ int GC_collect_a_little(NO_PARAMS)
  * 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",
@@ -291,23 +340,17 @@ bool final;
             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++;
@@ -456,8 +499,14 @@ void GC_finish_collection()
 }
 
 /* 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();
@@ -466,10 +515,16 @@ void GC_gcollect(NO_PARAMS)
     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. */
@@ -528,6 +583,12 @@ ptr_t x, y;
     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.
@@ -545,6 +606,11 @@ word n;
 
     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);
@@ -604,9 +670,6 @@ word needed_blocks;
     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)
@@ -622,14 +685,16 @@ word needed_blocks;
       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;
       }
     }
index 9c2fac8..c7836ea 100644 (file)
@@ -79,6 +79,12 @@ word *doomed;
     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()
@@ -96,6 +102,14 @@ 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.                                  */
index 5042057..da53263 100644 (file)
@@ -10,7 +10,7 @@
  * 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"
@@ -22,7 +22,7 @@
 /* safe under other conditions.)                                       */
 # define NSUMS 2000
 
-# define OFFSET 100000
+# define OFFSET 0x10000
 
 typedef struct {
        bool new_valid;
@@ -44,7 +44,7 @@ struct hblk *h;
     while (p < lim) {
         result += *p++;
     }
-    return(result);
+    return(result | 0x80000000 /* doesn't look like pointer */);
 }
 
 # ifdef STUBBORN_ALLOC
@@ -111,6 +111,43 @@ int index;
     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()
 {
@@ -119,6 +156,8 @@ 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;
index 1f844e6..2ccc774 100644 (file)
--- a/config.h
+++ b/config.h
@@ -11,7 +11,7 @@
  * 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;
index 405a051..8386962 100644 (file)
@@ -159,30 +159,30 @@ int CORD_riter(CORD x, CORD_iter_fn f1, void * client_data);
        
        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) \
index c561d29..20810c9 100644 (file)
--- a/cord/de.c
+++ b/cord/de.c
@@ -26,7 +26,7 @@
  *     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"
index 1356751..119d0fa 100644 (file)
@@ -10,7 +10,7 @@
  * 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.  
@@ -94,8 +94,8 @@ int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
    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);
index 1827162..9ebbfe4 100644 (file)
--- a/cord/gc.h
+++ b/cord/gc.h
@@ -11,7 +11,7 @@
  * 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
@@ -86,7 +86,7 @@ extern GC_word GC_free_space_divisor;
                        /* at the expense of space.                     */
                        /* GC_free_space_divisor = 1 will effectively   */
                        /* disable collections.                         */
-
+                       
                        
 /* Public procedures */
 /*
@@ -186,6 +186,11 @@ void GC_end_stubborn_change(/* p */);
 /* 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);
 
@@ -213,11 +218,29 @@ void GC_debug_register_displacement(/* GC_word n */);
 /* 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          */
@@ -414,8 +437,13 @@ void GC_debug_end_stubborn_change(/* p */);
 /* 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   */
@@ -434,7 +462,11 @@ int GC_register_disappearing_link(/* void ** link */);
        /* 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    */
@@ -452,7 +484,11 @@ int GC_general_register_disappearing_link(/* void ** link, void * obj */);
        /* 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.                                            */
@@ -467,6 +503,15 @@ int GC_unregister_disappearing_link(/* void ** link */);
     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    */
index 3102b28..cec1b56 100644 (file)
@@ -11,7 +11,7 @@
  * 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"
@@ -123,9 +123,12 @@ signed_word * log_size_ptr;
     *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;
     
@@ -135,9 +138,15 @@ extern_ptr_t * link;
     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;
@@ -199,8 +208,12 @@ extern_ptr_t obj;
     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;
@@ -503,11 +516,9 @@ void GC_finalize()
                    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);
             }
-            */
         }
         
       }
diff --git a/gc.h b/gc.h
index 1827162..9ebbfe4 100644 (file)
--- a/gc.h
+++ b/gc.h
@@ -11,7 +11,7 @@
  * 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
@@ -86,7 +86,7 @@ extern GC_word GC_free_space_divisor;
                        /* at the expense of space.                     */
                        /* GC_free_space_divisor = 1 will effectively   */
                        /* disable collections.                         */
-
+                       
                        
 /* Public procedures */
 /*
@@ -186,6 +186,11 @@ void GC_end_stubborn_change(/* p */);
 /* 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);
 
@@ -213,11 +218,29 @@ void GC_debug_register_displacement(/* GC_word n */);
 /* 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          */
@@ -414,8 +437,13 @@ void GC_debug_end_stubborn_change(/* p */);
 /* 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   */
@@ -434,7 +462,11 @@ int GC_register_disappearing_link(/* void ** link */);
        /* 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    */
@@ -452,7 +484,11 @@ int GC_general_register_disappearing_link(/* void ** link, void * obj */);
        /* 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.                                            */
@@ -467,6 +503,15 @@ int GC_unregister_disappearing_link(/* void ** link */);
     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    */
index 86ad2ec..14eccf3 100644 (file)
--- a/gc_cpp.h
+++ b/gc_cpp.h
@@ -16,7 +16,7 @@ the code was modified is included with the above copyright notice.
 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
@@ -125,6 +125,10 @@ for that to occur.
 #define _cdecl
 #endif
 
+#if __BORLANDC__ >= 0x450 && !defined(OPERATOR_NEW_ARRAY)
+#   define OPERATOR_NEW_ARRAY
+#endif
+
 enum GCPlacement {GC, NoGC};
 
 class gc {public:
@@ -228,9 +232,10 @@ inline void gc_cleanup::cleanup( void* obj, void* displ ) {
     ((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, 
index d4cf878..2750a33 100644 (file)
--- a/gc_priv.h
+++ b/gc_priv.h
@@ -11,7 +11,7 @@
  * 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
@@ -168,7 +168,7 @@ typedef char * ptr_t;       /* A generic pointer to which we can add        */
 #   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. */
@@ -207,6 +207,18 @@ typedef char * ptr_t;      /* A generic pointer to which we can add        */
 # 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   */
@@ -486,7 +498,8 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 # 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;
 
 /*********************************/
 /*                               */
@@ -707,6 +720,7 @@ struct hblk {
 
 struct _GC_arrays {
   word _heapsize;
+  word _max_heapsize;
   ptr_t _last_heap_addr;
   ptr_t _prev_heap_addr;
   word _words_allocd_before_gc;
@@ -849,6 +863,7 @@ extern GC_FAR struct _GC_arrays GC_arrays;
 # 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
@@ -977,6 +992,11 @@ void GC_apply_to_all_blocks(/*fn, client_data*/);
 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.                                   */
@@ -1063,6 +1083,10 @@ struct hblk * GC_is_black_listed(/* h, len */);
                        /* 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    */
@@ -1115,18 +1139,26 @@ void GC_reclaim_or_delete_all();
                                /* 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 */);
index 405a051..8386962 100644 (file)
@@ -159,30 +159,30 @@ int CORD_riter(CORD x, CORD_iter_fn f1, void * client_data);
        
        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) \
index 1827162..9ebbfe4 100644 (file)
@@ -11,7 +11,7 @@
  * 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
@@ -86,7 +86,7 @@ extern GC_word GC_free_space_divisor;
                        /* at the expense of space.                     */
                        /* GC_free_space_divisor = 1 will effectively   */
                        /* disable collections.                         */
-
+                       
                        
 /* Public procedures */
 /*
@@ -186,6 +186,11 @@ void GC_end_stubborn_change(/* p */);
 /* 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);
 
@@ -213,11 +218,29 @@ void GC_debug_register_displacement(/* GC_word n */);
 /* 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          */
@@ -414,8 +437,13 @@ void GC_debug_end_stubborn_change(/* p */);
 /* 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   */
@@ -434,7 +462,11 @@ int GC_register_disappearing_link(/* void ** link */);
        /* 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    */
@@ -452,7 +484,11 @@ int GC_general_register_disappearing_link(/* void ** link, void * obj */);
        /* 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.                                            */
@@ -467,6 +503,15 @@ int GC_unregister_disappearing_link(/* void ** link */);
     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    */
index a4b5b59..14eccf3 100644 (file)
@@ -16,7 +16,7 @@ the code was modified is included with the above copyright notice.
 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
@@ -105,10 +105,17 @@ The elements of "a" will not have their destructors invoked when the
 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.
 
 ****************************************************************************/
 
@@ -118,6 +125,10 @@ 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:
@@ -129,7 +140,7 @@ 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 
@@ -221,9 +232,10 @@ inline void gc_cleanup::cleanup( void* obj, void* displ ) {
     ((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, 
@@ -253,7 +265,7 @@ inline void* operator new[](
 {
     return ::operator new( size, gcp, cleanup, clientData );}
 
-#endif OPERATOR_NEW_ARRAY
+#endif /* OPERATOR_NEW_ARRAY */
 
 
 #endif /* GC_CPP_H */
index 29536d3..7c44de5 100644 (file)
@@ -122,7 +122,6 @@ void GC_push_regs()
 
 #       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));
@@ -312,7 +311,7 @@ void GC_push_regs()
       /* 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
index 72d934e..56caa48 100644 (file)
--- a/malloc.c
+++ b/malloc.c
@@ -11,7 +11,7 @@
  * 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"
@@ -375,6 +375,31 @@ DCL_LOCK_STATE;
    }
 }
 
+# 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)
@@ -527,6 +552,19 @@ int obj_kind;
     }
 }
 
+# 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)
@@ -558,7 +596,7 @@ int obj_kind;
        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));
        }
@@ -573,10 +611,21 @@ int obj_kind;
        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 */
diff --git a/mark.c b/mark.c
index 5fd7191..8fcd49f 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -1,7 +1,7 @@
 
 /*
  * 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.
@@ -362,6 +362,12 @@ register hdr * hhdr;
 #   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;
 {
@@ -421,7 +427,7 @@ void GC_mark_from_mark_stack()
                        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--;
@@ -903,7 +909,7 @@ register hdr * hhdr;
 #   undef GC_least_plausible_heap_addr        
 }
 
-#endif UNALIGNED
+#endif /* UNALIGNED */
 
 #endif /* SMALL_CONFIG */
 
diff --git a/misc.c b/misc.c
index 7a6b160..31e18c0 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -11,7 +11,7 @@
  * 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>
@@ -361,6 +361,11 @@ size_t GC_get_heap_size(NO_PARAMS)
     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()
@@ -532,29 +537,35 @@ out:
 # 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) {
@@ -566,10 +577,31 @@ out:
   }
 #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 */
@@ -588,15 +620,7 @@ long 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_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)
@@ -608,31 +632,45 @@ long 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;
index 5a5ca8b..0519bc5 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -10,7 +10,7 @@
  * 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)
@@ -604,7 +604,7 @@ void GC_register_data_segments()
        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);
@@ -614,19 +614,23 @@ void GC_register_data_segments()
   /* 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);
      }
@@ -648,7 +652,8 @@ void GC_register_data_segments()
       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
@@ -706,7 +711,14 @@ void GC_register_data_segments()
 
     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]);
+         }
     }
   }
 
@@ -1616,7 +1628,7 @@ int dummy;
                 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
index 834d013..65ac8d3 100644 (file)
@@ -10,7 +10,7 @@
  * 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"
@@ -249,7 +249,7 @@ void (*GC_is_visible_print_proc)() =
     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
index 2029227..2278a5a 100644 (file)
--- a/reclaim.c
+++ b/reclaim.c
@@ -11,7 +11,7 @@
  * 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"
@@ -665,7 +665,8 @@ int kind;
  * 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()
@@ -708,3 +709,48 @@ 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);
+}
diff --git a/test.c b/test.c
index 52152dc..48191be 100644 (file)
--- a/test.c
+++ b/test.c
@@ -11,7 +11,7 @@
  * 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.       */
 
@@ -648,6 +648,11 @@ void run_one_test()
 #   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");
@@ -785,6 +790,19 @@ void SetMinimumStack(long minSize)
 
 #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)
@@ -801,6 +819,7 @@ void SetMinimumStack(long minSize)
        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");
@@ -826,7 +845,8 @@ void SetMinimumStack(long minSize)
                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);
 }
@@ -841,6 +861,7 @@ test()
 
     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();
@@ -878,6 +899,7 @@ main()
     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;
index 9361f6f..f0615ea 100644 (file)
@@ -10,8 +10,10 @@ Permission to modify the code and to distribute modified code is
 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
@@ -21,7 +23,6 @@ A recommended value for number-of-iterations is 10, which will take a
 few minutes to complete.
 
 ***************************************************************************/
-/* Boehm, December 20, 1994 7:27 pm PST */
 
 #include "gc_cpp.h"
 #include <assert.h>
@@ -113,7 +114,7 @@ int main( int argc, char* argv[] ) {
     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++) {
@@ -132,6 +133,7 @@ int main( int argc, char* argv[] ) {
             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;}