Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Unity-Technologies/bdwgc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Chambers <joncham@gmail.com>2017-02-06 20:41:13 +0300
committerJonathan Chambers <joncham@gmail.com>2017-02-06 20:41:13 +0300
commit8ca017118a4669ac36051f193aad7c9ba13f8c8c (patch)
treef7a2810c66f9bbe717af71bafe784bf2471fcfe2
parent9379c66bccdf2b911a50cbb77e18c080dbead02a (diff)
Merge additional upstream changes from release-7_4unity-release-7_4-merge
-rw-r--r--.gitignore22
-rw-r--r--.travis.yml19
-rw-r--r--AUTHORS381
-rw-r--r--CMakeLists.txt42
-rw-r--r--ChangeLog1256
-rw-r--r--Makefile.am12
-rw-r--r--Makefile.direct85
-rw-r--r--Makefile.dj4
-rw-r--r--README.QUICK5
-rw-r--r--README.md29
-rw-r--r--TODO100
-rw-r--r--allchblk.c8
-rw-r--r--alloc.c44
-rw-r--r--appveyor.yml11
-rw-r--r--backgraph.c16
-rw-r--r--configure.ac50
-rw-r--r--cord/cord.am5
-rw-r--r--cord/cordbscs.c24
-rw-r--r--cord/cordprnt.c23
-rw-r--r--cord/cordxtra.c21
-rw-r--r--cord/tests/cordtest.c35
-rw-r--r--cord/tests/de.c69
-rw-r--r--cord/tests/de_win.c50
-rw-r--r--cord/tests/de_win.h6
-rw-r--r--darwin_stop_world.c19
-rw-r--r--dbg_mlc.c68
-rw-r--r--doc/README.DGUX3868
-rw-r--r--doc/README.Mac2
-rw-r--r--doc/README.cmake4
-rw-r--r--doc/README.cords3
-rw-r--r--doc/README.environment6
-rw-r--r--doc/README.ews48006
-rw-r--r--doc/README.macros13
-rw-r--r--doc/README.solaris22
-rw-r--r--doc/README.win329
-rw-r--r--doc/barrett_diagram106
-rw-r--r--doc/debugging.html2
-rw-r--r--doc/doc.am1
-rw-r--r--doc/gc.man6
-rw-r--r--doc/gcdescr.html25
-rw-r--r--doc/gcinterface.html2
-rw-r--r--doc/overview.html182
-rw-r--r--doc/porting.html2
-rw-r--r--doc/scale.html14
-rw-r--r--doc/simple_example.html16
-rw-r--r--doc/tree.html38
-rw-r--r--dyn_load.c171
-rw-r--r--extra/AmigaOS.c37
-rw-r--r--extra/MacOS.c21
-rw-r--r--extra/Mac_files/MacOS_config.h15
-rw-r--r--extra/gc.c2
-rw-r--r--extra/msvc_dbg.c11
-rw-r--r--finalize.c32
-rw-r--r--fnlz_mlc.c54
-rw-r--r--gc.mak323
-rw-r--r--gc_cpp.cc4
-rw-r--r--gcj_mlc.c11
-rw-r--r--headers.c21
-rw-r--r--ia64_save_regs_in_stack.s (renamed from src/ia64_save_regs_in_stack.s)0
-rw-r--r--include/cord.h4
-rw-r--r--include/gc.h77
-rw-r--r--include/gc_config_macros.h27
-rw-r--r--include/gc_cpp.h10
-rw-r--r--include/gc_inline.h49
-rw-r--r--include/gc_pthread_redirects.h54
-rw-r--r--include/gc_version.h2
-rw-r--r--include/include.am1
-rw-r--r--include/javaxfc.h2
-rw-r--r--include/leak_detector.h2
-rw-r--r--include/private/darwin_semaphore.h55
-rw-r--r--include/private/dbg_mlc.h4
-rw-r--r--include/private/gc_hdrs.h2
-rw-r--r--include/private/gc_locks.h14
-rw-r--r--include/private/gc_priv.h133
-rw-r--r--include/private/gcconfig.h171
-rw-r--r--include/private/thread_local_alloc.h2
-rw-r--r--mach_dep.c71
-rw-r--r--malloc.c57
-rw-r--r--mallocx.c133
-rw-r--r--mark.c134
-rw-r--r--mark_rts.c2
-rw-r--r--misc.c68
-rw-r--r--new_hblk.c12
-rw-r--r--obj_map.c6
-rw-r--r--os_dep.c279
-rw-r--r--pthread_stop_world.c48
-rw-r--r--pthread_support.c154
-rw-r--r--ptr_chck.c2
-rw-r--r--sparc_mach_dep.S (renamed from src/sparc_mach_dep.S)0
-rw-r--r--sparc_netbsd_mach_dep.s (renamed from src/sparc_netbsd_mach_dep.s)0
-rw-r--r--sparc_sunos4_mach_dep.s (renamed from src/sparc_sunos4_mach_dep.s)0
-rw-r--r--specific.c4
-rw-r--r--stubborn.c4
-rw-r--r--tests/CMakeLists.txt1
-rw-r--r--tests/disclaim_bench.c21
-rw-r--r--tests/disclaim_test.c1
-rw-r--r--tests/initsecondarythread.c1
-rw-r--r--tests/test.c53
-rw-r--r--tests/thread_leak_test.c1
-rw-r--r--tests/threadkey_test.c11
-rw-r--r--thread_local_alloc.c9
-rw-r--r--tools/if_not_there.c10
-rw-r--r--tools/setjmp_t.c16
-rw-r--r--typd_mlc.c93
-rw-r--r--win32_threads.c309
-rw-r--r--windows-untested/vc60/gc.dsp4
-rw-r--r--windows-untested/vc60/libgc.dsp4
-rw-r--r--windows-untested/vc60/libgcmt.dsp4
-rw-r--r--windows-untested/vc70/gc.vcproj4
-rw-r--r--windows-untested/vc70/libgc.vcproj4
-rw-r--r--windows-untested/vc70/libgcmt.vcproj4
-rw-r--r--windows-untested/vc71/gc.vcproj4
-rw-r--r--windows-untested/vc71/libgc.vcproj4
-rw-r--r--windows-untested/vc71/libgcmt.vcproj4
114 files changed, 3188 insertions, 2510 deletions
diff --git a/.gitignore b/.gitignore
index 14cdcae4..1b57c8b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
# Ignored files in bdwgc Git repo.
-# Binary files (in root dir, cord, src, tests):
+# Binary files (in root dir, cord, tests):
*.dll
*.exe
*.gcda
@@ -12,12 +12,12 @@
*.o
*.obj
+.dirstamp
/*.gc.log
/*_bench.log
/*_bench.trs
/*test.log
/*test.trs
-/.deps/
/.libs/
/Makefile
/add_gc_prefix
@@ -63,7 +63,8 @@
/threadlibs
/tracetest
-# Config and stamp files generated by configure:
+# Config, dependency and stamp files generated by configure:
+.deps/
config.h
config.h.in~
stamp-h1
@@ -107,18 +108,25 @@ stamp-h1
/tests/cmake_install.cmake
# Rarely generated files (mostly by some Win/DOS compilers):
-/*.bsc
+/*.copied.c
/*.csm
/*.err
-/*.exp
/*.lb1
/*.lnk
/*.map
/*.out
-/*.pdb
/*.rbj
/*.res
-/*.sbr
/*.stackdump
/*.sym
/*.tmp
+*.bsc
+*.dll.manifest
+*.exp
+*.idb
+*.ilk
+*.pdb
+*.sbr
+
+# Stuff from VS build system and IDE
+*.vcproj.*.user
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..23571047
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,19 @@
+language: c
+
+os:
+ - linux
+ - osx
+
+compiler:
+ - clang
+ - gcc
+
+sudo: false
+
+install:
+ - git clone --depth=50 https://github.com/ivmai/libatomic_ops.git -b release-7_4
+ - ./autogen.sh
+
+script:
+ - ./configure --enable-munmap
+ - make -j check
diff --git a/AUTHORS b/AUTHORS
index 05175bb0..2eb8825e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,6 @@
-This is an attempt to acknowledge early contributions to the garbage
-collector. Later contributions should be also mentioned in "git log".
+This is an attempt to acknowledge contributions to the garbage collector.
+Early contributions also mentioned (duplicated) in ChangeLog file; details of
+later ones should be in "git log".
HISTORY -
@@ -9,7 +10,7 @@ and the Defense Advance Research Projects Agency.
The garbage collector originated as part of the run-time system for
the Russell programming language implementation. The first version of the
-garbage collector was written primarily by Al Demers. It was then refined
+garbage collector was written primarily by Alan Demers. It was then refined
and mostly rewritten, primarily by Hans-J. Boehm, at Cornell U.,
the University of Washington, Rice University (where it was first used for
C and assembly code), Xerox PARC, SGI, and HP Labs. However, significant
@@ -19,321 +20,351 @@ Other contributors (my apologies for any omissions):
Adam Megacz <adam@megac.com>
Adnan Ali
-Adrian Bunk
-Akira Tagoh
-Alain Novak
+Adrian Bunk <bunk@fs.tum.de>
+Adrian Pop <adrian.pop@liu.se>
+Akira Tagoh <tagoh@redhat.com>
+Alain Novak <alain.novak@hermes.si>
Alan Dosser <dosser@src.dec.com>
Alan J. Demers <ademers@cs.cornell.edu>
-Aleksey Demakov
+Aleksey Demakov <ademakov@gmail.com>
Alexander Belchenko <bialix@ukr.net>
Alexander Gavrilov <angavrilov@gmail.com>
Alexander Herz <alexander.herz@mytum.de>
-Alexandr Petrosian
+Alexandr Petrosian <paf@design.ru>
Alexandr Shadchin <ShadchinAV@mail.ru>
+Alexandre Oliva <aoliva@redhat.com>
Alistair G. Crooks <agc@uts.amdahl.com>
Allan Hsu <allan@counterpop.net>
-Andre Leiradella
-Andreas Farber <afaerber@mono-cvs.ximian.com>
-Andreas Jaeger
+Andre Leiradella <andre@leiradella.com>
+Andreas Jaeger <aj@suse.de>
Andreas Tobler <a.tobler@schweiz.org>
-Andrei Polushin
+Andrei Polushin <polushin@gmail.com>
Andrej Cedilnik <acedil1@csee.umbc.edu>
-Andrew Begel
-Andrew Haley
-Andrew Pinski
-Andrew Stitcher
-Andrew Stone
+Andrew Begel <abegel@eecs.berkeley.edu>
+Andrew Buss <abuss@ucsd.edu>
+Andrew Gray <andrew.gray@anu.edu.au>
+Andrew Haley <aph@redhat.com>
+Andrew Horton <andrew.j.horton@gmail.com>
+Andrew McKinlay <mckinlay@axonsoft.com>
+Andrew Pinski <pinskia@physics.uc.edu>
+Andrew Stitcher <astitcher@redhat.com>
+Andrew Stone <andrew@stone.com>
+Andy Li <andy@onthewings.net>
Andy Wingo <wingo@pobox.com>
Anselm Baird-Smith <Anselm.BairdSmith@inria.fr>
-Anthony Green
+Anthony Green <green@redhat.com>
+Antoine de Maricourt
Ari Huttunen <Ari.Huttunen@hut.fi>
Arrigo Triulzi <arrigo@ic.ac.uk>
-Ashley Bone
+Ashley Bone <ashley.bone@nvl.army.mil>
Assar Westerlund <assar@sics.se>
-Barry DeFreese
+Barry DeFreese <bdefreese@debian.org>
+Baruch Siach <baruch@tkos.co.il>
Ben A. Mesander <ben@piglet.cr.usgs.gov>
-Ben Cottrell
-Ben Hutchings
+Ben Cottrell <tamino@wolfhut.org>
+Ben Hutchings <ben@decadentplace.org.uk>
Ben Maurer <benm@mono-cvs.ximian.com>
-Bernie Solomon
+Benjamin Lerman <Benjamin.Lerman@ambre.net>
+Bernd Edlinger <bernd.edlinger@hotmail.de>
+Bernie Solomon <bernard@mono-cvs.ximian.com>
Bill Janssen <janssen@parc.xerox.com>
-Bo Thorsen
+Bo Thorsen <bo@berlioz.suse.de>
Bradley D. LaRonde <brad@ltc.com>
Bradley Smith <brad@brad-smith.co.uk>
Brent Benson <brent@jade.ssd.csd.harris.com>
Brian Alliet <brian@brianweb.net>
Brian Beuning <bbeuning@corecard.com>
-Brian Burton
+Brian Burton <bburton@users.sourceforge.net>
Brian D. Carlstrom <bdc@clark.lcs.mit.edu>
Brian F. Dennis <xjam@cork.cs.berkeley.edu>
Brian Lewis <btlewis@eng.sun.com>
Bruce Hoult <bruce@hoult.org>
Bruce Mitchener <bruce.mitchener@gmail.com>
-Bryce McKinley
+Bruno Haible <bruno@clisp.org>
+Bryce McKinlay <mckinlay@redhat.com>
Burkhard Linke <blinke@cebitec.uni-bielefeld.de>
-Cesar Eduardo Barros
-Charles Mills
-Chris Dodd
-Chris Lingard
-Christian Joensson
-Christian Limpach
-Christian Thalinger
-Christoffe Raffali
+Carlos J. Puga Medina <cpm@fbsd.es>
+Cesar Eduardo Barros <cesarb@nitnet.com.br>
+Charles Fiterman <cef@geode.geodesic.com>
+Charles Mills <boson@cyberspace.org>
+Chris Dodd <chrisd@reservoir.com>
+Chris Lingard <chris@highludworth.freeserve.co.uk>
+Christian Joensson <christian.joensson@gmail.com>
+Christian Limpach <chris@pin.lu>
+Christian Thalinger <twisti@complang.tuwien.ac.at>
+Christoffe Raffali <christophe.raffalli@univ-savoie.fr>
Clay Spence <cds@peanut.sarnoff.com>
Colin LeMahieu <clemahieu@gmail.com>
-Craig McDaniel
-Dai Sato
-Dan Bonachea
-Dan Fandrich
-Dan Sullivan
+Craig McDaniel <kreg7@bellsouth.net>
+Dai Sato <satodai@dog.intcul.tohoku.ac.jp>
+Dan Bonachea <bonachea@cs.berkeley.edu>
+Dan Fandrich <dan@coneharvesters.com>
+Dan Sullivan <sullivan@epa.gov>
Daniel R. Grayson <dan@math.uiuc.edu>
-Danny Smith
-Darrell Schiebel
+Danny Smith <danny_r_smith_2001@yahoo.co.nz>
+Darrell Schiebel <drs@nrao.edu>
Dave Barrett <barrett@asgard.cs.colorado.edu>
Dave Detlefs <detlefs@src.dec.com>
-Dave Grove
Dave Korn <dave.korn.cygwin@googlemail.com>
-Dave Love
-David Ayers
+Dave Love <d.love@dl.ac.uk>
+David Ayers <d.ayers@inode.at>
+David Brownlee <abs@absd.org>
+David Butenhof <david.butenhof@hp.com>
+David Chase <dr2chase@mac.com>
David Daney <ddaney@avtrex.com>
-David Leonard
-David Miller
+David Grove <groved@us.ibm.com>
+David Leonard <leonard@users.sourceforge.net>
+David Miller <davem@davemloft.net>
David Mossberger
-David Peroutka
-David Pickens
-David Stes
-Davide Angelocola
-Dick Porter
+David Peroutka <djp@volny.cz>
+David Pickens <dsp@rci.rutgers.edu>
+David Stes <stes@d5e02b1d.kabel.telenet.be>
+David Van Horn <dvanhorn@ccs.neu.edu>
+Davide Angelocola <davide.angelocola@tiscali.it>
+Dick Porter <dick@acm.org>
Dietmar Planitzer <dave.pl@ping.at>
-Dimitris Vyzovitis
-Dimitry Andric
+Dimitris Vyzovitis <vyzo@media.mit.edu>
+Dimitry Andric <dim@freebsd.org>
Djamel Magri <djamel.magri@googlemail.com>
-Doug Kaufman
+Doug Kaufman <dkaufman@rahul.net>
+Doug Moen <doug@moens.org>
Douglas Steel <doug@wg.icl.co.uk>
+Eli Barzilay <eli@racket-lang.org>
Elijah Taylor <elijahtaylor@google.com>
Elvenlord Elrond <elrond@samba-tng.org>
Emmanual Stumpf
+Eric Benson <eb@kaleida.com>
Eric Holk <eric.holk@gmail.com>
Fabian Thylman
-Fergus Henderson
+Fergus Henderson <fjh@cs.mu.oz.au>
Franklin Chen <chen@adi.com>
+Fred Gilham <gilham@csl.sri.com>
Fred Stearns
Friedrich Dominicus <friedrichdominicus@googlemail.com>
+Gabor Drescher <gabor.drescher@cs.fau.de>
Gary Leavens <leavens@eecs.ucf.edu>
Geoff Norton <grompf@sublimeintervention.com>
George Talbot <Gtalbot@ansarisbio.com>
Gerard A Allan
-Glauco Masotti
-Gonzalo Paniagua Javier <gonzalo.mono@gmail.com>
+Glauco Masotti <glauco.masotti@libero.it>
Grzegorz Jakacki <jakacki@acm.org>
-Gustavo Rodriguez-Rivera
+Gustavo Rodriguez-Rivera <grr@cs.purdue.edu>
H.J. Lu <hjl.tools@gmail.com>
-Hanno Boeck
-Hans Boehm <hans.boehm@hp.com>
+Hannes Mehnert <hannes@mehnert.org>
+Hanno Boeck <hanno@gentoo.org>
+Hans Boehm <boehm@acm.org>
Hans-Peter Nilsson <hp@gcc.gnu.org>
-Harris NightHawk
Henning Makholm <Henning@octoshape.com>
-Henrik Theiling
+Henrik Theiling <theiling@absint.com>
Hironori Sakamoto <hsaka@mth.biglobe.ne.jp>
-Hiroshi Kawashima
+Hiroshi Kawashima <kei@arch.sony.co.jp>
+Hubert Garavel <Hubert.Garavel@imag.fr>
Iain Sandoe <developer@sandoe-acoustics.co.uk>
-Ian Piumarta
-Ian Searle
-Igor Khavkine
+Ian Piumarta <piumarta@prof.inria.fr>
+Ian Searle <ians@eskimo.com>
+Igor Khavkine <i_khavki@alcor.concordia.ca>
Ivan Demakov <ivan@tgrad.nsk.su>
Ivan Maidanski <ivmai@mail.ru>
-Jaap Boender
+Jaap Boender <jaapb@netbsd.org>
Jack Andrews <effbiae@gmail.com>
-Jack Howarth <howarth@bromo.med.uc.edu>
-Jacob Navia
-Jakub Jelinek
+Jacob Navia <jacob.navia@jacob.remcomp.fr>
+Jakub Jelinek <jakub@redhat.com>
James Clark <jjc@jclark.com>
James Dominy
+Jan Alexander Steffens <jan.steffens@gmail.com>
Jan Wielemaker <J.Wielemaker@cs.vu.nl>
-Jani Kajala
+Jani Kajala <jani@sumea.com>
Jean-Baptiste Nivois
Jean-Claude Beaudoin <jean.claude.beaudoin@gmail.com>
-Jean-Daniel Fekete
-Jeff Sturm
+Jean-Daniel Fekete <fekete@cs.umd.edu>
+Jeff Sturm <jsturm@one-point.com>
Jeffrey Hsu <hsu@soda.berkeley.edu>
Jeffrey Mark Siskind
-Jeffrey Stedfast <fejj@gnome.org>
-Jeremy Fitzhardinge
+Jeremy Fitzhardinge <jeremy@goop.org>
Jesper Peterson <jep@mtiame.mtia.oz.au>
Jesse Hull
-Jesse Jones
-Jesse Rosenstock
+Jesse Jones <jesjones@mindspring.com>
+Jesse Rosenstock <jmr@ugcs.caltech.edu>
Ji-Yong Chung
Jie Liu <lj8175@gmail.com>
Jim Marshall <jim.marshall@wbemsolutions.com>
Jim Meyering <jim@meyering.net>
-Joerg Sonnenberger
-Johannes Schmidt
+Joerg Sonnenberger <joerg@britannica.bec.de>
+Johannes Schmidt <jschmidt@avtrex.com>
Johannes Totz <jtotz@ic.ac.uk>
-John Bowman
-John Clements
-John Ellis
-John Merryweather Cooper
-Jon Moore
+John Bowman <bowman@ualberta.ca>
+John Clements <clements@brinkerhoff.org>
+John Ellis <ellis@xerox.parc.com>
+John Merryweather Cooper <jmerry@mono-cvs.ximian.com>
+Jon Moore <jonm@apache.org>
Jonathan Bachrach <jonathan@harlequin.com>
-Jonathan Chambers <joncham@gmail.com>
Jonathan Clark
Jonathan Pryor <jpryor@novell.com>
Juan Jose Garcia-Ripoll <juanjose.garciaripoll@googlemail.com>
Kai Tietz <ktietz70@googlemail.com>
-Kazu Hirata
-Kazuhiro Inaoka
-Keith Seitz <keiths@redhat.com>
-Kenjiro Taura
-Kenneth Schalk
+Kaz Kojima <kkojima@rr.iij4u.or.jp>
+Kazu Hirata <kazu@codesourcery.com>
+Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+Kenjiro Taura <tau@eidos.ic.i.u-tokyo.ac.jp>
+Kenneth Schalk <schalk@cadtls.hlo.dec.com>
Kevin Kenny <kenny@m.cs.uiuc.edu>
Kevin Tew <tewk@racket-lang.org>
-Kjetil S. Matheussen <ksvalast@ifi.uio.no>
+Kevin Warne <kevinw@direct.ca>
+Kjetil Matheussen <k.s.matheussen@notam02.no>
Klaus Treichel <ktreichel@web.de>
Knut Tvedten <knuttv@ifi.uio.no>
-Kornel Pal <kornelpal@gmail.com>
-Koushik Dutta <koushd@gmail.com>
-Krister Walfridsson
-Kristian Kristensen
+Krister Walfridsson <cato@df.lth.se>
+Kristian Kristensen <kk@cs.aau.dk>
+Kumar Srikantan
Kurt Miller <kurt@intricatesoftware.com>
Lars Farm <lars.farm@ite.mh.se>
-Laurent Morichetti
+Laurent Morichetti <l_m@pacbell.net>
Linas Vepstas <linasvepstas@gmail.com>
Loren J. Rittle <rittle@latour.labs.mot.com>
Louis Zhuang <louis.zhuang@acm.org>
Ludovic Courtes <ludo@gnu.org>
+Maarten Thibaut <mthibaut@cisco.com>
Manuel Serrano <serrano@cornas.inria.fr>
-Marc Recht
-Marco Maggi
-Marcos Dione
+Marc Recht <recht@netbsd.org>
+Marco Maggi <marco.maggi-ipsu@poste.it>
+Marcos Dione <Marcos_David.Dione@sophia.inria.fr>
Marcus Herbert
-Marek Safar <marek.safar@gmail.com>
Margaret Fleck <mfleck@illinois.edu>
Mark Boulter <mboulter@vnet.ibm.com>
-Mark Mitchell
-Mark Probst <mark.probst@gmail.com>
-Mark Reichert
+Mark Mitchell <mark@codesourcery.com>
+Mark Reichert <markr@sirs.com>
Mark Sibly
Mark Weiser <weiser@ubiq.com>
-Martin Baulig <martin@novell.com>
+Martin Hirzel <hirzel@cs.colorado.edu>
Martin Tauchmann <martintauchmann@bigfoot.com>
-Massimiliano Mantione <massi@mono-cvs.ximian.com>
-Matt Austern
-Matthew Flatt
-Matthias Andree
-Matthias Drochner
-Maurizio Vairani
+Matt Austern <austern@google.com>
+Matthew Flatt <mflatt@plt-scheme.org>
+Matthias Andree <matthias.andree@gmx.de>
+Matthias Drochner <M.Drochner@fz-juelich.de>
+Maurizio Vairani <maurizio.vairani@cloverinformatica.it>
+Melissa O'Neill <oneill@cs.sfu.ca>
Michael Arnoldus <chime@proinf.dk>
-Michael Smith
-Michael Spertus
+Michael Smith <msmith@spinnakernet.com>
+Michael Spertus <mps@geodesic.com>
Michel Schinz <schinz@alphanet.ch>
Miguel de Icaza <miguel@gnome.org>
Mike Gran <spk121@yahoo.com>
Mike McGaughey <mmcg@cs.monash.edu.au>
Mike Stump <mrs@windriver.com>
Mitch Harris <maharri@uiuc.edu>
-Mohan Embar
-Nathanael Nerode
+Mohan Embar <gnustuff@thisiscool.com>
+Nathanael Nerode <neroden@twcny.rr.com>
Neale Ferguson <neale@mono-cvs.ximian.com>
Neil Sharman <neil@cs.mu.oz.au>
-Nicolas Cannasse
+Nicolas Cannasse <ncannasse@motion-twin.com>
Niibe Yutaka <gniibe@fsij.org>
Niklas Therning <niklas@therning.org>
Noah Lavine <noah.b.lavine@gmail.com>
+Nobuyuki Hikichi <hikichi@sra.co.jp>
Oliver Kurth <oliver.kurth@innominate.com>
Ondrej Bilka <neleai@seznam.cz>
Paolo Molaro <lupus@ximian.com>
Parag Patel <parag@netcom.com>
-Patrick Bridges
+Patrick Bridges <bridges@cs.arizona.edu>
Patrick C. Beard <beard@netscape.com>
-Patrick Doyle
-Patrick Marlier <patrick.marlier@gmail.com>
-Paul Brook
-Peter Chubb
-Peter Colson
-Peter Housel
-Peter Monks
-Peter Ross
+Patrick Doyle <doylep@eecg.toronto.edu>
+Paul Brook <paul@codesourcery.com>
+Paul Graham
+Paul Nash <paulnash@wildseed.com>
+Per Bothner <per@bothner.com>
+Peter Bigot <bigotp@acm.org>
+Peter Chubb <peterc@sour.sw.oz.au>
+Peter Colson <pcolson@connexus.net.au>
+Peter Housel <housel@acm.org>
+Peter Monks <pmonks@iname.com>
+Peter Ross <pro@missioncriticalit.com>
Peter Seebach <seebs@taniemarie.solon.com>
-Peter Wang
+Peter Wang <novalazy@gmail.com>
Petr Krajca <krajcap@inf.upol.cz>
-Petr Salinger
+Petr Salinger <Petr.Salinger@seznam.cz>
Petter Urkedal <paurkedal@gmail.com>
-Philipp Tomsich
-Philippe Queinnec
-Phillip Musumeci
-Philp Brown
+Philip Brown <phil@opencsw.org>
+Philipp Tomsich <phil@complang.tuwien.ac.at>
+Philippe Queinnec <queinnec@enseeiht.fr>
+Phillip Musumeci <p.musumeci@ieee.org>
+Phong Vo <kpv@research.att.com>
Pierre de Rop
-Radek Polak
+Pontus Rydin <P.Rydin@astea.se>
+Radek Polak <psonek2@seznam.cz>
Rainer Orth <ro@cebitec.uni-bielefeld.de>
-Raja R Harinath <harinath@hurrynot.org>
-Rauli Ruohonen
+Ranjit Mathew <rmathew@gcc.gnu.org>
+Rauli Ruohonen <rruohone@cc.hut.fi>
Regis Cridlig <Regis.Cridlig@cl.cam.ac.uk>
Reimer Behrends <behrends@gmail.com>
Renaud Blanch <renaud.blanch@lri.fr>
Rene Girard
Rex Dieter <rdieter@math.unl.edu>
Reza Shahidi
-Richard Earnshaw
+Richard Earnshaw <rearnsha@arm.com>
+Richard Henderson <rth@redhat.com>
Richard Sandiford <rsandifo@nildram.co.uk>
Rob Haack <rhaack@polaris.unm.edu>
Robert Brazile <brazile@diamond.bbn.com>
-Robert Jordan <robertj@gmx.net>
-Robert Nagy <robert@openbsd.org>
-Rodrigo Kumpera <kumpera@gmail.com>
-Roger Sayle
-Roman Hodek
+Roger Sayle <roger@eyesopen.com>
+Roland McGrath <roland@redhat.com>
+Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
Romano Paolo Tenca <rotenca@telvia.it>
-Russell Ruby <russ@sludge.net>
-Rutger Ovidus
-Ryan Murray
-Salvador Eduardo Tropea
-Samuel Thibault
-Scott Ananian
+Rutger Ovidius <ovidr@users.sourceforge.net>
+Ryan Murray <rmurray@debian.org>
+Salvador Eduardo Tropea <salvador@inti.gov.ar>
+Samuel Thibault <samuel.thibault@gnu.org>
+Scott Ananian <cananian@lesser-magoo.lcs.mit.edu>
Scott Schwartz <schwartz@groucho.cse.psu.edu>
-Sebastien Pouliot <sebastien@ximian.com>
-Shawn Wagner
-Simon Posnjak
-Slava Sysoltev
-Stefan Ring
+Shawn Wagner <shawnw@speakeasy.org>
+Shiro Kawai <shiro@lava.net>
+Simon Gornall <simon@gornall.net>
+Simon Posnjak <simon.posnjak@siol.net>
+Slava Sysoltsev <Viatcheslav.Sysoltsev@h-d-gmbh.de>
+Stefan Ring <stefanrin@gmail.com>
Stefano Rivera <stefano@rivera.za.net>
-Sugioka Toshinobu
-Suzuki Toshiya
-Sven Hartrumpf
-Sven Verdoolaege
-Tagliapietra Tommaso
+Sugioka Toshinobu <sugioka@itonet.co.jp>
+Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
+Sven Hartrumpf <Sven.Hartrumpf@fernuni-hagen.de>
+Sven Verdoolaege <skimo@kotnet.org>
Takis Psarogiannakopoulos <takis@xfree86.org>
-Tatsuya Bizenn
+Tatsuya Bizenn <bizenn@visha.org>
+Terrell Russell <terrellrussell@gmail.com>
Thiemo Seufer <ths@networkno.de>
Thomas Funke <thf@zelator.in-berlin.de>
Thomas Klausner <tk@giga.or.at>
-Thomas Maier
+Thomas Maier <Thomas.Maier@uni-kassel.de>
+Thomas Schwinge <thomas@codesourcery.com>
Thorsten Glaser <tg@debian.org>
Tilman Vogel <Tilman.Vogel@web.de>
-Tim Bingham
-Timothy N. Newsham
-Todd Berman <tberman@mono-cvs.ximian.com>
+Tim Bingham <tjb@zko.dec.com>
+Timothy N. Newsham <newsham@wiliki.eng.hawaii.edu>
Tom Tromey <tromey@cygnus.com>
-Toralf Foerster
-Toshio Endo
+Tommaso Tagliapietra <tommaso.tagliapietra@enel.it>
+Toralf Foerster <toralf.foerster@gmx.de>
+Toshio Endo <endo@is.titech.ac.jp>
Tsugutomo Enami <tsugutomo.enami@jp.sony.com>
-Tum Nguyen
-Tyson Dowd
-Uchiyama Yasushi
-Ulrich Drepper
-Ulrich Weigand
+Tum Nguyen <tum@veridicus.com>
+Tyson Dowd <trd@cs.mu.oz.au>
+Uchiyama Yasushi <uch@netbsd.org>
+Ulrich Drepper <drepper@redhat.com>
+Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Uros Bizjak <ubizjak@gmail.com>
-Victor Ivrii
+Vernon Lee <scorpion@rice.edu>
+Victor Ivrii <ivrii@math.toronto.edu>
Vitaly Magerya <vmagerya@gmail.com>
-Vladimir Tsichevski
-Walter Bright
-Walter Underwood
-Wilson Ho
-Wink Saville
+Vladimir Tsichevski <wowa@jet.msk.su>
+Walter Bright <walter@walterbright.com>
+Walter Underwood <wunder@hp-ses.sde.hp.com>
+Wilson Ho <how@ivy.ucdavis.edu>
+Wink Saville <wink@saville.com>
Xi Wang <xi.wang@gmail.com>
Xiaokun Zhu <xiaokun@aero.gla.ac.uk>
-Yannis Bres
+Yann Dirson <dirson@debian.org>
+Yannis Bres <Yannis@bres.name>
+Yuki Okumura <mjt@cltn.org>
+Yusuke Suzuki <utatane.tea@gmail.com>
Yvan Roux <yvan.roux@linaro.org>
Zach Saw <zach.saw@gmail.com>
-Zhong Shao
+Zhiying Chen
+Zhong Shao <zhong.shao@yale.edu>
Zoltan Varga <vargaz@gmail.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a19cabb4..0c17a068 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,13 +25,17 @@ SET(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
PROJECT(gc)
+INCLUDE(CTest)
+
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
ADD_DEFINITIONS("-D_CRT_SECURE_NO_DEPRECATE
-DALL_INTERIOR_POINTERS")
IF(APPLE)
- SET(CMAKE_OSX_ARCHITECTURES "ppc;i386;x86_64" CACHE STRING "Build architectures for Mac OS X" FORCE)
+ IF("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
+ SET(CMAKE_OSX_ARCHITECTURES "ppc;i386;x86_64" CACHE STRING "Build architectures for Mac OS X" FORCE)
+ ENDIF()
ENDIF(APPLE)
#LIBATOMIC #TODO
@@ -80,7 +84,7 @@ MESSAGE("HOST = ${HOST}")
#TODO check cmake detection
IF(CMAKE_USE_PTHREADS_INIT)
SET(SRC ${SRC} pthread_start.c pthread_support.c pthread_stop_world.c)
- IF( "HOST" MATCHES x86-.*-linux.*|ia64-.*-linux.*|i586-.*-linux.*|i686-.*-linux.*|x86_64-.*-linux.*|alpha-.*-linux.*|sparc.*-.*-linux.*)
+ IF( HOST MATCHES x86-.*-linux.*|ia64-.*-linux.*|i586-.*-linux.*|i686-.*-linux.*|x86_64-.*-linux.*|alpha-.*-linux.*|sparc.*-.*-linux.*)
ADD_DEFINITIONS("-DGC_LINUX_THREADS")
ADD_DEFINITIONS("-D_REENTRANT")
IF (${enable_parallel_mark})
@@ -89,15 +93,15 @@ IF(CMAKE_USE_PTHREADS_INIT)
ADD_DEFINITIONS("-DTHREAD_LOCAL_ALLOC")
MESSAGE("Explicit GC_INIT() calls may be required.")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-linux.*)
+ IF ( HOST MATCHES .*-.*-linux.*)
ADD_DEFINITIONS("-DGC_LINUX_THREADS")
ADD_DEFINITIONS("-D_REENTRANT")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-aix.*)
+ IF ( HOST MATCHES .*-.*-aix.*)
ADD_DEFINITIONS("-DGC_AIX_THREADS")
ADD_DEFINITIONS("-D_REENTRANT")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-hpux11.*)
+ IF ( HOST MATCHES .*-.*-hpux11.*)
MESSAGE("Only HP/UX 11 POSIX threads are supported.")
ADD_DEFINITIONS("-DGC_HPUX_THREADS")
ADD_DEFINITIONS("-D_POSIX_C_SOURCE=199506L") #TODO test -DVAR=value. Alternative is COMPILE_DEFINITIONS property
@@ -107,37 +111,37 @@ IF(CMAKE_USE_PTHREADS_INIT)
MESSAGE("Explicit GC_INIT() calls may be required.")
ADD_DEFINITIONS("-D_REENTRANT") #TODO
ENDIF()
- IF ( "HOST" MATCHES .*-.*-hpux10.*)
+ IF ( HOST MATCHES .*-.*-hpux10.*)
MESSAGE("Only HP/UX 11 POSIX threads are supported.")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-openbsd.*)
+ IF ( HOST MATCHES .*-.*-openbsd.*)
ADD_DEFINITIONS("-DGC_OPENBSD_THREADS")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-freebsd.*)
+ IF ( HOST MATCHES .*-.*-freebsd.*)
MESSAGE("FreeBSD does not yet fully support threads with Boehm GC.")
ADD_DEFINITIONS("-DGC_FREEBSD_THREADS")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-kfreebsd.*-gnu)
+ IF ( HOST MATCHES .*-.*-kfreebsd.*-gnu)
ADD_DEFINITIONS("-DGC_FREEBSD_THREADS")
ADD_DEFINITIONS("-D_REENTRANT")
IF (${enable_parallel_mark})
ADD_DEFINITIONS("-DPARALLEL_MARK")
ENDIF()
- ADD_DEFINITIONS(THREAD_LOCAL_ALLOC")
- ADD_DEFINITIONS(USE_COMPILER_TLS")
+ ADD_DEFINITIONS("-DTHREAD_LOCAL_ALLOC")
+ ADD_DEFINITIONS("-DUSE_COMPILER_TLS")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-gnu.*)
+ IF ( HOST MATCHES .*-.*-gnu.*)
ADD_DEFINITIONS("-DGC_GNU_THREADS")
ADD_DEFINITIONS("-D_REENTRANT")
ADD_DEFINITIONS("-DTHREAD_LOCAL_ALLOC")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-netbsd.*)
+ IF ( HOST MATCHES .*-.*-netbsd.*)
MESSAGE("Only on NetBSD 2.0 or later.")
ADD_DEFINITIONS("-DGC_NETBSD_THREADS")
ADD_DEFINITIONS("-D_REENTRANT")
ADD_DEFINITIONS("-D_PTHREADS")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-solaris.*)
+ IF ( HOST MATCHES .*-.*-solaris.*)
ADD_DEFINITIONS("-DGC_SOLARIS_THREADS")
ADD_DEFINITIONS("-DTHREAD_LOCAL_ALLOC")
#TODO
@@ -147,10 +151,10 @@ IF(CMAKE_USE_PTHREADS_INIT)
# fi
ENDIF()
- IF ( "HOST" MATCHES .*-.*-irix.*)
+ IF ( HOST MATCHES .*-.*-irix.*)
ADD_DEFINITIONS("-DGC_IRIX_THREADS")
ENDIF()
- IF ( "HOST" MATCHES .*-.*-cygwin.*)
+ IF ( HOST MATCHES .*-.*-cygwin.*)
ADD_DEFINITIONS("-DGC_THREADS")
IF (${enable_parallel_mark})
ADD_DEFINITIONS("-DPARALLEL_MARK")
@@ -160,7 +164,7 @@ IF(CMAKE_USE_PTHREADS_INIT)
#TODO
# win32_threads=true
ENDIF()
- IF ( "HOST" MATCHES .*-.*-darwin.*)
+ IF ( HOST MATCHES .*-.*-darwin.*)
ADD_DEFINITIONS("-DGC_DARWIN_THREADS")
ADD_DEFINITIONS("-DTHREAD_LOCAL_ALLOC")
MESSAGE("Explicit GC_INIT() calls may be required.")
@@ -171,7 +175,7 @@ IF(CMAKE_USE_PTHREADS_INIT)
#TODO
#darwin_threads=true
ENDIF()
- IF ( "HOST" MATCHES .*-.*-osf*)
+ IF ( HOST MATCHES .*-.*-osf*)
ADD_DEFINITIONS("-DGC_OSF1_THREADS")
IF (${enable_parallel_mark})
ADD_DEFINITIONS("-DPARALLEL_MARK")
@@ -181,7 +185,7 @@ IF(CMAKE_USE_PTHREADS_INIT)
# Measurements haven't yet been done.
ENDIF()
ENDIF()
- IF ( "HOST" MATCHES .*-.*-linux.*)
+ IF ( HOST MATCHES .*-.*-linux.*)
ADD_DEFINITIONS("-DGC_LINUX_THREADS")
ADD_DEFINITIONS("-D_REENTRANT")
ENDIF()
diff --git a/ChangeLog b/ChangeLog
index 24483ed5..ad84781d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,132 @@
+== [7.4.6] (unset) ==
+
+* Adjust GC_memalign comment.
+* Do not define amiga_get_mem, MacTemporaryNewPtr unless really used (extra).
+* Do not warn of missing PT_GNU_RELRO segment when custom DSO filter used.
+* Eliminate 'cast to void* from int' compiler warnings (Darwin/x64).
+* Eliminate 'FP divide-by-zero' static analyzer warning.
+* Eliminate 'ISO C forbids an empty translation unit' GCC pedantic warning.
+* Eliminate 'null dereference' code defect warning in register_finalizer.
+* Eliminate 'printf format specifier mismatch' compiler warning (tools).
+* Eliminate 'value stored is never read' warning of Clang static analyzer.
+* Eliminate duplicate log messages in GC_mark_from.
+* Fix 'arg parameter might be clobbered by setjmp' compiler warning.
+* Fix 'GetVersion deprecated' compiler warning in os_dep (MS VC).
+* Fix 'incompatible pointer' compiler warning in GC_init_dyld (OS X 64-bit).
+* Fix 'incompatible ptr-to-int conversion' compiler warning in push_all_stack.
+* Fix 'ISO C90 does not support %lf, %lg gnu_printf formats' GCC warnings.
+* Fix 'ISO C90 forbids mixed declarations and code' compiler warning.
+* Fix 'replacement operator delete cannot be inline' GCC warning (Cygwin).
+* Fix 'variable unused' compiler warning in FirstDLOpenedLinkMap.
+* Fix GC_bytes_allocd incrementation in case of allocation failure.
+* Fix GC_jmp_buf multiple definition.
+* Fix initsecondarythread_test runtime failure if GC compiled w/o threads.
+* Fix local variable declarations in disclaim_bench.
+* Fix missing #error pragma.
+* Fix missing new-line and redundant trailing dot in WARN messages.
+* Fix potential overflow in decrement when computing GC_markers_m1.
+* Fix printf format specifiers in extra files (cppcheck warnings).
+* Fix register_finalizer call in disclaim_bench for GC_DEBUG.
+* Fix tag collision between ENABLE_DISCLAIM and KEEP_BACK_PTRS.
+* Fix threaded tests runtime crash if GC_NO_THREAD_REDIRECTS supplied.
+* Fix tools/setjmp_t to prevent nested_sp inlining.
+* Fix typo in CHECK_GCLIB_VERSION name (test).
+* Fix unchecked fork() result in gctest (Unix, Cygwin).
+* Process all PT_LOAD segments before PT_GNU_RELRO segments (Glibc).
+* Refine README about library source downloading.
+* Replace C++ style comments to C ones, remove commented out code (extra).
+* Workaround 'mmap() resource handle leak' static analyzer warning.
+* Workaround 'resource leak' error reported by cppcheck (tools, test).
+Also, includes 7.2h changes.
+
+
+== [7.4.4] 2016-05-25 ==
+
+* Allow GC_FAST_MALLOC_GRANS() multiple use in a function.
+* Also enable the TSX workaround for i386 (Linux).
+* Avoid unstructured procfs on Solaris.
+* Change cord/de main() declaration style from K-R to ANSI C.
+* Change no-argument functions declaration style to ANSI C (cord).
+* Do not include sigcontext.h and asm/sigcontext.h.
+* Eliminate 'divide by zero' compiler warning in cordtest.
+* Eliminate warning about 64-bit pointer-to-int cast (Win64/pthreads-w32).
+* Eliminate warnings detected by Cppcheck in cord de[_win].
+* Fix 'comparison of non-null parameter is always false' warning (Clang).
+* Fix 'CORD_iter5 unused result' code defect in cordxtra.
+* Fix 'GC_generic_malloc_inner_ignore_off_page not used' compiler warning.
+* Fix 'implicit declaration of vsnprintf' GCC warning (if strict ANSI mode).
+* Fix 'signed-to-bigger-unsigned value assignment' in GC_init_size_map.
+* Fix 'signed-to-bigger-unsigned value assignment' warning for hb_map.
+* Fix 'signed-to-bigger-unsigned value assignment' warning in GC_setpagesize.
+* Fix 'statement unreachable' compiler warning in GC_mark_from.
+* Fix 'statement unreachable' compiler warning in memalign.
+* Fix 'unused label' compiler warning in cord/de.
+* Fix 'value truncated' compiler warning in CORD_cat (MS VC).
+* Fix 'variable unused' warning in GC_save_callers.
+* Fix 'visibility attribute not supported' GCC warning (IBM AIX).
+* Fix CMake warning about CMP0054 by unquoting instances of HOST.
+* Fix Cygwin64 build.
+* Fix GC_REALLOC to call GC_FREE if new size is zero and pointer is non-NULL.
+* Fix Makefile.direct for Cygwin.
+* Fix __alloc_size__ availability detection (Clang).
+* Fix abort message in GC_move_long_link.
+* Fix and code refactoring of lock elision workaround (Linux/x64).
+* Fix assertion on mark_lock_holder for non-unique NUMERIC_THREAD_ID.
+* Fix data race in GC_init_explicit_typing.
+* Fix gc.mak regarding msvc_dbg and test (MSVC).
+* Fix missing error handling of pthread_attr_init/getstacksize.
+* Fix missing error handling of pthreads_mutex_init and cond_wait.
+* Fix missing numeric casts in cord.
+* Fix potential left shift overflows in finalize.c (64-bit targets).
+* Fix pthreads-win32 name in comments and documentation.
+* Fix setup_mark_lock missing prototype.
+* Fix unchecked fcntl() result.
+* Fix unchecked pointer dereference in check_ints (gctest).
+* Fix unchecked pthread_join() result in threadkey_test.
+* Fix unchecked sigdelset() result in pthread_support.
+* Fix undefined PTRFREE/NORMAL in gc_inline.h.
+* Prefix PREFETCH_FOR_WRITE with GC_ as used in gc_inline.h public header.
+* Relax mark_mutex attribute needed to disable elision (Linux/x64).
+* Remove (deprecate) TODO file.
+* Remove code duplication in GC_realloc.
+* Remove duplicate new-line in OUT_OF_MEMORY message (cord).
+* Remove references to missing linux_threads.c from documentation.
+* Revert "Move asm machine-dependent files to 'src' folder" (partly).
+* Support Android API level 21.
+* Update compiler options in gc.mak (Win32).
+* Use mmap instead of sbrk (Hurd).
+* Workaround 'comparison is always false' GCC warning in GC_FAST_MALLOC_GRANS.
+* Workaround 'identical expr on both sides of bitwise op' warning.
+* Workaround Linux NTPL lock elision bug.
+* Workaround false warning about unreachable code path.
+* Workaround invalid '_end' symbol on Android clang 3.5+.
+Also, includes 7.2g changes.
+
+
+== [7.4.2] 2014-06-03 ==
+
+* Add config option to use STGRTMIN-based signals for thread suspend/resume.
+* Allow parallel mark to be enabled on powerpc-linux systems.
+* Check for Fujitsu compiler in builtin_unwind logic (enable FX10/K-Computer).
+* Fix 'Array subscript is above array bounds' GCC warning in GC_new_kind/proc.
+* Fix 'attribute declaration must precede definition' warning (clang-3.1).
+* Fix (enable) Cygwin-64 build.
+* Fix GC_finalized_malloc failure on disclaim_test.
+* Fix GC_sig_suspend initialization when non-constant SIGRTMIN used.
+* Fix MS VC redefinition warning for functions declared with GC_ATTR_MALLOC.
+* Fix TEXT() usage for concatenated strings in GC_CreateLogFile (Win32).
+* Fix data roots registration for Android/x86 and NDK ARM 'gold' linker.
+* Fix find stackbottom on BlueGene P/Q systems.
+* Fix machdep .lo files path in configure (SPARC, IA-64).
+* Fix ok_init assignment (missing cast) in GC_new_kind_inner.
+* Fix typos in names in AUTHORS and ChangeLog files.
+* Remove barrett_diagram file duplicated by tree.html.
+* Remove non-existing DISCARD_WORDS from GC data structure ASCII diagram.
+* Restore contribution information for ancient releases in ChangeLog.
+Also, includes 7.2f changes.
+
+
== [7.4.0] 2013-11-17 ==
* Add 'bytes reclaimed' counters to public GC_prof_stats_s.
@@ -148,6 +276,7 @@
* Use pthread API to operate thread-local data on Linux if no compiler TLS.
* Workaround 'ELF_DATA/EM_ALPHA redefined' warning in Android linker.h.
* Workaround 'unresolved __tls_get_addr' error for Android NDK Clang.
+Also, includes 7.2e, 7.2d, 7.2c, 7.2b changes.
== [7.3alpha2] 2012-05-11 ==
@@ -157,7 +286,7 @@
* Add GC_get_thr_restart_signal, GC_thread_is_registered to GC API.
* Add GC_is_heap_ptr, GC_move_disappearing_link to GC API.
* Add SHORT_DBG_HDRS macro template to configure.
-* Add Symbian port to mainline.
+* Add Symbian port to mainline (porting done by Djamel Magri).
* Add TODO file.
* Add assertion ensuring proper alignment of 'pushed' GC symbols.
* Add assertion in GC_getspecific on qtid.
@@ -240,6 +369,94 @@
* Use USE_COMPILER_TLS on Cygwin.
* Use pthread_key for thread-local storage on FreeBSD.
* Use union of AO_t and word to favor strict-aliasing compiler optimization.
+Also, includes 7.2 changes.
+
+
+== [7.2h] (unset) ==
+
+* Add gctest as a test (CMake).
+* Change no-argument functions declaration style to ANSI C (extra files).
+* Do not allow SHORT_DBG_HDRS if KEEP_BACK_PTRS or MAKE_BACK_GRAPH.
+* Ensure oom_fn callback executed on out-of-memory in calloc.
+* Fix 'shift count >= width of type' compiler warning in GC_SQRT_SIZE_MAX.
+* Fix assertion in GC_mark_from for non-heap regions.
+* Fix assertion violation in GC_repeat_read if --enable-redirect-malloc.
+* Fix assertion violation in GC_wait_builder called from start_mark_threads.
+* Fix assertion violation in mark_local checking GC_mark_stack_top.
+* Fix calloc_explicitly_typed in case of lb*n overflow.
+* Fix conditional expression in pos_fetch, next non-macro definitions (cord).
+* Fix CORD_substr_closure for the case when CORD_from_fn returns C string.
+* Fix double multiplication of lb by n in calloc_explicitly_typed.
+* Fix GC_collect_or_expand to prevent allocation size value wrap-around.
+* Fix GC_requested_heapsize increment in GC_init.
+* Fix header filename in gcconfig.h comment.
+* Fix integer shift undefined behavior in GC_init_explicit_typing.
+* Fix malloc routines to prevent size value wrap-around (fix CVE-2016-9427).
+* Fix potential integer overflow in GC_find_limit_* functions.
+* Fix Solaris/sparc detection in case of strict C compliance is enforced.
+* Fix STACKBOTTOM for Solaris 11/x86.
+* Fix typo in comment of GC_lock (Win32).
+* Fix various typos in comments and documentation.
+* Handle load_segs overflow in register_dynlib_callback gracefully.
+* Replace (fix) 'objs' acronym in comments with 'objects' word.
+* Workaround a bug in winpthreads causing parallel marks deadlock (MinGW).
+* Workaround missing getcontext() in Docker osrf/ubuntu_32bit.
+
+
+== [7.2g] 2016-05-23 ==
+
+* Fix 'illegal option -xassembler-with-cpp' error (Oracle SunCC).
+* Fix 'implicit declaration of function' compiler warnings in cord/de.
+* Fix CFLAGS in configure regarding -O flag passing to SunCC compiler.
+* Fix FirstDLOpenedLinkMap for case libgc not 1st dynamically linked (NetBSD).
+* Fix GC initialization in cord de_win for Cygwin.
+* Fix GC_get_stack_base if called before GC_init (Win32).
+* Fix OSX issue with pthread_attr_setstacksize failure.
+* Fix Unicode Win32 API calls in cord de_win.
+* Fix USE_COMPILER_TLS macro duplicate description in README.
+* Fix cord de_win WndProc prototype parameters for 64-bit (Win64).
+* Fix file descriptor resource leak in GC_register_data_segments (OS/2).
+* Fix filename printing in cordtest.
+* Fix missing cord_pos.h, ec.h among installed headers (Automake).
+* Fix missing GC_get_stack_base for Amiga.
+* Fix missing msvc_dbg.h in dist_noinst_HEADERS (Automake).
+* Fix mistyped ARM_THREAD_STATE macro (Darwin/arm).
+* Fix null-pointer dereferences on out-of-memory in cord and tests.
+* Fix potential multiplication overflow in check_heap_stats (gctest).
+* Fix race (and potential deadlock) at marker threads initialization.
+* Fix signedness of char values passed to isspace, iscntrl, isxdigit.
+* Fix typo (items numbering) in GC_finalize_all documentation.
+* Fix typos in ERROR_FL, GC_malloc_uncollectable comments.
+* Fix typos in gc_priv.h, in README for ews4800.
+* Fix unresolved vsnprintf in misc.c and snprintf in cordtest (DJGPP, VC).
+* Fix various spelling errors.
+* Fix vsprintf_args initialization/cleanup in CORD_vsprintf for EMX.
+* Regenerate configure files using official libtool release (v2.4.2).
+* Remove documentation about obsolete GC_REDIRECT_TO_LOCAL.
+* Skip GC_DS_PER_OBJECT objects with negative descriptor in GC_mark_from.
+* windows-untested: Fix paths to msvc_dbg.c/h.
+
+
+== [7.2f] 2014-06-03 ==
+
+* Fix 'Bad signal in suspend_handler' abort on FreeBSD-9.2.
+* Fix 'source file in a subdirectory' Automake warnings.
+* Fix ABORT message in GC_restart_handler.
+* Fix ADD_DEFINITION in CMakeLists.txt for kFreeBSD.
+* Fix CMakeLists.txt: do not override CMAKE_OSX_ARCHITECTURES.
+* Fix GC_alloc_large by bumping GC_collect_at_heapsize in GC_add_to_heap.
+* Fix GC_scratch_last_end_ptr update on GC_scratch_alloc failure.
+* Fix GET_MEM argument rounding in GC_scratch_alloc and similar.
+* Fix PARALLEL_MARK for Windows 7+.
+* Fix build (broken by fenv.h inclusion) on Linux/x86_64 under uClibc.
+* Fix crash when using GC_malloc_many() as first allocation call.
+* Fix mark stack excessive growth during parallel mark.
+* Fix or remove broken URLs in documentation.
+* Fix out-of-memory case in new_back_edges, push_in_progress (backgraph).
+* Fix typo in GC_collect_or_expand comment.
+* Fix typos in GC overview file, gc_config_macros.h, gc_cpp.h, README.changes.
+* Regenerate configure files by automake 1.14.1, libtool 2.4.2.418.
+* Update emails/links due to project site and ML transition.
== [7.2e] 2013-11-10 ==
@@ -5484,7 +5701,7 @@ value, would be negative.
* mark.c (GC_push_next_marked): correct comment.
* Makefile.direct: document NO_PROC_STAT.
-* include/private/gcconfig.h: Accomodate NO_PROC_STAT.
+* include/private/gcconfig.h: Accommodate NO_PROC_STAT.
== [7.1alpha2] 2008-01-10 ==
@@ -5576,7 +5793,7 @@ for HURD.
* dbg_mlc.c: Use random() on all glibc systems.
* mach_dep.c (GC_with_callee_saves_pushed): Don't use getcontext() on
HURD. Add comment.
-* pthread_stop_world.c (GC_suspend_handler, GC_stop_init): Accomodate
+* pthread_stop_world.c (GC_suspend_handler, GC_stop_init): Accommodate
systems without SA_SIGINFO.
* include/gc.h (GC_PTR_STORE): Fix non-DEBUG parentheses.
@@ -5712,7 +5929,7 @@ GC_WIN32_PTHREADS. Define USE_PTHREAD_LOCKS only if we have
pthreads.
* gc_dlopen.c, thread_local_alloc.c, threadlibs.c, win32_threads.c,
-tests/test.c: Accomodate GC_WIN32_PTHREADS.
+tests/test.c: Accommodate GC_WIN32_PTHREADS.
* include/gc.h: Don't include windows.h for GC_WIN32_PTHREADS.
* include/gc_config_macros.h: Define both PTHREADS and
GC_WIN32_THREADS.
@@ -5760,10 +5977,13 @@ value.
* Some gc6.9 changes.
* Change FindTopOfStack decl in darwin_stop_world.c.
* Move some static tests from misc.c to gcconfig.h. Use #error.
-* Add GC_print_free_list() function.
-* Add GC_GNU_THREADS support on HURD.
-* __GNUC__ was misspelled as __GNUC in thread_local_alloc.h.
-* Integrated various MacOSX patches and tried to reconcile them.
+* Add GC_print_free_list() function (thanks to Bruce Hoult).
+* Add GC_GNU_THREADS support on HURD (thanks to Aleksey Demakov,
+Barry DeFreese, and possibly other Debian maintainers).
+* __GNUC__ was misspelled as __GNUC in thread_local_alloc.h (thanks to
+Peter Wang).
+* Integrated various MacOSX patches and tried to reconcile them (thanks to
+Allan Hsu, several contributors at Apple, and probably others).
* Added some casts to powerpc.h in libatomic_ops to silence warnings.
* Makefile.am: Include NT_STSTIC_THREADS_MAKEFILE in dist.
@@ -5884,11 +6104,12 @@ x86_EXCEPTION_STATE32_*. Add X86_64 for exc_state.faultvaddr.
* More 6.7 changes.
* Declare GC_dump() in gc.h.
* Add --enable-large-config, which just defines the LARGE_CONFIG macro.
-* Make GlobalAlloc address alignment a bit more intuitive.
+* Make GlobalAlloc address alignment a bit more intuitive (thanks to
+Charles Mills).
* Use #elif in the definitions of GET_MEM.
* Overhaul porting.html. Remove corresponding text from README.
* Fix typo in DARWIN section of gcconfig.h.
-* Fix Darwin thread memory leak.
+* Fix Darwin thread memory leak (thanks to Bruce Mitchener).
* Update x86 AO_test_and_set implementation to use "=q".
* Add $(EXEEXT) to many tests in tests/tests.am. (Corresponds to a
6.7 fix, which no longer applied.)
@@ -5924,9 +6145,10 @@ and then switching to mmap if that fails.
* Fix REDIRECT_MALLOC with threads on Linux. It now usually seems to work
with ugly hacks that include having calloc behave differently when it is
called from ld.so or the pthreads library. A reasonable amount of
-infrastructure was added to support some of this.
+infrastructure was added to support some of this. (Thanks to Roland McGrath
+for ideas and information.)
* Import various updated build scripts.
-* Add GC_register_has_static_roots_callback.
+* Add GC_register_has_static_roots_callback (thanks to Andrew Haley).
* Fix serious bugs in GC_malloc_atomic_uncollectable().
* Return GC_SUCCESS form GC_get_stack_base().
* Fix several atomic_ops problems on IA64 with HP Compiler.
@@ -5936,7 +6158,7 @@ infrastructure was added to support some of this.
* Enable GC_ASSERTIONS for Debug build with NT_THREADS_MAKEFILE.
-== [7.0alpha5] ==
+== [7.0alpha5] 2005-09-29 ==
* More 6.6, 6.7 changes.
* Some Solaris fixes, including some more general changes in how
@@ -5975,11 +6197,12 @@ be there to deal with other Windows variants, But non-Cygwin Windows
threads need more bug fixes.
-== [7.0alpha4] ==
+== [7.0alpha4] 2005-08-02 ==
* Various 6.5, 6.6 changes.
-* Removed GC_brief_async_signal_safe_sleep and used atomic_ops instead.
-* Integrated build patches from David Angelocola and Petter Urkedal.
+* Removed GC_brief_async_signal_safe_sleep and used atomic_ops instead
+(thanks to Ben Maurer).
+* Integrated build patches from Davide Angelocola and Petter Urkedal.
* Fix dynamic-linker-based pthread call redirection.
* Renamed RS6000 to POWERPC/AIX.
* Allow recovery from SIGSEGV in marker on Linux. This works around
@@ -5995,18 +6218,19 @@ memory overwrite errors.
beginning of win32 support for that.
-== [7.0alpha3] ==
+== [7.0alpha3] 2005-04-28 ==
* Added support for dlopen-based interception of pthread functions.
This is only half done. The gc.h redefinitions currently interfere.
* Integrated major automake overhaul from Petter Urkedal.
-== [7.0alpha2] ==
+== [7.0alpha2] 2005-04-07 ==
* GC_bytes_allocd was incremented by a possibly uninitialized variable
-in GC_generic_malloc_inner. (Bug introduced in gc7.0alpha1.)
-* Win32 fixes.
+in GC_generic_malloc_inner. (Bug introduced in gc7.0alpha1. Thanks
+to Ben Hutchings for tracking it down.)
+* Win32 fixes (thanks to Ben Hutchings and Maurizio Vairani).
* Integrated Ben Hutchings' GetWriteWatch-based virtual dirty bit
implementation for win32.
* Removed pc_gc.tar and floppy targets in Makefile.direct. Removed
@@ -6049,7 +6273,7 @@ redefines GC_malloc.
* Various minor fixes for bugs introduced in 7.0alpha1.
-== [7.0alpha1] ==
+== [7.0alpha1] 2004-11-09 ==
* Remove GC_PROTO, VOLATILE, GC_PTR, and GC_CONST. Assume ANSI C compiler
and use ANSI constructs unconditionally.
@@ -6130,75 +6354,90 @@ in anticipation of a merge with the inline allocation code.
== [6.9] ==
-* Fix typo in PREFETCH implementation for X86_64.
-* Fix M68K LINUX port.
-* __GNUC__ was misspelled as __GNUC in new_gc_alloc.h.
+* Fix typo in PREFETCH implementation for X86_64 (thanks to Peter Wang).
+* Fix M68K LINUX port (thanks to Debian packagers).
+* __GNUC__ was misspelled as __GNUC in new_gc_alloc.h (thanks to Peter Wang).
* Integrated Allan Hsu's patch for OS X VM deallocation problems.
* Applied FreeBSD/X86_64 patch.
-== [6.8] ==
+== [6.8] 2006-07-08 ==
-* Added some support for Dragonfly BSD.
-* Improvements to the HP/UX section of configure.in/configure.ac.
+* Added some support for Dragonfly BSD (thanks to Joerg Sonnenberger and
+Thomas Klausner).
+* Improvements to the HP/UX section of configure.in/configure.ac (thanks
+to Andreas Tobler).
* GC_unix_get_mem could neglect to release the malloc lock on Irix, under
-extremely unlikely circumstances.
-* Added support for kFreeBSD + glibc
-* Fix more MacOS threads memory leaks
-* Added initial Solaris/X86-64 support
+extremely unlikely circumstances. (Thanks to Jean-Baptiste Nivois for
+some careful code inspection.)
+* Added support for kFreeBSD + glibc (thanks to Petr Salinger).
+* Fix more MacOS threads memory leaks (thanks to Allan Hsu).
+* Added initial Solaris/X86-64 support (thanks to Rainer Orth).
-== [6.7] ==
+== [6.7] 2006-03-03 ==
* Add "int" to Solaris "end" and "etext" declaration in gc.h. Declared
the symbols with underscores and as arrays, since that's what's actually
-used. Perhaps this could all just be removed.
-* Fixed ARM GC_test_and_set code.
+used. Perhaps this could all just be removed. (Thanks to John Bowman.)
+* Fixed ARM GC_test_and_set code (thanks to Kazu Hirata and Paul Brook).
* Added casts for assignments to hb_last_reclaimed, which truncate the
value. Added a cast to GC_adj_words_allocd. Use GetModuleHandleA
when retrieving a handle to kernel32.dll under win32.
-* Added Tandem S-Series support.
-* Remove spurious gc:: qualifier for operator delete[] in gc_cpp.h.
+* Added Tandem S-Series support. (Thanks to Craig McDaniel. A modified
+version of his patch was applied, and hence breakage is probably not
+his fault.)
+* Remove spurious gc:: qualifier for operator delete[] in gc_cpp.h (thanks
+to Hanno Boeck).
* Changed a test for LINUX in config_macros.h to one for __linux__.
-* Add prototypes for GC_finalizer_notifier and GC_thr_init.
-* Use ld instead of nonexistent ldz instruction in Darwin FindTopOfStack.
-* Add support for Darwin/X86.
-* Merge in some recent gcc fixes. Add ppc64 asm code.
+* Add prototypes for GC_finalizer_notifier and GC_thr_init (thanks to
+David Ayers).
+* Use ld instead of nonexistent ldz instruction in Darwin FindTopOfStack
+(thanks to Andreas Tobler).
+* Add support for Darwin/X86 (thanks to Geoff Norton and the Mono
+developers).
+* Merge in some recent gcc fixes. Add ppc64 asm code. (Thanks to
+Bryce McKinlay and other GCJ developers.)
* Scan MEM_PRIVATE sections under Windows ME and predecessors.
* Interior pointers with some largish offsets into large objects could
be ignored, if GC_all_interior_pointers was set. (Oddly this worked
correctly for stack references if it was not set. Otherwise it failed
-for both stack and heap references.)
+for both stack and heap references. Thanks to Andrew McKinlay for the
+critical test case.)
* Integrated Tatsuya Bizenn's NETBSD threads support, with some
untested changes.
* Added GC_strdup and friends to make leak detection work correctly
-for strdup clients. Fixed the existing strdup
+for strdup clients (thanks to Jon Moore). Fixed the existing strdup
with malloc redirection to handle a null malloc return correctly.
-== [6.6] ==
+== [6.6] 2005-09-09 ==
-* Fix CPU count detection for Irix and FreeBSD.
+* Fix CPU count detection for Irix and FreeBSD (thanks to Dan Bonachea).
* Integrate Dan Bonachea's patch for the IBM XLC compiler on Darwin.
* Integrated Andreas Tobler's FreeBSD/PowerPC patch.
* Don't access the GC thread structure from the restart handler. It's
-unsafe, since the handler may run too late.
+unsafe, since the handler may run too late. (Thanks to Ben Maurer for
+tracking this down.)
* Applied Christian Thalinger's patch to change comment syntax in
alpha_mach_dep.S.
-* Added test for GC_no_dls in GC_dyld_image_add for DARWIN.
-* Use LINUX_STACKBOTTOM for Linux/SH and LINUX/ARM.
+* Added test for GC_no_dls in GC_dyld_image_add for DARWIN (thanks to
+Juan Jose Garcia-Ripoll).
+* Use LINUX_STACKBOTTOM for Linux/SH and LINUX/ARM (thanks to
+Sugioka Toshinobu and Christian Thalinger).
* Rewrote GC_parse_map_entry. This assumed a fixed column layout of
/proc/self/maps on Linux. This ceased to be true about 2 years ago.
The old code is probably quite problematic with -DREDIRECT_MALLOC. It
is also used by default for IA64, though I haven't seen actual failures
there.
* More consistently define HBLKSIZE to 4096 on 64 bit architectures with
-4K pages.
-* With win32 threads, GC_stop_world needs to acquire GC_write_cs.
-* Move up struct callinfo declaration to make gcc 4.0.2. happy.
+4K pages (thanks to Andrew Haley).
+* With win32 threads, GC_stop_world needs to acquire GC_write_cs (thanks
+to Ben Hutchings for the observation and patch).
+* Move up struct callinfo declaration to make gcc 4.0.2 happy.
-== [6.5] ==
+== [6.5] 2005-05-22 ==
* Integrated Paolo Molaro's patch to deal with EINTR in sem_wait.
* Make GC_approx_sp() write to dummy location to ensure that stack
@@ -6218,13 +6457,14 @@ from Andreas Tobler, which I had lost.
pickier compiler versions.
* Fixed Itanium 32-bit ABI support (HP/UX). In particular, the
compare_and_exchange implementation didn't consider that possibility.
-* Undefine GC_pthread_detach in win32_threads.c.
+* Undefine GC_pthread_detach in win32_threads.c (thanks to
+Tommaso Tagliapietra).
* Fixed inclusion of frame.h for NETBSD in os_dep.c.
* Applied Dan Bonachea's patch to use mmap on AIX.
* Several fixes to resurrect the Irix port on recent OS versions.
* Change ALPHA to use LINUX_STACKBOTTOM.
* Change SPARC64/LINUX to also use LINUX_STACKBOTTOM. Deal with potential
-bad values of __libc_stack_end on that platform.
+bad values of __libc_stack_end on that platform (thanks to David Miller).
* Relax gctest to allow larger heap if ALIGN_DOUBLE isn't set.
(Unnecessary in 7.0)
* Force a define of __STDC__=0 for the IBM compiler on AIX, so that
@@ -6239,7 +6479,8 @@ support. This may need additional work.
the system backtrace calls malloc. The workaround currently requires
__thread support if this code is used with threads.
* Avoided another similar infinite recursion by conditionally
-invoking GC_save_callers in alloc.c.
+invoking GC_save_callers in alloc.c (thanks to Matthias Andree
+for helping to track down both of these).
* Removed all traces of aix_irix_threads.c. AIX and Irix now use
pthread_support.c and pthread_stop_world.c. The old code appeared
to be unreliable for AIX, and was not regularly maintained.
@@ -6251,7 +6492,7 @@ in GC_remove_from_fl.
* Fix assertion in GC_steal_mark_stack.
-== [6.4] ==
+== [6.4] 2004-12-21 ==
* Merge gcconfig.h changes from gcc tree.
* Unconditionally include gc_priv.h in solaris_pthreads.c, win32_threads.h,
@@ -6260,28 +6501,34 @@ aix_irix_threads.c, and solaris_threads.c to get thread definitions.
if no other threads are ever started. (Oddly enough, the parallel
collector worked correctly, though not well, with no helper threads.)
* Go ahead and split large blocks in GC_allochblk_nth if GC_dont_gc
-is set.
+is set (thanks to Alexander Petrossian).
* GC_PRINT_BACK_HEIGHT would deadlock with thread support.
* Let in_progress_space in backgraph.s grow dynamically.
* Fix README.solaris2. The GC_thr_init() hack doesn't work anymore.
* Convert GC_finalizer_mem_freed to bytes in allchblk.c.
* Add missing declaration for GC_generic_malloc_words_small_inner.
-Without it, s390x breaks.
-* Applied several MacOSX patches to support older tool chains.
-* Bug fix for NetBSD/amd64. Add NetBSD/sh3 support.
+Without it, s390x breaks. (Thanks to Ulrich Weigand.)
+* Applied several MacOSX patches to support older tool chains (thanks
+to Stefan Ring).
+* Bug fix for NetBSD/amd64 (thanks to Marc Recht).
+* Add NetBSD/sh3 support (thanks to Uchiyama Yasushi).
* Fixed an uninitialized variable in cordprnt.c.
* Eliminated some, but not all, gcc -Wall warnings.
-* Changed some old style casts to reinterpret_cast in new_gc_alloc.h.
+* Changed some old style casts to reinterpret_cast in new_gc_alloc.h
+(thanks to Dan Grayson).
* GC_extend_size_map shouldn't adjust for GC_all_interior_pointers if
GC_DONT_ADD_BYTE_AT_END is set.
-* Changed some (long) casts to (word) in preparation for win64.
+* Changed some (long) casts to (word) in preparation for win64 (thanks
+to Peter Colson).
* Changed "int stack_size" declaration in pthread_support.c to use
size_t. (Only mattered with GC_ASSERTIONS enabled.)
-* Added CRIS (etrax) support.
+* Added CRIS (etrax) support (thanks to Simon Posnjak and Hans-Peter Nilsson).
* Removed GC_IGNORE_FB frame buffer recognition, and replaced
it with a check that the mapping type is MEM_IMAGE.
In theory, this should work much better, but it is a high
-risk change for win32.
+risk change for win32. (Thanks to Ashley Bone for the crucial
+experimental data behind this, and to Rutger Ovidius for
+some further experiments.)
* GC_allochblk_nth incremented GC_words_wasted by bytes rather than
words.
* Consider GC_words_wasted in GC_adj_words_allocd only if it is within
@@ -6291,14 +6538,15 @@ we manage to allocate only "wasted" space. 7.0 has a better fix.)
eieio, since the documentation recommends against eieio, and
it seems to be incorrect if the preceding memory op is a load.
* Fixed print_block_list to print the correct kind number for
-STUBBORN.
+STUBBORN (thanks to Rutger Ovidius).
* Have configure.in generate an error if it is asked to support
pthreads, but doesn't know how to.
* Added Kazuhiro Inaoka's patch for Renesas M32R support.
* Have the GNU build mechanism link with -ldl. Rename THREADLIBS
-to THREADDLLIBS to reflect this.
+to THREADDLLIBS to reflect this. (Thanks to Sven Verdoolaege.)
* Added Hannes Mehnert's patch for FreeBSD/SPARC support.
* Merged some FreeBSD specific patches to threadlibs.c and dyn_load.c.
+(Thanks to John Merryweather Cooper.)
* Define MPROTECT_VDB on MACOSX only if threads are being used, since the
dirty page tracking mechanism uses threads. (This avoids an undefined
reference to _GC_darwin_register_mach_handler_thread.)
@@ -6309,7 +6557,7 @@ The GC itself will dirty lots of pages in this cases, probably making
it counterproductive on all platforms. And the DARWIN port crashes.
-== [6.3] ==
+== [6.3] 2004-07-08 ==
* Compile test_cpp.cc with CXXCOMPILE instead of COMPILE.
* Very large allocations could cause a collector hang. Correct
@@ -6317,24 +6565,26 @@ calculation of GC_collect_at_heapsize.
* GC_print_hblkfreelist printed some bogus results if USE_MUNMAP
was defined.
* Include gc_config_macros.h in threadlibs.c.
-* Correct MacOSX thread stop code.
+* Correct MacOSX thread stop code (thanks to Dick Porter).
* SMALL_OBJ definition was off by one. This could cause crashes
-at startup.
-* Integrate Paolo Molara's patch to deal with a race in the Darwin
+at startup. (Thanks to Zoltan Varga for narrowing this down to
+a trivial test case.)
+* Integrate Paolo Molaro's patch to deal with a race in the Darwin
thread stopping code.
* Changed X86_64 implementation to use SA_SIGINFO in the MPROTECT_VDB
implementation. The old approach appears to have been broken by
recent kernels.
-* Added GC_ATTR_UNUSED to eliminate a warning in gc_allocator.h.
-* Fix GC_task_self declaration in os_dep.c.
+* Added GC_ATTR_UNUSED to eliminate a warning in gc_allocator.h (thanks
+to Andrew Begel).
+* Fix GC_task_self declaration in os_dep.c (thanks to Andrew Pinski).
* Increase INITIAL_BUF_SZ in os_dep.c for Solaris /proc reads.
-== [6.3alpha6] ==
+== [6.3alpha6] 2004-05-06 ==
* Define USE_GENERIC_PUSH_REGS for NetBSD/M68K.
* Fixed the X86_64 PREFETCH macros to correctly handle ia32e (which uses
-different prefetch instructions from AMD64).
+different prefetch instructions from AMD64). (Thanks to H.J. Lu.)
* GC_config_macros.h did not correctly define GC_WIN32_THREADS from
GC_THREADS.
* Added simple_example.html.
@@ -6344,27 +6594,30 @@ FreeBSD.
on x86-64. Added some other casts so that the PREFETCH macros
always get a ptr_t argument. Removed some casts in the PREFETCH
implementations.
-* Added a header guard for gc_allocator.h
-and changed GC_debug_free to clobber contents of deallocated object.
+* Added a header guard for gc_allocator.h and changed GC_debug_free to
+clobber contents of deallocated object (suggested by Jesse Jones).
* The signal masking code in pthread_stop_world.c contained some errors.
In particular SIGSEGV was masked in the handler, in spite of the fact that
it wrote to the heap. This could lead to an uncaught SIGSEGV, which
apparently became much more likely in Linux 2.6. Also fixed some
typos, and reduced code duplication in the same area.
-* Remove ltconfig, clean up configure messages for DGUX.
+* Remove ltconfig, clean up configure messages for DG/UX (thanks to
+Adrian Bunk for the patches).
* Integrated NetBSD/OpenBSD patches from Marc Recht and Matthias Drochner.
-== [6.3alpha5] ==
+== [6.3alpha5] 2004-03-30 ==
* Fix & vs && typo in GC_generic_malloc and
GC_generic_malloc_ignore_off_page. (Propagated from the gcc tree.)
* Removed SA_NODEFER hack from NetBSD and Solaris write-protect handler.
(According to Christian Limpach, the NetBSD problem is fixed.
Presumably so is the Solaris 2.3 problem.)
-* Removed placement delete from gc_cpp.h for the SGI compiler.
-* Changed semantics of the GC_IGNORE_FB environment variable.
-We still need help in identifying win32
+* Removed placement delete from gc_cpp.h for the SGI compiler (thanks
+to Simon Gornall for the patch).
+* Changed semantics of the GC_IGNORE_FB environment variable, based
+on experimentation by Nicolas Cannasse pointing out that the old
+interpretation was useless. We still need help in identifying win32
graphics memory mappings. The current "solution" is a hack.
* Removed "MAKEOVERRIDES =" from Makefile.am and thus Makefile.in.
It probably made more sense in the gcc context.
@@ -6375,7 +6628,8 @@ supports the same extension on various platforms.
of future work.
* Declared GC_jmp_buf in os_dep.s as JMP_BUF instead of jmp_buf, fixing
a memory overwrite bug on Solaris and perhaps other platforms.
-* Added 0 != __libc_stack_end test to GC_linux_stack_base.
+* Added 0 != __libc_stack_end test to GC_linux_stack_base (thanks to
+Jakub Jelinek for the patch and explaining the problem).
Otherwise pre-linking could cause the collector to fail.
* Changed default thread local storage implementation to USE_PTHREAD_SPECIFIC
for HP/UX with gcc. The compiler-based implementation appears to work
@@ -6386,7 +6640,8 @@ making client mark code cleaner and less dependent on GC version.
to support user-defined kinds. Use the new procedures to replace existing
code in gcj_mlc.c and typd_mlc.c.
* Added support for GC_BACKTRACES.
-* Fixed a remaining problem in CORD_str with signed characters.
+* Fixed a remaining problem in CORD_str with signed characters (thanks
+to Alexandr Petrosian for the patch).
* Removed supposedly redundant, but very buggy, definitions of finalizer
macros from javaxfc.h. Fortunately this file probably has no users.
The correct declarations were already in gc.h.
@@ -6394,7 +6649,7 @@ The correct declarations were already in gc.h.
thread termination, since it is also possible to collect from an
unregistered thread in that case.
* Define NO_GETENV for Windows CE, since getenv doesn't appear to exist.
-Plus some other minor WinCE fixes.
+Plus some other minor WinCE fixes (thanks to Alain Novak).
* Added GC_register_describe_type_fn.
* Arrange for debugging finalizer registration to ignore non-heap
registrations, since the regular version of the routine also behaves
@@ -6415,7 +6670,7 @@ fixed to reflect original intent, but that may not always be an
improvement.
-== [6.3alpha4] ==
+== [6.3alpha4] 2004-01-01 ==
* USE_MMAP was broken by confusion in the code dealing with USE_MMAP_ANON.
* Darwin support was broken in alpha3 as a result of my mis-integration of
@@ -6426,7 +6681,7 @@ thread creation. Fixed by explicitly checking for that case. (Added
GC_in_thread_creation.)
-== [6.3alpha3] ==
+== [6.3alpha3] 2003-12-20 ==
* Removed -DSMALL_CONFIG from BCC_MAKEFILE.
* Changed macros to test for an ARM processor (Patch from Richard Earnshaw.)
@@ -6440,13 +6695,18 @@ an intervening mmap grabbing the address space out from underneath us.
Updated this code to reflect a cleaner patch from Ulrich Drepper.
* Replaced _T with _Tp in new_gc_alloc.h to avoid a MACOS X conflict.
(Patch from Andrew Begel.)
-* Dynamically choose whether or not lock should spin on win32.
-This may be a significant performance improvement for win32.
+* Dynamically choose whether or not lock should spin on win32 (thanks
+to Maurizio Vairani for the patch). This may be a significant performance
+improvement for win32.
* Fix Makefile.direct to actually include NT_STATIC_THREADS_MAKEFILE
-in the distribution.
+in the distribution (thanks to Maurizio Vairani).
* Maybe_install_looping_handler() was accidentally exported, violating
our name space convention.
-* Made os_dep.c use sigsetjmp and SA_NODEFER for NetBSD.
+* Made os_dep.c use sigsetjmp and SA_NODEFER for NetBSD. (Thanks to
+Christian Limpach. I generalized the patch to use sigsetjmp on all
+UNIX_LIKE platforms, admittedly a slightly risky move. But it may avoid
+similar problems on some other platforms. I also cleaned up the definition
+of UNIX_LIKE a bit.)
* Integrated Andrew Begel's Darwin threads patch, adjusted according to
some of Fergus Hendersons's comments. (Patch didn't apply cleanly,
errors are possible.)
@@ -6455,40 +6715,45 @@ confusing it with gcc. The single-threaded collector should now build
with icc, at least on ia64.
-== [6.3alpha2] ==
+== [6.3alpha2] 2003-11-04 ==
* Re-enabled I_HOLD_LOCK assertion in aix_irix_threads.h.
-* Put back the WINABI qualifier for GC_CreateThread.
+* Put back the WINABI qualifier for GC_CreateThread. (Thanks to
+Danny Smith for the patch. 6.3alpha1 had the qualifier in one place
+but not elsewhere, which was clearly wrong.)
* Sometimes explicitly define __private_extern__ before DARWIN dyld.h
-include.
+include. (Thanks to Andreas Tobler for posting the patch.)
* Included signal.h from pthread_support.c. Removed GC_looping_handler,
which was dead code.
* GC_find_start was misdeclared by gc_pmark.h if PRINT_BLACK_LIST was
-defined.
+defined (thanks to Glauco Masotti for testing and reporting this).
Changed GC_find_start to never just return 0. According to its
comment it doesn't, and it's unclear that's correct.
* GC_alloc_large had several largely compensating bugs in the
computation of GC_words_wasted. (It was confused about bytes vs.
words in two places.)
-* Integrated Slava Sysoltev's patch to support more recent versions of
+* Integrated Slava Sysoltsev's patch to support more recent versions of
the Intel compiler on IA64/Linux.
* Changed win32 spinlock initialization to conditionally set a spin count.
(Emmanual Stumpf pointed out that enabling this makes a large performance
difference on win32 multiprocessors.) Also cleaned up the win32 spinlock
initialization code a bit.
* Fixed thread support for HP/UX/IA64. The register backing store base for
-the main thread was sometimes not set correctly.
+the main thread was sometimes not set correctly. (Thanks to
+Laurent Morichetti.)
* Added -DEMPTY_GETENV_RESULTS flag to work around Wine problem.
* Declare GC_stack_alloc and GC_stack_free in solaris_threads.h to
-avoid 64-bit size mismatches.
+avoid 64-bit size mismatches (thanks to Bernie Solomon).
* Fixed GC_generic_push_regs to avoid a potential and very unfortunate
tail call optimization. This could lead to prematurely reclaimed
objects on configurations that used the generic routine and the new
build infrastructure (which potentially optimizes mach_dep.c).
This was a serious bug, but it's unclear whether it has resulted in
any real failures.
-* Fixed CORD_str to deal with signed characters.
-* Merged a couple of NOSYS/ECOS tests into os_dep.c from gcj.
+* Fixed CORD_str to deal with signed characters (thanks to Alexandr Petrosian
+for noticing the problem and supplying the patch).
+* Merged a couple of NOSYS/ECOS tests into os_dep.c from gcj (thanks
+to Anthony Green).
* Partially merged a win32 patch from Ben Hutchings, and substantially
revised other parts of win32_threads.c. It had several problems.
Under MinGW with a statically linked library, the main thread was
@@ -6502,43 +6767,71 @@ removed the thread context from them.)
* Integrated a Solaris configure.in patch from Rainer Orth.
* Added GC_IGNORE_FB and associated warning to very partially address
the issue of the collector treating a mapped frame buffer as part
-of the root set.
+of the root set. (Thanks to David Peroutka for providing some
+insight. More would be helpful. Is there anything that can be used
+to at least partially identify such memory segments?)
-== [6.3alpha1] ==
+== [6.3alpha1] 2003-07-26 ==
-* Integrated some NetBSD patches forwarded to me by Marc Recht. These
+* Integrated some NetBSD patches by Marc Recht. These
were already in the NetBSD package.
* GC_pthread_create waited for the semaphore even if pthread_create failed.
-Applied the analogous fix for aix_irix_threads.c.
+(Thanks to Dick Porter for the pthread_support.c patch.) Applied the
+analogous fix for aix_irix_threads.c.
* Added Rainer Orth's Tru64 fixes.
* The check for exceeding the thread table size in win32 threadDetach
-was incorrect.
+was incorrect (thanks to Alexandr Petrosian for the patch).
* Applied Andrew Begel's patch to correct some reentrancy issues
with dynamic loading on Darwin.
* GC_CreateThread() was neglecting to duplicate the thread handle in
-the table.
-* Pass +ESdbgasm only on PA-RISC machines with vendor compiler.
+the table (thanks to Tum Nguyen for the patch).
+* Pass +ESdbgasm only on PA-RISC machines with vendor compiler (thanks to
+Roger Sayle for the patch).
* Applied more AIX threads patches from Scott Ananian.
-== [6.2] ==
+== [6.2] 2003-06-21 ==
* Integrated a second round of Irix/AIX patches from Dan Bonachea.
Renamed mips_sgi_mach_dep.S back to mips_sgi_mach_dep.s, since it requires
the Irix assembler to do the C preprocessing; gcc -E doesn't work.
-* Fixed Makefile.direct for DARWIN.
+* Fixed Makefile.direct for DARWIN (thanks to Manuel Serrano).
* There was a race between GC_pthread_detach and thread exit that could
result in a thread structure being deallocated by GC_pthread_detach
-even though it was still needed by the thread exit code.
+even though it was still needed by the thread exit code (thanks to
+Dick Porter for the small test case that allowed this to be debugged).
* Fixed version parsing for non-alpha versions in acinclude.m4 and
version checking in version.h.
-
-
-== [6.2alpha6] ==
+* Issues identified (not yet fixed):
+- A dynamic libgc.so references dlopen unconditionally, but doesn't link
+against libdl.
+- GC_proc_fd for Solaris is not correctly updated in response to a
+fork() call. Thus incremental collection in the child won't work
+correctly. (Thanks to Ben Cottrell for pointing this out.)
+- --enable-redirect-malloc is mostly untested and known not to work
+on some platforms.
+- There seem to be outstanding issues on Solaris/X86, possibly with
+finding the data segment starting address.
+- Very large root set sizes (> 16 MB or so) could cause the collector
+to abort with an unexpected mark stack overflow. (Thanks to
+Peter Chubb.) NOT YET FIXED. Workaround is to increase the initial
+size.
+- The SGI version of the collector marks from mmapped pages, even
+if they are not part of dynamic library static data areas. This
+causes performance problems with some SGI libraries that use mmap
+as a bitmap allocator. NOT YET FIXED. It may be possible to turn
+off DYNAMIC_LOADING in the collector as a workaround. It may also
+be possible to conditionally intercept mmap and use GC_exclude_static_roots.
+The real fix is to walk rld data structures, which looks possible.
+- Incremental collector should handle large objects better. Currently,
+it looks like the whole object is treated as dirty if any part of it is.
+
+
+== [6.2alpha6] 2003-06-05 ==
* There was an extra underscore in the name of GC_save_registers_in_stack
-for NetBSD/SPARC.
+for NetBSD/SPARC (thanks to Jaap Boender for the patch).
* Integrated Brian Alliet's patch for Darwin. This restructured the
linuxthreads/pthreads support to separate generic pthreads support
from more the system-dependent thread-stopping code. I believe this
@@ -6554,8 +6847,8 @@ anyway and it cluttered up the code. And anything we can do to migrate
towards generic pthreads support is a good thing.
* Added a more explicit test for tracing of function arguments to test.c.
* Added Akira Tagoh's PowerPC64 patch.
-* Fixed some bit rot in the Cygwin port.
-gc.h now includes just windows.h, not winbase.h.
+* Fixed some bit rot in the Cygwin port (thanks to Dan Bonachea for
+pointing it out). gc.h now includes just windows.h, not winbase.h.
* Declared GC_save_regs_in_stack() in gc_priv.h. Remove other declarations.
* Changed --enable-cplusplus to use automake consistently. The old way
confused libtool. "Make install" didn't work correctly for the old version.
@@ -6566,7 +6859,7 @@ or two subtle failures on unusual platforms. Those failures should
now occur at build time and be easily fixable.
-== [6.2alpha5] ==
+== [6.2alpha5] 2003-05-14 ==
* GC_invoke_finalizers could, under rare conditions, set
GC_finalizer_mem_freed to an essentially random value. This could
@@ -6577,23 +6870,26 @@ is not in gcc3.3.)
GC_DLL is used instead. All internal tests are now on GC_DLL.
README.macros is now more precise about the intended meaning.
* Include DllMain in the multi-threaded win32 version only if the
-collector is actually built as a dll.
+collector is actually built as a dll (thanks to Mohan Embar for
+a version of the patch).
* Hide the cygwin threadAttach/Detach functions. They were violating our
namespace rules.
-* Fixed an assertion in GC_check_heap_proc. Added GC_STATIC_ASSERT.
+* Fixed an assertion in GC_check_heap_proc. Added GC_STATIC_ASSERT
+(thanks again to Ben Hutchings).
* Removed some obsolete definitions for Linux/PowerPC in gcconfig.h.
* CORD_cat was not rebalancing unbalanced trees in some cases, violating
a CORD invariant. Also tweaked the re-balancing rule for
-CORD_cat_char_star.
+CORD_cat_char_star. (Thanks to Alexandr Petrosian for the bug report
+and patch.)
* Added hand-coded structured exception handling support to mark.c.
This should enable support of dynamic libraries under win32 with
-gcc-compiled code.
+gcc-compiled code. (Thanks to Ranjit Mathew for the patch.)
Turned on dynamic library scanning for win32/gcc.
-* Removed some remnants of read wrapping.
-GC_USE_LD_WRAP ws probably broken in recent versions.
+* Removed some remnants of read wrapping (thanks to Kenneth Schalk).
+GC_USE_LD_WRAP was probably broken in recent versions.
* The build could fail on some platforms since gcconfig.h could include
declarations mentioning ptr_t, which was not defined, e.g. when if_mach
-was built. Also
+was built (thanks to Yann Dirson for pointing this out). Also
cleaned up tests for GC_PRIVATE_H in gcconfig.h a bit.
* The GC_LOOP_ON_ABORT environment variable interfered with incremental
collection, since the write fault handler was erroneously overridden.
@@ -6605,7 +6901,7 @@ to avoid it. (This caused occasional crashes in GC_set_fl_marks
with thread local allocation and incremental GC. This probably happened
primarily on old, slow multiprocessors.)
* Allowed overriding of MAX_THREADS in win32_threads.c from the build
-command line.
+command line (thanks to Yannis Bres for the patch).
* Taught the IA64/linux code to determine the register backing store base from
/proc/self/maps after checking the __libc symbol, but before guessing.
(__libc symbols are on the endangered list, and the guess is likely to not
@@ -6620,7 +6916,7 @@ dynamic library that includes C++ code, I separated out the c++ code into
libgccpp.
-== [6.2alpha4] ==
+== [6.2alpha4] 2003-03-10 ==
* Use LINUX_STACKBOTTOM for >= glibc2.2 on Linux/MIPS. (See Debian bug
# 177204)
@@ -6628,8 +6924,9 @@ libgccpp.
* Integrated Grzegorz Jakacki's substantial GNU build patch. "Make dist"
should now work for the GNU build process. Documentation files
are installed under share/gc.
-* Tweaked gc_cpp.h to again support the Borland compiler.
-* Updated BCC_MAKEFILE.
+* Tweaked gc_cpp.h to again support the Borland compiler (thanks to
+Rene Girard for pointing out the problems).
+* Updated BCC_MAKEFILE (thanks to Rene Girard).
* Added GC_ASSERT check for minimum thread stack size.
* Added --enable-gc-assertions.
* Added some web documentation to the distribution. Updated it in the
@@ -6647,7 +6944,7 @@ when it should have called the lower case version, since it was
explicitly computing a base pointer.
-== [6.2alpha3] ==
+== [6.2alpha3] 2003-01-30 ==
* Don't include execinfo.h in os_dep.c when it's not needed, and may not
exist.
@@ -6655,8 +6952,9 @@ exist.
== [6.2alpha2] ==
-* Fixed the completely broken FreeBSD code in 6.2alpha1.
-* Changed IRIX reference in dbg_mlc.c to IRIX5.
+* Fixed the completely broken FreeBSD code in 6.2alpha1 (thanks to
+Hironori Sakamoto for the patch).
+* Changed IRIX reference in dbg_mlc.c to IRIX5 (thanks to Marcus Herbert).
* Attempted to work around the problems with .S filenames and the SGI
compiler. (Untested.)
* Worked around an HP/UX make issue with the GNU-style build process.
@@ -6667,16 +6965,16 @@ address for Linux and XXXBSD on hardware for which we can't get stack
traces. Use __builtin_return_address(0) to generate it when possible.
Some of the configuration work was cleaned up (good) and moved to gc.h
(bad, but necessary). This should make leak detection more useful
-on a number of platforms.
+on a number of platforms. (Thanks to Fabian Thylman for the suggestion.)
* Fixed compilation problems in dbg_mlc.c with GC_ADD_CALLER.
* Bumped revision number for dynamic library.
-== [6.2alpha1] ==
+== [6.2alpha1] 2003-01-23 ==
* Guard the test for GC_DUMP_REGULARLY in misc.c with
"#ifndef NO_DEBUGGING". Otherwise it fails to build with NO_DEBUGGING
-defined.
+defined. (Thanks to Manuel Serrano.)
* Message about retrying suspend signals was incorrectly generated even when
flag was not set.
* Cleaned up MACOSX/NEXT root registration code. There was apparently a
@@ -6685,14 +6983,15 @@ separate ifdef case in GC_register_data_segments() for no reason.
* Arrange for gc.h and friends to be correctly installed with GNU-style
"make install".
* Enable the GNU-style build facility include C++ support in the library
-with --enable-cplusplus.
+with --enable-cplusplus (thanks to Thomas Maier for some of the patch).
* Mark from GC_thread_key in linux_threads.c, in case that's allocated
from the garbage collected heap, as it is with our own thread-specific
-storage implementation.
+storage implementation (thanks to Jeff Sturm).
* Mark all free list header blocks if they are heap allocated. This avoids
some unnecessary tracing. And it remains correct if we clear the
-root set.
-* Improved S390/Linux support. Add S390/Linux 64-bit support.
+root set. (Thanks to Jeff Sturm for identifying the bug.)
+* Improved S390/Linux support. Add S390/Linux 64-bit support (thanks to
+Ulrich Weigand).
* Corrected the spelling of GC_{M,C}ALLOC_EXPLICTLY_TYPED to
GC_{M,C}ALLOC_EXPLICITLY_TYPED in gc_typed.h. This is technically
an interface change. Based on the fact that nobody reported this,
@@ -6708,14 +7007,17 @@ under win32. Based on my tests, this tends to eventually find all
segments, though it may take a while. There appear to be cleaner,
but slower solutions under NT/XP. But they rely on an API that's
unsupported under 9X.
-* Changed Linux PowerPC stack finding to LINUX_STACKBOTTOM.
+* Changed Linux PowerPC stack finding to LINUX_STACKBOTTOM. (Thanks
+to Akira Tagoh for pointing out that HEURISTIC1 does not work on
+64-bit kernels.)
* Added GC_set_free_space_divisor to avoid some Windows dll issues.
* Added FIXUP_POINTER, POINTER_SHIFT, POINTER_MASK to allow preprocessing
of candidate pointers for tagging, etc.
* Always lock around GC_notify_full_gc(). Simplified code for
invoking GC_notify_full_gc().
* Changed the way DATASTART is defined on FreeBSD to be robust against
-an unmapped page after etext.
+an unmapped page after etext. (Thanks to Hironori Sakamoto for
+tracking down the intermittent failure.)
* Made GC_enable() and GC_disable() official. Deprecated direct update
of GC_dont_gc. Changed GC_gcollect to be a noop when garbage collection
is disabled.
@@ -6730,10 +7032,11 @@ The latter is more reliable and easier on Linux with dl_iterate_phdr.
== [6.1] ==
* Added GC_MAXIMUM_HEAP_SIZE environment variable.
-* Fix configure.in for MIPS/LINUX.
+* Fix configure.in for MIPS/LINUX (thanks to H.J. Lu).
* Double page hash table size for -DLARGE_CONFIG.
* Integrated Bo Thorsen's X86-64 support.
-* STACKBOTTOM definition for LINUX/MIPS was partially changed back.
+* STACKBOTTOM definition for LINUX/MIPS was partially changed back
+(thanks to H.J. Lu and Hiroshi Kawashima for resolving this).
* Replaced all occurrences of LINUX_DATA_START in gcconfig.h with
SEARCH_FOR_DATA_START. It doesn't hurt to fall back to a search.
And __data_start doesn't seem to get defined correctly of the GC
@@ -6754,9 +7057,9 @@ alpha_mach_dep.s.
* Incorporated a change to new_gc_alloc.h,
which should make it work with gcc3.1.
* Use alpha_mach_dep.S only on Linux. (It's not clear that this is
-optimal, but it otherwise didn't build on Tru64.)
+optimal, but it otherwise didn't build on Tru64. Thanks to Fergus Henderson.)
* Added ifdef to guard free() in os_dep.c. Otherwise we get a
-compilation error on Irix.
+compilation error on Irix (thanks to Dai Sato).
* Added an experimental version of GC_memalign to mallocx.c. This can't
always work, since we don't handle alignment requests in the hblk-level
allocator, and we can't handle arbitrary pointer displacements unless
@@ -6775,61 +7078,73 @@ to work correctly with these.
* Fixed Linux USE_PROC_FOR_LIBRARIES to work with a 64-bit /proc format.
-== [6.1alpha5] ==
+== [6.1alpha5] 2002-06-19 ==
* Added GC_finalizer_mem_freed, and changed some of the code that
decided on heap expansion to look at it. Memory explicitly
deallocated by finalizers essentially needs to be counted as reclaimed
by the GC. Otherwise there are cases in which the heap can grow
-infinitely.
+infinitely. (Thanks to Mark Reichert for the test case.)
* Integrated Adam Megacz patches to not scan dynamic libraries if
we are compiling with gcc on win32. Otherwise we need structured
exception handling to deal with asynchronously unmapped root
segments, and gcc doesn't directly support that.
* Integrated Anthony Green's patch to support Wine.
* GC_OPERATOR_NEW_ARRAY was misspelled OPERATOR_NEW_ARRAY in several
-places, including gc_cpp.cc.
-* Integrated Loren James Rittle's Alpha FreeBSD patches. These also
+places, including gc_cpp.cc (thanks to Wink Saville for pointing this out).
+* Integrated Loren J. Rittle's Alpha FreeBSD patches. These also
changed the declarations of symbols like _end on many platforms to
-that they wouldn't mistakenly be declared as short data symbols.
-* Integrated changes from the Debian distribution.
+that they wouldn't mistakenly be declared as short data symbols (suggested by
+Richard Henderson).
+* Integrated changes from the Debian distribution (thanks to Ryan Murray
+for pointing these out).
Fix C++ comments in POWERPC port. Add ARM32
incremental GC support. Get rid of USE_GENERIC_PUSH_REGS for alpha/Linux,
this time for real. Use va_copy to get rid of cord printf problems
(finally).
-* Close file descriptor used to count cpus.
+* Close file descriptor used to count CPUs (thanks to Jeff Sturm for
+pointing out the omission).
* Don't just drop gcj free lists in GC_start_reclaim, since that can
eventually cause the marker to see a bogus mark descriptor in the
dropped objects. The usual symptom was a very intermittent segmentation
fault in the marker. This mattered only if one of the GC_gcj_malloc
-variants was used.
-* Fixed Linux and Solaris/64 SPARC configuration.
-* Fixed a typo in strdup definition.
+variants was used (thanks to Michael Smith, Jeff Sturm, Bryce McKinlay and
+Tom Tromey for helping to track this down).
+* Fixed Linux and Solaris/64 SPARC configuration (thanks to David Miller,
+Jeff Sturm, Tom Tromey, and Christian Joensson).
+* Fixed a typo in strdup definition (thanks to Gerard A Allan).
* Changed Makefile.direct to invoke $(CC) to assemble alpha_mach_dep.S.
This is needed on Linux. I'm not sure whether it's better or worse
on Tru64.
* Changed gc_cpp.h once more to declare operator new and friends only in
-a Microsoft environment. This may need further fine tuning.
-* Don't ever override strdup if it's already macro defined.
+a Microsoft environment. This may need further fine tuning (thanks to
+Johannes Schmidt for pointing out that the older code breaks on gcc3.0.4).
+* Don't ever override strdup if it's already macro defined (thanks to
+Adnan Ali for pointing out the problem).
* Changed gc_cpp.h yet again to also overload placement new. Due to the
C++ overloading rules, the other overloaded new operations otherwise hide
-placement new, which causes many STL uses to break.
+placement new, which causes many STL uses to break (thanks to Reza Shahidi
+for reporting this, and to Matt Austern for proposing a fix).
* Integrated cygwin pthreads support from Dan Bonachea.
-* Turn on DYNAMIC_LOADING for NetBSD.
+* Turn on DYNAMIC_LOADING for NetBSD (thanks to Krister Walfridsson).
* Changed printing code to print more complete GC times.
-* Applied Mark Mitchell's Irix patch to correct some bitrot.
+* Applied Mark Mitchell's Irix patch to correct some bit rot.
* Clarified which object-printing routines in dbg_mlc.c should hold
the allocation lock. Restructured the code to allow reasonable object
printing with -DREDIRECT_MALLOC.
* Fix the Linux mmap code to always start with 0x1000 as the initial hint.
-Minor patches for 64-bit AIX, particularly to STACKBOTTOM.
+Minor patches for 64-bit AIX, particularly to STACKBOTTOM (thanks to
+Jeffrey Mark Siskind).
* Renamed "SUSPENDED" flag for Solaris threads support to avoid a conflict
-with a system header.
+with a system header (thanks to Philip Brown).
* Cause win32_threads.c to handle an out of range stack pointer correctly,
-though currently with a warning.
+though currently with a warning. (Thanks to Jonathan Clark for
+observing that win32 applications may temporarily use the stack
+pointer for other purposes, and suggesting a fix. Unfortunately, it's
+not clear that there is a complete solution to this problem.)
-== [6.1alpha4] ==
+== [6.1alpha4] 2002-06-16 ==
* Fixed typo in sparc_mach_dep.S, preventing the 64-bit version from
building. Increased 64-bit heap size limit in test.c slightly, since
@@ -6844,28 +7159,30 @@ postpone the collection until the heap is (nearly) full.
* Remove read() wrapper for MPROTECT_VDB. It was causing more harm than
good. It is often no longer needed if system calls avoid writing to
pointerfull heap objects.
-* Fix MACOSX test in gcconfig.h.
+* Fix MACOSX test in gcconfig.h (thanks to John Clements).
* Change GC_test_and_set so that it consistently has one argument.
-Add spaces to ::: in powerpc assembly code in gc_locks.h.
+Add spaces to ::: in powerpc assembly code in gc_locks.h (thanks to
+Ryan Murray).
* Fixed a formatting error in dbg_mlc.c. Added prototype to GC_abort()
-declaration.
+declaration (thanks to Michael Smith).
* Removed "source" argument to GC_find_start(). Eliminate GC_FIND_START().
* Added win32 recognition code in configure.in. Changed some of the
-dllimport/export defines in gc.h.
+dllimport/export defines in gc.h (thanks to Adam Megacz).
* GC_malloc_many didn't set hb_last_reclaimed when it called
GC_reclaim_generic. (I'm not sure this matters much, but ...)
* Allocating uncollectible objects with debug information sometimes
allocated objects that were one byte too small, since uncollectible
-objects don't have the extra byte added at the end.
+objects don't have the extra byte added at the end (thanks to
+Wink Saville for pointing this out).
* Added a bit more assertion checking to make sure that gcj objects
on free lists never have a nonzero second word.
-* Replaced BCC_MAKEFILE with an up-to-date one.
+* Replaced BCC_MAKEFILE with an up-to-date one (thanks to Andre Leiradella).
* Upgraded libtool, cinfigure.in and some related files to hopefully
-support NetBSD/SPARC. Unfortunately,
+support NetBSD/SPARC (thanks to Adrian Bunk). Unfortunately,
libtool 1.4.2 seemed to be buggy due to missing quotes in several
"test" invocations. Fixed those in the ltmain.sh script.
* Some win32-specific patches, including the introduction of
-GC_CreateThread.
+GC_CreateThread (thanks to Adam Megacz).
* Merged in gcj changes from Anthony Green to support embedded systems.
* Tried to consistently rename preprocessed assembly files with a capital
.S extension.
@@ -6877,19 +7194,22 @@ later in gc_priv.h to avoid forward references to ptr_t.
* Add some testing of local allocation to test.c.
* Change definition of INVALID_QTID in specific.h. The -1 value was used
inconsistently, and too likely to collide with a valid stack address.
-Some general clean-up of specific.[ch]. Added assertions.
+Some general clean-up of specific.[ch]. Added assertions. (Thanks
+to Michael Smith for tracking down an intermittent bug to this
+general area. I'm not sure it has been squashed yet, however.)
* On Pthread systems it was not safe to call GC_malloc() between fork()
and exec(). According to the applicable standards, it doesn't appear
to be safe to call malloc() or many other libc functions either, thus
it's not clear this is fixable. Added experimental support for
-DHANDLE_FORK in linux_threads.c which tries to support it. It may
succeed if libc does the right thing. I'm not sure whether it does.
+(Thanks to Kenneth Schalk for pointing out this issue.)
* Documented thread local allocation primitives to require an
explicit GC_init call. GC_init_parallel is no longer declared to
be a constructor function, since that isn't portable and often
seems to lead to initialization order problems.
* Changed gc_cpp.cc and gc_cpp.h in one more attempt to make them
-compatible with Visual C++ 6.
+compatible with Visual C++ 6 (thanks to Wink Saville for the patch).
* Some more patches for Linux on HP PA-RISC.
* Added include/gc_allocator.h. It implements (hopefully) standard
conforming (as opposed to SGI-style) allocators that allocate
@@ -6900,9 +7220,10 @@ which was written by Matt Austern. Changed test_cpp.cc to very
minimally test this.
* On Linux/X86, retry mmap with a different start argument. That should
allow the collector to use more (closer to 3GB) of the address space.
-* Force 64 bit alignment with GCJ support.
+* Force 64 bit alignment with GCJ support (reflects Bryce McKinlay's
+patch to the gcc tree).
* Refined the choice of sa_handler vs. sa_sigaction in GC_dirty_init
-to accommodate some glibc5 systems.
+to accommodate some glibc5 systems (thanks to Dan Fandrich for the patch).
* Compensated for the fact that current versions of glibc set
__libc_stack_end incorrectly on Linux/IA64 while initialization code
is running. This could cause the collector to miss 16 bytes of
@@ -6911,14 +7232,17 @@ the memory stack if GC_malloc or friends where called before main().
This will probably take another iteration to work, since his
patch conflicted with the libtool upgrade.
* Added README.arm.cross containing some information about cross-
-compiling to an ARM processor from Margaret Fleck.
+compiling to an ARM processor from Margaret Fleck (original code provided by
+Bradley D. LaRonde; edited by Andrej Cedilnik using some of solutions by
+Tilman Vogel; also ported for iPAQ by Oliver Kurth).
-== [6.1alpha3] ==
+== [6.1alpha3] 2002-02-07 ==
* Minor cleanup on the gcconfig.h section for SPARC.
-* Minor fix to support Intel compiler for I386/Linux.
-* Added SPARC V9 (64-bit) support.
+* Minor fix to support Intel compiler for I386/Linux (thanks to
+Sven Hartrumpf).
+* Added SPARC V9 (64-bit) support (thanks to Jeff Sturm).
* Restructured the way in which we determine whether or not to keep
call stacks for debug allocation. By default SAVE_CALL_COUNT is
now zero on all platforms. Added SAVE_CALL_NARGS parameters.
@@ -6943,7 +7267,7 @@ environment variable.
GC_init_inner().
-== [6.1alpha2] ==
+== [6.1alpha2] 2001-12-20 ==
* No longer wrap read by default in multi-threaded applications. It was
pointed out on the libgcj list that this holds the allocation lock for
@@ -6956,23 +7280,26 @@ first).
* Added printing of stop-the-world GC times if GC_PRINT_STATS environment
variable is set.
* The calloc definition in leak_detector.h was missing parentheses, and
-realloc was missing a second argument to GC_REALLOC.
+realloc was missing a second argument to GC_REALLOC (thanks to
+Elvenlord Elrond).
* Added GC_PRINT_BACK_HEIGHT environment variable and associated
code, mostly in the new file backgraph.c. See doc/README.environment.
-* Added -DUSE_GLOBAL_ALLOC to work around a Windows NT issue.
+* Added -DUSE_GLOBAL_ALLOC to work around a Windows NT issue (thanks to
+Jonathan Clark).
* Integrated port to NEC EWS4800 (MIPS-based workstation, with somewhat
-different address-space layout). This may help for other machines with
-holes in the data segment.
+different address-space layout). This may help for other machines with
+holes in the data segment. (Thanks to Hironori Sakamoto.)
* Changed the order in which GC_push_roots and friends push things onto
the mark stack. GC_push_all calls need to come first, since we can't
-necessarily recover if those overflow the mark stack.
+necessarily recover if those overflow the mark stack. (Thanks to
+Matthew Flatt for tracking down the problem.)
* Some minor cleanups to mostly support the Intel compiler on Linux/IA64.
-== [6.1alpha1] ==
+== [6.1alpha1] 2001-09-22 ==
* Non-debug, atomic allocations could result in bogus smashed object
-reports with debugging on.
+reports with debugging on (thanks to Patrick Doyle for the small test case).
* Fixed GC_get_register_stack_base (Itanium only) to work around a glibc
2.2.4 bug.
* Initial port to HP/UX on Itanium. Thread support and both 32 and 64
@@ -6981,32 +7308,35 @@ some inline assembly code issues. Thread local allocation does appear
to work.
* ifdef'ed out glibc2.1/Itanium workaround. I suspect nobody is using
that combination anymore.
-* Added a patch to make new_gc_alloc.h usable with gcc3.0.
+* Added a patch to make new_gc_alloc.h usable with gcc3.0 (thanks to
+Dimitris Vyzovitis for the patch).
* Debugged 64-bit support on HP/UX PA-RISC.
-* Turned on dynamic loading support for FreeBSD/ELF.
-* Unregistering of finalizers with debugging allocation was broken.
+* Turned on dynamic loading support for FreeBSD/ELF (thanks to Peter Housel).
+* Unregistering of finalizers with debugging allocation was broken (thanks
+to Jani Kajala for the test case).
* Old finalizers were not returned correctly from GC_debug_register_finalizer.
* Disabled MPROTECT_VDB for Linux/M68K based on a report that it doesn't work.
-* Cleaned up some statistics gathering code in reclaim.c.
-* Added some support for OpenBSD/ELF/Linux.
+* Cleaned up some statistics gathering code in reclaim.c (thanks to
+Walter Bright).
+* Added some support for OpenBSD/ELF/Linux (thanks to Suzuki Toshiya).
* Added Jakub Jelinek's patch to use dl_iterate_phdr for dynamic library
traversal to dyn_load.c. Changed it to weakly reference dl_iterate_phdr,
so that the old code is still used with old versions of glibc.
* Cleaned up feature test macros for various threads packages and
-integrated (partially functional) FreeBSD threads code from Loren Rittle.
+integrated (partially functional) FreeBSD threads code from Loren J. Rittle.
It's likely that the cleanup broke something, since it touched lots of
-code. It's also likelly that it fixed some unreported bugs in the
+code. It's also likely that it fixed some unreported bugs in the
less common thread implementations, since some of the original code
didn't stand up to close scrutiny. Support for the next pthreads
implementation should be easier to add.
-== [6.0] ==
+== [6.0] 2001-07-26 ==
* Two more bug fixes for KEEP_BACK_PTRS and DBG_HDRS_ALL.
* Fixed a stack clearing problem that resulted in SIGILL with a
misaligned stack pointer for multi-threaded SPARC builds.
-* Integrated another HURD patch.
+* Integrated another HURD patch (thanks to Igor Khavkine).
== [6.0alpha9] ==
@@ -7016,30 +7346,32 @@ misaligned stack pointer for multi-threaded SPARC builds.
hard links.
* Simplified the setting of NEED_FIND_LIMIT in os_dep.c, possibly breaking
it on untested platforms.
-* Integrated initial GNU HURD port.
-* A few more fixes for Digital Mars compiler (Walter Bright).
+* Integrated initial GNU HURD port (thanks to Chris Lingard and
+Igor Khavkine).
+* A few more fixes for Digital Mars compiler (by Walter Bright).
* Fixed gcc version recognition. Renamed OPERATOR_NEW_ARRAY to
GC_OPERATOR_NEW_ARRAY. Changed GC_OPERATOR_NEW_ARRAY to be the default.
-It can be overridden with -DGC_NO_OPERATOR_NEW_ARRAY.
+It can be overridden with -DGC_NO_OPERATOR_NEW_ARRAY (thanks to
+Cesar Eduardo Barros).
* Changed the byte size to free-list mapping in thread local allocation
so that size 0 allocations are handled correctly.
-* Fixed Linux/MIPS stackbottom for new toolchain.
+* Fixed Linux/MIPS stackbottom for new toolchain (thanks to Ryan Murray).
* Changed finalization registration to invoke GC_oom_fn when it runs out
of memory.
* Removed lvalue cast in finalize.c. This caused some debug configurations
not to build with some non-gcc compilers.
-== [6.0alpha8] ==
+== [6.0alpha8] 2001-06-15 ==
* Changed GC_debug_malloc_replacement and GC_debug_realloc_replacement
-so that they compile under Irix.
+so that they compile under Irix (thanks to Dave Love).
* Updated powerpc_macosx_mach_dep.s so that it works if the collector
-is in a dynamic library.
+is in a dynamic library (thanks to Andrew Begel).
* Transformed README.debugging into debugging.html, updating and
expanding it in the process. Added gcdescr.html and tree.html
from the web site to the GC distribution.
-* Fixed several problems related to PRINT_BLACK_LIST. This involved
+* Fixed several problems related to PRINT_BLACK_LIST. This involved
restructuring some of the marker macros.
* Fixed some problems with the sizing of objects with debug information.
Finalization was broken KEEP_BACK_PTRS or PRINT_BLACK_LIST. Reduced the
@@ -7052,8 +7384,8 @@ They were messy and the performance improvement seemed minimal. We'll
leave such scheduling issues to the compiler.
* Changed Linux/PowerPC test to also check for __powerpc__ in response
to a discussion on the gcc mailing list.
-* Removed the "static" from the jmp_buf
-declaration in GC_generic_push_regs. This was causing problems in
+* Removed the "static" from the jmp_buf declaration in GC_generic_push_regs
+(suggested by Matthew Flatt). This was causing problems in
systems that register all of their own roots. It looks far more correct
to me without the "static" anyway.
* Fixed several problems with thread local allocation of pointer-free or
@@ -7066,48 +7398,50 @@ the corresponding dirt bit. I believe this did not affect Solaris or PCR,
which use a different dirty-bit implementation. Fixed this by installing
signal handlers with sigaction instead of signal, and disabling the thread
suspend signal while in the write-protect handler. (It is unclear
-whether this scenario ever actually occurred. I found it while tracking
-down the following:)
+whether this scenario ever actually occurred.)
* Incremental collection did not cooperate correctly with the PARALLEL_MARK
implementation of GC_malloc_many or the local_malloc primitives. It still
doesn't work well, but it shouldn't lose memory anymore.
* Integrated some changes from the gcc source tree that I had previously
-missed.
+missed (thanks to Bryce McKinlay for the reminder and patch).
* Added Makefile.direct as a copy of the default Makefile, which would
normally be overwritten if configure is run.
* Changed the gc.tar target in Makefile.direct to embed the version number
in the gc directory name. This will affect future tar file distributions.
* Changed the Irix dynamic library finding code to no longer try to
eliminate writable text segments under Irix6.x, since that is probably no
-longer necessary, and can apparently be unsafe on occasion.
+longer necessary, and can apparently be unsafe on occasion (thanks to
+Shiro Kawai for pointing this out).
* GC_cleanup with GC_DEBUG enabled passed a real object base address to
GC_debug_register_finalizer_ignore_self, which expected a pointer past the
debug header. Call GC_register_finalizer_ignore_self instead, even with
-debugging enabled.
+debugging enabled (thanks to Jean-Daniel Fekete for catching this).
* The collector didn't build with call chain saving enabled but NARGS=0.
* Fixed up the GNU-style build files enough so that they work in some
-obvious cases.
-* Added initial port to Digital Mars compiler for win32.
+obvious cases (thanks to Maarten Thibaut).
+* Added initial port to Digital Mars compiler for win32 (thanks to Walter
+Bright).
-== [6.0alpha7] ==
+== [6.0alpha7] 2001-04-19 ==
* Added GC_finalizer_notifier. Fixed GC_finalize_on_demand. (The variable
actually wasn't being tested at the right points. The build-time flag
was.)
* Added Tom Tromey's S390 Linux patch.
-* Added code to push GC_finalize_now in GC_push_finalizer_structures.
+* Added code to push GC_finalize_now in GC_push_finalizer_structures
+(thanks to Matthew Flatt).
* Added GC_push_gc_structures() to push all GC internal roots.
* Integrated some FreeBSD changes from Matthew Flatt.
* It looks like USRSTACK is not always correctly defined under Solaris.
Hacked gcconfig.h to attempt to work around the problem. The result
-is not well tested.
+is not well tested. (Thanks again to Matthew Flatt for pointing this out.)
* Added Ji-Yong Chung's win32 threads and C++ fixes.
* Arranged for hpux_test_and_clear.s to no longer be needed or built.
It was causing build problems with gas, and it's not clear this is
better than the pthreads alternative on this platform.
* Some MINGW32 fixes from Hubert Garavel.
-* Added Initial Hitachi SH4 port from Kaz Kojima.
+* Added initial Hitachi SH4 port from Kaz Kojima.
* Ported thread-local allocation and parallel mark code to HP/UX on PA_RISC.
* Made include/gc_mark.h more public and separated out the really private
pieces. This is probably still not quite sufficient for clients that
@@ -7123,9 +7457,9 @@ yet supported. (Incremental collection should work if you have the
right kernel. Threads may work with a sufficiently patched pthread
library.)
* Changed gcconfig.h to recognize __i386__ as an alternative to i386 in
-many places.
+many places (thanks to Benjamin Lerman).
* Made win32_threads.c more tolerant of detaching a thread that it didn't
-know about.
+know about (thanks to Paul Nash).
* Added Makefile.am and configure.in from gcc to the distribution, with
minimal changes. For the moment, those are just placeholders. In the
future, we're planning to switch to a GNU-style build environment for
@@ -7159,24 +7493,28 @@ This should now remain reliable on future kernels. But since it relies
on /proc, it will no longer work in the simulated NUE environment.
* Made the call to random() in dbg_mlc.c with -DKEEP_BACK_PTRS dependent
on the OS. On non-Unix systems, rand() should be used instead. Handled
-small RAND_MAX.
-* Fixed the cord make rules to create the cord subdirectory, if necessary.
+small RAND_MAX (thanks to Peter Ross for pointing this out).
+* Fixed the cord make rules to create the cord subdirectory, if necessary
+(thanks to Doug Moen).
* Changed fo_object_size calculation in finalize.c. Turned finalization
of non-heap object into a no-op. Removed anachronism from GC_size()
implementation.
* Changed GC_push_dirty call in solaris_threads.c to GC_push_selected.
-It was missed in a previous renaming.
-* Arranged to not not mask SIGABRT in linux_threads.c.
+It was missed in a previous renaming (thanks to Vladimir Tsichevski
+for pointing this out).
+* Arranged to not mask SIGABRT in linux_threads.c (thanks to Bryce McKinlay).
* Added GC_no_dls hook for applications that want to register their own
roots.
* Integrated Kjetil Matheussen's Amiga changes.
-* Added FREEBSD_STACKBOTTOM. Changed the X86/FreeBSD port to use it.
+* Added FREEBSD_STACKBOTTOM. Changed the X86/FreeBSD port to use it
+(thanks to Matthew Flatt).
* Added pthread_detach interception for platforms supported by linux_threads.c
and irix_threads.c.
* Changed the USE_MMAP code to check for the case in which we got the
high end of the address space, i.e. mem_ptr + mem_sz == 0. It appears
that this can happen under Solaris 7. It seems to be allowed by what
-I would claim is an oversight in the mmap specification.
+I would claim is an oversight in the mmap specification. (Thanks to
+Toshio Endo for pointing out the problem.)
* Cleanup of linux_threads.c. Some code was originally cloned from
irix_threads.c and now unnecessary. Some comments were obviously wrong.
* (Mostly) fixed a longstanding problem with setting of dirty bits from
@@ -7248,9 +7586,9 @@ object from the global free list.
of increasing addresses instead of decreasing addresses for cache performance
reasons. But this seems to be only a very minor gain with -DEAGER_SWEEP,
and a loss in other cases. So the change was backed out.)
-* Fixed some of the documentation.
+* Fixed some of the documentation (thanks in large part to Fergus Henderson).
* Fixed the Linux USE_PROC_FOR_LIBRARIES code to deal with apps that perform
-large numbers of mmaps. Also fixed that code to
+large numbers of mmaps (thanks to Eric Benson). Also fixed that code to
deal with short reads.
* Added GC_get_total_bytes().
* Fixed leak detection mode to avoid spurious messages under linuxthreads.
@@ -7261,7 +7599,7 @@ explicitly deallocated.)
* Made it possible (with luck) to redirect malloc to GC_local_malloc.
-== [6.0alpha3] ==
+== [6.0alpha3] 2000-09-26 ==
* Fixed the /proc/self/maps code to not seek, since that apparently is not
reliable across all interesting kernels.
@@ -7302,7 +7640,8 @@ To turn it on, define SAVE_CALL_CHAIN.
for which that's expensive.
* Fixed a locking bug ib GC_gcj_malloc and some locking assertion problems.
* Added a missing volatile to OR_WORD and renamed the parameter to
-GC_compare_and_swap so it's not a C++ reserved word.
+GC_compare_and_swap so it's not a C++ reserved word (thanks to
+Toshio Endo for pointing out both of those).
* Changed Linux dynamic library registration code to look at /proc/self/maps
instead of the rld data structures when REDIRECT_MALLOC is defined.
Otherwise some of the rld data data structures may be prematurely garbage
@@ -7312,7 +7651,7 @@ collected.
Temporarily added some backward compatibility definitions. Renamed
USE_LD_WRAP to GC_USE_LD_WRAP.
* Many MACOSX POWERPC changes, some additions to the gctest output, and
-a few minor generic bug fixes.
+a few minor generic bug fixes (thanks to Dietmar Planitzer).
== [6.0alpha1] ==
@@ -7357,14 +7696,16 @@ serious, but seemed to generate some confusion.)
== [5.4] ==
-* Fixed a typo that prevented compilation with -DUSE_3DNOW_PREFETCH.
+* Fixed a typo that prevented compilation with -DUSE_3DNOW_PREFETCH (thanks to
+Shawn Wagner for actually testing this).
* Fixed GC_is_thread_stack in solaris_threads.c. It forgot to return a value
in the common case.
-* Fixed another silly syntax problem in GC_double_descr.
+* Fixed another silly syntax problem in GC_double_descr (thanks to
+Fergus Henderson for finding it).
* Fixed a GC_gcj_malloc bug: It tended to release the allocator lock twice.
-== [5.3] ==
+== [5.3] 2000-09-24 ==
* Fixed _end declaration for OSF1.
* There were lots of spurious leak reports in leak detection mode, caused
@@ -7372,7 +7713,7 @@ by the fact that some pages were not being swept, and hence unmarked
objects weren't making it onto free lists. (This bug dated back to 5.0.)
* Fixed a typo in the liblinuxgc.so Makefile rule.
* Added the GetExitCodeThread to Win32 GC_stop_world to (mostly) work
-around a Windows 95 GetOpenFileName problem.
+around a Windows 95 GetOpenFileName problem (thanks to Jacob Navia).
== [5.2] ==
@@ -7383,18 +7724,20 @@ Irix.
* We quietly assumed that indirect mark descriptors were never 0.
Our own typed allocation interface violated that. This could result
in segmentation faults in the marker with typed allocation.
-* Fixed a _DUSE_MUNMAP bug in the heap block allocation code.
-* Taught the collector about VC++ handling array operator new.
+* Fixed a _DUSE_MUNMAP bug in the heap block allocation code (thanks to
+Ben Hutchings for the patch).
+* Taught the collector about VC++ handling array operator new (thanks to
+Ben Hutchings for the patch).
* The two copies of gc_hdrs.h had diverged. Made one a link to the other
again.
== [5.1] ==
-* Fixed a gc.h header bug which showed up under Irix.
+* Fixed a gc.h header bug which showed up under Irix (thanks to Dan Sullivan).
* Fixed a typo in GC_double_descr in typd_mlc.c.
This probably could result in objects described by array descriptors not
-getting traced correctly.
+getting traced correctly (thanks to Ben Hutchings for pointing this out).
* The block nearly full tests in reclaim.c were not correct for 64 bit
environments. This could result in unnecessary heap growth under unlikely
conditions.
@@ -7427,9 +7770,10 @@ when SMALL_CONFIG was defined. This was no doubt a major performance bug for
the default win32 configuration.
* Removed -DSMALL_CONFIG from NT_MAKEFILE. It seemed like an anachronism now
that the average PC has 64MB or so.
-* Integrated Bryce McKinley's patches for linux threads and dynamic loading
+* Integrated Bryce McKinlay's patches for linux threads and dynamic loading
from the libgcj tree. Turned on dynamic loading support for Linux/PPC.
-* Changed the stack finding code to use environ on HP/UX. This should
+* Changed the stack finding code to use environ on HP/UX (thanks
+to Gustavo Rodriguez-Rivera for the suggestion). This should
probably be done on other platforms, too. Since I can't test those, that'll
wait until after 5.0.
@@ -7447,14 +7791,14 @@ mode if the actual used heap size is less than what was explicitly
requested.
* The Solaris pthreads version of GC_pthread_create didn't handle a NULL
attribute pointer. Solaris thread support used the wrong default thread
-stack size.
+stack size (thanks to Melissa O'Neill for the patch).
* Changed PUSH_CONTENTS macro to no longer modify first parameter.
This usually doesn't matter, but it was certainly an accident waiting
to happen ...
* Added GC_register_finalizer_no_order and friends to gc.h. They're
needed by Java implementations.
* Integrated a fix for a win32 deadlock resulting from clock() calling
-malloc.
+malloc (thanks to Chris Dodd).
* Integrated Hiroshi Kawashima's port to Linux/MIPS. This was designed
for a handheld platform, and may or may not be sufficient for other
machines.
@@ -7475,27 +7819,29 @@ gain is currently near zero, and it adds to code size.
__data_start, since nothing else seems to be portable.
* Added -DUSE_LD_WRAP to optionally take advantage of the GNU ld function
wrapping mechanism. Probably currently useful only on Linux.
-* Moved some variables for the scratch allocator into GC_arrays.
+* Moved some variables for the scratch allocator into GC_arrays (suggested
+by Martin Hirzel).
* Fixed a win32 threads bug that caused the collector to not look for
interior pointers from one of the thread stacks without
-ALL_INTERIOR_POINTERS.
-* Added Mingw32 support.
+ALL_INTERIOR_POINTERS (thanks to Jeff Sturm).
+* Added Mingw32 support (thanks to Jeff Sturm for the patch).
* Changed the alpha port to use the generic register scanning code instead
of alpha_mach_dep.s. Alpha_mach_dep.s doesn't look for pointers in fp
-registers, but gcc sometimes spills pointers there. Changed the IA64 code to
+registers, but gcc sometimes spills pointers there (thanks to Manuel Serrano
+for helping debug this). Changed the IA64 code to
do something similar for similar reasons.
-== [5.0alpha4] ==
+== [5.0alpha4] 1999-10-30 ==
* Added protection fault handling patch for Linux/M68K from Fergus
Henderson and Roman Hodek.
* Removed the tests for SGI_SOURCE in new_gc_alloc.h. This was causing that
-interface to fail on nonSGI platforms.
+interface to fail on non-SGI platforms.
* Changed the Linux stack finding code to use /proc, after changing it
-to use HEURISTIC1.
+to use HEURISTIC1 (thanks to David Mossberger for pointing out /proc hook).
* Added HP/UX incremental GC support and HP/UX 11 thread support.
-Thread support is currently still flakey.
+Thread support is currently still flaky.
* Added basic Linux/IA64 support.
* Integrated Anthony Green's PicoJava support.
* Integrated Scott Ananian's StrongARM/NetBSD support.
@@ -7510,11 +7856,13 @@ touching them.
frequency by default, but to explicitly trigger full GCs during
heap growth. This doesn't always improve things, but on average it's
probably a win.
-* GC_debug_free(0, ...) failed.
+* GC_debug_free(0, ...) failed (thanks to Fergus Henderson for the
+bug report and fix).
-== [5.0alpha3] ==
+== [5.0alpha3] 1999-09-15 ==
+(Also known as 4.15alpha3.)
* Added some highly incomplete code to support a copied young generation.
Comments on nursery.h are appreciated.
* Changed -DFIND_LEAK, -DJAVA_FINALIZATION, and -DFINALIZE_ON_DEMAND,
@@ -7524,15 +7872,16 @@ a step towards standardizing on a single dynamic GC library.
of the above.
-== [5.0alpha2] ==
+== [5.0alpha2] 1999-07-23 ==
* Fixed bugs introduced in alpha1 (OpenBSD & large block initialization).
* Added -DKEEP_BACK_PTRS and backptr.h interface. (The implementation
-idea came from Al Demers.)
+idea came from Alan Demers.)
-== [5.0alpha1] ==
+== [5.0alpha1] 1999-06-30 ==
+(Also known as 4.15alpha1.)
* Reworked large block allocator. Now uses multiple doubly linked free
lists to approximate best fit.
* Changed heap expansion heuristic. Entirely free blocks are no longer
@@ -7553,7 +7902,7 @@ GC_register_finalizer, so that it would continue to work with GC_DEBUG.
* allochblk sometimes cleared the wrong block for debugging purposes
when it dropped blacklisted blocks. This could result in spurious
error reports with GC_DEBUG.
-* added MACOS X Server support.
+* added MACOS X Server support (thanks to Andrew Stone).
* Changed the Solaris threads code to ignore stack limits > 8 MB with
a warning. Empirically, it is not safe to access arbitrary pages
in such large stacks. And the dirty bit implementation does not
@@ -7562,12 +7911,12 @@ guarantee that none of them will be accessed.
* Integrated James Dominy's OpenBSD/SPARC port.
-== [4.14] ==
+== [4.14] 1999-04-16 ==
-* changed STACKBOTTOM for DJGPP.
+* changed STACKBOTTOM for DJGPP (thanks to Salvador Eduardo Tropea).
-== [4.14alpha2] ==
+== [4.14alpha2] 1999-03-26 ==
* -DSMALL_CONFIG did not work reliably with large (> 4K) pages.
Recycling the mark stack during expansion could result in a size
@@ -7577,14 +7926,15 @@ issue with the normal config and huge pages.)
completely, even with the setjmp-based code. Added USE_GENERIC_PUSH_REGS
macro to facilitate testing on machines I have access to.
* Added code to explicitly push register contents for win32 threads.
-This seems to be necessary.
+This seems to be necessary. (Thanks to Pierre de Rop.)
-== [4.14alpha1] ==
+== [4.14alpha1] 1999-03-10 ==
* Fixed GC_print_source_ptr to not use a prototype.
* generalized CYGWIN test.
-* gc::new did the wrong thing with PointerFreeGC placement.
+* gc::new did the wrong thing with PointerFreeGC placement (thanks to
+Rauli Ruohonen).
* In the ALL_INTERIOR_POINTERS (default) case, some callee-save register
values could fail to be scanned if the register was saved and
reused in a GC frame. This showed up in verbose mode with gctest
@@ -7594,15 +7944,16 @@ bug report that may have been related. The bug was probably quite old.
after the relevant frame was overwritten, and the new save location
might be outside the scanned area. Fixed by more eager stack scanning.)
* PRINT_BLACK_LIST had some problems. A few source addresses were garbage.
-* Replaced Makefile.dj and added -I flags to cord make targets.
+* Replaced Makefile.dj and added -I flags to cord make targets (thanks to
+Gary Leavens).
* GC_try_to_collect was broken with the non-incremental collector.
* gc_cleanup destructors could pass the wrong address to
GC_register_finalizer_ignore_self in the presence of multiple
-inheritance.
+inheritance (thanks to Darrell Schiebel).
* Changed PowerPC Linux stack finding code.
-== [4.13] ==
+== [4.13] 1999-02-19 ==
* Fixed a crucial bug in the Watcom port. There was a redundant declaration
of GC_push_one in gc_priv.h.
@@ -7613,39 +7964,40 @@ or two versions.
* Fixed bool handling for SPARCCompiler version 4.2.
* Fixed some files in include that had gotten unlinked from the main
copy.
-* Some RS/6000 fixes (missing casts).
+* Some RS/6000 fixes (missing casts). (Thanks to Toralf Foerster.)
* Fixed several problems in GC_debug_realloc, affecting mostly the
FIND_LEAK case.
* GC_exclude_static_roots contained a buggy unsigned comparison to
-terminate a loop.
+terminate a loop (thanks to Wilson Ho).
* CORD_str failed if the substring occurred at the last possible position.
(Only affects cord users.)
* Fixed Linux code to deal with RedHat 5.0 and integrated Peter Bigot's
os_dep.c code for dealing with various Linux versions.
* Added workaround for Irix pthreads sigaction bug and possible signal
misdirection problems.
-Since alpha1:
-* Changed RS6000 STACKBOTTOM.
-* Integrated Patrick Beard's Mac changes.
-* Alpha1 didn't compile on Irix m.n, m < 6.
-* Replaced Makefile.dj with a new one from Gary Leavens.
-* Added Andrew Stitcher's changes to support SCO OpenServer.
-* Added PRINT_BLACK_LIST, to allow debugging of high densities of false
-pointers.
-* Added code to debug allocator to keep track of return address
-in GC_malloc caller, thus giving a bit more context.
-* Changed default behavior of large block allocator to more
-aggressively avoid fragmentation. This is likely to slow down the
-collector when it succeeds at reducing space cost.
-* Integrated Fergus Henderson's CYGWIN32 changes. They are untested,
-but needed for newer versions.
-* USE_MMAP had some serious bugs. This caused the collector to fail
-consistently on Solaris with -DSMALL_CONFIG.
-* Added Linux threads support.
+
+
+== [4.13alpha3] 1998-12-08 ==
+
+* Fixed MSWIN32 recognition test, which interfered with cygwin.
+* Removed unnecessary gc_watcom.asm from distribution. Removed
+some obsolete README.win32 text.
+* Added Alpha Linux incremental GC support (thanks to Philipp Tomsich
+for code for retrieving the fault address in a signal handler).
+Changed Linux signal handler context argument to be a pointer.
+* Took care of some new warnings generated by the 7.3 SGI compiler.
+* Integrated Phillip Musumeci's FreeBSD/ELF fixes.
+* -DIRIX_THREADS was broken with the -o32 ABI (typo in gc_priv.h).
+
+
+== [4.13alpha2] 1998-08-08 ==
+
* Fixed more Linux threads problems.
-* Changed default GC_free_space_divisor to 3 with new large block allocation.
+* Changed default GC_free_space_divisor to 3 with new large block allocation
+(thanks to Matthew Flatt for some measurements that suggest the old
+value sometimes favors space too much over time).
* More CYGWIN32 fixes.
-* Integrated Tyson-Dowd's Linux-M68K port.
+* Integrated Tyson Dowd's Linux-M68K port.
* Minor HP PA and DEC UNIX fixes from Fergus Henderson.
* Integrated Christoffe Raffali's Linux-SPARC changes.
* Allowed for one more GC fixup iteration after a full GC in incremental
@@ -7667,76 +8019,96 @@ across platforms.
* Fixed a USE_MMAP typo that caused out-of-memory handling to fail
on Solaris.
* Added code to test.c to test thread creation a bit more.
-* Integrated GC_win32_free_heap.
+* Integrated GC_win32_free_heap (as suggested by Ivan Demakov).
* Fixed Solaris 2.7 stack base finding problem. (This may actually
have been done in an earlier alpha release.)
-Since alpha3:
-* Fixed MSWIN32 recognition test, which interfered with cygwin.
-* Removed unnecessary gc_watcom.asm from distribution. Removed
-some obsolete README.win32 text.
-* Added Alpha Linux incremental GC support.
-Changed Linux signal handler context argument to be a pointer.
-* Took care of some new warnings generated by the 7.3 SGI compiler.
-* Integrated Phillip Musumeci's FreeBSD/ELF fixes.
-* -DIRIX_THREADS was broken with the -o32 ABI (typo in gc_priv.h>
-== [4.12] ==
+== [4.13alpha1] 1998-02-17 ==
+
+* Changed RS6000 STACKBOTTOM.
+* Integrated Patrick Beard's Mac changes.
+* Alpha1 didn't compile on Irix m.n, m < 6.
+* Replaced Makefile.dj with a new one from Gary Leavens.
+* Added Andrew Stitcher's changes to support SCO OpenServer.
+* Added PRINT_BLACK_LIST, to allow debugging of high densities of false
+pointers.
+* Added code to debug allocator to keep track of return address
+in GC_malloc caller, thus giving a bit more context.
+* Changed default behavior of large block allocator to more
+aggressively avoid fragmentation. This is likely to slow down the
+collector when it succeeds at reducing space cost.
+* Integrated Fergus Henderson's CYGWIN32 changes. They are untested,
+but needed for newer versions.
+* USE_MMAP had some serious bugs. This caused the collector to fail
+consistently on Solaris with -DSMALL_CONFIG.
+* Added Linux threads support (thanks to Fergus Henderson).
+
+
+== [4.12] 1997-08-26 ==
* Fixed ElfW definition in dyn_load.c.
This prevented the dynamic library support from compiling on some
older ELF Linux systems.
-* Fixed UTS4 port (which I apparently mangled during the integration)
+* Fixed UTS4 port (which I apparently mangled during the integration).
+(Thanks to Alistair Crooks.)
* "Make C++" failed on Suns with SC4.0, due to a problem with "bool".
Fixed in gc_priv.h.
-* Added more pieces for GNU win32.
+* Added more pieces for GNU win32 (thanks to Timothy N. Newsham).
The current state of things should suffice for at least some
applications.
* Changed the out of memory retry count handling. (This matters only
if GC_max_retries > 0, which is no longer the default.)
* If a /proc read failed repeatedly, GC_written_pages was not updated
-correctly.
+correctly (thanks to Peter Chubb for diagnosing this).
* Under unlikely circumstances, the allocator could infinite loop in
-an out of memory situation.
+an out of memory situation (thanks to Kenjiro Taura for
+identifying the problem and supplying a fix).
* Fixed a syntactic error in the DJGPP code. Also fixed a test program
-problem with DJGPP.
+problem with DJGPP (thanks to Fergus Henderson and Peter Monks).
* Atomic uncollectible objects were not treated correctly by the
incremental collector. This resulted in weird log statistics and
-occasional performance problems.
+occasional performance problems (thanks to Peter Chubb for pointing this out).
* Fixed some problems resulting from compilers that don't define
__STDC__. In this case void * and char * were used inconsistently
in some cases. (Void * should not have been used at all. If
you have an ANSI superset compiler that does not define __STDC__,
-please compile with -D__STDC__=0.)
+please compile with -D__STDC__=0. Thanks to Manuel Serrano and others
+for pointing out the problem.)
* Fixed a compilation problem on Irix with -n32 and -DIRIX_THREADS.
Also fixed some other IRIX_THREADS problems which may or may not have
had observable symptoms.
-* Fixed an HP PA compilation problem in dyn_load.c.
-* SEGV fault handlers sometimes did not get reset correctly.
-* Added a fix for SOLARIS_THREADS on Intel.
+* Fixed an HP PA compilation problem in dyn_load.c (thanks to
+Philippe Queinnec).
+* SEGV fault handlers sometimes did not get reset correctly (thanks
+to David Pickens).
+* Added a fix for SOLARIS_THREADS on Intel (thanks to David Pickens).
This probably needs more work to become functional.
* Fixed struct sigcontext_struct in os_dep.c for compilation under
-Linux 2.1.X.
-* Changed the DJGPP STACKBOTTOM and DATASTART values to those ones suggested.
-These may still not be right, but it is
+Linux 2.1.X (thanks to Fergus Henderson).
+* Changed the DJGPP STACKBOTTOM and DATASTART values to those ones suggested
+(by Kristian Kristensen). These may still not be right, but it is
it is likely to work more often than what was there before. They may
even be exactly right.
* Added a #include <string.h> to test_cpp.cc. This appears to help
-with HP/UX and gcc.
+with HP/UX and gcc (thanks to Assar Westerlund).
* Version 4.11 failed to run in incremental mode on recent 64-bit Irix
kernels. This was a problem related to page unaligned heap segments.
Changed the code to page align heap sections on all platforms.
(I had mistakenly identified this as a kernel problem earlier.
It was not.)
* Version 4.11 did not make allocated storage executable, except on
-one or two platforms, due to a bug in a #if test.
+one or two platforms, due to a bug in a #if test (thanks to David Grove
+for pointing this out).
* Added sparc_sunos4_mach_dep.s to support Sun's compilers under SunOS4.
* Added GC_exclude_static_roots.
* Fixed the object size mapping algorithm. This shouldn't matter,
but the old code was ugly.
* Heap checking code could die if one of the allocated objects was
-larger than its base address. (Unsigned underflow problem.)
-* Added RS6000 (AIX) dynamic library support and fixed STACK_BOTTOM.
+larger than its base address. (Unsigned underflow problem. Thanks
+to Clay Spence for isolating the problem.)
+* Added RS6000 (AIX) dynamic library support and fixed STACK_BOTTOM (thanks
+to Fred Stearns).
* Added Fergus Henderson's patches for improved robustness with large
heaps and lots of blacklisting.
* Added Peter Chubb's changes to support Solaris Pthreads, to support
@@ -7752,13 +8124,19 @@ supported. The collector now defines USE_MMAP by default on Solaris.
a DLL under GNU win32.
* Added Ivan V. Demakov's port to Watcom C on X86.
* Added Ian Piumarta's Linux/PowerPC port.
-* Added PointerFreeGC to the placement
-options in gc_cpp.h. This is of course unsafe, and may be controversial.
+* Added PointerFreeGC to the placement options in gc_cpp.h (suggested by
+Brian Burton). This is of course unsafe, and may be controversial.
On the other hand, it seems to be needed often enough that it's worth
adding as a standard facility.
+* Add Lars Farm's suggestions on building the collector for MacOS.
+
+== [4.12alpha2] ==
-== [4.11] ==
+(Changes not specified.)
+
+
+== [4.11] 1996-12-03 ==
* Rationalized (hopefully) GC_try_to_collect in an incremental collection
environment. It appeared to not handle a call while a collection was in
@@ -7770,7 +8148,8 @@ modifications.
* Fixed the MPROTECT_VDB code to deal with large pages and imprecise
fault addresses (as on an UltraSPARC running Solaris 2.5). Note that this
was not a problem in the default configuration, which uses PROC_VDB.
-* The DEC Alpha assembly code needed to restore $gp between calls.
+* The DEC Alpha assembly code needed to restore $gp between calls (thanks to
+Fergus Henderson for tracking this down and supplying a patch).
* The write command for "de" was completely broken for large files.
I used the easiest portable fix, which involved changing the semantics
so that f.new is written instead of overwriting f. That's safer anyway.
@@ -7780,7 +8159,7 @@ mixing the collector's sbrk allocation with malloc/realloc.
old code failed under IRIX6.
* Required double word alignment for MIPS.
* Various minor fixes to remove warnings.
-* Attempted to fix some Solaris threads problems.
+* Attempted to fix some Solaris threads problems (reported by Zhiying Chen).
In particular, the collector could try to fork a thread with the
world stopped as part of GC_thr_init. It also failed to deal with
the case in which the original thread terminated before the whole
@@ -7790,24 +8169,30 @@ on the incremental collector under Irix, and perhaps under other
operating systems.
* Added some code to support allocating the heap with mmap. This may
be preferable under some circumstances.
-* Integrated dynamic library support for HP.
+* Integrated dynamic library support for HP (thanks to Knut Tvedten).
* Integrated James Clark's win32 threads support, and made a number
-of changes to it. This is still not 100% solid.
-* Integrated Alistair Crooks' support for UTS4 running on an Amdahl
+of changes to it (many of which suggested by Pontus Rydin). This is still
+not 100% solid.
+* Integrated Alistair G. Crooks' support for UTS4 running on an Amdahl
370-class machine.
* Fixed a serious bug in explicitly typed allocation. Objects requiring
large descriptors where handled in a way that usually resulted in
-a segmentation fault in the marker.
-* Added partial support for GNU win32 development.
-* Added optional support for Java-style finalization semantics.
-This is recommended only for Java implementations.
+a segmentation fault in the marker (thanks to Jeremy Fitzhardinge
+for helping to track this down).
+* Added partial support for GNU win32 development (thanks to
+Fergus Henderson).
+* Added optional support for Java-style finalization semantics (thanks to
+Patrick Bridges). This is recommended only for Java implementations.
* GC_malloc_uncollectable faulted instead of returning 0 when out of
-memory.
+memory (thanks to Daniel R. Grayson for noticing).
* Calls to GC_base before the collector was initialized failed on a
-DEC Alpha.
-* Added base pointer checking to GC_REGISTER_FINALIZER in debugging mode.
-* GC_debug_realloc failed for uncollectible objects.
-* Explicitly typed allocation could crash if it ran out of memory.
+DEC Alpha (thanks to Matthew Flatt).
+* Added base pointer checking to GC_REGISTER_FINALIZER in debugging mode
+(thanks to Jeremy Fitzhardinge).
+* GC_debug_realloc failed for uncollectible objects (thanks to
+Jeremy Fitzhardinge).
+* Explicitly typed allocation could crash if it ran out of memory (thanks to
+Jeremy Fitzhardinge).
* Added minimal support for a DEC Alpha running Linux.
* Fixed a problem with allocation of objects whose size overflowed
ptrdiff_t. (This now fails unconditionally, as it should.)
@@ -7817,21 +8202,27 @@ ptrdiff_t. (This now fails unconditionally, as it should.)
* Fixed a serious bug in README.solaris2.
Multi-threaded programs must include
gc.h with SOLARIS_THREADS defined.
-* Changed GC_free so it actually deallocates uncollectible objects.
-* Added Linux ELF support for dynamic libraries.
+* Changed GC_free so it actually deallocates uncollectible objects (thanks
+to Peter Chubb for pointing out the problem).
+* Added Linux ELF support for dynamic libraries (thanks to Patrick Bridges).
* Changed the Borland cc configuration so that the assembler is not
required.
* Fixed a bug in the C++ test that caused it to fail in 64-bit
environments.
-== [4.10] ==
+== [4.10t3] 1996-11-18 ==
+
+Some changes related to threads support.
+
+
+== [4.10] 1996-02-19 ==
* Fixed a typo around a call to GC_collect_or_expand in alloc.c. It broke
-handling of out of memory.
+handling of out of memory. (Thanks to Patrick C. Beard for noticing.)
-== [4.9] ==
+== [4.9] 1996-02-12 ==
* More README.debugging fixes.
* Objects ready for finalization, but not finalized in the same GC
@@ -7851,44 +8242,51 @@ didn't test.
occurred a while ago.
-== [4.8] ==
+== [4.8] 1995-11-20 ==
* Changed a "comment" in a MacOS specific part of mach_dep.c that caused
gcc to fail on other platforms.
-== [4.7] ==
+== [4.7] 1995-11-18 ==
-* Fixed some compilation problems with -DCHECKSUMS.
-* Updated some Mac specific files.
+* Fixed some compilation problems with -DCHECKSUMS (thanks to Ian Searle).
+* Updated some Mac specific files (to synchronize with Patrick C. Beard).
* Fixed a serious bug for machines with non-word-aligned pointers.
+(Thanks to Patrick C. Beard for pointing out the problem. The collector
+should fail almost any conceivable test immediately on such machines.)
-== [4.6] ==
+== [4.6] 1995-11-09 ==
-* Added Linux ELF support.
+* Added Linux ELF support (thanks to Arrigo Triulzi).
* GC_base crashed if it was called before any other GC_ routines.
This could happen if a gc_cleanup object was allocated outside the heap
before any heap allocation.
* The heap expansion heuristic was not stable if all objects had finalization
enabled. Fixed finalize.c to count memory in finalization queue and
avoid explicit deallocation. Changed alloc.c to also consider this count.
-(This is still not recommended. It's expensive if nothing else.)
-* GC_malloc_uncollectable(0) was broken.
-* The collector didn't compile under Linux 1.3.X.
-The current workaround is ugly, but expected to be temporary.
+(This is still not recommended. It's expensive if nothing else. Thanks
+to John Ellis for pointing this out.)
+* GC_malloc_uncollectable(0) was broken (thanks to Phong Vo for pointing
+this out).
+* The collector didn't compile under Linux 1.3.X (thanks to Fred Gilham for
+pointing this out). The current workaround is ugly, but expected to be
+temporary.
* Fixed a formatting problem for SPARC stack traces.
* Fixed some '=='s in os_dep.c that should have been assignments.
-Fortunately these were in code that should never be executed anyway.
+Fortunately these were in code that should never be executed anyway (thanks
+to Fergus Henderson).
* Fixed the heap block allocator to only drop blacklisted blocks in small
chunks. Made BL_LIMIT self adjusting. (Both of these were in response
to heap growth observed by Paul Graham.)
-* Fixed the Metrowerks/68K Mac code to also mark from a6.
+* Fixed the Metrowerks/68K Mac code to also mark from a6 (thanks to
+Patrick C. Beard).
* Significantly updated README.debugging.
* Fixed some problems with longjmps out of signal handlers, especially under
Solaris. Added a workaround for the fact that siglongjmp doesn't appear to
do the right thing with -lthread under Solaris.
-* Added MSDOS/djgpp port.
+* Added MSDOS/djgpp port (thanks to Mitch Harris).
* Added "make reserved_namespace" and "make user_namespace". The
first renames ALL "GC_xxx" identifiers as "_GC_xxx". The second is the
inverse transformation. Note that doing this is guaranteed to break all
@@ -7905,13 +8303,15 @@ beginning to hopefully specify the remaining dangers.
* Fixed some of the .h file organization. Fixed "make floppy".
-== [4.5] ==
+== [4.5] 1995-06-14 ==
-* Fixed many minor and one major README bugs.
-* Fixed ALPHA/OSF/1 dynamic library support.
+* Fixed many minor and one major README bugs (thanks to Franklin Chen
+for pointing out many of them).
+* Fixed ALPHA/OSF/1 dynamic library support (thanks to Jonathan Bachrach).
* Added incremental GC support (MPROTECT_VDB) for Linux (with some
help from Bruno Haible).
-* Altered SPARC recognition tests in gc.h and config.h.
+* Altered SPARC recognition tests in gc.h and config.h (mostly as
+suggested by Fergus Henderson).
* Added basic incremental GC support for win32, as implemented by
Windows NT and Windows 95. GC_enable_incremental is a no-op
under win32s, which doesn't implement enough of the VM interface.
@@ -7931,16 +8331,17 @@ The old way turned out to be a performance bug on some machines.
* Added -DNO_DEBUGGING and GC_dump.
* Fixed a couple of bugs arising with SOLARIS_THREADS +
REDIRECT_MALLOC.
-* Added NetBSD/M68K port.
+* Added NetBSD/M68K port (thanks to Peter Seebach).
* Fixed a serious realloc bug. For certain object sizes, the collector
-wouldn't scan the expanded part of the object.
+wouldn't scan the expanded part of the object. (Thanks to Clay Spence
+for noticing the problem, and helping me to track it down.)
-== [4.4] ==
+== [4.4] 1995-02-18 ==
* ASM_CLEAR_CODE was erroneously defined for HP
PA machines, resulting in a compile error.
-* Fixed OS/2 Makefile to create a library.
+* Fixed OS/2 Makefile to create a library (thanks to Mark Boulter).
* 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
@@ -7954,7 +8355,7 @@ gc_cleanup is miscompiled.
a new and different VirtualQuery bug under newer
versions of win32S.
* GC_non_gc_bytes was not correctly maintained by
-GC_free. Fixed.
+GC_free. Fixed (thanks to James Clark).
* 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
@@ -7967,17 +8368,22 @@ 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.
-* Added some support for the Borland development environment.
+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.
+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.
+* Fixed Amiga port (thanks to Michel Schinz).
* 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.
@@ -7986,7 +8392,7 @@ objects allocated with the system malloc.
* Added REDIRECT_MALLOC.
-== [4.3] ==
+== [4.3] 1994-12-23 ==
* Fixed SPARC alignment problem with GC_DEBUG.
* Fixed Solaris threads /proc workaround. The real
@@ -7995,8 +8401,9 @@ problem was an interaction with mprotect.
* Slightly improved allocator space utilization by
fixing the GC_size_map mechanism.
* Integrated some Sony News and MIPS RISCos 4.51
-patches.
-* Fixed HP_PA alignment problem.
+patches (thanks to Nobuyuki Hikichi at Software Research Associates,
+Inc., Japan).
+* Fixed HP_PA alignment problem (thanks to Brian F. Dennis).
* Added GC_same_obj and friends. Changed GC_base
to return 0 for pointers past the end of large objects.
Improved GC_base performance with ALL_INTERIOR_POINTERS
@@ -8013,15 +8420,15 @@ Can be changed back with a minor Makefile edit.
following my own naming convention. Added the function
CORD_to_const_char_star.
* Fixed a gross bug in GC_finalize. Symptom: occasional
-address faults in that function.
+address faults in that function (thanks to Anselm Baird-Smith).
* Added port to ICL DRS6000 running DRS/NX. Restructured
things a bit to factor out common code, and remove obsolete
code. Collector should now run under SUNOS5 with either
-mprotect or /proc dirty bits.
+mprotect or /proc dirty bits. (Thanks to Douglas Steel.)
* More bug fixes and workarounds for Solaris 2.X. (These were
mostly related to putting the collector in a dynamic library,
which didn't really work before. Also SOLARIS_THREADS
-didn't interact well with dl_open.)
+didn't interact well with dl_open.) (Thanks to Brian Lewis.)
* Fixed a serious performance bug on the DEC Alpha. The text
segment was getting registered as part of the root set.
(Amazingly, the result was still fast enough that the bug
@@ -8029,28 +8436,27 @@ was not conspicuous.) The fix works on OSF/1, version 1.3.
Hopefully it also works on other versions of OSF/1 ...
* Fixed a bug in GC_clear_roots.
* Fixed a bug in GC_generic_malloc_words_small that broke
-gc_inl.h.
+gc_inl.h (reported by Antoine de Maricourt).
* Fixed some problems with cord/de under Linux.
* Fixed some cord problems, notably with CORD_riter4.
-* Added DG/UX port.
+* Added DG/UX port (thanks to Ben A. Mesander).
* Added finalization registration routines with weaker ordering
constraints. (This is necessary for C++ finalization with
multiple inheritance, since the compiler often adds self-cycles.)
-* Filled the holes in the SCO port.
-* John Ellis' additions to the C++ support: From John:
-* I completely rewrote the documentation in the interface gc_c++.h
-(later renamed gc_cpp.h). I've tried to make it both clearer and more
-precise.
-* The definition of accessibility now ignores pointers from an
-finalizable object (an object with a clean-up function) to itself.
+* Filled the holes in the SCO port (thanks to Michael Arnoldus).
+* Completely rewritten the documentation in the interface gc_c++.h
+(later renamed gc_cpp.h) making it both clearer and more precise (done by
+John Ellis).
+* The definition of accessibility now ignores pointers from a finalizable
+object (an object with a clean-up function) to itself (done by John Ellis).
This allows objects with virtual base classes to be finalizable by the
collector. Compilers typically implement virtual base classes using
pointers from an object to itself, which under the old definition of
accessibility prevented objects with virtual base classes from ever
being collected or finalized.
* gc_cleanup now includes gc as a virtual base. This was enabled by
-the change in the definition of accessibility.
-* I added support for operator new[]. Since most compilers
+the change in the definition of accessibility (by John Ellis).
+* Added support for operator new[] (by John Ellis). Since most compilers
don't yet support operator new[], it is conditionalized on
-DOPERATOR_NEW_ARRAY. The code is untested, but its trivial and looks
correct.
@@ -8058,19 +8464,19 @@ correct.
tries to test for the C++-specific functionality not tested by the
other programs.
* Added unistd.h include to misc.c. (Needed for ppcr.)
-* Added PowerMac port.
+* Added PowerMac port (thanks to Patrick C. Beard).
* Fixed "srcdir"-related Makefile problems. Changed things so
that all externally visible include files always appear in the
include subdirectory of the source. Made gc.h directly
-includable from C++ code.
-* Changed Intel code to also mark from ebp
+includable from C++ code (thanks to Per Bothner).
+* Changed Intel code to also mark from ebp (thanks to Kevin Warne).
* Renamed C++ related files so they could live in a FAT
-file system.
+file system (thanks to Charles Fiterman).
* Changed Windows NT Makefile to include C++ support in
gc.lib. Added C++ test as Makefile target.
-== [4.2] ==
+== [4.2] 1994-08-03 ==
* Multiple bug fixes/workarounds in the Solaris threads version.
(It occasionally failed to locate some register contents for
@@ -8081,7 +8487,8 @@ circumstances. My stack marking code
contained a serious performance bug. The new code is
extremely defensive, and has not failed in several CPU
hours of testing. But no guarantees ...)
-* Added MacOS support.
+* Added MacOS support. (Thanks to Patrick C. Beard.
+David Chase suggested several improvements.)
* Fixed several syntactic bugs in gc_c++.h and friends. (These
didn't bother g++, but did bother most other compilers.)
Fixed gc_c++.h finalization interface.
@@ -8091,8 +8498,8 @@ few cases in which it should have been.
* Added GC_collect_a_little.
* Added some prototypes to gc.h.
* Some other minor bug fixes (notably in Makefile).
-* Fixed OS/2 / EMX port.
-* Fixed AmigaDOS port.
+* Fixed OS/2 / EMX port (thanks to Ari Huttunen).
+* Fixed AmigaDOS port (thanks to Michel Schinz).
* Fixed the DATASTART definition under Solaris. There
was a 1 in 16K chance of the collector missing the first
64K of static data (and thus crashing).
@@ -8100,7 +8507,7 @@ was a 1 in 16K chance of the collector missing the first
* Fixed PCR-Makefile for upcoming PPCR release.
-== [4.1] ==
+== [4.1] 1994-05-20 ==
* Changed finalization implementation to guarantee that
finalization procedures are called outside of the allocation
@@ -8114,7 +8521,8 @@ a problem.
heap growth during startup on machines that do not clear
memory obtained from the OS (e.g. win32S).
* Ported de editor to win32/win32S. (This is now the only
-version with a mouse-sensitive UI.)
+version with a mouse-sensitive UI. Thanks to Rob Haack for the
+implementation based on the generic Windows application template.)
* Added GC_malloc_ignore_off_page to allocate large arrays
in the presence of ALL_INTERIOR_POINTERS.
* Changed GC_call_with_alloc_lock to not disable signals in
@@ -8142,7 +8550,7 @@ optimizer bug.
* Fixed a Makefile bug for target "c++".
-== [4.0] ==
+== [4.0] 1994-04-07 ==
* Added support for Solaris threads (which was possible
only by reimplementing some fraction of Solaris threads,
@@ -8164,9 +8572,12 @@ destructors.)
* Added typed allocation primitives. Rewrote the marker to
accommodate them with more reasonable efficiency. This
change should also speed up marking for GC_malloc allocated
-objects a little. See gc_typed.h for new primitives.
+objects a little. See gc_typed.h for new primitives. (Thanks to
+Zhong Shao performed much of the experimentation that led to the
+current typed allocation facility.)
* Improved debugging facilities slightly. Allocation time
-stack traces are now kept by default on SPARC/SUNOS4.
+stack traces are now kept by default on SPARC/SUNOS4. (Thanks to
+Scott Schwartz.)
* Added better support for small heap applications.
* Significantly extended cord package. Fixed a bug in the
implementation of lazily read files. Printf and friends now
@@ -8174,8 +8585,9 @@ have cord variants. Cord traversals are a bit faster.
* Made ALL_INTERIOR_POINTERS recognition the default.
* Fixed de so that it can run in constant space, independent
of file size. Added simple string searching to cords and de.
-* Added the Hull-Ellis C++ interface.
-* Added dynamic library support for OSF/1.
+* Added the Hull-Ellis C++ interface (supplied by Jesse Hull and John Ellis).
+* Added dynamic library support for OSF/1 (thanks to Alan Dosser and
+Tim Bingham at DEC).
* Changed argument to GC_expand_hp to be expressed
in units of bytes instead of heap blocks. (Necessary
since the heap block size now varies depending on
@@ -8183,16 +8595,17 @@ configuration. The old version was never very clean.)
* Added GC_get_heap_size(). The previous "equivalent"
was broken.
* Restructured the Makefile a bit.
+* Added FreeBSD port (provided by Jeffrey Hsu).
-== [3.7] ==
+== [3.7] 1994-03-15 ==
* Added a workaround for an HP/UX compiler bug.
* Fixed another stack clearing performance bug. Reworked
that code once more.
-== [3.6] ==
+== [3.6] 1994-01-14 ==
* fixed a bug in the mark stack growth code that was introduced
in 3.4.
@@ -8227,31 +8640,33 @@ the data segment contained interesting roots. The workaround
assumes a demand-loadable executable. The original may have
have "worked" in some other cases.
* Added dynamic library support under IRIX5.
-* Added support for EMX under OS/2.
+* Added support for EMX under OS/2 (thanks to Ari Huttunen).
+* Added support of Motorola 88K processor running CX/UX (by Brent Benson).
== [3.4] ==
* Fixed a performance bug in GC_realloc.
* Updated the amiga port.
-* Added NetBSD and 386BSD ports.
+* Added NetBSD and 386BSD ports (supplied by Alistair G. Crooks).
* Added cord library.
* Added trivial performance enhancement for
-ALL_INTERIOR_POINTERS. (Don't scan last word.)
+ALL_INTERIOR_POINTERS (do not scan last word).
-== [3.3] ==
+== [3.3] 1993-10-02 ==
-* PCR-specific bugs.
+* PCR-specific bugs (thanks to Neil Sharman).
* Missing locking in GC_free, redundant FASTUNLOCK
in GC_malloc_stubborn, and 2 bugs in
-GC_unregister_disappearing_link.
+GC_unregister_disappearing_link (pointed out by Neil Sharman).
* Common symbols allocated by the SunOS4.X dynamic loader
were not included in the root set.
-* Bug in GC_finalize
-* Merged Amiga port from Jesper Peterson (untested)
+* Bug in GC_finalize (reported by Brian Beuning and Alan Dosser).
+* Merged Amiga port from Jesper Peterson (untested).
* Merged NeXT port from Thomas Funke (significantly
-modified and untested)
+modified and untested). (Also thanks to Brian D. Carlstrom for
+the supplied the NeXT ports.)
== [3.2] ==
@@ -8270,9 +8685,9 @@ misfeature that caused problems when the collector was turned into
a dynamic library.
* A fix for a bug in GC_base that could result in a memory fault.
* A fix for a performance bug (and several other misfeatures) pointed
-out by Dave Detlefs and Al Dosser.
+out by Dave Detlefs and Alan Dosser.
* Use of dirty bit information for static data under Solaris 2.X.
-* DEC Alpha/OSF1 support.
+* DEC Alpha/OSF1 support (thanks to Alan Dosser).
* Incremental collection on more platforms.
* A more refined heap expansion policy. Less space usage by default.
* Various minor enhancements to reduce space usage, and to reduce
@@ -8290,6 +8705,11 @@ objects with debugging allocation.
Added generational/incremental collection and stubborn objects.
+== [2.6] 1993-04-27 ==
+
+(Changes not specified.)
+
+
== [2.5] ==
* Removed an explicit call to exit(1)
@@ -8300,7 +8720,7 @@ doesn't require this to work. The ANSI sanctioned way of doing things
causes too many compatibility problems.)
-== [2.4] ==
+== [2.4] 1993-01-26 ==
Added GC_free_space_divisor as a tuning knob, added
support for OS/2 and linux, and fixed the following bugs:
@@ -8310,7 +8730,8 @@ fail to be considered for marking.
bss sections of the dynamic library. This could result in a bad memory
reference if the actual length was a multiple of a page. (Observed on
Sun 3. Can probably also happen on a Sun 4.)
-(Dynamic library handling is still broken on Sun 3s
+(Thanks to Robert Brazile for pointing out that the Sun 3 version
+was broken. Dynamic library handling is still broken on Sun 3s
under 4.1.1U1, but apparently not 4.1.1. If you have such a machine,
use -Bstatic.)
@@ -8329,7 +8750,7 @@ in a multi-threaded environment. (The locking primitives need to be
replaced for other threads packages.)
* GC_CONS was thoroughly broken.
* On a SPARC with dynamic linking, signals stayed disabled while the
-client code was running.
+client code was running (thanks to Manuel Serrano).
== [2.2] ==
@@ -8358,7 +8779,8 @@ on HP/PA machines.
* Introduced a consistent naming convention for collector
routines and added support for registering dynamic library data segments
-in the standard mark_roots.c. Most of the data structures were revamped.
+in the standard mark_roots.c (original code supporting the SunOS dynamic
+loader provided by Bill Janssen). Most of the data structures were revamped.
The treatment of interior pointers was completely changed. Finalization
was added. Support for locking was added. Object kinds were added.
We added a black listing facility to avoid allocating at addresses known
@@ -8367,14 +8789,16 @@ was accomplished by adapting ideas and code from the PCR collector.
The test program was changed and expanded.
-== [1.9] ==
+== [1.9] 1992-01-29 ==
* fixed a major bug in gc_realloc.
== [1.8] ==
-* added ULTRIX support in gc_private.h.
+* added ULTRIX support in gc_private.h. (Robert Brazile originally supplied
+the ULTRIX code. Alan Dosser and Regis Cridlig subsequently provided updates
+and information on variation between ULTRIX systems.)
== [1.5] ==
@@ -8401,3 +8825,11 @@ the assignments can lead to an unsaved register being overwritten.
Known to cause problems under SunOS 3.5 WITHOUT the -O option. (With
-O the compiler recognizes it as dead code. It probably shouldn't,
but that's another story.)
+The SPARC-specific code was originally contributed by Mark Weiser.
+The Encore Multimax modifications were supplied by Kevin Kenny.
+The adaptation to the IBM PC/RT is largely
+due to Vernon Lee, on machines made available to Rice by IBM.
+Much of the HP specific code and a number of good suggestions for improving
+the generic code are due to Walter Underwood.
+Parag Patel supplied the A/UX code.
+Manuel Serrano supplied linux and Sony News specific code.
diff --git a/Makefile.am b/Makefile.am
index 2aacca29..f46456d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -100,8 +100,8 @@ libgc_la_LIBADD = @addobjs@ $(THREADDLLIBS) $(UNWINDLIBS) $(ATOMIC_OPS_LIBS)
libgc_la_DEPENDENCIES = @addobjs@
libgc_la_LDFLAGS = $(extra_ldflags_libgc) -version-info 1:3:0 -no-undefined
-EXTRA_libgc_la_SOURCES = src/ia64_save_regs_in_stack.s src/sparc_mach_dep.S \
- src/sparc_netbsd_mach_dep.s src/sparc_sunos4_mach_dep.s
+EXTRA_libgc_la_SOURCES = ia64_save_regs_in_stack.s sparc_mach_dep.S \
+ sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s
# C++ Interface
@@ -141,14 +141,12 @@ AM_CFLAGS = @GC_CFLAGS@
## FIXME: we shouldn't have to do this, but automake forces us to.
## We use -Wp,-P to strip #line directives. Irix `as' chokes on
## these.
-if COMPILER_XLC
- ## XLC neither requires nor tolerates the unnecessary assembler goop
+if ASM_WITH_CPP_UNSUPPORTED
ASM_CPP_OPTIONS =
else
- ## We use -Wp,-P to strip #line directives. Irix `as' chokes on
- ## these.
ASM_CPP_OPTIONS = -Wp,-P -x assembler-with-cpp
endif
+
.s.lo:
$(LTCOMPILE) $(ASM_CPP_OPTIONS) -c $<
@@ -167,7 +165,7 @@ CCASFLAGS += $(DEFS)
# documentation which is not installed
#
-EXTRA_DIST += README.QUICK TODO
+EXTRA_DIST += README.QUICK
# other makefiles
# :GOTCHA: deliberately we do not include 'Makefile'
diff --git a/Makefile.direct b/Makefile.direct
index b5c1a642..6a7e94d9 100644
--- a/Makefile.direct
+++ b/Makefile.direct
@@ -21,10 +21,17 @@ AS_ABI_FLAG=$(ABI_FLAG)
# executables.
CC=cc $(ABI_FLAG)
+
CXX=g++ $(ABI_FLAG)
+# Needed only for "make c++", which adds the c++ interface.
+
AS=as $(AS_ABI_FLAG)
-# The above doesn't work with gas, which doesn't run cpp.
-# Define AS as `gcc -c -x assembler-with-cpp' instead.
+# The above doesn't work with gas, which doesn't run cpp.
+# Define AS as `gcc -c -x assembler-with-cpp' instead.
+# Under Irix 6, you have to specify the ABI (-o32, -n32, or -64)
+# if you use something other than the default ABI on your machine.
+
+LD=ld
# Redefining srcdir allows object code for the nonPCR version of the collector
# to be generated in different directories.
@@ -107,16 +114,15 @@ SRCS= $(CSRCS) \
include/gc_config_macros.h include/private/pthread_support.h \
include/private/pthread_stop_world.h include/private/darwin_semaphore.h \
include/private/darwin_stop_world.h include/private/thread_local_alloc.h \
- src/ia64_save_regs_in_stack.s src/sparc_mach_dep.S \
- src/sparc_netbsd_mach_dep.s src/sparc_sunos4_mach_dep.s $(CORD_SRCS)
+ ia64_save_regs_in_stack.s sparc_mach_dep.S \
+ sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s $(CORD_SRCS)
-DOC_FILES= README.QUICK TODO doc/README.Mac doc/README.OS2 \
+DOC_FILES= README.QUICK doc/README.Mac doc/README.OS2 \
doc/README.amiga doc/README.cords doc/debugging.html \
doc/finalization.html doc/porting.html doc/overview.html \
doc/README.dj doc/README.hp doc/README.linux doc/README.rs6000 \
doc/README.sgi doc/README.solaris2 doc/README.uts \
- doc/README.symbian doc/README.win32 doc/barrett_diagram \
- README.md AUTHORS doc/gc.man \
+ doc/README.symbian doc/README.win32 README.md AUTHORS doc/gc.man \
doc/README.environment doc/tree.html doc/gcdescr.html \
doc/README.autoconf doc/README.macros doc/README.ews4800 \
doc/README.DGUX386 doc/README.arm.cross doc/leak.html \
@@ -163,7 +169,7 @@ CURSES= -lcurses -ltermlib
# the SHELL environment variable.
SHELL= /bin/sh
-SPECIALCFLAGS = -I$(srcdir)/include -I$(AO_INSTALL_DIR)/include
+SPECIALCFLAGS= -I$(srcdir)/include -I$(AO_INSTALL_DIR)/include
# Alternative flags to the C compiler for mach_dep.c.
# Mach_dep.c often doesn't like optimization, and it's
# not time-critical anyway.
@@ -176,7 +182,7 @@ all: gc.a gctest
$(AO_INSTALL_DIR):
CC=$(CC) MAKE=$(MAKE) $(srcdir)/build_atomic_ops.sh
-LEAKFLAGS=$(CFLAGS) -DFIND_LEAK
+LEAKFLAGS= $(CFLAGS) -DFIND_LEAK
BSD-pkg-all: bsd-libgc.a bsd-libleak.a
@@ -201,11 +207,11 @@ mach_dep.o $(SRCS)
$(MAKE) -f PCR-Makefile
$(OBJS) tests/test.o dyn_load.o dyn_load_sunos53.o: \
- $(srcdir)/include/private/gc_priv.h \
- $(srcdir)/include/private/gc_hdrs.h $(srcdir)/include/private/gc_locks.h \
- $(srcdir)/include/gc.h $(srcdir)/include/gc_pthread_redirects.h \
- $(srcdir)/include/private/gcconfig.h $(srcdir)/include/gc_typed.h \
- $(srcdir)/include/gc_config_macros.h Makefile $(AO_INSTALL_DIR)
+ $(srcdir)/include/private/gc_priv.h \
+ $(srcdir)/include/private/gc_hdrs.h $(srcdir)/include/private/gc_locks.h \
+ $(srcdir)/include/gc.h $(srcdir)/include/gc_pthread_redirects.h \
+ $(srcdir)/include/private/gcconfig.h $(srcdir)/include/gc_typed.h \
+ $(srcdir)/include/gc_config_macros.h Makefile $(AO_INSTALL_DIR)
# The dependency on Makefile is needed. Changing
# options affects the size of GC_arrays,
# invalidating all .o files that rely on gc_priv.h
@@ -217,8 +223,8 @@ mark.o typd_mlc.o finalize.o ptr_chck.o: $(srcdir)/include/gc_mark.h \
$(srcdir)/include/private/gc_pmark.h
specific.o pthread_support.o thread_local_alloc.o win32_threads.o: \
- $(srcdir)/include/private/specific.h $(srcdir)/include/gc_inline.h \
- $(srcdir)/include/private/thread_local_alloc.h
+ $(srcdir)/include/private/specific.h $(srcdir)/include/gc_inline.h \
+ $(srcdir)/include/private/thread_local_alloc.h
dbg_mlc.o gcj_mlc.o: $(srcdir)/include/private/dbg_mlc.h
@@ -239,7 +245,8 @@ base_lib gc.a: $(OBJS) dyn_load.o $(UTILS)
./if_mach M68K AMIGA $(AR) -vrus gc.a $(OBJS) dyn_load.o
./if_not_there dont_ar_1 $(AR) ru gc.a $(OBJS) dyn_load.o
./if_not_there dont_ar_1 $(RANLIB) gc.a || cat /dev/null
-# ignore ranlib failure; that usually means it doesn't exist, and isn't needed
+# Ignore ranlib failure; that usually means it doesn't exist, and
+# isn't needed.
cords: $(CORD_OBJS) cord/cordtest $(UTILS)
rm -f dont_ar_3
@@ -254,7 +261,7 @@ gc_cpp.o: $(srcdir)/gc_cpp.cc $(srcdir)/include/gc_cpp.h $(srcdir)/include/gc.h
$(CXX) -c $(CXXFLAGS) $(srcdir)/gc_cpp.cc
test_cpp: $(srcdir)/tests/test_cpp.cc $(srcdir)/include/gc_cpp.h gc_cpp.o $(srcdir)/include/gc.h \
- base_lib $(UTILS)
+ base_lib $(UTILS)
rm -f test_cpp
./if_mach HP_PA HPUX $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/tests/test_cpp.cc gc_cpp.o gc.a -ldld `./threadlibs`
./if_not_there test_cpp $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/tests/test_cpp.cc gc_cpp.o gc.a `./threadlibs`
@@ -286,12 +293,12 @@ sunos5gc.so: $(OBJS) dyn_load_sunos53.o
# Alpha/OSF shared library version of the collector
libalphagc.so: $(OBJS)
- ld -shared -o libalphagc.so $(OBJS) dyn_load.o -lc
+ $(LD) -shared -o libalphagc.so $(OBJS) dyn_load.o -lc
ln libalphagc.so libgc.so
# IRIX shared library version of the collector
libirixgc.so: $(OBJS) dyn_load.o
- ld -shared $(ABI_FLAG) -o libirixgc.so $(OBJS) dyn_load.o -lc
+ $(LD) -shared $(ABI_FLAG) -o libirixgc.so $(OBJS) dyn_load.o -lc
ln libirixgc.so libgc.so
# Linux shared library version of the collector
@@ -311,33 +318,37 @@ dyn_test:
#.SUFFIXES: .lo $(SUFFIXES)
#
#.c.lo:
-# $(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c $< -o $@
+# $(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c $< -o $@
#
# liblinuxgc.so: $(LIBOBJS) dyn_load.lo
# gcc -shared -Wl,-soname=libgc.so.0 -o libgc.so.0 $(LIBOBJS) dyn_load.lo
# touch liblinuxgc.so
-mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/src/sparc_mach_dep.S \
- $(srcdir)/src/sparc_sunos4_mach_dep.s \
- $(srcdir)/src/ia64_save_regs_in_stack.s \
- $(srcdir)/src/sparc_netbsd_mach_dep.s $(UTILS)
+mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/sparc_mach_dep.S \
+ $(srcdir)/sparc_sunos4_mach_dep.s \
+ $(srcdir)/ia64_save_regs_in_stack.s \
+ $(srcdir)/sparc_netbsd_mach_dep.s $(UTILS)
rm -f mach_dep.o
- ./if_mach SPARC SOLARIS $(CC) -c -o mach_dep2.o $(srcdir)/src/sparc_mach_dep.S
- ./if_mach SPARC OPENBSD $(AS) -o mach_dep2.o $(srcdir)/src/sparc_sunos4_mach_dep.s
- ./if_mach SPARC NETBSD $(AS) -o mach_dep2.o $(srcdir)/src/sparc_netbsd_mach_dep.s
+ ./if_mach SPARC SOLARIS $(CC) -c -o mach_dep2.o $(srcdir)/sparc_mach_dep.S
+ ./if_mach SPARC OPENBSD $(AS) -o mach_dep2.o $(srcdir)/sparc_sunos4_mach_dep.s
+ ./if_mach SPARC NETBSD $(AS) -o mach_dep2.o $(srcdir)/sparc_netbsd_mach_dep.s
./if_mach SPARC "" $(CC) -c -o mach_dep1.o $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
- ./if_mach SPARC "" ld -r -o mach_dep.o mach_dep1.o mach_dep2.o
- ./if_mach IA64 "" as $(AS_ABI_FLAG) -o ia64_save_regs_in_stack.o $(srcdir)/src/ia64_save_regs_in_stack.s
+ ./if_mach SPARC "" $(LD) -r -o mach_dep.o mach_dep1.o mach_dep2.o
+ ./if_mach IA64 "" $(AS) -o ia64_save_regs_in_stack.o $(srcdir)/ia64_save_regs_in_stack.s
./if_mach IA64 "" $(CC) -c -o mach_dep1.o $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
- ./if_mach IA64 "" ld -r -o mach_dep.o mach_dep1.o ia64_save_regs_in_stack.o
- ./if_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
+ ./if_mach IA64 "" $(LD) -r -o mach_dep.o mach_dep1.o ia64_save_regs_in_stack.o
+ -./if_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
+ -./if_not_there mach_dep.o `cygpath -w /bin/sh` $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
+ -./if_not_there mach_dep.o /bin/sh $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
mark_rts.o: $(srcdir)/mark_rts.c $(UTILS)
rm -f mark_rts.o
-./if_mach ALPHA OSF1 $(CC) -c $(CFLAGS) -Wo,-notail $(srcdir)/mark_rts.c
- ./if_not_there mark_rts.o $(CC) -c $(CFLAGS) $(srcdir)/mark_rts.c
-# Work-around for DEC optimizer tail recursion elimination bug.
-# The ALPHA-specific line should be removed if gcc is used.
+ -./if_not_there mark_rts.o $(CC) -c $(CFLAGS) $(srcdir)/mark_rts.c
+ -./if_not_there mark_rts.o `cygpath -w /bin/sh` $(CC) -c $(CFLAGS) $(srcdir)/mark_rts.c
+ -./if_not_there mark_rts.o /bin/sh $(CC) -c $(CFLAGS) $(srcdir)/mark_rts.c
+# Work-around for DEC optimizer tail recursion elimination bug.
+# The ALPHA-specific line should be removed if gcc is used.
alloc.o: include/gc_version.h
@@ -418,7 +429,7 @@ add_gc_prefix: $(srcdir)/tools/add_gc_prefix.c $(srcdir)/include/gc_version.h
gcname: $(srcdir)/tools/gcname.c $(srcdir)/include/gc_version.h
$(CC) -o gcname $(srcdir)/tools/gcname.c
-#We assume this is being done from source directory.
+# We assume this is being done from source directory.
dist gc.tar: $(SRCS) $(DOC_FILES) $(OTHER_FILES) add_gc_prefix gcname
cp Makefile.direct Makefile
cd $(AO_SRC_DIR); $(MAKE) dist
@@ -449,7 +460,7 @@ lint: $(CSRCS) tests/test.c
# BTL: added to test shared library version of collector.
# Currently works only under SunOS5. Requires GC_INIT call from statically
# loaded client code.
-ABSDIR = `pwd`
+ABSDIR= `pwd`
gctest_dyn_link: tests/test.o libgc.so
$(CC) -L$(ABSDIR) -R$(ABSDIR) -o gctest_dyn_link tests/test.o -lgc -ldl -lthread
diff --git a/Makefile.dj b/Makefile.dj
index aea59bfe..84fe6e61 100644
--- a/Makefile.dj
+++ b/Makefile.dj
@@ -64,8 +64,8 @@ SRCS= $(CSRCS) \
OTHER_FILES= PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \
README.md tests/test.c test_cpp.cc tools/setjmp_t.c SMakefile.amiga \
doc/README.amiga doc/README.win32 doc/README.cords \
- doc/README.rs6000 README.QUICK TODO tools/callprocs.sh \
- pc_excludes barrett_diagram doc/README.OS2 doc/README.Mac \
+ doc/README.rs6000 README.QUICK tools/callprocs.sh \
+ pc_excludes doc/README.OS2 doc/README.Mac \
extra/MacOS.c EMX_MAKEFILE doc/debugging.html \
extra/Mac_files/datastart.c extra/Mac_files/dataend.c \
extra/Mac_files/MacOS_config.h \
diff --git a/README.QUICK b/README.QUICK
index 1f419cfd..ee8f4a11 100644
--- a/README.QUICK
+++ b/README.QUICK
@@ -69,9 +69,8 @@ instead of GC_MALLOC.
Define GC_DEBUG before including gc.h for additional checking.
-More documentation on the collector interface can be found at
-http://www.hpl.hp.com/personal/Hans_Boehm/gc/gcinterface.html,
-in README.md and other files in the doc directory, and in include/gc.h file.
+More documentation on the collector interface can be found in README.md,
+doc/gcinterface.html, include/gc.h, and other files in the doc directory.
WARNINGS:
diff --git a/README.md b/README.md
index cada89af..f2a5c7b3 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,15 @@
# Boehm-Demers-Weiser Garbage Collector
-This is version 7.4.0 of a conservative garbage collector for C and C++.
+This is version 7.4.4 of a conservative garbage collector for C and C++.
-You might find a more recent version
-[here](http://www.hpl.hp.com/personal/Hans_Boehm/gc).
+
+## Download
+
+You might find a more recent/stable version on the
+[BDWGC site](http://www.hboehm.info/gc/).
+
+Also, the latest bug fixes and new features are available in the
+[development repository](https://github.com/ivmai/bdwgc).
## Overview
@@ -35,9 +41,6 @@ and
* Boehm H., "Simple GC-safe Compilation", Proceedings of the ACM SIGPLAN '96
Conference on Programming Language Design and Implementation.
-(Some of these are also available from
-[here](http://www.hpl.hp.com/personal/Hans_Boehm/papers/), among other places.)
-
Unlike the collector described in the second reference, this collector
operates either with the mutator stopped during the entire collection
(default) or incrementally during allocations. (The latter is supported
@@ -54,8 +57,8 @@ CSL 84-7). Doug McIlroy wrote a simpler fully conservative collector that
was part of version 8 UNIX (tm), but appears to not have received
widespread use.
-Rudimentary tools for use of the collector as a leak detector are included
-([link](http://www.hpl.hp.com/personal/Hans_Boehm/gc/leak.html)),
+Rudimentary tools for use of the collector as a
+[leak detector](http://www.hboehm.info/gc/leak.html) are included,
as is a fairly sophisticated string package "cord" that makes use of the
collector. (See doc/README.cords and H.-J. Boehm, R. Atkinson, and M. Plass,
"Ropes: An Alternative to Strings", Software Practice and Experience 25, 12
@@ -63,7 +66,7 @@ collector. (See doc/README.cords and H.-J. Boehm, R. Atkinson, and M. Plass,
in Xerox Cedar, or the "rope" package in the SGI STL or the g++ distribution.)
Further collector documentation can be found
-[here](http://www.hpl.hp.com/personal/Hans_Boehm/gc).
+[here](http://www.hboehm.info/gc/).
## General Description
@@ -515,9 +518,9 @@ per MB of accessible memory that needs to be scanned and processor.
Your mileage may vary.) The incremental/generational collection facility
may help in some cases.
-Please address bug reports [here](mailto:gc@linux.hpl.hp.com). If you are
-contemplating a major addition, you might also send mail to ask whether
-it's already been done (or whether we tried and discarded it).
+Please address bug reports [here](mailto:bdwgc@lists.opendylan.org).
+If you are contemplating a major addition, you might also send mail to ask
+whether it's already been done (or whether we tried and discarded it).
## Copyright & Warranty
@@ -526,7 +529,7 @@ it's already been done (or whether we tried and discarded it).
* Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
* Copyright (c) 1999-2011 by Hewlett-Packard Development Company.
-The file linux_threads.c is also
+The files pthread_stop_world.c and pthread_support.c are also
* Copyright (c) 1998 by Fergus Henderson. All rights reserved.
diff --git a/TODO b/TODO
deleted file mode 100644
index 38add34f..00000000
--- a/TODO
+++ /dev/null
@@ -1,100 +0,0 @@
-== TODO tasks ==
-
-tests/CMakeLists.txt: Add more executables (see tests.am).
-
-Use C++0x ATM (atomic memory operations) if available (either from the
-compiler runtime, provided it is reliable, or from the future libatomic_ops).
-
-Add a test for libatomic_ops minimal version required (at compile time).
-
-windows-untested: Remove if CMake can generate MS Visual Studio 6.0, 7.0, 8.0
-project files.
-
-BCC_MAKEFILE: Remove if CMake can generate Makefile for this compiler.
-(Same for WCC_MAKEFILE, OS2_MAKEFILE, NT_MAKEFILE, NT_STATIC_THREADS_MAKEFILE,
-NT_X64_STATIC_THREADS_MAKEFILE, NT_X64_THREADS_MAKEFILE, digimars.mak,
-gc.mak.)
-
-Makefile.dj: Remove if it is possible to use Makefile.direct (or
-auto-generated Makefile) instead. (Same for EMX_MAKEFILE.)
-
-build_atomic_ops.sh[.cygwin]: Remove if really not needed.
-
-BCC_MAKEFILE, EMX_MAKEFILE, OS2_MAKEFILE, PCR-Makefile, WCC_MAKEFILE,
-SMakefile.amiga, Makefile.dj, digimars.mak: move to "build" folder.
-
-Do type-punning via union (instead of pointer type cast) to enable safe
-'-fstrict-aliasing' compiler optimization option.
-
-Support CAN_HANDLE_FORK if USE_WINALLOC for Cygwin.
-
-Use madvise() on Unix/Cygwin.
-
-Use Linux VM pressure notifications to force GC and unmapping.
-
-Filter overlaps in GC_add_roots for Unix (same as for Win32).
-
-Do not resume parallel markers if only 1 core is active at GC mark start.
-
-Enable GC_set_handle_fork(1) for Darwin with GC_dirty_maintained on (both
-single and multi-threaded modes).
-
-Add more fields to GC_prof_stats_s (potential candidates are:
-requested_heapsize, max_large_allocd_bytes, large_allocd_bytes, bytes_dropped,
-bytes_finalized, bytes_freed, finalizer_bytes_freed, composite_in_use,
-atomic_in_use, GC_n_heap_sects, GC_n_memory, GC_black_list_spacing,
-GC_root_size, GC_max_root_size, n_root_sets, GC_total_stacksize,
-GC_collect_at_heapsize, GC_fail_count, GC_mark_stack_size, last_fo_entries,
-last_bytes_finalized, last_finalizer_notification_no, GC_dl_entries,
-GC_old_dl_entries, GC_used_heap_size_after_full, GC_total_stack_black_listed,
-signed_log_dl_table_size, GC_n_rescuing_pages, signed_log_fo_table_size,
-GC_excl_table_entries, GC_stack_last_cleared, GC_bytes_allocd_at_reset,
-GC_n_heap_bases, registered_threads_cnt, GC_max_thread_index, GC_block_count,
-GC_unlocked_count, GC_hdr_cache_hits, GC_hdr_cache_misses, GC_spin_count).
-
-Support musl libc (on sabotage linux).
-
-== FIXME tasks ==
-
-Solaris + GCC: make check fails with the message:
-libc.so.1: gctest: fatal: libgcc_s.so.1: open failed: No such file or directory
-
-Solaris/x86[_64]: gctest fails if PROC_VDB.
-
-Sun C++ 5.11: test_cpp.cc:237: Error: Too few arguments in call to
-"operator delete(void*, GCPlacement, extern "C" void(*)(void*,void*), void*)".
-
-Darwin/x86_64: deadlock might occur between:
-dlclose() -> GC_dyld_image_remove() -> GC_lock() and
-GC_inner_start_routine()+LOCK -> dyld_stub_binder_().
-
-HP-UX 11.00 with the vendor cc fails:
-Perhaps GC_push_regs was configured incorrectly? FAIL: gctest.
-
-Android NDK: gcc4.7+ld.gold: gctest crashes due to incorrect __data_start.
-
-Linux/mips64el (N32): threadleaktest crashes once every 3-4 runs (SIGSEGV in
-GC_delete_gc_thread(t=0) called from GC_pthread_join) if configured with
---disable-shared.
-
-FreeBSD 9.0/x86_64 (gcc-4.2.1-20070831): gctest segfaults sometimes in
-GC_typed_mark_proc if configured with --enable-threads=pthreads.
-
-OpenBSD 5.1/i386: leaktest fails rarely (unless logging redirected to file):
-cannot write to stderr from GC_gcollect invoked from 'atexit' hook.
-
-NetBSD 5.1/x86: threadkey_test hangs sometimes.
-
-Cygwin: subthread_create: exception STATUS_ACCESS_VIOLATION.
-
-Cygwin: gctest: assertion failure at UNLOCK in GC_fork_parent_proc.
-
-Mingw-w32: gctest: "SuspendThread failed" sometimes occurs (if
-GC_DLL+GC_THREADS+GC_ASSERTIONS).
-
-Mingw: gctest (compiled with PARALLEL_MARK): launched in gdb with breakpoint
-at GC_mark_local, after several breakpoint hits, crashes with the messages
-"Caught ACCESS_VIOLATION in marker; memory mapping disappeared" and
-"Tried to start parallel mark in bad state", or enters deadlock.
-
-Mingw: test_cpp: crashes at some iteration if big argument (e.g., 1000) given.
diff --git a/allchblk.c b/allchblk.c
index 22256aa0..f797cdf5 100644
--- a/allchblk.c
+++ b/allchblk.c
@@ -513,7 +513,7 @@ STATIC struct hblk * GC_get_first_part(struct hblk *h, hdr *hhdr,
rest_hdr = GC_install_header(rest);
if (0 == rest_hdr) {
/* FIXME: This is likely to be very bad news ... */
- WARN("Header allocation failed: Dropping block.\n", 0);
+ WARN("Header allocation failed: dropping block\n", 0);
return(0);
}
rest_hdr -> hb_sz = total_size - bytes;
@@ -596,7 +596,7 @@ GC_allochblk(size_t sz, int kind, unsigned flags/* IGNORE_OFF_PAGE or 0 */)
/* split. */
GC_ASSERT((sz & (GRANULE_BYTES - 1)) == 0);
- blocks = OBJ_SZ_TO_BLOCKS(sz);
+ blocks = OBJ_SZ_TO_BLOCKS_CHECKED(sz);
if ((signed_word)(blocks * HBLKSIZE) < 0) {
return 0;
}
@@ -659,7 +659,7 @@ GC_allochblk_nth(size_t sz, int kind, unsigned flags, int n, int may_split)
signed_word size_needed; /* number of bytes in requested objects */
signed_word size_avail; /* bytes available in this block */
- size_needed = HBLKSIZE * OBJ_SZ_TO_BLOCKS(sz);
+ size_needed = HBLKSIZE * OBJ_SZ_TO_BLOCKS_CHECKED(sz);
/* search for a big enough block in free list */
for (hbp = GC_hblkfreelist[n];; hbp = hhdr -> hb_next) {
@@ -734,7 +734,7 @@ GC_allochblk_nth(size_t sz, int kind, unsigned flags, int n, int may_split)
>= GC_large_alloc_warn_interval) {
WARN("Repeated allocation of very large block "
"(appr. size %" WARN_PRIdPTR "):\n"
- "\tMay lead to memory leak and poor performance.\n",
+ "\tMay lead to memory leak and poor performance\n",
size_needed);
GC_large_alloc_warn_suppressed = 0;
}
diff --git a/alloc.c b/alloc.c
index 15de645d..e09ce342 100644
--- a/alloc.c
+++ b/alloc.c
@@ -149,7 +149,7 @@ STATIC GC_stop_func GC_default_stop_func = GC_never_stop_func;
GC_API void GC_CALL GC_set_stop_func(GC_stop_func stop_func)
{
DCL_LOCK_STATE;
- GC_ASSERT(stop_func != 0);
+ GC_ASSERT(NONNULL_ARG_NOT_NULL(stop_func));
LOCK();
GC_default_stop_func = stop_func;
UNLOCK();
@@ -1018,7 +1018,7 @@ STATIC GC_bool GC_try_to_collect_general(GC_stop_func stop_func,
/* Externally callable routines to invoke full, stop-the-world collection. */
GC_API int GC_CALL GC_try_to_collect(GC_stop_func stop_func)
{
- GC_ASSERT(stop_func != 0);
+ GC_ASSERT(NONNULL_ARG_NOT_NULL(stop_func));
return (int)GC_try_to_collect_general(stop_func, FALSE);
}
@@ -1097,6 +1097,16 @@ GC_INNER void GC_add_to_heap(struct hblk *p, size_t bytes)
phdr -> hb_flags = 0;
GC_freehblk(p);
GC_heapsize += bytes;
+
+ /* Normally the caller calculates a new GC_collect_at_heapsize,
+ * but this is also called directly from alloc_mark_stack, so
+ * adjust here. It will be recalculated when called from
+ * GC_expand_hp_inner.
+ */
+ GC_collect_at_heapsize += bytes;
+ if (GC_collect_at_heapsize < GC_heapsize /* wrapped */)
+ GC_collect_at_heapsize = (word)(-1);
+
if ((word)p <= (word)GC_least_plausible_heap_addr
|| GC_least_plausible_heap_addr == 0) {
GC_least_plausible_heap_addr = (void *)((ptr_t)p - sizeof(word));
@@ -1163,32 +1173,28 @@ GC_word GC_max_retries = 0;
/* Returns FALSE on failure. */
GC_INNER GC_bool GC_expand_hp_inner(word n)
{
- word bytes;
+ size_t bytes;
struct hblk * space;
word expansion_slop; /* Number of bytes by which we expect the */
/* heap to expand soon. */
if (n < MINHINCR) n = MINHINCR;
- bytes = n * HBLKSIZE;
- /* Make sure bytes is a multiple of GC_page_size */
- {
- word mask = GC_page_size - 1;
- bytes += mask;
- bytes &= ~mask;
- }
-
- if (GC_max_heapsize != 0 && GC_heapsize + bytes > GC_max_heapsize) {
+ bytes = ROUNDUP_PAGESIZE((size_t)n * HBLKSIZE);
+ if (GC_max_heapsize != 0
+ && (GC_max_heapsize < (word)bytes
+ || GC_heapsize > GC_max_heapsize - (word)bytes)) {
/* Exceeded self-imposed limit */
return(FALSE);
}
space = GET_MEM(bytes);
GC_add_to_our_memory((ptr_t)space, bytes);
if (space == 0) {
- WARN("Failed to expand heap by %" WARN_PRIdPTR " bytes\n", bytes);
+ WARN("Failed to expand heap by %" WARN_PRIdPTR " bytes\n",
+ (word)bytes);
return(FALSE);
}
GC_INFOLOG_PRINTF("Grow heap to %lu KiB after %lu bytes allocated\n",
- TO_KiB_UL(GC_heapsize + bytes),
+ TO_KiB_UL(GC_heapsize + (word)bytes),
(unsigned long)GC_bytes_allocd);
/* Adjust heap limits generously for blacklisting to work better. */
/* GC_add_to_heap performs minimal adjustment needed for */
@@ -1198,7 +1204,7 @@ GC_INNER GC_bool GC_expand_hp_inner(word n)
|| (GC_last_heap_addr != 0
&& (word)GC_last_heap_addr < (word)space)) {
/* Assume the heap is growing up */
- word new_limit = (word)space + bytes + expansion_slop;
+ word new_limit = (word)space + (word)bytes + expansion_slop;
if (new_limit > (word)space) {
GC_greatest_plausible_heap_addr =
(void *)GC_max((word)GC_greatest_plausible_heap_addr,
@@ -1251,9 +1257,11 @@ GC_INNER unsigned GC_fail_count = 0;
static word last_fo_entries = 0;
static word last_bytes_finalized = 0;
+#define GC_WORD_MAX (~(word)0)
+
/* Collect or expand heap in an attempt make the indicated number of */
/* free blocks available. Should be called until the blocks are */
-/* available (seting retry value to TRUE unless this is the first call */
+/* available (setting retry value to TRUE unless this is the first call */
/* in a loop) or until it fails by returning FALSE. */
GC_INNER GC_bool GC_collect_or_expand(word needed_blocks,
GC_bool ignore_off_page,
@@ -1304,6 +1312,8 @@ GC_INNER GC_bool GC_collect_or_expand(word needed_blocks,
} else {
blocks_to_get = MAXHINCR;
}
+ if (blocks_to_get > divHBLKSZ(GC_WORD_MAX))
+ blocks_to_get = divHBLKSZ(GC_WORD_MAX);
}
if (!GC_expand_hp_inner(blocks_to_get)
@@ -1313,7 +1323,7 @@ GC_INNER GC_bool GC_collect_or_expand(word needed_blocks,
GC_gcollect_inner();
GC_ASSERT(GC_bytes_allocd == 0);
} else if (GC_fail_count++ < GC_max_retries) {
- WARN("Out of Memory! Trying to continue ...\n", 0);
+ WARN("Out of Memory! Trying to continue...\n", 0);
GC_gcollect_inner();
} else {
# if !defined(AMIGA) || !defined(GC_AMIGA_FASTALLOC)
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000..feb14b3c
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,11 @@
+version: 7.4.x-{build}
+
+clone_depth: 50
+
+build_script:
+ - git clone --depth=50 https://github.com/ivmai/libatomic_ops.git -b release-7_4
+ - cmake .
+ - cmake --build . --config Debug
+
+test_script:
+ - ctest --build-config Debug -V
diff --git a/backgraph.c b/backgraph.c
index d6f3223d..4b087e43 100644
--- a/backgraph.c
+++ b/backgraph.c
@@ -86,8 +86,11 @@ static back_edges *avail_back_edges = 0;
static back_edges * new_back_edges(void)
{
if (0 == back_edge_space) {
- back_edge_space = (back_edges *)
- GET_MEM(MAX_BACK_EDGE_STRUCTS*sizeof(back_edges));
+ back_edge_space = (back_edges *)GET_MEM(
+ ROUNDUP_PAGESIZE_IF_MMAP(MAX_BACK_EDGE_STRUCTS
+ * sizeof(back_edges)));
+ if (NULL == back_edge_space)
+ ABORT("Insufficient memory for back edges");
GC_add_to_our_memory((ptr_t)back_edge_space,
MAX_BACK_EDGE_STRUCTS*sizeof(back_edges));
}
@@ -127,7 +130,9 @@ static void push_in_progress(ptr_t p)
{
if (n_in_progress >= in_progress_size) {
if (in_progress_size == 0) {
- in_progress_size = INITIAL_IN_PROGRESS;
+ in_progress_size = ROUNDUP_PAGESIZE_IF_MMAP(INITIAL_IN_PROGRESS
+ * sizeof(ptr_t))
+ / sizeof(ptr_t);
in_progress_space = (ptr_t *)GET_MEM(in_progress_size * sizeof(ptr_t));
GC_add_to_our_memory((ptr_t)in_progress_space,
in_progress_size * sizeof(ptr_t));
@@ -138,8 +143,9 @@ static void push_in_progress(ptr_t p)
GET_MEM(in_progress_size * sizeof(ptr_t));
GC_add_to_our_memory((ptr_t)new_in_progress_space,
in_progress_size * sizeof(ptr_t));
- BCOPY(in_progress_space, new_in_progress_space,
- n_in_progress * sizeof(ptr_t));
+ if (new_in_progress_space != NULL)
+ BCOPY(in_progress_space, new_in_progress_space,
+ n_in_progress * sizeof(ptr_t));
in_progress_space = new_in_progress_space;
/* FIXME: This just drops the old space. */
}
diff --git a/configure.ac b/configure.ac
index 2e9afca0..cb7706ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,14 +12,14 @@
dnl Process this file with autoconf to produce configure.
# Initialization
-AC_INIT(gc,7.4.0,gc@linux.hpl.hp.com)
+AC_INIT(gc,7.4.4,bdwgc@lists.opendylan.org)
## version must conform to [0-9]+[.][0-9]+[.][0-9]+
AC_CONFIG_SRCDIR(gcj_mlc.c)
AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_TARGET
AC_PREREQ(2.61)
GC_SET_VERSION
-AM_INIT_AUTOMAKE([foreign dist-bzip2 nostdinc])
+AM_INIT_AUTOMAKE([foreign dist-bzip2 nostdinc subdir-objects])
AC_CONFIG_HEADERS([include/config.h])
AM_MAINTAINER_MODE
@@ -145,7 +145,7 @@ AH_TEMPLATE([GC_OPENBSD_THREADS], [Define to support OpenBSD pthreads.])
AH_TEMPLATE([GC_OSF1_THREADS], [Define to support Tru64 pthreads.])
AH_TEMPLATE([GC_SOLARIS_THREADS], [Define to support Solaris pthreads.])
AH_TEMPLATE([GC_WIN32_THREADS], [Define to support Win32 threads.])
-AH_TEMPLATE([GC_WIN32_PTHREADS], [Define to support win32-pthreads.])
+AH_TEMPLATE([GC_WIN32_PTHREADS], [Define to support pthreads-win32.])
AH_TEMPLATE([GC_RTEMS_PTHREADS], [Define to support rtems-pthreads.])
dnl System header feature requests.
@@ -177,7 +177,7 @@ case "$THREADS" in
AC_CHECK_LIB(pthread, pthread_self, THREADDLLIBS="-lpthread",,)
case "$host" in
x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* \
- | x86_64-*-linux* | alpha-*-linux* | sparc*-*-linux*)
+ | x86_64-*-linux* | alpha-*-linux* | powerpc*-*-linux* | sparc*-*-linux*)
AC_DEFINE(GC_LINUX_THREADS)
AC_DEFINE(_REENTRANT)
if test "${enable_parallel_mark}" != no; then
@@ -275,7 +275,7 @@ case "$THREADS" in
;;
*-*-mingw*)
AC_DEFINE(GC_WIN32_PTHREADS)
- # Using win32-pthreads
+ # Using pthreads-win32 library.
if test "${enable_parallel_mark}" != no; then
AC_DEFINE(PARALLEL_MARK)
fi
@@ -310,9 +310,8 @@ case "$THREADS" in
;;
esac
case "$host" in
- sparc*-*-solaris*)
+ sparc*-*-solaris*)
if test "$GCC" != yes; then
- CFLAGS="-O $CFLAGS"
need_atomic_ops_asm=true
fi
;;
@@ -378,10 +377,18 @@ AM_CONDITIONAL(PTHREADS, test x$THREADS = xposix)
AM_CONDITIONAL(DARWIN_THREADS, test x$darwin_threads = xtrue)
AM_CONDITIONAL(WIN32_THREADS, test x$win32_threads = xtrue)
+compiler_suncc=no
case "$host" in
powerpc-*-darwin*)
powerpc_darwin=true
;;
+ *-*-solaris*)
+ if test "$GCC" != yes; then
+ # Solaris SunCC
+ compiler_suncc=yes
+ CFLAGS="-O $CFLAGS"
+ fi
+ ;;
*-*-wince*)
if test "$enable_gc_debug" != "no"; then
AC_DEFINE([GC_READ_ENV_FILE], 1,
@@ -409,12 +416,16 @@ AC_TRY_COMPILE([],[
#endif
], [compiler_xlc=yes], [compiler_xlc=no])
AC_MSG_RESULT($compiler_xlc)
-AM_CONDITIONAL(COMPILER_XLC,test $compiler_xlc = yes)
if test $compiler_xlc = yes -a "$powerpc_darwin" = true; then
# the darwin stack-frame-walking code is completely broken on xlc
AC_DEFINE([DARWIN_DONT_PARSE_STACK], 1, [See doc/README.macros.])
fi
+# XLC neither requires nor tolerates the unnecessary assembler goop.
+# Similar for the Sun C compiler.
+AM_CONDITIONAL([ASM_WITH_CPP_UNSUPPORTED],
+ [test $compiler_xlc = yes -o $compiler_suncc = yes])
+
if test "$GCC" = yes; then
# Disable aliasing optimization unless forced to.
AC_MSG_CHECKING([whether gcc supports -fno-strict-aliasing])
@@ -550,7 +561,8 @@ if test "${enable_shared}" = yes; then
[ac_cv_fvisibility_hidden=no])
CFLAGS="$old_CFLAGS"
AS_IF([test "$ac_cv_fvisibility_hidden" = yes],
- [CFLAGS="-DGC_VISIBILITY_HIDDEN_SET -fvisibility=hidden $CFLAGS"])
+ [CFLAGS="-DGC_VISIBILITY_HIDDEN_SET -fvisibility=hidden $CFLAGS"],
+ [CFLAGS="-DGC_NO_VISIBILITY $CFLAGS"])
AC_MSG_RESULT($ac_cv_fvisibility_hidden)
fi
fi
@@ -578,21 +590,21 @@ case "$host" in
dnl performance under Irix.
;;
sparc-*-netbsd*)
- machdep="src/sparc_netbsd_mach_dep.lo"
+ machdep="sparc_netbsd_mach_dep.lo"
;;
sparc*-*-linux* | sparc*-*-openbsd* | sparc64-*-freebsd* | sparc64-*-netbsd*)
- machdep="src/sparc_mach_dep.lo"
+ machdep="sparc_mach_dep.lo"
;;
sparc-sun-solaris2.3)
- machdep="src/sparc_mach_dep.lo"
+ machdep="sparc_mach_dep.lo"
AC_DEFINE(SUNOS53_SHARED_LIB, 1,
[Define to work around a Solaris 5.3 bug (see dyn_load.c).])
;;
sparc*-sun-solaris2*)
- machdep="src/sparc_mach_dep.lo"
+ machdep="sparc_mach_dep.lo"
;;
ia64-*-*)
- machdep="src/ia64_save_regs_in_stack.lo"
+ machdep="ia64_save_regs_in_stack.lo"
;;
esac
AC_MSG_RESULT($machdep)
@@ -668,6 +680,16 @@ if test x"$enable_gcj_support" != xno; then
AC_DEFINE(GC_GCJ_SUPPORT, 1, [Define to include support for gcj.])
fi
+dnl Interaction with other programs that might use signals.
+AC_ARG_ENABLE(sigrt-signals,
+ [AC_HELP_STRING([--enable-sigrt-signals],
+ [Force GC to use SIGRTMIN-based signals for thread suspend/resume])])
+if test x"${enable_sigrt_signals}" = xyes; then
+ AC_DEFINE([GC_USESIGRT_SIGNALS], 1,
+ [Force the GC to use signals based on SIGRTMIN+k.])
+fi
+
+
dnl Debugging
dnl ---------
diff --git a/cord/cord.am b/cord/cord.am
index 7d3fbe55..7793ec8f 100644
--- a/cord/cord.am
+++ b/cord/cord.am
@@ -22,4 +22,7 @@ EXTRA_DIST += \
cord/tests/de_win.h \
cord/tests/de_win.rc
-pkginclude_HEADERS += include/cord.h
+pkginclude_HEADERS += \
+ include/cord.h \
+ include/cord_pos.h \
+ include/ec.h
diff --git a/cord/cordbscs.c b/cord/cordbscs.c
index a05e6e04..277d1362 100644
--- a/cord/cordbscs.c
+++ b/cord/cordbscs.c
@@ -37,7 +37,7 @@ typedef void (* oom_fn)(void);
oom_fn CORD_oom_fn = (oom_fn) 0;
# define OUT_OF_MEMORY { if (CORD_oom_fn != (oom_fn) 0) (*CORD_oom_fn)(); \
- ABORT("Out of memory\n"); }
+ ABORT("Out of memory"); }
# define ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); }
typedef unsigned long word;
@@ -221,7 +221,8 @@ CORD CORD_cat_char_star(CORD x, const char * y, size_t leny)
if (result == 0) OUT_OF_MEMORY;
result->header = CONCAT_HDR;
result->depth = depth;
- if (lenx <= MAX_LEFT_LEN) result->left_len = lenx;
+ if (lenx <= MAX_LEFT_LEN)
+ result->left_len = (unsigned char)lenx;
result->len = result_len;
result->left = x;
result->right = y;
@@ -262,7 +263,8 @@ CORD CORD_cat(CORD x, CORD y)
if (result == 0) OUT_OF_MEMORY;
result->header = CONCAT_HDR;
result->depth = depth;
- if (lenx <= MAX_LEFT_LEN) result->left_len = lenx;
+ if (lenx <= MAX_LEFT_LEN)
+ result->left_len = (unsigned char)lenx;
result->len = result_len;
result->left = x;
result->right = y;
@@ -348,15 +350,15 @@ char CORD_apply_access_fn(size_t i, void * client_data)
CORD CORD_substr_closure(CORD x, size_t i, size_t n, CORD_fn f)
{
register struct substr_args * sa = GC_NEW(struct substr_args);
- CORD result;
+ CordRep * result;
if (sa == 0) OUT_OF_MEMORY;
sa->sa_cord = (CordRep *)x;
sa->sa_index = i;
- result = CORD_from_fn(f, (void *)sa, n);
- if (result == CORD_EMPTY) return CORD_EMPTY; /* n == 0 */
- ((CordRep *)result) -> function.header = SUBSTR_HDR;
- return (result);
+ result = (CordRep *)CORD_from_fn(f, (void *)sa, n);
+ if ((CORD)result != CORD_EMPTY && 0 == result -> function.null)
+ result -> function.header = SUBSTR_HDR;
+ return (CORD)result;
}
# define SUBSTR_LIMIT (10 * SHORT_LIMIT)
@@ -598,7 +600,7 @@ typedef ForestElement Forest [ MAX_DEPTH ];
/* of the forest in order of DECREASING */
/* indices. */
-void CORD_init_min_len()
+void CORD_init_min_len(void)
{
register int i;
register size_t last, previous, current;
@@ -869,7 +871,7 @@ void CORD__prev(register CORD_pos p)
char CORD_pos_fetch(register CORD_pos p)
{
- if (p[0].cur_start <= p[0].cur_pos && p[0].cur_pos < p[0].cur_end) {
+ if (p[0].cur_end != 0) {
return(p[0].cur_leaf[p[0].cur_pos - p[0].cur_start]);
} else {
return(CORD__pos_fetch(p));
@@ -878,7 +880,7 @@ char CORD_pos_fetch(register CORD_pos p)
void CORD_next(CORD_pos p)
{
- if (p[0].cur_pos < p[0].cur_end - 1) {
+ if (p[0].cur_pos + 1 < p[0].cur_end) {
p[0].cur_pos++;
} else {
CORD__next(p);
diff --git a/cord/cordprnt.c b/cord/cordprnt.c
index 94c49be8..a33e3f3b 100644
--- a/cord/cordprnt.c
+++ b/cord/cordprnt.c
@@ -30,9 +30,12 @@
#include "cord.h"
#include "ec.h"
-#include <stdio.h>
+
#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+
#include "gc.h"
#define CONV_SPEC_LEN 50 /* Maximum length of a single */
@@ -41,6 +44,11 @@
/* conversion with default */
/* width and prec. */
+#define OUT_OF_MEMORY do { \
+ if (CORD_oom_fn != 0) (*CORD_oom_fn)(); \
+ fprintf(stderr, "Out of memory\n"); \
+ abort(); \
+ } while (0)
static int ec_len(CORD_ec x)
{
@@ -220,11 +228,12 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args)
if (prec != NONE && len > (size_t)prec) {
if (prec < 0) return(-1);
arg = CORD_substr(arg, 0, prec);
- len = prec;
+ len = (unsigned)prec;
}
if (width != NONE && len < (size_t)width) {
char * blanks = GC_MALLOC_ATOMIC(width-len+1);
+ if (NULL == blanks) OUT_OF_MEMORY;
memset(blanks, ' ', width-len);
blanks[width-len] = '\0';
if (left_adj) {
@@ -267,7 +276,8 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args)
# ifdef __va_copy
__va_copy(vsprintf_args, args);
# else
-# if defined(__GNUC__) && !defined(__DJGPP__) /* and probably in other cases */
+# if defined(__GNUC__) && !defined(__DJGPP__) \
+ && !defined(__EMX__) /* and probably in other cases */
va_copy(vsprintf_args, args);
# else
vsprintf_args = args;
@@ -280,6 +290,7 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args)
max_size += CONV_RESULT_LEN;
if (max_size >= CORD_BUFSZ) {
buf = GC_MALLOC_ATOMIC(max_size + 1);
+ if (NULL == buf) OUT_OF_MEMORY;
} else {
if (CORD_BUFSZ - (result[0].ec_bufptr-result[0].ec_buf)
< max_size) {
@@ -314,14 +325,16 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args)
break;
default:
# if defined(__va_copy) \
- || (defined(__GNUC__) && !defined(__DJGPP__))
+ || (defined(__GNUC__) && !defined(__DJGPP__) \
+ && !defined(__EMX__))
va_end(vsprintf_args);
# endif
return(-1);
}
res = vsprintf(buf, conv_spec, vsprintf_args);
# if defined(__va_copy) \
- || (defined(__GNUC__) && !defined(__DJGPP__))
+ || (defined(__GNUC__) && !defined(__DJGPP__) \
+ && !defined(__EMX__))
va_end(vsprintf_args);
# endif
len = (size_t)res;
diff --git a/cord/cordxtra.c b/cord/cordxtra.c
index 610ea893..a185185c 100644
--- a/cord/cordxtra.c
+++ b/cord/cordxtra.c
@@ -59,8 +59,8 @@
typedef void (* oom_fn)(void);
-# define OUT_OF_MEMORY { if (CORD_oom_fn != (oom_fn) 0) (*CORD_oom_fn)(); \
- ABORT("Out of memory\n"); }
+# define OUT_OF_MEMORY { if (CORD_oom_fn != (oom_fn) 0) (*CORD_oom_fn)(); \
+ ABORT("Out of memory"); }
# define ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); }
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
@@ -136,15 +136,17 @@ int CORD_batched_fill_proc(const char * s, void * client_data)
}
/* Fill buf with len characters starting at i. */
-/* Assumes len characters are available. */
-void CORD_fill_buf(CORD x, size_t i, size_t len, char * buf)
+/* Assumes len characters are available in buf. */
+/* Return 1 if buf is filled fully (and len is */
+/* non-zero), 0 otherwise. */
+int CORD_fill_buf(CORD x, size_t i, size_t len, char * buf)
{
CORD_fill_data fd;
fd.len = len;
fd.buf = buf;
fd.count = 0;
- (void)CORD_iter5(x, i, CORD_fill_proc, CORD_batched_fill_proc, &fd);
+ return CORD_iter5(x, i, CORD_fill_proc, CORD_batched_fill_proc, &fd);
}
int CORD_cmp(CORD x, CORD y)
@@ -241,7 +243,8 @@ char * CORD_to_char_star(CORD x)
char * result = GC_MALLOC_ATOMIC(len + 1);
if (result == 0) OUT_OF_MEMORY;
- CORD_fill_buf(x, 0, len, result);
+ if (len > 0 && CORD_fill_buf(x, 0, len, result) != 1)
+ ABORT("CORD_fill_buf malfunction");
result[len] = '\0';
return(result);
}
@@ -428,6 +431,7 @@ void CORD_ec_flush_buf(CORD_ec x)
if (len == 0) return;
s = GC_MALLOC_ATOMIC(len+1);
+ if (NULL == s) OUT_OF_MEMORY;
memcpy(s, x[0].ec_buf, len);
s[len] = '\0';
x[0].ec_cord = CORD_cat_char_star(x[0].ec_cord, s, len);
@@ -442,13 +446,12 @@ void CORD_ec_append_cord(CORD_ec x, CORD s)
char CORD_nul_func(size_t i CORD_ATTR_UNUSED, void * client_data)
{
- return((char)(unsigned long)client_data);
+ return (char)(GC_word)client_data;
}
-
CORD CORD_chars(char c, size_t i)
{
- return(CORD_from_fn(CORD_nul_func, (void *)(unsigned long)c, i));
+ return CORD_from_fn(CORD_nul_func, (void *)(GC_word)(unsigned char)c, i);
}
CORD CORD_from_file_eager(FILE * f)
diff --git a/cord/tests/cordtest.c b/cord/tests/cordtest.c
index cf5c6966..061430df 100644
--- a/cord/tests/cordtest.c
+++ b/cord/tests/cordtest.c
@@ -21,7 +21,7 @@
/* that real clients shouldn't rely on. */
# define ABORT(string) \
- { int x = 0; fprintf(stderr, "FAILED: %s\n", string); x = 1 / x; abort(); }
+ { fprintf(stderr, "FAILED: %s\n", string); abort(); }
int count;
@@ -128,7 +128,7 @@ void test_extras(void)
register int i;
CORD y = "abcdefghijklmnopqrstuvwxyz0123456789";
CORD x = "{}";
- CORD w, z;
+ CORD u, w, z;
FILE *f;
FILE *f1a, *f1b, *f2;
@@ -180,7 +180,9 @@ void test_extras(void)
ABORT("file substr wrong");
if (strcmp(CORD_to_char_star(CORD_substr(w, 1000*36, 36)), y) != 0)
ABORT("char * file substr wrong");
- if (strcmp(CORD_substr(w, 1000*36, 2), "ab") != 0)
+ u = CORD_substr(w, 1000*36, 2);
+ if (!u) ABORT("CORD_substr returned NULL");
+ if (strcmp(u, "ab") != 0)
ABORT("short file substr wrong");
if (CORD_str(x,1,"9a") != 35) ABORT("CORD_str failed 1");
if (CORD_str(x,0,"9abcdefghijk") != 35) ABORT("CORD_str failed 2");
@@ -197,13 +199,28 @@ void test_extras(void)
if (remove(FNAME1) != 0) {
/* On some systems, e.g. OS2, this may fail if f1 is still open. */
/* But we cannot call fclose as it might lead to double close. */
- fprintf(stderr, "WARNING: remove(FNAME1) failed\n");
+ fprintf(stderr, "WARNING: remove failed: " FNAME1 "\n");
}
if (remove(FNAME2) != 0) {
- fprintf(stderr, "WARNING: remove(FNAME2) failed\n");
+ fprintf(stderr, "WARNING: remove failed: " FNAME2 "\n");
}
}
+#if defined(__DJGPP__) || defined(__STRICT_ANSI__)
+ /* snprintf is missing in DJGPP (v2.0.3) */
+#else
+# if defined(_MSC_VER)
+# if defined(_WIN32_WCE)
+ /* _snprintf is deprecated in WinCE */
+# define GC_SNPRINTF StringCchPrintfA
+# else
+# define GC_SNPRINTF _snprintf
+# endif
+# else
+# define GC_SNPRINTF snprintf
+# endif
+#endif
+
void test_printf(void)
{
CORD result;
@@ -226,8 +243,12 @@ void test_printf(void)
x = CORD_cat(x,x);
if (CORD_sprintf(&result, "->%-120.78r!\n", x) != 124)
ABORT("CORD_sprintf failed 3");
- (void)snprintf(result2, sizeof(result2), "->%-120.78s!\n",
- CORD_to_char_star(x));
+# ifdef GC_SNPRINTF
+ (void)GC_SNPRINTF(result2, sizeof(result2), "->%-120.78s!\n",
+ CORD_to_char_star(x));
+# else
+ (void)sprintf(result2, "->%-120.78s!\n", CORD_to_char_star(x));
+# endif
result2[sizeof(result2) - 1] = '\0';
if (CORD_cmp(result, result2) != 0)ABORT("CORD_sprintf goofed 5");
}
diff --git a/cord/tests/de.c b/cord/tests/de.c
index 068848c4..84aa4de8 100644
--- a/cord/tests/de.c
+++ b/cord/tests/de.c
@@ -27,13 +27,15 @@
*/
#include <stdio.h>
+#include <stdlib.h> /* for exit() */
+
#include "gc.h"
#include "cord.h"
#ifdef THINK_C
#define MACINTOSH
-#include <ctype.h>
#endif
+#include <ctype.h>
#if (defined(__BORLANDC__) || defined(__CYGWIN__)) && !defined(WIN32)
/* If this is DOS or win16, we'll fail anyway. */
@@ -63,10 +65,16 @@
# define COLS 80
#else
# include <curses.h>
+# include <unistd.h> /* for sleep() */
# define de_error(s) { fprintf(stderr, s); sleep(2); }
#endif
#include "de_cmds.h"
+#define OUT_OF_MEMORY do { \
+ fprintf(stderr, "Out of memory\n"); \
+ exit(3); \
+ } while (0)
+
/* List of line number to position mappings, in descending order. */
/* There may be holes. */
typedef struct LineMapRep {
@@ -116,24 +124,27 @@ void invalidate_map(int i)
/* Reduce the number of map entries to save space for huge files. */
/* This also affects maps in histories. */
-void prune_map()
+void prune_map(void)
{
line_map map = current_map;
int start_line = map -> line;
current_map_size = 0;
- for(; map != 0; map = map -> previous) {
+ do {
current_map_size++;
if (map -> line < start_line - LINES && map -> previous != 0) {
map -> previous = map -> previous -> previous;
}
- }
+ map = map -> previous;
+ } while (map != 0);
}
+
/* Add mapping entry */
void add_map(int line, size_t pos)
{
line_map new_map = GC_NEW(struct LineMapRep);
+ if (NULL == new_map) OUT_OF_MEMORY;
if (current_map_size >= MAX_MAP_SIZE) prune_map();
new_map -> line = line;
new_map -> pos = pos;
@@ -179,6 +190,7 @@ void add_hist(CORD s)
{
history new_file = GC_NEW(struct HistoryRep);
+ if (NULL == new_file) OUT_OF_MEMORY;
new_file -> file_contents = current = s;
current_len = CORD_len(s);
new_file -> previous = now;
@@ -206,16 +218,19 @@ void replace_line(int i, CORD s)
{
register int c;
CORD_pos p;
- size_t len = CORD_len(s);
+# if !defined(MACINTOSH)
+ size_t len = CORD_len(s);
+# endif
if (screen == 0 || LINES > screen_size) {
screen_size = LINES;
screen = (CORD *)GC_MALLOC(screen_size * sizeof(CORD));
+ if (NULL == screen) OUT_OF_MEMORY;
}
# if !defined(MACINTOSH)
/* A gross workaround for an apparent curses bug: */
- if (i == LINES-1 && len == COLS) {
- s = CORD_substr(s, 0, CORD_len(s) - 1);
+ if (i == LINES-1 && len == (unsigned)COLS) {
+ s = CORD_substr(s, 0, len - 1);
}
# endif
if (CORD_cmp(screen[i], s) != 0) {
@@ -290,7 +305,7 @@ int dis_granularity;
/* Update dis_line, dis_col, and dis_pos to make cursor visible. */
/* Assumes line, col, dis_line, dis_pos are in bounds. */
-void normalize_display()
+void normalize_display(void)
{
int old_line = dis_line;
int old_col = dis_col;
@@ -328,7 +343,7 @@ void fix_cursor(void)
/* Make sure line, col, and dis_pos are somewhere inside file. */
/* Recompute file_pos. Assumes dis_pos is accurate or past eof */
-void fix_pos()
+void fix_pos(void)
{
int my_col = col;
@@ -553,44 +568,44 @@ void generic_init(void)
#ifndef WIN32
-main(argc, argv)
-int argc;
-char ** argv;
+int main(int argc, char **argv)
{
int c;
+ void *buf;
-#if defined(MACINTOSH)
+# if defined(MACINTOSH)
console_options.title = "\pDumb Editor";
cshow(stdout);
argc = ccommand(&argv);
-#endif
+# endif
GC_INIT();
- if (argc != 2) goto usage;
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s file\n", argv[0]);
+ fprintf(stderr, "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n");
+ fprintf(stderr, "Undo: ^U Write to <file>.new: ^W");
+ fprintf(stderr, "Quit:^D Repeat count: ^R[n]\n");
+ fprintf(stderr, "Top: ^T Locate (search, find): ^L text ^L\n");
+ exit(1);
+ }
arg_file_name = argv[1];
- setvbuf(stdout, GC_MALLOC_ATOMIC(8192), _IOFBF, 8192);
+ buf = GC_MALLOC_ATOMIC(8192);
+ if (NULL == buf) OUT_OF_MEMORY;
+ setvbuf(stdout, buf, _IOFBF, 8192);
initscr();
noecho(); nonl(); cbreak();
generic_init();
while ((c = getchar()) != QUIT) {
- if (c == EOF) break;
- do_command(c);
+ if (c == EOF) break;
+ do_command(c);
}
-done:
move(LINES-1, 0);
clrtoeol();
refresh();
nl();
echo();
endwin();
- exit(0);
-usage:
- fprintf(stderr, "Usage: %s file\n", argv[0]);
- fprintf(stderr, "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n");
- fprintf(stderr, "Undo: ^U Write to <file>.new: ^W");
- fprintf(stderr, "Quit:^D Repeat count: ^R[n]\n");
- fprintf(stderr, "Top: ^T Locate (search, find): ^L text ^L\n");
- exit(1);
+ return 0;
}
#endif /* !WIN32 */
diff --git a/cord/tests/de_win.c b/cord/tests/de_win.c
index 1179b8f7..23c1e2a1 100644
--- a/cord/tests/de_win.c
+++ b/cord/tests/de_win.c
@@ -28,16 +28,14 @@
int LINES = 0;
int COLS = 0;
-char szAppName[] = "DE";
-char FullAppName[] = "Demonstration Editor";
+#define szAppName TEXT("DE")
HWND hwnd;
void de_error(char *s)
{
- MessageBox( hwnd, (LPSTR) s,
- (LPSTR) FullAppName,
- MB_ICONINFORMATION | MB_OK );
+ (void)MessageBoxA(hwnd, s, "Demonstration Editor",
+ MB_ICONINFORMATION | MB_OK);
InvalidateRect(hwnd, NULL, TRUE);
}
@@ -48,10 +46,7 @@ int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
WNDCLASS wndclass;
HANDLE hAccel;
-# ifdef THREAD_LOCAL_ALLOC
- GC_INIT(); /* Required if GC is built with THREAD_LOCAL_ALLOC */
- /* Always safe, but this is used as a GC test. */
-# endif
+ GC_INIT();
if (!hPrevInstance)
{
@@ -63,7 +58,7 @@ int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
wndclass.hIcon = LoadIcon (hInstance, szAppName);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = "DE";
+ wndclass.lpszMenuName = TEXT("DE");
wndclass.lpszClassName = szAppName;
if (RegisterClass (&wndclass) == 0) {
@@ -89,13 +84,14 @@ int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
} else {
char *p = command_line;
- while (*p != 0 && !isspace(*p)) p++;
+ while (*p != 0 && !isspace(*(unsigned char *)p))
+ p++;
arg_file_name = CORD_to_char_star(
CORD_substr(command_line, 0, p - command_line));
}
hwnd = CreateWindow (szAppName,
- FullAppName,
+ TEXT("Demonstration Editor"),
WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */
CW_USEDEFAULT, 0, /* default pos. */
CW_USEDEFAULT, 0, /* default width, height */
@@ -132,8 +128,9 @@ char * plain_chars(char * text, size_t len)
char * result = GC_MALLOC_ATOMIC(len + 1);
register size_t i;
+ if (NULL == result) return NULL;
for (i = 0; i < len; i++) {
- if (iscntrl(text[i])) {
+ if (iscntrl(((unsigned char *)text)[i])) {
result[i] = ' ';
} else {
result[i] = text[i];
@@ -150,8 +147,9 @@ char * control_chars(char * text, size_t len)
char * result = GC_MALLOC_ATOMIC(len + 1);
register size_t i;
+ if (NULL == result) return NULL;
for (i = 0; i < len; i++) {
- if (iscntrl(text[i])) {
+ if (iscntrl(((unsigned char *)text)[i])) {
result[i] = text[i] + 0x40;
} else {
result[i] = ' ';
@@ -260,7 +258,8 @@ LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
unsigned xpos = LOWORD(lParam); /* From left */
unsigned ypos = HIWORD(lParam); /* from top */
- set_position( xpos/char_width, ypos/char_height );
+ set_position(xpos / (unsigned)char_width,
+ ypos / (unsigned)char_height);
return(0);
}
@@ -277,7 +276,7 @@ LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
return( 0 );
case IDM_HELPABOUT:
- if( DialogBox( hInstance, "ABOUTBOX",
+ if( DialogBox( hInstance, TEXT("ABOUTBOX"),
hwnd, AboutBoxCallback ) )
InvalidateRect( hwnd, NULL, TRUE );
return( 0 );
@@ -317,20 +316,25 @@ LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
char * blanks = CORD_to_char_star(CORD_chars(' ',
COLS - len));
char * control = control_chars(text, len);
+ if (NULL == plain || NULL == control)
+ de_error("Out of memory!");
+
# define RED RGB(255,0,0)
SetBkMode(dc, OPAQUE);
SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
- TextOut(dc, this_line.left, this_line.top,
- plain, (int)len);
- TextOut(dc, this_line.left + (int)len * char_width,
- this_line.top,
- blanks, (int)(COLS - len));
+ if (plain != NULL)
+ TextOutA(dc, this_line.left, this_line.top,
+ plain, (int)len);
+ TextOutA(dc, this_line.left + (int)len * char_width,
+ this_line.top,
+ blanks, (int)(COLS - len));
SetBkMode(dc, TRANSPARENT);
SetTextColor(dc, RED);
- TextOut(dc, this_line.left, this_line.top,
- control, (int)strlen(control));
+ if (control != NULL)
+ TextOutA(dc, this_line.left, this_line.top,
+ control, (int)strlen(control));
}
}
EndPaint(hwnd, &ps);
diff --git a/cord/tests/de_win.h b/cord/tests/de_win.h
index a6a02f39..93c5eebd 100644
--- a/cord/tests/de_win.h
+++ b/cord/tests/de_win.h
@@ -44,11 +44,7 @@
/* Windows UI stuff */
LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
- UINT wParam, LONG lParam);
-
-LRESULT CALLBACK AboutBox( HWND hDlg, UINT message,
- UINT wParam, LONG lParam );
-
+ WPARAM wParam, LPARAM lParam);
/* Screen dimensions. Maintained by de_win.c. */
extern int LINES;
diff --git a/darwin_stop_world.c b/darwin_stop_world.c
index 1f48c991..1a03690e 100644
--- a/darwin_stop_world.c
+++ b/darwin_stop_world.c
@@ -288,7 +288,7 @@ STATIC ptr_t GC_stack_range_for(ptr_t *phi, thread_act_t thread, GC_thread p,
# endif
# ifdef DEBUG_THREADS
GC_log_printf("Darwin: Stack for thread %p = [%p,%p)\n",
- (void *)thread, lo, *phi);
+ (void *)(word)thread, lo, *phi);
# endif
return lo;
}
@@ -413,7 +413,8 @@ STATIC GC_bool GC_suspend_thread_list(thread_act_array_t act_list, int count,
# endif
# ifdef DEBUG_THREADS
- GC_log_printf("Attempting to suspend thread %p\n", (void *)thread);
+ GC_log_printf("Attempting to suspend thread %p\n",
+ (void *)(word)thread);
# endif
/* find the current thread in the old list */
found = FALSE;
@@ -457,7 +458,8 @@ STATIC GC_bool GC_suspend_thread_list(thread_act_array_t act_list, int count,
continue;
}
# ifdef DEBUG_THREADS
- GC_log_printf("Thread state for %p = %d\n", (void *)thread, info.run_state);
+ GC_log_printf("Thread state for %p = %d\n", (void *)(word)thread,
+ info.run_state);
# endif
if (info.suspend_count != 0) {
/* thread is already suspended. */
@@ -467,7 +469,7 @@ STATIC GC_bool GC_suspend_thread_list(thread_act_array_t act_list, int count,
}
# ifdef DEBUG_THREADS
- GC_log_printf("Suspending %p\n", (void *)thread);
+ GC_log_printf("Suspending %p\n", (void *)(word)thread);
# endif
kern_result = thread_suspend(thread);
if (kern_result != KERN_SUCCESS) {
@@ -494,7 +496,8 @@ GC_INNER void GC_stop_world(void)
kern_return_t kern_result;
# ifdef DEBUG_THREADS
- GC_log_printf("Stopping the world from thread %p\n", (void *)my_thread);
+ GC_log_printf("Stopping the world from thread %p\n",
+ (void *)(word)my_thread);
# endif
# ifdef PARALLEL_MARK
if (GC_parallel) {
@@ -583,7 +586,7 @@ GC_INNER void GC_stop_world(void)
# endif
# ifdef DEBUG_THREADS
- GC_log_printf("World stopped from %p\n", (void *)my_thread);
+ GC_log_printf("World stopped from %p\n", (void *)(word)my_thread);
# endif
mach_port_deallocate(my_task, my_thread);
}
@@ -600,7 +603,7 @@ GC_INLINE void GC_thread_resume(thread_act_t thread)
ABORT("thread_info failed");
# endif
# ifdef DEBUG_THREADS
- GC_log_printf("Resuming thread %p with state %d\n", (void *)thread,
+ GC_log_printf("Resuming thread %p with state %d\n", (void *)(word)thread,
info.run_state);
# endif
/* Resume the thread */
@@ -659,7 +662,7 @@ GC_INNER void GC_start_world(void)
if (GC_mach_threads[j].already_suspended) {
# ifdef DEBUG_THREADS
GC_log_printf("Not resuming already suspended thread %p\n",
- (void *)thread);
+ (void *)(word)thread);
# endif
} else {
GC_thread_resume(thread);
diff --git a/dbg_mlc.c b/dbg_mlc.c
index a0423e97..ea02bd51 100644
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -506,14 +506,15 @@ GC_API void GC_CALL GC_debug_register_displacement(size_t offset)
# endif
#endif /* GC_ADD_CALLER */
-GC_API void * GC_CALL GC_debug_malloc(size_t lb, GC_EXTRA_PARAMS)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc(size_t lb,
+ GC_EXTRA_PARAMS)
{
void * result;
/* Note that according to malloc() specification, if size is 0 then */
/* malloc() returns either NULL, or a unique pointer value that can */
/* later be successfully passed to free(). We always do the latter. */
- result = GC_malloc(lb + DEBUG_BYTES);
+ result = GC_malloc(SIZET_SAT_ADD(lb, DEBUG_BYTES));
# ifdef GC_ADD_CALLER
if (s == NULL) {
GC_caller_func_offset(ra, &s, &i);
@@ -531,10 +532,10 @@ GC_API void * GC_CALL GC_debug_malloc(size_t lb, GC_EXTRA_PARAMS)
return (GC_store_debug_info(result, (word)lb, s, i));
}
-GC_API void * GC_CALL GC_debug_malloc_ignore_off_page(size_t lb,
- GC_EXTRA_PARAMS)
+GC_API GC_ATTR_MALLOC void * GC_CALL
+ GC_debug_malloc_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
{
- void * result = GC_malloc_ignore_off_page(lb + DEBUG_BYTES);
+ void * result = GC_malloc_ignore_off_page(SIZET_SAT_ADD(lb, DEBUG_BYTES));
if (result == 0) {
GC_err_printf("GC_debug_malloc_ignore_off_page(%lu)"
@@ -548,10 +549,11 @@ GC_API void * GC_CALL GC_debug_malloc_ignore_off_page(size_t lb,
return (GC_store_debug_info(result, (word)lb, s, i));
}
-GC_API void * GC_CALL GC_debug_malloc_atomic_ignore_off_page(size_t lb,
- GC_EXTRA_PARAMS)
+GC_API GC_ATTR_MALLOC void * GC_CALL
+ GC_debug_malloc_atomic_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
{
- void * result = GC_malloc_atomic_ignore_off_page(lb + DEBUG_BYTES);
+ void * result = GC_malloc_atomic_ignore_off_page(
+ SIZET_SAT_ADD(lb, DEBUG_BYTES));
if (result == 0) {
GC_err_printf("GC_debug_malloc_atomic_ignore_off_page(%lu)"
@@ -573,7 +575,8 @@ GC_API void * GC_CALL GC_debug_malloc_atomic_ignore_off_page(size_t lb,
/* we already hold the GC lock. */
GC_INNER void * GC_debug_generic_malloc_inner(size_t lb, int k)
{
- void * result = GC_generic_malloc_inner(lb + DEBUG_BYTES, k);
+ void * result = GC_generic_malloc_inner(
+ SIZET_SAT_ADD(lb, DEBUG_BYTES), k);
if (result == 0) {
GC_err_printf("GC internal allocation (%lu bytes) returning NULL\n",
@@ -591,7 +594,7 @@ GC_API void * GC_CALL GC_debug_malloc_atomic_ignore_off_page(size_t lb,
int k)
{
void * result = GC_generic_malloc_inner_ignore_off_page(
- lb + DEBUG_BYTES, k);
+ SIZET_SAT_ADD(lb, DEBUG_BYTES), k);
if (result == 0) {
GC_err_printf("GC internal allocation (%lu bytes) returning NULL\n",
@@ -607,9 +610,10 @@ GC_API void * GC_CALL GC_debug_malloc_atomic_ignore_off_page(size_t lb,
#endif /* DBG_HDRS_ALL */
#ifdef STUBBORN_ALLOC
- GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc_stubborn(size_t lb,
+ GC_EXTRA_PARAMS)
{
- void * result = GC_malloc_stubborn(lb + DEBUG_BYTES);
+ void * result = GC_malloc_stubborn(SIZET_SAT_ADD(lb, DEBUG_BYTES));
if (result == 0) {
GC_err_printf("GC_debug_malloc_stubborn(%lu)"
@@ -656,7 +660,8 @@ GC_API void * GC_CALL GC_debug_malloc_atomic_ignore_off_page(size_t lb,
#else /* !STUBBORN_ALLOC */
- GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc_stubborn(size_t lb,
+ GC_EXTRA_PARAMS)
{
return GC_debug_malloc(lb, OPT_RA s, i);
}
@@ -668,9 +673,10 @@ GC_API void * GC_CALL GC_debug_malloc_atomic_ignore_off_page(size_t lb,
const void * p GC_ATTR_UNUSED) {}
#endif /* !STUBBORN_ALLOC */
-GC_API void * GC_CALL GC_debug_malloc_atomic(size_t lb, GC_EXTRA_PARAMS)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc_atomic(size_t lb,
+ GC_EXTRA_PARAMS)
{
- void * result = GC_malloc_atomic(lb + DEBUG_BYTES);
+ void * result = GC_malloc_atomic(SIZET_SAT_ADD(lb, DEBUG_BYTES));
if (result == 0) {
GC_err_printf("GC_debug_malloc_atomic(%lu) returning NULL (%s:%d)\n",
@@ -684,7 +690,8 @@ GC_API void * GC_CALL GC_debug_malloc_atomic(size_t lb, GC_EXTRA_PARAMS)
return (GC_store_debug_info(result, (word)lb, s, i));
}
-GC_API char * GC_CALL GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
+GC_API GC_ATTR_MALLOC char * GC_CALL GC_debug_strdup(const char *str,
+ GC_EXTRA_PARAMS)
{
char *copy;
size_t lb;
@@ -706,8 +713,8 @@ GC_API char * GC_CALL GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
return copy;
}
-GC_API char * GC_CALL GC_debug_strndup(const char *str, size_t size,
- GC_EXTRA_PARAMS)
+GC_API GC_ATTR_MALLOC char * GC_CALL GC_debug_strndup(const char *str,
+ size_t size, GC_EXTRA_PARAMS)
{
char *copy;
size_t len = strlen(str); /* str is expected to be non-NULL */
@@ -728,7 +735,8 @@ GC_API char * GC_CALL GC_debug_strndup(const char *str, size_t size,
#ifdef GC_REQUIRE_WCSDUP
# include <wchar.h> /* for wcslen() */
- GC_API wchar_t * GC_CALL GC_debug_wcsdup(const wchar_t *str, GC_EXTRA_PARAMS)
+ GC_API GC_ATTR_MALLOC wchar_t * GC_CALL GC_debug_wcsdup(const wchar_t *str,
+ GC_EXTRA_PARAMS)
{
size_t lb = (wcslen(str) + 1) * sizeof(wchar_t);
wchar_t *copy = GC_debug_malloc_atomic(lb, OPT_RA s, i);
@@ -743,10 +751,11 @@ GC_API char * GC_CALL GC_debug_strndup(const char *str, size_t size,
}
#endif /* GC_REQUIRE_WCSDUP */
-GC_API void * GC_CALL GC_debug_malloc_uncollectable(size_t lb,
- GC_EXTRA_PARAMS)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc_uncollectable(size_t lb,
+ GC_EXTRA_PARAMS)
{
- void * result = GC_malloc_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
+ void * result = GC_malloc_uncollectable(
+ SIZET_SAT_ADD(lb, UNCOLLECTABLE_DEBUG_BYTES));
if (result == 0) {
GC_err_printf("GC_debug_malloc_uncollectable(%lu)"
@@ -761,11 +770,11 @@ GC_API void * GC_CALL GC_debug_malloc_uncollectable(size_t lb,
}
#ifdef ATOMIC_UNCOLLECTABLE
- GC_API void * GC_CALL GC_debug_malloc_atomic_uncollectable(size_t lb,
- GC_EXTRA_PARAMS)
+ GC_API GC_ATTR_MALLOC void * GC_CALL
+ GC_debug_malloc_atomic_uncollectable(size_t lb, GC_EXTRA_PARAMS)
{
- void * result =
- GC_malloc_atomic_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
+ void * result = GC_malloc_atomic_uncollectable(
+ SIZET_SAT_ADD(lb, UNCOLLECTABLE_DEBUG_BYTES));
if (result == 0) {
GC_err_printf("GC_debug_malloc_atomic_uncollectable(%lu)"
@@ -871,6 +880,11 @@ GC_API void * GC_CALL GC_debug_realloc(void * p, size_t lb, GC_EXTRA_PARAMS)
if (p == 0) {
return GC_debug_malloc(lb, OPT_RA s, i);
}
+ if (0 == lb) /* and p != NULL */ {
+ GC_debug_free(p);
+ return NULL;
+ }
+
# ifdef GC_ADD_CALLER
if (s == NULL) {
GC_caller_func_offset(ra, &s, &i);
@@ -1207,7 +1221,7 @@ GC_API void GC_CALL GC_debug_register_finalizer_ignore_self
#endif /* !GC_NO_FINALIZATION */
-GC_API void * GC_CALL GC_debug_malloc_replacement(size_t lb)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc_replacement(size_t lb)
{
return GC_debug_malloc(lb, GC_DBG_EXTRAS);
}
diff --git a/doc/README.DGUX386 b/doc/README.DGUX386
index 0aa89bdf..48c800b8 100644
--- a/doc/README.DGUX386
+++ b/doc/README.DGUX386
@@ -24,13 +24,7 @@
To enable debugging messages please do:
1) Add the "--enable-gc-debug" flag during configuration.
- 2) Edit the file linux-threads.c and uncomment the line:
-
- /* #define DEBUG_THREADS 1 */ to --->
-
- #define DEBUG_THREADS 1
-
- Then give "make" as usual.
+ 2) Pass "CFLAGS=-DDEBUG_THREADS" to "make".
In a machine with 4 CPUs (my own machine) the option parallel
mark (aka --enable-parallel-mark) makes a BIG difference.
diff --git a/doc/README.Mac b/doc/README.Mac
index 55906697..f77d1c43 100644
--- a/doc/README.Mac
+++ b/doc/README.Mac
@@ -271,7 +271,7 @@ action! malloc will call GC_malloc and free GC_free, new/delete too. You
don't have to call free or delete. You may have to be a bit cautious about
delete if you're freeing other resources than RAM. See gc_cpp.h. You can
also keep coding as always with delete/free. That works too. If you want,
-"include <gc.h> and tweak it's use a bit.
+"include <gc.h> and tweak its use a bit.
== Symantec SPM ==
diff --git a/doc/README.cmake b/doc/README.cmake
index 3eb347c0..e691fa95 100644
--- a/doc/README.cmake
+++ b/doc/README.cmake
@@ -32,12 +32,12 @@ BUILD PROCESS
. install cmake (cmake.org)
. add directory containing cmake.exe to %PATH%
. run cmake from the gc root directory, passing the target with -G:
- eg.
+ e.g.,
> cmake -G "Visual Studio 8 2005"
use the gc.sln file generated by cmake to build gc
. you can also run cmake from a build directory to build outside of
the source tree. Just specify the path to the source tree:
- eg.
+ e.g.,
> mkdir build
> cd build
> cmake .. -G "Visual Studio 8 2005"
diff --git a/doc/README.cords b/doc/README.cords
index 0339a9a9..f64dd2e8 100644
--- a/doc/README.cords
+++ b/doc/README.cords
@@ -26,8 +26,7 @@ A fundamentally similar "rope" data structure is also part of SGI's standard
template library implementation, and its descendants, which include the
GNU C++ library. That uses reference counting by default.
There is a short description of that data structure at
-http://reality.sgi.com/boehm/ropeimpl.html . (The more official location
-http://www.sgi.com/tech/stl/ropeimpl.html is missing a figure.)
+http://www.sgi.com/tech/stl/ropeimpl.html .
All of these are descendants of the "ropes" in Xerox Cedar.
diff --git a/doc/README.environment b/doc/README.environment
index 79752f78..7d4d96c4 100644
--- a/doc/README.environment
+++ b/doc/README.environment
@@ -93,11 +93,11 @@ GC_PRINT_BACK_HEIGHT - Print max length of chain through unreachable objects
This feature is still somewhat experimental, and requires
that the collector have been built with MAKE_BACK_GRAPH
defined. For details, see Boehm, "Bounding Space Usage
- of Conservative Garbage Collectors", POPL 2001, or
- http://lib.hpl.hp.com/techpubs/2001/HPL-2001-251.html .
+ of Conservative Garbage Collectors", POPL 2001
+ (http://www.hpl.hp.com/techreports/2001/HPL-2001-251.html).
GC_RETRY_SIGNALS, GC_NO_RETRY_SIGNALS - Try to compensate for lost
- thread suspend signals in linux_threads.c. On by
+ thread suspend signals (Pthreads only). On by
default for GC_OSF1_THREADS, off otherwise. Note
that this does not work around a possible loss of
thread restart signals. This seems to be necessary for
diff --git a/doc/README.ews4800 b/doc/README.ews4800
index d4ea32aa..20ecbaab 100644
--- a/doc/README.ews4800
+++ b/doc/README.ews4800
@@ -4,7 +4,7 @@ GC on EWS4800
1. About EWS4800
EWS4800 is 32bit/64bit workstation.
- Vender: NEC Corporation
+ Vendor: NEC Corporation
OS: UX/4800 R9.* - R13.* (SystemV R4.2)
CPU: R4000, R4400, R10000 (MIPS)
@@ -20,7 +20,7 @@ GC on EWS4800
AR = /usr/ccs64/bin/ar
3. ELF file format
- *** Caution: The following infomation is empirical. ***
+ *** Caution: The following information is empirical. ***
32bit:
ELF file has an unique format. (See a.out(4) and end(3C).)
@@ -76,5 +76,5 @@ Hironori SAKAMOTO
When using the new "configure; make" build process, please
run configure with the --disable-shared option. "Make check" does not
-yet pass with dynamic libraries. Ther reasons for that are not yet
+yet pass with dynamic libraries. The reasons for that are not yet
understood. (HB, paraphrasing message from Hironori SAKAMOTO.)
diff --git a/doc/README.macros b/doc/README.macros
index a822f0f4..a836767d 100644
--- a/doc/README.macros
+++ b/doc/README.macros
@@ -107,10 +107,6 @@ SUNOS5SIGS Solaris-like signal handling. This is probably misnamed,
PCR Set if the collector is being built as part of the Xerox Portable
Common Runtime.
-USE_COMPILER_TLS Assume the existence of __thread-style thread-local storage.
- Set automatically for thread-local allocation with the HP/UX vendor
- compiler. Usable with gcc on sufficiently up-to-date ELF platforms.
-
IMPORTANT: Any of the _THREADS options must normally also be defined in
the client before including gc.h. This redefines thread primitives to
invoke the GC_ versions instead. Alternatively, linker-based symbol
@@ -149,7 +145,7 @@ GC_DGUX386_THREADS Enables support for DB/UX on I386 threads.
GC_WIN32_THREADS Enables support for Win32 threads. That makes sense
for this Makefile only under Cygwin.
-GC_WIN32_PTHREADS Enables support for Ming32 pthreads. This cannot be
+GC_WIN32_PTHREADS Enables support for pthreads-win32. This cannot be
enabled automatically by GC_THREADS, which would assume Win32 native
threads.
@@ -393,13 +389,6 @@ USE_COMPILER_TLS Causes thread local allocation to use
PARALLEL_MARK Allows the marker to run in multiple threads. Recommended
for multiprocessors.
-DONT_USE_SIGNALANDWAIT (Win32 only) Use an alternate implementation for
- marker threads (if PARALLEL_MARK defined) synchronization routines based
- on InterlockedExchange() (instead of AO_fetch_and_add()) and on multiple
- event objects (one per each marker instead of that based on Win32
- SignalObjectAndWait() using a single event object). This is the default
- for WinCE.
-
GC_WINMAIN_REDIRECT (Win32 only) Redirect (rename) an application
WinMain to GC_WinMain; implement the "real" WinMain which starts a new
thread to call GC_WinMain after initializing the GC. Useful for WinCE.
diff --git a/doc/README.solaris2 b/doc/README.solaris2
index 2f3b511a..ba7bb2b2 100644
--- a/doc/README.solaris2
+++ b/doc/README.solaris2
@@ -19,7 +19,7 @@ You may want to reverse this decisions if you use -DREDIRECT_MALLOC=...
Note:
Before you run "make check", you need to set your LD_LIBRARY_PATH correctly
-(eg., to "/usr/local/lib") so that tests can find the shared library
+(e.g., to "/usr/local/lib") so that tests can find the shared library
libgcc_s.so.1. Alternatively, you can configure with --disable-shared.
SOLARIS THREADS:
diff --git a/doc/README.win32 b/doc/README.win32
index 471126e2..134681cf 100644
--- a/doc/README.win32
+++ b/doc/README.win32
@@ -142,7 +142,7 @@ important, otherwise resulting programs will not run.
Special note for OpenWatcom users: the C (unlike the C++) compiler (of the
latest stable release, not sure for older ones) doesn't force pointer global
variables (i.e. not struct fields, not sure for locals) to be aligned unless
-optimizing for speed (eg. "-ot" option is set); the "-zp" option (or align
+optimizing for speed (e.g., "-ot" option is set); the "-zp" option (or align
pragma) only controls alignment for structs; I don't know whether it's a bug or
a feature (see an old report of same kind -
http://bugzilla.openwatcom.org/show_bug.cgi?id=664), so You are warned.
@@ -217,6 +217,7 @@ especially with the garbage collector. Any use is likely to provoke a
crash in the GC, since it makes it impossible for the collector to
correctly track threads.
-To build the collector for Mingw32 Pthreads, use Makefile.direct and
-explicitly set GC_WIN32_PTHREADS. Use -DPTW32_STATIC_LIB for the static
-threads library.
+To build the collector for MinGW pthreads-win32,
+use Makefile.direct and explicitly set
+GC_WIN32_PTHREADS (or pass --enable-threads=pthreads to configure).
+Use -DPTW32_STATIC_LIB for the static threads library.
diff --git a/doc/barrett_diagram b/doc/barrett_diagram
deleted file mode 100644
index 6f7d2fe3..00000000
--- a/doc/barrett_diagram
+++ /dev/null
@@ -1,106 +0,0 @@
-This is an ASCII diagram of the data structure used to check pointer
-validity. It was provided by Dave Barrett,
-and should be of use to others attempting to understand the code.
-The data structure in GC4.X is essentially the same. -HB
-
-
-
-
- Data Structure used by GC_base in gc3.7:
- 21-Apr-94
-
-
-
-
- 63 LOG_TOP_SZ[11] LOG_BOTTOM_SZ[10] LOG_HBLKSIZE[13]
- +------------------+----------------+------------------+------------------+
- p:| | TL_HASH(hi) | | HBLKDISPL(p) |
- +------------------+----------------+------------------+------------------+
- \-----------------------HBLKPTR(p)-------------------/
- \------------hi-------------------/
- \______ ________/ \________ _______/ \________ _______/
- V V V
- | | |
- GC_top_index[] | | |
- --- +--------------+ | | |
- ^ | | | | |
- | | | | | |
- TOP +--------------+<--+ | |
- _SZ +-<| [] | * | |
-(items)| +--------------+ if 0 < bi< HBLKSIZE | |
- | | | | then large object | |
- | | | | starts at the bi'th | |
- v | | | HBLK before p. | i |
- --- | +--------------+ | (word- |
- v | aligned) |
- bi= |GET_BI(p){->hash_link}->key==hi | |
- v | |
- | (bottom_index) \ scratch_alloc'd | |
- | ( struct bi ) / by get_index() | |
- --- +->+--------------+ | |
- ^ | | | |
- ^ | | | |
- BOTTOM | | ha=GET_HDR_ADDR(p) | |
-_SZ(items)+--------------+<----------------------+ +-------+
- | +--<| index[] | |
- | | +--------------+ GC_obj_map: v
- | | | | from / +-+-+-----+-+-+-+-+ ---
- v | | | GC_add < 0| | | | | | | | ^
- --- | +--------------+ _map_entry \ +-+-+-----+-+-+-+-+ |
- | | asc_link | +-+-+-----+-+-+-+-+ MAXOBJSZ
- | +--------------+ +-->| | | j | | | | | +1
- | | key | | +-+-+-----+-+-+-+-+ |
- | +--------------+ | +-+-+-----+-+-+-+-+ |
- | | hash_link | | | | | | | | | | v
- | +--------------+ | +-+-+-----+-+-+-+-+ ---
- | | |<--MAX_OFFSET--->|
- | | (bytes)
-HDR(p)| GC_find_header(p) | |<--MAP_ENTRIES-->|
- | \ from | =HBLKSIZE/WORDSZ
- | (hdr) (struct hblkhdr) / alloc_hdr() | (1024 on Alpha)
- +-->+----------------------+ | (8/16 bits each)
-GET_HDR(p)| word hb_sz (words) | |
- +----------------------+ |
- | struct hblk *hb_next | |
- +----------------------+ |
- |mark_proc hb_mark_proc| |
- +----------------------+ |
- | char * hb_map |>-------------+
- +----------------------+
- | ushort hb_obj_kind |
- +----------------------+
- | hb_last_reclaimed |
- --- +----------------------+
- ^ | |
- MARK_BITS| hb_marks[] | *if hdr is free, hb_sz + DISCARD_WORDS
-_SZ(words)| | is the size of a heap chunk (struct hblk)
- v | | of at least MININCR*HBLKSIZE bytes (below),
- --- +----------------------+ otherwise, size of each object in chunk.
-
-Dynamic data structures above are interleaved throughout the heap in blocks of
-size MININCR * HBLKSIZE bytes as done by gc_scratch_alloc which cannot be
-freed; free lists are used (e.g. alloc_hdr). HBLKs's below are collected.
-
- (struct hblk)
- --- +----------------------+ < HBLKSIZE --- --- DISCARD_
- ^ |garbage[DISCARD_WORDS]| aligned ^ ^ HDR_BYTES WORDS
- | | | | v (bytes) (words)
- | +-----hb_body----------+ < WORDSZ | --- ---
- | | | aligned | ^ ^
- | | Object 0 | | hb_sz |
- | | | i |(word- (words)|
- | | | (bytes)|aligned) v |
- | + - - - - - - - - - - -+ --- | --- |
- | | | ^ | ^ |
- n * | | j (words) | hb_sz BODY_SZ
- HBLKSIZE | Object 1 | v v | (words)
- (bytes) | |--------------- v MAX_OFFSET
- | + - - - - - - - - - - -+ --- (bytes)
- | | | !All_INTERIOR_PTRS ^ |
- | | | sets j only for hb_sz |
- | | Object N | valid object offsets. | |
- v | | All objects WORDSZ v v
- --- +----------------------+ aligned. --- ---
-
-DISCARD_WORDS is normally zero. Indeed the collector has not been tested
-with another value in ages.
diff --git a/doc/debugging.html b/doc/debugging.html
index 241875ce..01281291 100644
--- a/doc/debugging.html
+++ b/doc/debugging.html
@@ -285,7 +285,7 @@ collector's layout description for <TT>s</tt> is such that the pointer field
will be scanned. Call <TT>*GC_find_header(s)</tt> to look at the descriptor
for the heap chunk. The <TT>hb_descr</tt> field specifies the layout
of objects in that chunk. See gc_mark.h for the meaning of the descriptor.
-(If it's low order 2 bits are zero, then it is just the length of the
+(If its low order 2 bits are zero, then it is just the length of the
object prefix to be scanned. This form is always used for objects allocated
with <TT>GC_malloc</tt> or <TT>GC_malloc_atomic</tt>.)
<LI> If the failure is not deterministic, you may still be able to apply some
diff --git a/doc/doc.am b/doc/doc.am
index dcae4d73..ef541505 100644
--- a/doc/doc.am
+++ b/doc/doc.am
@@ -37,7 +37,6 @@ dist_pkgdata_DATA = \
doc/README.uts \
doc/README.win32 \
doc/README.win64 \
- doc/barrett_diagram \
doc/debugging.html \
doc/finalization.html \
doc/gc.man \
diff --git a/doc/gc.man b/doc/gc.man
index ef159289..45537376 100644
--- a/doc/gc.man
+++ b/doc/gc.man
@@ -91,13 +91,13 @@ Other facilities not discussed here include limited facilities to support increm
.SH "SEE ALSO"
The README and gc.h files in the distribution. More detailed definitions of the functions exported by the collector are given there. (The above list is not complete.)
.LP
-The web site at http://www.hpl.hp.com/personal/Hans_Boehm/gc .
+The web site at http://www.hboehm.info/gc/ .
.LP
Boehm, H., and M. Weiser, "Garbage Collection in an Uncooperative Environment",
-\fISoftware Practice & Experience\fP, September 1988, pp. 807-820.
+"Software Practice & Experience", September 1988, pp. 807-820.
.LP
The malloc(3) man page.
.LP
.SH AUTHOR
-Hans-J. Boehm (Hans.Boehm@hp.com).
+Hans-J. Boehm (boehm@acm.org).
Some of the code was written by others, most notably Alan Demers.
diff --git a/doc/gcdescr.html b/doc/gcdescr.html
index 8a1dae06..a30e776b 100644
--- a/doc/gcdescr.html
+++ b/doc/gcdescr.html
@@ -272,7 +272,7 @@ each call, so that it can also be used by the incremental collector.
It is fairly carefully tuned, since it usually consumes a large majority
of the garbage collection time.
<P>
-The fact that it perform a only a small amount of work per call also
+The fact that it performs only a small amount of work per call also
allows it to be used as the core routine of the parallel marker. In that
case it is normally invoked on thread-private mark stacks instead of the
global mark stack. More details can be found in
@@ -425,7 +425,7 @@ Java-style unordered finalization, and to ignore certain kinds of cycles,
<H2>Generational Collection and Dirty Bits</h2>
We basically use the concurrent and generational GC algorithm described in
-<A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers/pldi91.ps.Z">"Mostly Parallel Garbage Collection"</a>,
+<A HREF="http://www.hboehm.info/gc/papers/pldi91.ps.Z">"Mostly Parallel Garbage Collection"</a>,
by Boehm, Demers, and Shenker.
<P>
The most significant modification is that
@@ -534,23 +534,16 @@ common Pthreads implementations.
In particular, it is very difficult for the collector to stop all other
threads in the system and examine the register contents. This is currently
accomplished with very different mechanisms for some Pthreads
-implementations. The Solaris implementation temporarily disables much
-of the user-level threads implementation by stopping kernel-level threads
-("lwp"s). The Linux/HPUX/OSF1 and Irix implementations sends signals to
+implementations. For Linux/HPUX/OSF1, Solaris and Irix it sends signals to
individual Pthreads and has them wait in the signal handler.
<P>
The Linux and Irix implementations use
only documented Pthreads calls, but rely on extensions to their semantics.
-The Linux implementation <TT>linux_threads.c</tt> relies on only very
+The Linux implementation <TT>pthread_stop_world.c</tt> relies on only very
mild extensions to the pthreads semantics, and already supports a large number
of other Unix-like pthreads implementations. Our goal is to make this the
only pthread support in the collector.
<P>
-(The Irix implementation is separate only for historical reasons and should
-clearly be merged. The current Solaris implementation probably performs
-better in the uniprocessor case, but does not support thread operations in the
-collector. Hence it cannot support the parallel marker.)
-<P>
All implementations must
intercept thread creation and a few other thread-specific calls to allow
enumeration of threads and location of thread stacks. This is current
@@ -616,17 +609,13 @@ GC versions before 7 do not invoke the thread-local allocator by default.
For some more details see <A HREF="scale.html">here</a>, and the
technical report entitled
<A HREF="http://www.hpl.hp.com/techreports/2000/HPL-2000-165.html">
-``Fast Multiprocessor Memory Allocation and Garbage Collection''
-</a>
+"Fast Multiprocessor Memory Allocation and Garbage Collection"</a>
<P>
<HR>
<P>
Comments are appreciated. Please send mail to
-<A HREF="mailto:gc@linux.hpl.hp.com"><tt>gc@linux.hpl.hp.com</tt></a>
+<A HREF="mailto:bdwgc@lists.opendylan.org"><tt>bdwgc@lists.opendylan.org</tt></a>
(GC mailing list) or
-<A HREF="mailto:Hans.Boehm@hp.com"><TT>Hans.Boehm@hp.com</tt></a>
-<P>
-This is a modified copy of a page written while the author was at SGI.
-The original was <A HREF="http://reality.sgi.com/boehm/gcdescr.html">here</a>.
+<A HREF="mailto:boehm@acm.org"><TT>boehm@acm.org</tt></a>
</body>
</html>
diff --git a/doc/gcinterface.html b/doc/gcinterface.html
index 31a41fcd..c315af88 100644
--- a/doc/gcinterface.html
+++ b/doc/gcinterface.html
@@ -249,7 +249,7 @@ memory, while the second two allocate collectible memory.
The <TT>single_client</tt> versions are not safe for concurrent access by
multiple threads, but are faster.
<P>
-For an example, click <A HREF="http://hpl.hp.com/personal/Hans_Boehm/gc/gc_alloc_exC.txt">here</a>.
+For an example, click <A HREF="http://www.hboehm.info/gc/gc_alloc_exC.txt">here</a>.
<DT> <B> Class inheritance based interface for new-based allocation</b>
<DD>
Users may include gc_cpp.h and then cause members of classes to
diff --git a/doc/overview.html b/doc/overview.html
index 6ea9f2ed..003ed7a6 100644
--- a/doc/overview.html
+++ b/doc/overview.html
@@ -4,11 +4,11 @@
<table bgcolor="#f0f0ff" cellpadding="10%">
<tbody><tr>
<td><a href="gcinterface.html">Interface Overview</a></td>
- <td><a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/04tutorial.pdf">Tutorial Slides</a></td>
- <td><a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/faq.html">FAQ</a></td>
+ <td><a href="http://www.hboehm.info/gc/04tutorial.pdf">Tutorial Slides</a></td>
+ <td><a href="http://www.hboehm.info/gc/faq.html">FAQ</a></td>
<td><a href="simple_example.html">Example</a></td>
- <td><a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source">Download</a></td>
- <td><a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/license.txt">License</a></td>
+ <td><a href="http://www.hboehm.info/gc/gc_source/">Download</a></td>
+ <td><a href="http://www.hboehm.info/gc/license.txt">License</a></td>
</tr>
</tbody></table>
<h1>A garbage collector for C and C++</h1>
@@ -23,12 +23,14 @@
</li><li><a href="#contacts">Contacts and Mailing List</a>
</li></ul>
[ This is an updated version of the page formerly at
+<tt>www.hpl.hp.com/personal/Hans_Boehm/gc/</tt>,
+before that at
<tt>http://reality.sgi.com/boehm/gc.html</tt>
and before that at
-<a href="ftp://parcftp.xerox.com/pub/gc/gc.html">
-<tt>ftp://parcftp.xerox.com/pub/gc/gc.html</tt></a>.]
+<a href="ftp://ftp.parc.xerox.com/pub/gc/gc.html">
+<tt>ftp://ftp.parc.xerox.com/pub/gc/gc.html</tt></a>. ]
<p>
-The <a href="http://www.hpl.hp.com/personal/Hans_Boehm">Boehm</a>-<a href="http://www.cs.cornell.edu/annual_report/00-01/bios.htm#demers">Demers</a>-<a href="http://www-sul.stanford.edu/weiser/">Weiser</a>
+The <a href="http://www.hboehm.info">Boehm</a>-<a href="http://www.cs.cornell.edu/annual_report/00-01/bios.htm#demers">Demers</a>-<a href="http://www-sul.stanford.edu/weiser/">Weiser</a>
conservative garbage collector can
be used as a garbage collecting
replacement for C <tt>malloc</tt> or C++ <tt>new</tt>.
@@ -52,11 +54,11 @@ for C or C++ programs, though that is not its primary goal.
</p><p>
Typically several versions will be available.
Usually you should first try to use
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc.tar.gz"><tt>gc_source/gc.tar.gz</tt></a>,
+<a href="http://www.hboehm.info/gc/gc_source/gc.tar.gz"><tt>gc_source/gc.tar.gz</tt></a>,
which is normally an older, more stable version.
</p><p>
If that fails, try the latest explicitly numbered version
-in <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/">
+in <a href="http://www.hboehm.info/gc/gc_source/">
<tt>gc_source/</tt></a>.
Later versions may contain additional features, platform support,
or bug fixes, but are likely to be less well tested.
@@ -71,19 +73,20 @@ code for that version is available for browsing
The arguments for and against conservative garbage collection
in C and C++ are briefly
discussed in
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/issues.html">issues.html</a>. The beginnings of
-a frequently-asked-questions list are <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/faq.html">here</a>.
+<a href="http://www.hboehm.info/gc/issues.html">issues.html</a>.
+The beginnings of a frequently-asked-questions list are
+<a href="http://www.hboehm.info/gc/faq.html">here</a>.
</p><p>
The garbage collector code is copyrighted by
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm">Hans-J. Boehm</a>,
+<a href="http://www.hboehm.info">Hans-J. Boehm</a>,
Alan J. Demers,
<a href="http://www.xerox.com/">Xerox Corporation</a>,
<a href="http://www.sgi.com/">Silicon Graphics</a>,
and
<a href="http://www.hp.com/">Hewlett-Packard Company</a>.
It may be used and copied without payment of a fee under minimal restrictions.
-See the README file in the distribution or the
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/license.txt">license</a> for more details.
+See the README file in the distribution or the
+<a href="http://www.hboehm.info/gc/license.txt">license</a> for more details.
<b>IT IS PROVIDED AS IS,
WITH ABSOLUTELY NO WARRANTY EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK</b>.
</p><p>
@@ -92,7 +95,7 @@ simply by replacing
<tt>malloc</tt> with <tt>GC_malloc</tt> calls,
replacing <tt>realloc</tt> with <tt>GC_realloc</tt> calls, and removing
free calls. Exceptions are discussed
-in <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/issues.html">issues.html</a>.
+in <a href="http://www.hboehm.info/gc/issues.html">issues.html</a>.
</p><h2><a name="platforms">Platforms</a></h2>
The collector is not completely portable, but the distribution
includes ports to most standard PC and UNIX/Linux platforms.
@@ -115,22 +118,20 @@ incorporate changes, it is impossible for
me to update the project file.)
<p>
Precompiled versions of the collector for NetBSD are available
-<a href="ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/devel/boehm-gc/README.html">here</a>
-or
-<a href="http://www.netbsd.org/packages/devel/boehm-gc/README.html">here</a>.
+<a href="ftp://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/devel/boehm-gc/README.html">here</a>.
</p><p>
<a href="http://www.debian.org/">Debian Linux</a> includes prepackaged
versions of the collector.
</p><h2><a name="multiprocessors">Scalable multiprocessor versions</a></h2>
Kenjiro Taura, Toshio Endo, and Akinori Yonezawa have made available
-a <a href="http://www.yl.is.s.u-tokyo.ac.jp/gc/">parallel collector</a>
+a <a href="http://web.yl.is.s.u-tokyo.ac.jp/gc/">parallel collector</a>
based on this one. Their collector takes advantage of multiple processors
during a collection. Starting with collector version 6.0alpha1
we also do this, though with more modest processor scalability goals.
Our approach is discussed briefly in
<a href="scale.html"><tt>scale.html</tt></a>.
<h2><a name="details">Some Collector Details</a></h2>
-The collector uses a <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/complexity.html">mark-sweep</a> algorithm.
+The collector uses a <a href="http://www.hboehm.info/gc/complexity.html">mark-sweep</a> algorithm.
It provides incremental and generational
collection under operating systems which provide the right kind of
virtual memory support. (Currently this includes SunOS[45], IRIX,
@@ -139,7 +140,7 @@ It allows <a href="finalization.html"><i>finalization</i></a> code
to be invoked when an object is collected.
It can take advantage of type information to locate pointers if such
information is provided, but it is usually used without such information.
-ee the README and
+See the README and
<tt>gc.h</tt> files in the distribution for more details.
<p>
For an overview of the implementation, see <a href="gcdescr.html">here</a>.
@@ -156,7 +157,7 @@ with malloc/free implementations. Both space and time overhead are
likely to be only slightly higher
for programs written for malloc/free
(see Detlefs, Dosser and Zorn's
-<a href="ftp://ftp.cs.colorado.edu/pub/techreports/zorn/CU-CS-665-93.ps.Z">Memory Allocation Costs in Large C and C++ Programs</a>.)
+<a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.30.3073&rep=rep1&type=ps">Memory Allocation Costs in Large C and C++ Programs</a>.)
For programs allocating primarily very small objects, the collector
may be faster; for programs allocating primarily large objects it will
be slower. If the collector is used in a multi-threaded environment
@@ -169,7 +170,7 @@ if programs are written
and tuned for garbage collection.
</p><h1><a name="further">Further Reading:</a></h1>
<b>The beginnings of a frequently asked questions list for this
-collector are <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/faq.html">here</a></b>.
+collector are <a href="http://www.hboehm.info/gc/faq.html">here</a></b>.
<p>
<b>The following provide information on garbage collection in general</b>:
</p><p>
@@ -182,8 +183,8 @@ David Chase's
<a href="http://www.iecc.com/gclist/GC-faq.html">GC FAQ</a>.
</p><p>
Richard Jones'
-<a href="http://www.ukc.ac.uk/computer_science/Html/Jones/gc.html">
-GC page</a> and
+<a href="https://www.cs.kent.ac.uk/people/staff/rej/gc.html">
+Garbage Collection Page</a> and
<a href="http://www.cs.kent.ac.uk/people/staff/rej/gcbook/gcbook.html">
his book</a>.
</p><p>
@@ -205,16 +206,16 @@ from those in the implementation. There is a related letter to the editor and a
correction in the next issue.
</p><p>
Boehm, H., and <a href="http://www.ubiq.com/hypertext/weiser/weiser.html">M. Weiser</a>,
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/spe_gc_paper">"Garbage Collection in an Uncooperative Environment"</a>,
+<a href="http://www.hboehm.info/spe_gc_paper/">"Garbage Collection in an Uncooperative Environment"</a>,
<i>Software Practice &amp; Experience</i>, September 1988, pp. 807-820.
</p><p>
-Boehm, H., A. Demers, and S. Shenker, <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers/pldi91.ps.Z">"Mostly Parallel Garbage Collection"</a>, Proceedings
-of the ACM SIGPLAN '91 Conference on Programming Language Design and Implementation,
+Boehm, H., A. Demers, and S. Shenker, <a href="http://www.hboehm.info/gc/papers/pldi91.ps.Z">"Mostly Parallel Garbage Collection"</a>,
+Proceedings of the ACM SIGPLAN '91 Conference on Programming Language Design and Implementation,
<i>SIGPLAN Notices 26</i>, 6 (June 1991), pp. 157-164.
</p><p>
-Boehm, H., <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers/pldi93.ps.Z">"Space Efficient Conservative Garbage Collection"</a>, Proceedings of the ACM
-SIGPLAN '93 Conference on Programming Language Design and Implementation, <i>SIGPLAN
-Notices 28</i>, 6 (June 1993), pp. 197-206.
+Boehm, H., <a href="http://www.hboehm.info/gc/papers/pldi93.ps.Z">"Space Efficient Conservative Garbage Collection"</a>,
+Proceedings of the ACM SIGPLAN '93 Conference on Programming Language Design
+and Implementation, <i>SIGPLAN Notices 28</i>, 6 (June 1993), pp. 197-206.
</p><p>
Boehm, H., "Reducing Garbage Collector Cache Misses",
<i> Proceedings of the 2000 International Symposium on Memory Management </i>.
@@ -230,7 +231,7 @@ M. Serrano, H. Boehm,
"Understanding Memory Allocation of Scheme Programs",
<i>Proceedings of the Fifth ACM SIGPLAN International Conference on
Functional Programming</i>, 2000, Montreal, Canada, pp. 245-256.
-<a href="http://www.acm.org/pubs/citations/proceedings/fp/351240/p245-serrano/">
+<a href="http://dl.acm.org/citation.cfm?id=351264">
Official version.</a>
<a href="http://www.hpl.hp.com/techreports/2000/HPL-2000-62.html">
Earlier Technical Report version.</a> Includes some discussion of the
@@ -259,28 +260,26 @@ We thank John Levine and JCLT for allowing
us to make the second paper available electronically, and providing PostScript for the final
version.
</p><p>
-Boehm, H., <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers/pldi96.ps.gz">``Simple
-Garbage-Collector-Safety''</a>, Proceedings
-of the ACM SIGPLAN '96 Conference on Programming Language Design
+Boehm, H., <a href="http://www.hboehm.info/gc/papers/pldi96.ps.gz">"Simple Garbage-Collector-Safety"</a>,
+Proceedings of the ACM SIGPLAN '96 Conference on Programming Language Design
and Implementation.
</p><p>
-Boehm, H., and D. Chase, <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers/boecha.ps.gz">
-``A Proposal for Garbage-Collector-Safe C Compilation''</a>,
+Boehm, H., and D. Chase, <a href="http://www.hboehm.info/gc/papers/boecha.ps.gz">"A Proposal for Garbage-Collector-Safe C Compilation"</a>,
<i>Journal of C Language Translation 4</i>, 2 (Decemeber 1992), pp. 126-141.
</p><p>
<b>Other related information: </b>
</p><p>
-The Detlefs, Dosser and Zorn's <a href="ftp://ftp.cs.colorado.edu/pub/techreports/zorn/CU-CS-665-93.ps.Z">Memory Allocation Costs in Large C and C++ Programs</a>.
+The Detlefs, Dosser and Zorn's <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.30.3073&rep=rep1&type=ps">Memory Allocation Costs in Large C and C++ Programs</a>.
This is a performance comparison of the Boehm-Demers-Weiser collector to malloc/free,
using programs written for malloc/free.
</p><p>
-Joel Bartlett's <a href="ftp://ftp.digital.com/pub/DEC/CCgc">mostly copying conservative garbage collector for C++</a>.
+Joel Bartlett's <a href="ftp://gatekeeper.dec.com/pub/compaq/WRL/research-reports/WRL-TN-12.ps">mostly copying conservative garbage collector for C++</a>.
</p><p>
-John Ellis and David Detlef's <a href="ftp://parcftp.xerox.com/pub/ellis/gc/gc.ps">Safe Efficient Garbage Collection for C++</a> proposal.
+John Ellis and David Detlef's <a href="ftp://ftp.parc.xerox.com/pub/ellis/gc/gc.ps">Safe Efficient Garbage Collection for C++</a> proposal.
</p><p>
Henry Baker's <a href="http://home.pipeline.com/%7Ehbaker1/">paper collection</a>.
</p><p>
-Slides for Hans Boehm's <a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/myths.ps">Allocation and GC Myths</a> talk.
+Slides for Hans Boehm's <a href="http://www.hboehm.info/gc/myths.ps">Allocation and GC Myths</a> talk.
</p><h1><a name="users">Current users:</a></h1>
Known current users of some variant of this collector include:
<p>
@@ -294,7 +293,7 @@ Some versions of the Xerox DocuPrint printer software.
The <a href="http://www.mozilla.org/">Mozilla</a> project, as leak
detector.
</p><p>
-The <a href="http://www.go-mono.com/">Mono</a> project,
+The <a href="http://www.mono-project.com">Mono</a> project,
an open source implementation of the .NET development framework.
</p><p>
The <a href="http://www.gnu.org/projects/dotgnu/">DotGNU Portable.NET
@@ -304,28 +303,25 @@ The <a href="http://irssi.org/">Irssi IRC client</a>.
</p><p>
<a href="http://titanium.cs.berkeley.edu/">The Berkeley Titanium project</a>.
</p><p>
-<a href="http://www.nag.co.uk/nagware_fortran_compilers.asp">The NAGWare f90 Fortran 90 compiler</a>.
+<a href="http://www.nag.co.uk/nagware/NP/NP_desc.asp">The NAGWare f90 Fortran 90 compiler</a>.
</p><p>
-Elwood Corporation's <a href="http://www.elwood.com/eclipse-info/index.htm">
-Eclipse</a> Common Lisp system, C library, and translator.
+Elwood Corporation's Eclipse Common Lisp system, C library, and translator.
</p><p>
-The <a href="http://www-sop.inria.fr/mimosa/fp/Bigloo/">Bigloo
-Scheme</a>
-and <a href="http://kaolin.unice.fr/%7Eserrano/camloo.html">Camloo ML
-compilers</a>
+The <a href="http://www-sop.inria.fr/mimosa/fp/Bigloo/">Bigloo Scheme</a>
+and <a href="https://github.com/samoht/camloo">Camloo ML compilers</a>
written by Manuel Serrano and others.
</p><p>
-Brent Benson's <a href="http://ftp.cs.indiana.edu/pub/scheme-repository/imp/">libscheme</a>.
+Brent Benson's <a href="http://www.cs.indiana.edu/scheme-repository/libscheme-vhll/final.html">libscheme</a>.
</p><p>
-The <a href="http://www.cs.rice.edu/CS/PLT/packages/mzscheme/index.html">MzScheme</a> scheme implementation.
+The MzScheme scheme implementation.
</p><p>
The <a href="http://www.cs.washington.edu/research/projects/cecil/www/cecil-home.html">University of Washington Cecil Implementation</a>.
</p><p>
-<a href="http://www.icsi.berkeley.edu/Sather/">The Berkeley Sather implementation</a>.
+<a href="http://www1.icsi.berkeley.edu/~sather/">The Berkeley Sather implementation</a>.
</p><p>
-<a href="http://www.cs.berkeley.edu/%7Eharmonia/">The Berkeley Harmonia Project</a>.
+<a href="http://www.cs.berkeley.edu/~harmonia/harmonia/index.html">The Berkeley Harmonia Project</a>.
</p><p>
-The <a href="http://www.cs.arizona.edu/sumatra/toba/">Toba</a> Java Virtual
+The <a href="http://www.cs.arizona.edu/projects/sumatra/toba/">Toba</a> Java Virtual
Machine to C translator.
</p><p>
The <a href="http://www.gwydiondylan.org/">Gwydion Dylan compiler</a>.
@@ -343,17 +339,16 @@ system.
</p><p>
<a href="http://asymptote.sf.net/">Asymptote LaTeX-compatible
vector graphics language.</a>
-
</p><h1><a name="collector">More collector information at this site</a></h1>
<a href="simple_example.html">A simple illustration of how to build and
-use the collector.</a>.
+use the collector</a>.
<p>
<a href="gcinterface.html">Description of alternate interfaces to the
garbage collector.</a>
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/04tutorial.pdf">Slides from an ISMM 2004 tutorial about the GC.</a>
+<a href="http://www.hboehm.info/gc/04tutorial.pdf">Slides from an ISMM 2004 tutorial about the GC</a>.
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/faq.html">A FAQ (frequently asked questions) list.</a>
+<a href="http://www.hboehm.info/gc/faq.html">A FAQ (frequently asked questions) list</a>.
</p><p>
<a href="leak.html">How to use the garbage collector as a leak detector.</a>
</p><p>
@@ -367,67 +362,64 @@ garbage collector.</a>
</p><p>
<a href="scale.html">Scalability of the collector to multiprocessors.</a>
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source">Directory containing garbage collector source.</a>
-
+<a href="http://www.hboehm.info/gc/gc_source/">Directory containing garbage collector source</a>.
</p><h1><a name="background">More background information at this site</a></h1>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/bounds.html">An attempt to establish a bound on space usage of
-conservative garbage collectors.</a>
+<a href="http://www.hboehm.info/gc/bounds.html">An attempt to establish a bound on space usage of
+conservative garbage collectors</a>.
<p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/complexity.html">Mark-sweep versus copying garbage collectors
-and their complexity.</a>
+<a href="http://www.hboehm.info/gc/complexity.html">Mark-sweep versus copying garbage collectors
+and their complexity</a>.
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/conservative.html">Pros and cons of conservative garbage collectors,
-in comparison to other collectors.
-</a>
+<a href="http://www.hboehm.info/gc/conservative.html">Pros and cons of conservative garbage collectors,
+in comparison to other collectors</a>.
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/issues.html">Issues related to garbage collection vs.
-manual memory management in C/C++.</a>
+<a href="http://www.hboehm.info/gc/issues.html">Issues related to garbage collection vs.
+manual memory management in C/C++</a>.
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/example.html">An example of a case in which garbage collection
-results in a much faster implementation as a result of reduced
-synchronization.</a>
+<a href="http://www.hboehm.info/gc/example.html">An example of a case in which garbage collection
+results in a much faster implementation as a result of reduced synchronization</a>.
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/nonmoving">Slide set discussing performance of nonmoving
-garbage collectors.</a>
+<a href="http://www.hboehm.info/gc/nonmoving/">Slide set discussing performance of nonmoving
+garbage collectors</a>.
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/popl03/web">
+<a href="http://www.hboehm.info/popl03/web/">
Slide set discussing <i>Destructors, Finalizers, and Synchronization</i>
-(POPL 2003).</a>
+(POPL 2003)</a>.
</p><p>
<a href="http://portal.acm.org/citation.cfm?doid=604131.604153">
-Paper corresponding to above slide set.</a>
+Paper corresponding to above slide set</a>
(<a href="http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html">
-Technical Report version</a>.)
+Technical Report version</a>).
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_bench.html">A Java/Scheme/C/C++ garbage collection benchmark.</a>
+<a href="http://www.hboehm.info/gc/gc_bench/">A Java/Scheme/C/C++ garbage collection benchmark</a>.
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/myths.ps">Slides for talk on memory allocation myths.</a>
+<a href="http://www.hboehm.info/gc/myths.ps">Slides for talk on memory allocation myths</a>.
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/gctalk.ps">Slides for OOPSLA 98 garbage collection talk.</a>
+<a href="http://www.hboehm.info/gc/gctalk.ps">Slides for OOPSLA 98 garbage collection talk</a>.
</p><p>
-<a href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers">Related papers.</a>
-</p><h1><a name="contacts">Contacts and Mailing List</a><a></a></h1>
+<a href="http://www.hboehm.info/gc/papers/">Related papers</a>.
+</p><h1><a name="contacts">Contacts and Mailing List</a></h1>
<a>We have recently set up two mailing list for collector announcements
and discussions:
</a><ul>
-<li><a href="mailto:gc-announce@linux.hpl.hp.com">gc-announce@linux.hpl.hp.com</a>
+<li><a href="mailto:bdwgc-announce@lists.opendylan.org">bdwgc-announce@lists.opendylan.org</a>
is used for announcements of new versions. Postings are restricted.
We expect this to always remain a very low volume list.
-</li><li><a href="mailto:gc@linux.hpl.hp.com">gc@linux.hpl.hp.com</a> is used for
-discussions, bug reports, and the like. Subscribers may post.
+</li><li><a href="mailto:bdwgc@lists.opendylan.org">bdwgc@lists.opendylan.org</a>
+is used for discussions, bug reports, and the like. Subscribers may post.
On-topic posts by nonsubscribers will usually also be accepted, but
it may take some time to review them.
</li></ul>
-To subscribe to these lists, send a mail message containing the
-word "subscribe" to
-<a href="mailto:gc-announce-request@linux.hpl.hp.com?subject=subscribe">gc-announce-request@linux.hpl.hp.com</a>
-or to
-<a href="mailto:gc-request@linux.hpl.hp.com?subject=subscribe">gc-request@linux.hpl.hp.com</a>.
-(Please ignore the instructions about web-based subscription.
-The listed web site is behind the HP firewall.)
+To subscribe to these lists, please visit
+<a href="https://lists.opendylan.org/mailman/listinfo/bdwgc-announce">lists.opendylan.org/mailman/listinfo/bdwgc-announce</a>
+and
+<a href="https://lists.opendylan.org/mailman/listinfo/bdwgc">lists.opendylan.org/mailman/listinfo/bdwgc</a>,
+respectively.
<p>
The archives for these lists appear
-<a href="http://www.hpl.hp.com/hosted/linux/mail-archives">here</a>.
+<a href="https://lists.opendylan.org/pipermail/bdwgc-announce/">here</a> and
+<a href="https://lists.opendylan.org/pipermail/bdwgc/">here</a>,
+respectively.
The gc list archive may also be read at
<a href="http://dir.gmane.org/gmane.comp.programming.garbage-collection.boehmgc">gmane.org</a>.
</p><p>
@@ -437,8 +429,6 @@ java mailing list, whose archives appear
<a href="http://lists.tunes.org/mailman/listinfo/gclist">gclist@iecc.com</a>.
</p><p>
Comments and bug reports may also be sent to
-(<a href="mailto:Hans.Boehm@hp.com">Hans.Boehm@hp.com</a>) or
(<a href="mailto:boehm@acm.org">boehm@acm.org</a>), but the gc
mailing list is usually preferred.
-
</p></body></html>
diff --git a/doc/porting.html b/doc/porting.html
index f22f654e..751cbc59 100644
--- a/doc/porting.html
+++ b/doc/porting.html
@@ -181,7 +181,7 @@ allows incremental/generational garbage collection.
<TT>MPROTECT_VDB</tt> identifies modified pages by
write protecting the heap and catching faults.
<TT>PROC_VDB</tt> uses the /proc primitives to read dirty bits.
-<DT><TT>PREFETCH, PREFETCH_FOR_WRITE</tt>
+<DT><TT>PREFETCH, GC_PREFETCH_FOR_WRITE</tt>
<DD>
The collector uses <TT>PREFETCH</tt>(<I>x</i>) to preload the cache
with *<I>x</i>.
diff --git a/doc/scale.html b/doc/scale.html
index feb14f13..67928277 100644
--- a/doc/scale.html
+++ b/doc/scale.html
@@ -70,17 +70,6 @@ though it usually improves performance when thread-local allocation is
used heavily, and thus the number of short-duration lock acquisitions
is greatly reduced.
</ul>
-<P>
-The easiest way to switch an application to thread-local allocation
-in a pre-version-7.0 collector was to
-<OL>
-<LI> Define the macro <TT>GC_REDIRECT_TO_LOCAL</tt>,
-and then include the <TT>gc.h</tt>
-header in each client source file.
-<LI> Invoke <TT>GC_thr_init()</tt> before any allocation.
-<LI> Allocate using <TT>GC_MALLOC</tt>, <TT>GC_MALLOC_ATOMIC</tt>,
-and/or <TT>GC_GCJ_MALLOC</tt>.
-</ol>
<H2>The Parallel Marking Algorithm</h2>
We use an algorithm similar to
<A HREF="http://www.yl.is.s.u-tokyo.ac.jp/gc/">that developed by
@@ -132,7 +121,8 @@ simultaneously runnable threads, this may have disastrous performance
consequences (e.g. a factor of 10 slowdown).
<H2>Performance</h2>
We conducted some simple experiments with a version of
-<A HREF="gc_bench.html">our GC benchmark</a> that was slightly modified to
+<a href="http://www.hboehm.info/gc/gc_bench/">our GC benchmark</a>
+that was slightly modified to
run multiple concurrent client threads in the same address space.
Each client thread does the same work as the original benchmark, but they share
a heap.
diff --git a/doc/simple_example.html b/doc/simple_example.html
index 98ae4244..22bf6948 100644
--- a/doc/simple_example.html
+++ b/doc/simple_example.html
@@ -143,22 +143,6 @@ should first define the macro <TT>GC_THREADS</tt>, and then
include <TT>"gc.h"</tt>. On some platforms this will redefine some
threads primitives, e.g. to let the collector keep track of thread creation.
</font>
-<LI>
-<FONT COLOR=green>
-To take advantage of fast thread-local allocation in versions before 7.0,
-use the following instead
-of including <TT>gc.h</tt>:
-</font>
-<PRE style="color:green">
-#define GC_REDIRECT_TO_LOCAL
-#include "gc_local_alloc.h"
-</pre>
-<FONT COLOR=green>
-This will cause GC_MALLOC and GC_MALLOC_ATOMIC to keep per-thread allocation
-caches, and greatly reduce the number of lock acquisitions during allocation.
-For versions after 7.0, this happens implicitly if the collector is built
-with thread-local allocation enabled.
-</font>
</ul>
<H3><FONT COLOR=green>C++</font></h3>
diff --git a/doc/tree.html b/doc/tree.html
index d52e2fa2..f1c6e269 100644
--- a/doc/tree.html
+++ b/doc/tree.html
@@ -6,9 +6,7 @@
<BODY>
<H1>Two-Level Tree Structure for Fast Pointer Lookup</h1>
<P>
-The conservative garbage collector described
-<A HREF="http://www.hpl.hp.com/personal/Hans_Boehm/gc/">here</a>
-uses a 2-level tree
+The BDWGC conservative garbage collector uses a 2-level tree
data structure to aid in fast pointer identification.
This data structure is described in a bit more detail here, since
<OL>
@@ -163,7 +161,7 @@ GET_HDR(p)| word hb_sz (words) | |
| hb_last_reclaimed |
--- +----------------------+
^ | |
- MARK_BITS| hb_marks[] | *if hdr is free, hb_sz + DISCARD_WORDS
+ MARK_BITS| hb_marks[] | *if hdr is free, hb_sz
_SZ(words)| | is the size of a heap chunk (struct hblk)
v | | of at least MININCR*HBLKSIZE bytes (below),
--- +----------------------+ otherwise, size of each object in chunk.
@@ -172,20 +170,20 @@ Dynamic data structures above are interleaved throughout the heap in blocks of
size MININCR * HBLKSIZE bytes as done by gc_scratch_alloc which cannot be
freed; free lists are used (e.g. alloc_hdr). HBLK's below are collected.
- (struct hblk)
- --- +----------------------+ < HBLKSIZE --- --- DISCARD_
- ^ |garbage[DISCARD_WORDS]| aligned ^ ^ HDR_BYTES WORDS
- | | | | v (bytes) (words)
- | +-----hb_body----------+ < WORDSZ | --- ---
- | | | aligned | ^ ^
- | | Object 0 | | hb_sz |
- | | | i |(word- (words)|
- | | | (bytes)|aligned) v |
- | + - - - - - - - - - - -+ --- | --- |
- | | | ^ | ^ |
- n * | | j (words) | hb_sz BODY_SZ
- HBLKSIZE | Object 1 | v v | (words)
- (bytes) | |--------------- v MAX_OFFSET
+ (struct hblk) HDR_BYTES
+ --- +----------------------+ < HBLKSIZE --- (bytes)
+ ^ +-----hb_body----------+ (and WORDSZ) ^ --- ---
+ | | | aligned | ^ ^
+ | | | | hb_sz |
+ | | | | (words) |
+ | | Object 0 | | | |
+ | | | i |(word- v |
+ | + - - - - - - - - - - -+ --- (bytes)|aligned) --- |
+ | | | ^ | ^ |
+ | | | j (words) | | |
+ n * | Object 1 | v v hb_sz BODY_SZ
+ HBLKSIZE | |--------------- | (words)
+ (bytes) | | v MAX_OFFSET
| + - - - - - - - - - - -+ --- (bytes)
| | | !All_INTERIOR_PTRS ^ |
| | | sets j only for hb_sz |
@@ -193,7 +191,5 @@ freed; free lists are used (e.g. alloc_hdr). HBLK's below are collected.
v | | All objects WORDSZ v v
--- +----------------------+ aligned. --- ---
-DISCARD_WORDS is normally zero. Indeed the collector has not been tested
-with another value in ages.
-</pre>
+</PRE>
</body>
diff --git a/dyn_load.c b/dyn_load.c
index 87f48fff..bf64145b 100644
--- a/dyn_load.c
+++ b/dyn_load.c
@@ -61,9 +61,8 @@ STATIC GC_has_static_roots_func GC_has_static_roots = 0;
!(defined(OPENBSD) && (defined(__ELF__) || defined(M68K))) && \
!(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \
!defined(DARWIN) && !defined(CYGWIN32)
- --> We only know how to find data segments of dynamic libraries for the
- --> above. Additional SVR4 variants might not be too
- --> hard to add.
+# error We only know how to find data segments of dynamic libraries for above.
+# error Additional SVR4 variants might not be too hard to add.
#endif
#include <stdio.h>
@@ -109,9 +108,9 @@ STATIC GC_has_static_roots_func GC_has_static_roots = 0;
# undef EM_ALPHA
# endif
# include <link.h>
-# if !defined(GC_DONT_DEFINE_LINK_MAP)
- /* link_map and r_debug should be defined explicitly, */
- /* as only bionic/linker/linker.h defines them but the header */
+# if !defined(GC_DONT_DEFINE_LINK_MAP) && !(__ANDROID_API__ >= 21)
+ /* link_map and r_debug are defined in link.h of NDK r10+. */
+ /* bionic/linker/linker.h defines them too but the header */
/* itself is a C++ one starting from Android 4.3. */
struct link_map {
uintptr_t l_addr;
@@ -214,7 +213,7 @@ GC_FirstDLOpenedLinkMap(void)
/* Add dynamic library data sections to the root set. */
# if !defined(PCR) && !defined(GC_SOLARIS_THREADS) && defined(THREADS)
- --> fix mutual exclusion with dlopen
+# error Fix mutual exclusion with dlopen
# endif
# ifndef USE_PROC_FOR_LIBRARIES
@@ -464,6 +463,7 @@ GC_INNER GC_bool GC_register_main_static_data(void)
} load_segs[MAX_LOAD_SEGS];
static int n_load_segs;
+ static GC_bool load_segs_overflow;
# endif /* PT_GNU_RELRO */
STATIC int GC_register_dynlib_callback(struct dl_phdr_info * info,
@@ -479,74 +479,79 @@ STATIC int GC_register_dynlib_callback(struct dl_phdr_info * info,
return -1;
p = info->dlpi_phdr;
- for( i = 0; i < (int)info->dlpi_phnum; i++, p++ ) {
- switch( p->p_type ) {
+ for (i = 0; i < (int)info->dlpi_phnum; i++, p++) {
+ if (p->p_type == PT_LOAD) {
+ GC_has_static_roots_func callback = GC_has_static_roots;
+ if ((p->p_flags & PF_W) == 0) continue;
+
+ start = (ptr_t)p->p_vaddr + info->dlpi_addr;
+ end = start + p->p_memsz;
+ if (callback != 0 && !callback(info->dlpi_name, start, p->p_memsz))
+ continue;
# ifdef PT_GNU_RELRO
- case PT_GNU_RELRO:
- /* This entry is known to be constant and will eventually be remapped
- read-only. However, the address range covered by this entry is
- typically a subset of a previously encountered "LOAD" segment, so
- we need to exclude it. */
- {
- int j;
-
- start = ((ptr_t)(p->p_vaddr)) + info->dlpi_addr;
- end = start + p->p_memsz;
- for (j = n_load_segs; --j >= 0; ) {
- if ((word)start >= (word)load_segs[j].start
- && (word)start < (word)load_segs[j].end) {
- if (load_segs[j].start2 != 0) {
- WARN("More than one GNU_RELRO segment per load seg\n",0);
- } else {
- GC_ASSERT((word)end <= (word)load_segs[j].end);
- /* Remove from the existing load segment */
- load_segs[j].end2 = load_segs[j].end;
- load_segs[j].end = start;
- load_segs[j].start2 = end;
- }
- break;
- }
- if (j == 0) WARN("Failed to find PT_GNU_RELRO segment"
- " inside PT_LOAD region", 0);
- }
+# if CPP_WORDSZ == 64
+ /* TODO: GC_push_all eventually does the correct */
+ /* rounding to the next multiple of ALIGNMENT, so, most */
+ /* probably, we should remove the corresponding assertion */
+ /* check in GC_add_roots_inner along with this code line. */
+ /* start pointer value may require aligning */
+ start = (ptr_t)((word)start & ~(sizeof(word) - 1));
+# endif
+ if (n_load_segs >= MAX_LOAD_SEGS) {
+ if (!load_segs_overflow) {
+ WARN("Too many PT_LOAD segments;"
+ " registering as roots directly...\n", 0);
+ load_segs_overflow = TRUE;
+ }
+ GC_add_roots_inner(start, end, TRUE);
+ } else {
+ load_segs[n_load_segs].start = start;
+ load_segs[n_load_segs].end = end;
+ load_segs[n_load_segs].start2 = 0;
+ load_segs[n_load_segs].end2 = 0;
+ ++n_load_segs;
}
+# else
+ GC_add_roots_inner(start, end, TRUE);
+# endif /* !PT_GNU_RELRO */
+ }
+ }
- break;
-# endif
-
- case PT_LOAD:
- {
- GC_has_static_roots_func callback = GC_has_static_roots;
- if( !(p->p_flags & PF_W) ) break;
- start = ((char *)(p->p_vaddr)) + info->dlpi_addr;
- end = start + p->p_memsz;
-
- if (callback != 0 && !callback(info->dlpi_name, start, p->p_memsz))
+# ifdef PT_GNU_RELRO
+ p = info->dlpi_phdr;
+ for (i = 0; i < (int)info->dlpi_phnum; i++, p++) {
+ if (p->p_type == PT_GNU_RELRO) {
+ /* This entry is known to be constant and will eventually be */
+ /* remapped as read-only. However, the address range covered */
+ /* by this entry is typically a subset of a previously */
+ /* encountered "LOAD" segment, so we need to exclude it. */
+ int j;
+
+ start = (ptr_t)p->p_vaddr + info->dlpi_addr;
+ end = start + p->p_memsz;
+ for (j = n_load_segs; --j >= 0; ) {
+ if ((word)start >= (word)load_segs[j].start
+ && (word)start < (word)load_segs[j].end) {
+ if (load_segs[j].start2 != 0) {
+ WARN("More than one GNU_RELRO segment per load one\n",0);
+ } else {
+ GC_ASSERT((word)end <= (word)load_segs[j].end);
+ /* Remove from the existing load segment */
+ load_segs[j].end2 = load_segs[j].end;
+ load_segs[j].end = start;
+ load_segs[j].start2 = end;
+ }
break;
-# ifdef PT_GNU_RELRO
- if (n_load_segs >= MAX_LOAD_SEGS) ABORT("Too many PT_LOAD segs");
-# if CPP_WORDSZ == 64
- /* FIXME: GC_push_all eventually does the correct */
- /* rounding to the next multiple of ALIGNMENT, so, most */
- /* probably, we should remove the corresponding assertion */
- /* check in GC_add_roots_inner along with this code line. */
- /* start pointer value may require aligning */
- start = (ptr_t)((word)start & ~(sizeof(word) - 1));
-# endif
- load_segs[n_load_segs].start = start;
- load_segs[n_load_segs].end = end;
- load_segs[n_load_segs].start2 = 0;
- load_segs[n_load_segs].end2 = 0;
- ++n_load_segs;
-# else
- GC_add_roots_inner(start, end, TRUE);
-# endif /* PT_GNU_RELRO */
+ }
+ if (0 == j && 0 == GC_has_static_roots)
+ WARN("Failed to find PT_GNU_RELRO segment"
+ " inside PT_LOAD region\n", 0);
+ /* No warning reported in case of the callback is present */
+ /* because most likely the segment has been excluded. */
}
- break;
- default:
- break;
+ }
}
- }
+# endif
*(int *)ptr = 1; /* Signal that we were called */
return 0;
@@ -575,6 +580,7 @@ STATIC GC_bool GC_register_dynamic_libraries_dl_iterate_phdr(void)
{
static GC_bool excluded_segs = FALSE;
n_load_segs = 0;
+ load_segs_overflow = FALSE;
if (!EXPECT(excluded_segs, TRUE)) {
GC_exclude_static_roots_inner((ptr_t)load_segs,
(ptr_t)load_segs + sizeof(load_segs));
@@ -677,7 +683,6 @@ extern ElfW(Dyn) _DYNAMIC[];
STATIC struct link_map *
GC_FirstDLOpenedLinkMap(void)
{
- ElfW(Dyn) *dp;
static struct link_map *cachedResult = 0;
if (0 == (ptr_t)_DYNAMIC) {
@@ -687,10 +692,19 @@ GC_FirstDLOpenedLinkMap(void)
if( cachedResult == 0 ) {
# if defined(NETBSD) && defined(RTLD_DI_LINKMAP)
struct link_map *lm = NULL;
- if (!dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lm))
- cachedResult = lm;
+ if (!dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lm) && lm != NULL) {
+ /* Now lm points link_map object of libgc. Since it */
+ /* might not be the first dynamically linked object, */
+ /* try to find it (object next to the main object). */
+ while (lm->l_prev != NULL) {
+ lm = lm->l_prev;
+ }
+ cachedResult = lm->l_next;
+ }
# else
+ ElfW(Dyn) *dp;
int tag;
+
for( dp = _DYNAMIC; (tag = dp->d_tag) != 0; dp++ ) {
if( tag == DT_DEBUG ) {
struct link_map *lm
@@ -1417,12 +1431,13 @@ GC_INNER void GC_init_dyld(void)
This WILL properly register already linked libraries and libraries
linked in the future.
*/
-
- _dyld_register_func_for_add_image(GC_dyld_image_add);
- _dyld_register_func_for_remove_image(GC_dyld_image_remove);
- /* Ignore 2 compiler warnings here: passing argument 1 of */
- /* '_dyld_register_func_for_add/remove_image' from incompatible */
- /* pointer type. */
+ _dyld_register_func_for_add_image(
+ (void (*)(const struct mach_header*, intptr_t))GC_dyld_image_add);
+ _dyld_register_func_for_remove_image(
+ (void (*)(const struct mach_header*, intptr_t))GC_dyld_image_remove);
+ /* Structure mach_header64 has the same fields */
+ /* as mach_header except for the reserved one */
+ /* at the end, so these casts are OK. */
/* Set this early to avoid reentrancy issues. */
initialized = TRUE;
diff --git a/extra/AmigaOS.c b/extra/AmigaOS.c
index 8f99b746..7d4fb6cf 100644
--- a/extra/AmigaOS.c
+++ b/extra/AmigaOS.c
@@ -40,7 +40,7 @@
Find the base of the stack.
******************************************************************/
-ptr_t GC_get_main_stack_base()
+ptr_t GC_get_main_stack_base(void)
{
struct Process *proc = (struct Process*)SysBase->ThisTask;
@@ -93,7 +93,7 @@ ptr_t GC_get_stack_base()
Register data segments.
******************************************************************/
- void GC_register_data_segments()
+ void GC_register_data_segments(void)
{
struct Process *proc;
struct CommandLineInterface *cli;
@@ -340,6 +340,8 @@ size_t latestsize;
#endif
+#ifdef GC_AMIGA_FASTALLOC
+
/*
* The actual function that is called with the GET_MEM macro.
*
@@ -350,11 +352,10 @@ void *GC_amiga_get_mem(size_t size){
#ifndef GC_AMIGA_ONLYFAST
if(GC_amiga_dontalloc==TRUE){
-// printf("rejected, size: %d, latestsize: %d\n",size,latestsize);
return NULL;
}
- // We really don't want to use chip-mem, but if we must, then as little as possible.
+ /* We really don't want to use chip-mem, but if we must, then as little as possible. */
if(GC_AMIGA_MEMF==(MEMF_ANY|MEMF_CLEAR) && size>100000 && latestsize<50000) return NULL;
#endif
@@ -365,8 +366,6 @@ void *GC_amiga_get_mem(size_t size){
gc_am->size=size + sizeof(struct GC_Amiga_AllocedMemoryHeader);
GC_AMIGAMEM=(struct GC_Amiga_AllocedMemoryHeader *)(~(int)(gc_am));
-// printf("Allocated %d (%d) bytes at address: %x. Latest: %d\n",size,tot,gc_am,latestsize);
-
#ifdef GC_AMIGA_PRINTSTATS
if((char *)gc_am<chipmax){
allochip+=size;
@@ -379,7 +378,7 @@ void *GC_amiga_get_mem(size_t size){
}
-
+#endif
#ifndef GC_AMIGA_ONLYFAST
@@ -421,7 +420,6 @@ void *GC_amiga_rec_alloc(size_t size,void *(*AllocFunction)(size_t size2),const
if (((char *)ret)<=chipmax && ret!=NULL && (rec<(size>500000?9:size/5000))){
ret=GC_amiga_rec_alloc(size,AllocFunction,rec+1);
-// GC_free(ret2);
}
return ret;
@@ -437,14 +435,14 @@ void *GC_amiga_rec_alloc(size_t size,void *(*AllocFunction)(size_t size2),const
void *GC_amiga_allocwrapper_any(size_t size,void *(*AllocFunction)(size_t size2)){
void *ret,*ret2;
- GC_amiga_dontalloc=TRUE; // Pretty tough thing to do, but its indeed necessary.
+ GC_amiga_dontalloc=TRUE; /* Pretty tough thing to do, but its indeed necessary. */
latestsize=size;
ret=(*AllocFunction)(size);
if(((char *)ret) <= chipmax){
if(ret==NULL){
- //Give GC access to allocate memory.
+ /* Give GC access to allocate memory. */
#ifdef GC_AMIGA_GC
if(!GC_dont_gc){
GC_gcollect();
@@ -473,7 +471,6 @@ void *GC_amiga_allocwrapper_any(size_t size,void *(*AllocFunction)(size_t size2)
/* We got chip-mem. Better try again and again and again etc., we might get fast-mem sooner or later... */
/* Using gctest to check the effectiveness of doing this, does seldom give a very good result. */
/* However, real programs doesn't normally rapidly allocate and deallocate. */
-// printf("trying to force... %d bytes... ",size);
if(
AllocFunction!=GC_malloc_uncollectable
#ifdef ATOMIC_UNCOLLECTABLE
@@ -496,12 +493,10 @@ void *GC_amiga_allocwrapper_any(size_t size,void *(*AllocFunction)(size_t size2)
#endif
}
if(((char *)ret2)>chipmax){
-// printf("Succeeded.\n");
GC_free(ret);
ret=ret2;
}else{
GC_free(ret2);
-// printf("But did not succeed.\n");
}
}
#endif
@@ -520,7 +515,7 @@ void GC_amiga_set_toany(void (*func)(void)){
GC_amiga_toany=func;
}
-#endif // !GC_AMIGA_ONLYFAST
+#endif /* !GC_AMIGA_ONLYFAST */
void *GC_amiga_allocwrapper_fast(size_t size,void *(*AllocFunction)(size_t size2)){
@@ -529,8 +524,7 @@ void *GC_amiga_allocwrapper_fast(size_t size,void *(*AllocFunction)(size_t size2
ret=(*AllocFunction)(size);
if(ret==NULL){
- // Enable chip-mem allocation.
-// printf("ret==NULL\n");
+ /* Enable chip-mem allocation. */
#ifdef GC_AMIGA_GC
if(!GC_dont_gc){
GC_gcollect();
@@ -560,13 +554,13 @@ void *GC_amiga_allocwrapper_fast(size_t size,void *(*AllocFunction)(size_t size2
void *GC_amiga_allocwrapper_firsttime(size_t size,void *(*AllocFunction)(size_t size2)){
atexit(&GC_amiga_free_all_mem);
- chipmax=(char *)SysBase->MaxLocMem; // For people still having SysBase in chip-mem, this might speed up a bit.
+ chipmax=(char *)SysBase->MaxLocMem; /* For people still having SysBase in chip-mem, this might speed up a bit. */
GC_amiga_allocwrapper_do=GC_amiga_allocwrapper_fast;
return GC_amiga_allocwrapper_fast(size,AllocFunction);
}
-#endif //GC_AMIGA_FASTALLOC
+#endif /* GC_AMIGA_FASTALLOC */
@@ -581,7 +575,8 @@ void *GC_amiga_realloc(void *old_object,size_t new_size_in_bytes){
void *ret;
latestsize=new_size_in_bytes;
ret=GC_realloc(old_object,new_size_in_bytes);
- if(ret==NULL && GC_AMIGA_MEMF==(MEMF_FAST | MEMF_CLEAR)){
+ if(ret==NULL && new_size_in_bytes != 0
+ && GC_AMIGA_MEMF==(MEMF_FAST | MEMF_CLEAR)){
/* Out of fast-mem. */
#ifdef GC_AMIGA_GC
if(!GC_dont_gc){
@@ -606,7 +601,7 @@ void *GC_amiga_realloc(void *old_object,size_t new_size_in_bytes){
}
#endif
}
- if(ret==NULL){
+ if(ret==NULL && new_size_in_bytes != 0){
WARN("Out of Memory! Returning NIL!\n", 0);
}
#ifdef GC_AMIGA_PRINTSTATS
@@ -618,4 +613,4 @@ void *GC_amiga_realloc(void *old_object,size_t new_size_in_bytes){
#endif
}
-#endif //GC_AMIGA_AM
+#endif /* GC_AMIGA_AM */
diff --git a/extra/MacOS.c b/extra/MacOS.c
index 27f07eb4..f1d71a0d 100644
--- a/extra/MacOS.c
+++ b/extra/MacOS.c
@@ -26,7 +26,7 @@ unloading shared library.
#include "gc.h"
#include "gc_priv.h"
-// use 'CODE' resource 0 to get exact location of the beginning of global space.
+/* use 'CODE' resource 0 to get exact location of the beginning of global space. */
typedef struct {
unsigned long aboveA5;
@@ -35,7 +35,7 @@ typedef struct {
unsigned long JTOffset;
} *CodeZeroPtr, **CodeZeroHandle;
-void* GC_MacGetDataStart()
+void* GC_MacGetDataStart(void)
{
CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
if (code0) {
@@ -48,6 +48,8 @@ void* GC_MacGetDataStart()
return 0;
}
+#ifdef USE_TEMPORARY_MEMORY
+
/* track the use of temporary memory so it can be freed all at once. */
typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle;
@@ -76,13 +78,13 @@ Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory)
if (clearMemory) memset(tempPtr, 0, size);
tempPtr = StripAddress(tempPtr);
- // keep track of the allocated blocks.
+ /* keep track of the allocated blocks. */
(**tempMemBlock).nextBlock = theTemporaryMemory;
theTemporaryMemory = tempMemBlock;
}
# if !defined(SHARED_LIBRARY_BUILD)
- // install an exit routine to clean up the memory used at the end.
+ /* install an exit routine to clean up the memory used at the end. */
if (firstTime) {
atexit(&GC_MacFreeTemporaryMemory);
firstTime = false;
@@ -94,7 +96,7 @@ Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory)
extern word GC_fo_entries;
-static void perform_final_collection()
+static void perform_final_collection(void)
{
unsigned i;
word last_fo_entries = 0;
@@ -111,7 +113,7 @@ static void perform_final_collection()
}
-void GC_MacFreeTemporaryMemory()
+void GC_MacFreeTemporaryMemory(void)
{
# if defined(SHARED_LIBRARY_BUILD)
/* if possible, collect all memory, and invoke all finalizers. */
@@ -133,15 +135,18 @@ void GC_MacFreeTemporaryMemory()
if (GC_print_stats) {
fprintf(stdout, "[total memory used: %ld bytes.]\n",
totalMemoryUsed);
- fprintf(stdout, "[total collections: %ld.]\n", GC_gc_no);
+ fprintf(stdout, "[total collections: %lu]\n",
+ (unsigned long)GC_gc_no);
}
# endif
}
}
+#endif /* USE_TEMPORARY_MEMORY */
+
#if __option(far_data)
- void* GC_MacGetDataEnd()
+ void* GC_MacGetDataEnd(void)
{
CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
if (code0) {
diff --git a/extra/Mac_files/MacOS_config.h b/extra/Mac_files/MacOS_config.h
index ec8f82c3..abbf9d8e 100644
--- a/extra/Mac_files/MacOS_config.h
+++ b/extra/Mac_files/MacOS_config.h
@@ -12,17 +12,16 @@
/* Boehm, November 17, 1995 12:10 pm PST */
#ifdef __MWERKS__
-
-// for CodeWarrior Pro with Metrowerks Standard Library (MSL).
-// #define MSL_USE_PRECOMPILED_HEADERS 0
+/* for CodeWarrior Pro with Metrowerks Standard Library (MSL). */
+/* #define MSL_USE_PRECOMPILED_HEADERS 0 */
#include <ansi_prefix.mac.h>
#endif /* __MWERKS__ */
-// these are defined again in gc_priv.h.
+/* these are defined again in gc_priv.h. */
#undef TRUE
#undef FALSE
-#define ALL_INTERIOR_POINTERS // follows interior pointers.
-//#define DONT_ADD_BYTE_AT_END // no padding.
-//#define SMALL_CONFIG // whether to use a smaller heap.
-#define USE_TEMPORARY_MEMORY // use Macintosh temporary memory.
+#define ALL_INTERIOR_POINTERS /* follows interior pointers. */
+/* #define DONT_ADD_BYTE_AT_END */ /* no padding. */
+/* #define SMALL_CONFIG */ /* whether to use a smaller heap. */
+#define USE_TEMPORARY_MEMORY /* use Macintosh temporary memory. */
diff --git a/extra/gc.c b/extra/gc.c
index 5fc0de0b..510a63cf 100644
--- a/extra/gc.c
+++ b/extra/gc.c
@@ -44,6 +44,7 @@
#include "../ptr_chck.c"
#include "../stubborn.c"
+#include "gc_inline.h"
#include "../allchblk.c"
#include "../alloc.c"
#include "../dbg_mlc.c"
@@ -82,6 +83,7 @@
/* This is only useful if directly included from application */
/* (instead of linking gc). */
#ifndef GC_NO_THREAD_REDIRECTS
+# define GC_PTHREAD_REDIRECTS_ONLY
# include "gc_pthread_redirects.h"
#endif
diff --git a/extra/msvc_dbg.c b/extra/msvc_dbg.c
index ea7fc7b6..6855243e 100644
--- a/extra/msvc_dbg.c
+++ b/extra/msvc_dbg.c
@@ -47,7 +47,7 @@ typedef GC_word word;
typedef ULONG ULONG_ADDR;
#endif
-static HANDLE GetSymHandle()
+static HANDLE GetSymHandle(void)
{
static HANDLE symHandle = NULL;
if (!symHandle) {
@@ -317,7 +317,7 @@ size_t GetDescriptionFromAddress(void* address, const char* format,
size = (GC_ULONG_PTR)end < (GC_ULONG_PTR)buffer ? 0 : end - buffer;
if (line_number) {
- wsprintf(str, "(%d) : ", line_number);
+ wsprintf(str, "(%d) : ", (int)line_number);
if (size) {
strncpy(buffer, str, size)[size - 1] = 0;
}
@@ -378,4 +378,9 @@ char** backtrace_symbols(void*const* addresses, int count)
return symbols;
}
-#endif /* !_M_AMD64 */
+#else
+
+ extern int GC_quiet;
+ /* ANSI C does not allow translation units to be empty. */
+
+#endif /* _M_AMD64 */
diff --git a/finalize.c b/finalize.c
index c2e8af02..1c04deb4 100644
--- a/finalize.c
+++ b/finalize.c
@@ -26,7 +26,7 @@ typedef void (* finalization_mark_proc)(ptr_t /* finalizable_obj_ptr */);
#define HASH3(addr,size,log_size) \
((((word)(addr) >> 3) ^ ((word)(addr) >> (3 + (log_size)))) \
& ((size) - 1))
-#define HASH2(addr,log_size) HASH3(addr, 1 << (log_size), log_size)
+#define HASH2(addr,log_size) HASH3(addr, (word)1 << (log_size), log_size)
struct hash_chain_entry {
word hidden_key;
@@ -104,7 +104,7 @@ STATIC void GC_grow_table(struct hash_chain_entry ***table,
register struct hash_chain_entry *p;
signed_word log_old_size = *log_size_ptr;
signed_word log_new_size = log_old_size + 1;
- word old_size = ((log_old_size == -1)? 0: (1 << log_old_size));
+ word old_size = log_old_size == -1 ? 0 : (word)1 << log_old_size;
word new_size = (word)1 << log_new_size;
/* FIXME: Power of 2 size often gets rounded up to one more page. */
struct hash_chain_entry **new_table = (struct hash_chain_entry **)
@@ -211,7 +211,7 @@ STATIC int GC_register_disappearing_link_inner(
GC_API int GC_CALL GC_general_register_disappearing_link(void * * link,
const void * obj)
{
- if (((word)link & (ALIGNMENT-1)) != 0 || NULL == link)
+ if (((word)link & (ALIGNMENT-1)) != 0 || !NONNULL_ARG_NOT_NULL(link))
ABORT("Bad arg to GC_general_register_disappearing_link");
return GC_register_disappearing_link_inner(&GC_dl_hashtbl, link, obj);
}
@@ -266,7 +266,7 @@ GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
#ifndef GC_LONG_REFS_NOT_NEEDED
GC_API int GC_CALL GC_register_long_link(void * * link, const void * obj)
{
- if (((word)link & (ALIGNMENT-1)) != 0 || NULL == link)
+ if (((word)link & (ALIGNMENT-1)) != 0 || !NONNULL_ARG_NOT_NULL(link))
ABORT("Bad arg to GC_register_long_link");
return GC_register_disappearing_link_inner(&GC_ll_hashtbl, link, obj);
}
@@ -345,7 +345,8 @@ GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
int result;
DCL_LOCK_STATE;
- if (((word)new_link & (ALIGNMENT-1)) != 0 || new_link == NULL)
+ if (((word)new_link & (ALIGNMENT-1)) != 0
+ || !NONNULL_ARG_NOT_NULL(new_link))
ABORT("Bad new_link arg to GC_move_disappearing_link");
if (((word)link & (ALIGNMENT-1)) != 0)
return GC_NOT_FOUND; /* Nothing to do. */
@@ -362,8 +363,9 @@ GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
int result;
DCL_LOCK_STATE;
- if (((word)new_link & (ALIGNMENT-1)) != 0 || new_link == NULL)
- ABORT("Bad new_link arg to GC_move_disappearing_link");
+ if (((word)new_link & (ALIGNMENT-1)) != 0
+ || !NONNULL_ARG_NOT_NULL(new_link))
+ ABORT("Bad new_link arg to GC_move_long_link");
if (((word)link & (ALIGNMENT-1)) != 0)
return GC_NOT_FOUND; /* Nothing to do. */
@@ -504,7 +506,11 @@ STATIC void GC_register_finalizer_inner(void * obj,
curr_fo = fo_next(curr_fo);
}
if (EXPECT(new_fo != 0, FALSE)) {
- /* new_fo is returned by GC_oom_fn(), so fn != 0 and hhdr != 0. */
+ /* new_fo is returned by GC_oom_fn(). */
+ GC_ASSERT(fn != 0);
+# ifdef LINT2
+ if (NULL == hhdr) ABORT("Bad hhdr in GC_register_finalizer_inner");
+# endif
break;
}
if (fn == 0) {
@@ -596,7 +602,7 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj,
struct disappearing_link *curr_dl;
ptr_t real_ptr, real_link;
size_t dl_size = dl_hashtbl->log_size == -1 ? 0 :
- 1 << dl_hashtbl->log_size;
+ (size_t)1 << dl_hashtbl->log_size;
size_t i;
for (i = 0; i < dl_size; i++) {
@@ -612,7 +618,8 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj,
void GC_dump_finalization(void)
{
struct finalizable_object * curr_fo;
- size_t fo_size = log_fo_table_size == -1 ? 0 : 1 << log_fo_table_size;
+ size_t fo_size = log_fo_table_size == -1 ? 0 :
+ (size_t)1 << log_fo_table_size;
ptr_t real_ptr;
size_t i;
@@ -672,7 +679,7 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj,
{ \
size_t i; \
size_t dl_size = dl_hashtbl->log_size == -1 ? 0 : \
- 1 << dl_hashtbl->log_size; \
+ (size_t)1 << dl_hashtbl->log_size; \
for (i = 0; i < dl_size; i++) { \
curr_dl = dl_hashtbl -> head[i]; \
prev_dl = NULL; \
@@ -739,7 +746,8 @@ GC_INNER void GC_finalize(void)
struct finalizable_object * curr_fo, * prev_fo, * next_fo;
ptr_t real_ptr;
size_t i;
- size_t fo_size = log_fo_table_size == -1 ? 0 : 1 << log_fo_table_size;
+ size_t fo_size = log_fo_table_size == -1 ? 0 :
+ (size_t)1 << log_fo_table_size;
# ifndef SMALL_CONFIG
/* Save current GC_[dl/ll]_entries value for stats printing */
diff --git a/fnlz_mlc.c b/fnlz_mlc.c
index 0dad28a6..ddda9c0e 100644
--- a/fnlz_mlc.c
+++ b/fnlz_mlc.c
@@ -26,15 +26,19 @@
STATIC int GC_finalized_kind = 0;
+#if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH)
+ /* The first bit is already used for a debug purpose. */
+# define FINALIZER_CLOSURE_FLAG 0x2
+#else
+# define FINALIZER_CLOSURE_FLAG 0x1
+#endif
+
STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj)
{
- void **fc_addr;
- const struct GC_finalizer_closure *fc;
+ word fc_word = *(word *)obj;
- fc_addr = &((void **)obj)[GC_size(obj) / sizeof(void *) - 1];
- fc = *fc_addr;
- if (fc != NULL) {
- /* [1] The disclaim function may be passed fragments from the */
+ if ((fc_word & FINALIZER_CLOSURE_FLAG) != 0) {
+ /* The disclaim function may be passed fragments from the */
/* free-list, on which it should not run finalization. */
/* To recognize this case, we use the fact that the first word */
/* on such fragments are always even (a link to the next */
@@ -42,8 +46,9 @@ STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj)
/* which does not use the first word for storing finalization */
/* info, GC_reclaim_with_finalization must be extended to clear */
/* fragments so that the assumption holds for the selected word. */
- (*fc->proc)(obj, fc->cd);
- *fc_addr = NULL;
+ const struct GC_finalizer_closure *fc
+ = (void *)(fc_word & ~(word)FINALIZER_CLOSURE_FLAG);
+ (*fc->proc)((word *)obj + 1, fc->cd);
}
return 0;
}
@@ -62,6 +67,13 @@ GC_API void GC_CALL GC_init_finalized_malloc(void)
}
done_init = TRUE;
+ /* The finalizer closure is placed in the first word in order to */
+ /* use the lower bits to distinguish live objects from objects on */
+ /* the free list. The downside of this is that we need one-word */
+ /* offset interior pointers, and that GC_base does not return the */
+ /* start of the user region. */
+ GC_register_displacement_inner(sizeof(word));
+
GC_finalized_objfreelist = (ptr_t *)GC_new_free_list_inner();
GC_finalized_kind = GC_new_kind_inner((void **)GC_finalized_objfreelist,
GC_DS_LENGTH, TRUE, TRUE);
@@ -81,7 +93,7 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc,
STATIC void * GC_core_finalized_malloc(size_t lb,
const struct GC_finalizer_closure *fclos)
#else
- GC_API void * GC_CALL GC_finalized_malloc(size_t lb,
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t lb,
const struct GC_finalizer_closure *fclos)
#endif
{
@@ -90,7 +102,7 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc,
word lg;
DCL_LOCK_STATE;
- lb += sizeof(void *);
+ lb = SIZET_SAT_ADD(lb, sizeof(word));
GC_ASSERT(done_init);
if (SMALL_OBJ(lb)) {
GC_DBG_COLLECT_AT_MALLOC(lb);
@@ -112,25 +124,21 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc,
UNLOCK();
}
GC_ASSERT(lg > 0);
- ((const void **)op)[GRANULES_TO_WORDS(lg) - 1] = fclos;
} else {
- size_t op_sz;
-
- op = GC_generic_malloc((word)lb, GC_finalized_kind);
+ op = GC_generic_malloc(lb, GC_finalized_kind);
if (NULL == op)
return NULL;
- op_sz = GC_size(op);
- GC_ASSERT(op_sz >= lb);
- ((const void **)op)[op_sz / sizeof(void *) - 1] = fclos;
+ GC_ASSERT(GC_size(op) >= lb);
}
- return GC_clear_stack(op);
+ *(word *)op = (word)fclos | FINALIZER_CLOSURE_FLAG;
+ return GC_clear_stack((word *)op + 1);
}
#ifdef THREAD_LOCAL_ALLOC
- GC_API void * GC_CALL GC_finalized_malloc(size_t client_lb,
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t client_lb,
const struct GC_finalizer_closure *fclos)
{
- size_t lb = client_lb + sizeof(void *);
+ size_t lb = client_lb + sizeof(word);
size_t lg = ROUNDED_UP_GRANULES(lb);
GC_tlfs tsd;
void *result;
@@ -163,9 +171,9 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc,
result = (void *)my_entry;
*my_fl = next;
obj_link(result) = 0;
- ((const void **)result)[GRANULES_TO_WORDS(lg) - 1] = fclos;
- PREFETCH_FOR_WRITE(next);
- return result;
+ *(word *)result = (word)fclos | FINALIZER_CLOSURE_FLAG;
+ GC_PREFETCH_FOR_WRITE(next);
+ return (word *)result + 1;
}
#endif /* THREAD_LOCAL_ALLOC */
diff --git a/gc.mak b/gc.mak
index 9f92d381..c0d142a8 100644
--- a/gc.mak
+++ b/gc.mak
@@ -7,7 +7,7 @@
!IF "$(CFG)" == ""
CFG=gctest - Win32 Release
-!MESSAGE No configuration specified. Defaulting to cord - Win32 Debug.
+!MESSAGE No configuration specified. Defaulting to gctest - Win32 Release.
!ENDIF
!IF "$(CFG)" != "gc - Win32 Release" && "$(CFG)" != "gc - Win32 Debug" &&\
@@ -110,8 +110,9 @@ CLEAN :
-@erase ".\Release\typd_mlc.sbr"
-@erase ".\Release\win32_threads.obj"
-@erase ".\Release\win32_threads.sbr"
- -@erase ".\Release\msvc_dbg.obj"
- -@erase ".\Release\msvc_dbg.sbr"
+ -@erase ".\Release\msvc_dbg.copied.obj"
+ -@erase ".\Release\msvc_dbg.copied.sbr"
+ -@erase ".\msvc_dbg.copied.c"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
@@ -119,10 +120,10 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /FR /YX /c
-CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D\
- "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" \
- /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" \
- /I./libatomic_ops/src /YX /Fo"$(INTDIR)/" /c
+CPP_PROJ=/nologo /MD /W3 /EHsc /O2 /I include /D "NDEBUG" /D "WIN32"\
+ /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /D "_CRT_SECURE_NO_DEPRECATE"\
+ /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch"\
+ /I./libatomic_ops/src /Fo"$(INTDIR)/" /c
CPP_OBJS=.\Release/
CPP_SBRS=.\Release/
@@ -155,31 +156,31 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/gc.bsc"
-BSC32_SBRS= \
- ".\Release\allchblk.sbr" \
- ".\Release\alloc.sbr" \
- ".\Release\blacklst.sbr" \
- ".\Release\checksums.sbr" \
- ".\Release\dbg_mlc.sbr" \
- ".\Release\dyn_load.sbr" \
- ".\Release\finalize.sbr" \
- ".\Release\fnlz_mlc.sbr" \
- ".\Release\gc_cpp.sbr" \
- ".\Release\headers.sbr" \
- ".\Release\mach_dep.sbr" \
- ".\Release\malloc.sbr" \
- ".\Release\mallocx.sbr" \
- ".\Release\mark.sbr" \
- ".\Release\mark_rts.sbr" \
- ".\Release\misc.sbr" \
- ".\Release\new_hblk.sbr" \
- ".\Release\obj_map.sbr" \
- ".\Release\os_dep.sbr" \
- ".\Release\ptr_chck.sbr" \
- ".\Release\reclaim.sbr" \
- ".\Release\stubborn.sbr" \
- ".\Release\typd_mlc.sbr" \
- ".\Release\msvc_dbg.sbr" \
+BSC32_SBRS=\
+ ".\Release\allchblk.sbr"\
+ ".\Release\alloc.sbr"\
+ ".\Release\blacklst.sbr"\
+ ".\Release\checksums.sbr"\
+ ".\Release\dbg_mlc.sbr"\
+ ".\Release\dyn_load.sbr"\
+ ".\Release\finalize.sbr"\
+ ".\Release\fnlz_mlc.sbr"\
+ ".\Release\gc_cpp.sbr"\
+ ".\Release\headers.sbr"\
+ ".\Release\mach_dep.sbr"\
+ ".\Release\malloc.sbr"\
+ ".\Release\mallocx.sbr"\
+ ".\Release\mark.sbr"\
+ ".\Release\mark_rts.sbr"\
+ ".\Release\misc.sbr"\
+ ".\Release\new_hblk.sbr"\
+ ".\Release\obj_map.sbr"\
+ ".\Release\os_dep.sbr"\
+ ".\Release\ptr_chck.sbr"\
+ ".\Release\reclaim.sbr"\
+ ".\Release\stubborn.sbr"\
+ ".\Release\typd_mlc.sbr"\
+ ".\Release\msvc_dbg.copied.sbr"\
".\Release\win32_threads.sbr"
".\Release\gc.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
@@ -195,31 +196,31 @@ LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\
/pdb:"$(OUTDIR)/gc.pdb" /machine:I386 /out:"$(OUTDIR)/gc.dll"\
/implib:"$(OUTDIR)/gc.lib"
-LINK32_OBJS= \
- ".\Release\allchblk.obj" \
- ".\Release\alloc.obj" \
- ".\Release\blacklst.obj" \
- ".\Release\checksums.obj" \
- ".\Release\dbg_mlc.obj" \
- ".\Release\dyn_load.obj" \
- ".\Release\finalize.obj" \
- ".\Release\fnlz_mlc.obj" \
- ".\Release\gc_cpp.obj" \
- ".\Release\headers.obj" \
- ".\Release\mach_dep.obj" \
- ".\Release\malloc.obj" \
- ".\Release\mallocx.obj" \
- ".\Release\mark.obj" \
- ".\Release\mark_rts.obj" \
- ".\Release\misc.obj" \
- ".\Release\new_hblk.obj" \
- ".\Release\obj_map.obj" \
- ".\Release\os_dep.obj" \
- ".\Release\ptr_chck.obj" \
- ".\Release\reclaim.obj" \
- ".\Release\stubborn.obj" \
- ".\Release\typd_mlc.obj" \
- ".\Release\msvc_dbg.obj" \
+LINK32_OBJS=\
+ ".\Release\allchblk.obj"\
+ ".\Release\alloc.obj"\
+ ".\Release\blacklst.obj"\
+ ".\Release\checksums.obj"\
+ ".\Release\dbg_mlc.obj"\
+ ".\Release\dyn_load.obj"\
+ ".\Release\finalize.obj"\
+ ".\Release\fnlz_mlc.obj"\
+ ".\Release\gc_cpp.obj"\
+ ".\Release\headers.obj"\
+ ".\Release\mach_dep.obj"\
+ ".\Release\malloc.obj"\
+ ".\Release\mallocx.obj"\
+ ".\Release\mark.obj"\
+ ".\Release\mark_rts.obj"\
+ ".\Release\misc.obj"\
+ ".\Release\new_hblk.obj"\
+ ".\Release\obj_map.obj"\
+ ".\Release\os_dep.obj"\
+ ".\Release\ptr_chck.obj"\
+ ".\Release\reclaim.obj"\
+ ".\Release\stubborn.obj"\
+ ".\Release\typd_mlc.obj"\
+ ".\Release\msvc_dbg.copied.obj"\
".\Release\win32_threads.obj"
".\Release\gc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
@@ -301,8 +302,9 @@ CLEAN :
-@erase ".\Debug\vc40.pdb"
-@erase ".\Debug\win32_threads.obj"
-@erase ".\Debug\win32_threads.sbr"
- -@erase ".\Debug\msvc_dbg.obj"
- -@erase ".\Debug\msvc_dbg.sbr"
+ -@erase ".\Debug\msvc_dbg.copied.obj"
+ -@erase ".\Debug\msvc_dbg.copied.sbr"
+ -@erase ".\msvc_dbg.copied.c"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
@@ -310,10 +312,10 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /FR /YX /c
-CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG"\
- /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" \
- /D "GC_ASSERTIONS" /D "GC_THREADS" \
- /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\
+CPP_PROJ=/nologo /MDd /W3 /Gm /EHsc /Zi /Od /I include /D "_DEBUG"\
+ /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS"\
+ /D "GC_ASSERTIONS" /D "GC_THREADS" /D "_CRT_SECURE_NO_DEPRECATE"\
+ /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /Fo"$(INTDIR)/"\
/I./libatomic_ops/src /Fd"$(INTDIR)/" /c
CPP_OBJS=.\Debug/
CPP_SBRS=.\Debug/
@@ -347,31 +349,31 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/gc.bsc"
-BSC32_SBRS= \
- ".\Debug\allchblk.sbr" \
- ".\Debug\alloc.sbr" \
- ".\Debug\blacklst.sbr" \
- ".\Debug\checksums.sbr" \
- ".\Debug\dbg_mlc.sbr" \
- ".\Debug\dyn_load.sbr" \
- ".\Debug\finalize.sbr" \
- ".\Debug\fnlz_mlc.sbr" \
- ".\Debug\gc_cpp.sbr" \
- ".\Debug\headers.sbr" \
- ".\Debug\mach_dep.sbr" \
- ".\Debug\malloc.sbr" \
- ".\Debug\mallocx.sbr" \
- ".\Debug\mark.sbr" \
- ".\Debug\mark_rts.sbr" \
- ".\Debug\misc.sbr" \
- ".\Debug\new_hblk.sbr" \
- ".\Debug\obj_map.sbr" \
- ".\Debug\os_dep.sbr" \
- ".\Debug\ptr_chck.sbr" \
- ".\Debug\reclaim.sbr" \
- ".\Debug\stubborn.sbr" \
- ".\Debug\typd_mlc.sbr" \
- ".\Debug\msvc_dbg.sbr" \
+BSC32_SBRS=\
+ ".\Debug\allchblk.sbr"\
+ ".\Debug\alloc.sbr"\
+ ".\Debug\blacklst.sbr"\
+ ".\Debug\checksums.sbr"\
+ ".\Debug\dbg_mlc.sbr"\
+ ".\Debug\dyn_load.sbr"\
+ ".\Debug\finalize.sbr"\
+ ".\Debug\fnlz_mlc.sbr"\
+ ".\Debug\gc_cpp.sbr"\
+ ".\Debug\headers.sbr"\
+ ".\Debug\mach_dep.sbr"\
+ ".\Debug\malloc.sbr"\
+ ".\Debug\mallocx.sbr"\
+ ".\Debug\mark.sbr"\
+ ".\Debug\mark_rts.sbr"\
+ ".\Debug\misc.sbr"\
+ ".\Debug\new_hblk.sbr"\
+ ".\Debug\obj_map.sbr"\
+ ".\Debug\os_dep.sbr"\
+ ".\Debug\ptr_chck.sbr"\
+ ".\Debug\reclaim.sbr"\
+ ".\Debug\stubborn.sbr"\
+ ".\Debug\typd_mlc.sbr"\
+ ".\Debug\msvc_dbg.copied.sbr"\
".\Debug\win32_threads.sbr"
".\Debug\gc.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
@@ -387,31 +389,31 @@ LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\
/pdb:"$(OUTDIR)/gc.pdb" /map:"$(INTDIR)/gc.map" /debug /machine:I386\
/out:"$(OUTDIR)/gc.dll" /implib:"$(OUTDIR)/gc.lib"
-LINK32_OBJS= \
- ".\Debug\allchblk.obj" \
- ".\Debug\alloc.obj" \
- ".\Debug\blacklst.obj" \
- ".\Debug\checksums.obj" \
- ".\Debug\dbg_mlc.obj" \
- ".\Debug\dyn_load.obj" \
- ".\Debug\finalize.obj" \
- ".\Debug\fnlz_mlc.obj" \
- ".\Debug\gc_cpp.obj" \
- ".\Debug\headers.obj" \
- ".\Debug\mach_dep.obj" \
- ".\Debug\malloc.obj" \
- ".\Debug\mallocx.obj" \
- ".\Debug\mark.obj" \
- ".\Debug\mark_rts.obj" \
- ".\Debug\misc.obj" \
- ".\Debug\new_hblk.obj" \
- ".\Debug\obj_map.obj" \
- ".\Debug\os_dep.obj" \
- ".\Debug\ptr_chck.obj" \
- ".\Debug\reclaim.obj" \
- ".\Debug\stubborn.obj" \
- ".\Debug\typd_mlc.obj" \
- ".\Debug\msvc_dbg.obj" \
+LINK32_OBJS=\
+ ".\Debug\allchblk.obj"\
+ ".\Debug\alloc.obj"\
+ ".\Debug\blacklst.obj"\
+ ".\Debug\checksums.obj"\
+ ".\Debug\dbg_mlc.obj"\
+ ".\Debug\dyn_load.obj"\
+ ".\Debug\finalize.obj"\
+ ".\Debug\fnlz_mlc.obj"\
+ ".\Debug\gc_cpp.obj"\
+ ".\Debug\headers.obj"\
+ ".\Debug\mach_dep.obj"\
+ ".\Debug\malloc.obj"\
+ ".\Debug\mallocx.obj"\
+ ".\Debug\mark.obj"\
+ ".\Debug\mark_rts.obj"\
+ ".\Debug\misc.obj"\
+ ".\Debug\new_hblk.obj"\
+ ".\Debug\obj_map.obj"\
+ ".\Debug\os_dep.obj"\
+ ".\Debug\ptr_chck.obj"\
+ ".\Debug\reclaim.obj"\
+ ".\Debug\stubborn.obj"\
+ ".\Debug\typd_mlc.obj"\
+ ".\Debug\msvc_dbg.copied.obj"\
".\Debug\win32_threads.obj"
".\Debug\gc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
@@ -437,22 +439,23 @@ INTDIR=.\gctest\Release
ALL : "gc - Win32 Release" ".\Release\gctest.exe"
CLEAN :
- -@erase ".\gctest\Release\test.obj"
+ -@erase ".\gctest\Release\test.copied.obj"
+ -@erase ".\test.copied.c"
-@erase ".\Release\gctest.exe"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-test.c : tests\test.c
- copy tests\test.c test.c
+test.copied.c : tests\test.c
+ copy tests\test.c test.copied.c
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /YX /c
-CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
- "ALL_INTERIOR_POINTERS" /D "GC_THREADS" \
- /I./libatomic_ops/src /Fp"$(INTDIR)/gctest.pch" \
- /YX /Fo"$(INTDIR)/" /c
+CPP_PROJ=/nologo /MD /W3 /EHsc /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS"\
+ /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /D "_CRT_SECURE_NO_DEPRECATE"\
+ /I./libatomic_ops/src /Fp"$(INTDIR)/gctest.pch"\
+ /Fo"$(INTDIR)/" /c
CPP_OBJS=.\gctest\Release/
CPP_SBRS=.\.
@@ -485,7 +488,7 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/gctest.bsc"
-BSC32_SBRS= \
+BSC32_SBRS=\
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
@@ -494,8 +497,8 @@ LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
odbccp32.lib /nologo /subsystem:windows /incremental:no\
/pdb:"$(OUTDIR)/gctest.pdb" /machine:I386 /out:"Release/gctest.exe"
-LINK32_OBJS= \
- ".\gctest\Release\test.obj" \
+LINK32_OBJS=\
+ ".\gctest\Release\test.copied.obj"\
".\Release\gc.lib"
".\Release\gctest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
@@ -525,8 +528,9 @@ CLEAN :
-@erase ".\gctest\Debug\gctest.bsc"
-@erase ".\gctest\Debug\gctest.map"
-@erase ".\gctest\Debug\gctest.pdb"
- -@erase ".\gctest\Debug\test.obj"
- -@erase ".\gctest\Debug\test.sbr"
+ -@erase ".\gctest\Debug\test.copied.obj"
+ -@erase ".\gctest\Debug\test.copied.sbr"
+ -@erase ".\test.copied.c"
-@erase ".\gctest\Debug\vc40.idb"
-@erase ".\gctest\Debug\vc40.pdb"
@@ -536,9 +540,9 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /FR /YX /c
-CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\
- /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /FR"$(INTDIR)/"\
- /I./libatomic_ops/src /Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
+CPP_PROJ=/nologo /MDd /W3 /Gm /EHsc /Zi /Od /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\
+ /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /D "_CRT_SECURE_NO_DEPRECATE" /FR"$(INTDIR)/"\
+ /I./libatomic_ops/src /Fp"$(INTDIR)/gctest.pch" /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
CPP_OBJS=.\gctest\Debug/
CPP_SBRS=.\gctest\Debug/
@@ -571,8 +575,8 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/gctest.bsc"
-BSC32_SBRS= \
- ".\gctest\Debug\test.sbr"
+BSC32_SBRS=\
+ ".\gctest\Debug\test.copied.sbr"
".\gctest\Debug\gctest.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
$(BSC32) @<<
@@ -587,9 +591,9 @@ LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
odbccp32.lib /nologo /subsystem:windows /incremental:no\
/pdb:"$(OUTDIR)/gctest.pdb" /map:"$(INTDIR)/gctest.map" /debug /machine:I386\
/out:"Debug/gctest.exe"
-LINK32_OBJS= \
- ".\Debug\gc.lib" \
- ".\gctest\Debug\test.obj"
+LINK32_OBJS=\
+ ".\Debug\gc.lib"\
+ ".\gctest\Debug\test.copied.obj"
".\Debug\gctest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
@@ -627,8 +631,8 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /YX /c
-CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "." /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
- /I./libatomic_ops/src "ALL_INTERIOR_POINTERS" /Fp"$(INTDIR)/cord.pch" /YX /Fo"$(INTDIR)/" /c
+CPP_PROJ=/nologo /MD /W3 /EHsc /O2 /I "." /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS"\
+ /D "ALL_INTERIOR_POINTERS" /I./libatomic_ops/src /Fp"$(INTDIR)/cord.pch" /Fo"$(INTDIR)/" /c
CPP_OBJS=.\cord\Release/
CPP_SBRS=.\.
@@ -662,7 +666,7 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/cord.bsc"
-BSC32_SBRS= \
+BSC32_SBRS=\
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
@@ -671,12 +675,12 @@ LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
odbccp32.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)/de.pdb"\
/machine:I386 /out:"Release/de.exe"
-LINK32_OBJS= \
- ".\cord\Release\cordbscs.obj" \
- ".\cord\Release\cordxtra.obj" \
- ".\cord\Release\de.obj" \
- ".\cord\Release\de_win.obj" \
- ".\cord\Release\de_win.res" \
+LINK32_OBJS=\
+ ".\cord\Release\cordbscs.obj"\
+ ".\cord\Release\cordxtra.obj"\
+ ".\cord\Release\de.obj"\
+ ".\cord\Release\de_win.obj"\
+ ".\cord\Release\de_win.res"\
".\Release\gc.lib"
".\Release\de.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
@@ -719,8 +723,8 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /YX /c
-CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "." /I include /D "_DEBUG" /D "WIN32" /D\
- "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /Fp"$(INTDIR)/cord.pch" /YX\
+CPP_PROJ=/nologo /MDd /W3 /Gm /EHsc /Zi /Od /I "." /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\
+ /D "ALL_INTERIOR_POINTERS" /Fp"$(INTDIR)/cord.pch"\
/I./libatomic_ops/src /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
CPP_OBJS=.\cord\Debug/
CPP_SBRS=.\.
@@ -755,7 +759,7 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/cord.bsc"
-BSC32_SBRS= \
+BSC32_SBRS=\
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
@@ -764,12 +768,12 @@ LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
odbccp32.lib /nologo /subsystem:windows /incremental:yes\
/pdb:"$(OUTDIR)/de.pdb" /debug /machine:I386 /out:"Debug/de.exe"
-LINK32_OBJS= \
- ".\cord\Debug\cordbscs.obj" \
- ".\cord\Debug\cordxtra.obj" \
- ".\cord\Debug\de.obj" \
- ".\cord\Debug\de_win.obj" \
- ".\cord\Debug\de_win.res" \
+LINK32_OBJS=\
+ ".\cord\Debug\cordbscs.obj"\
+ ".\cord\Debug\cordxtra.obj"\
+ ".\cord\Debug\de.obj"\
+ ".\cord\Debug\de_win.obj"\
+ ".\cord\Debug\de_win.res"\
".\Debug\gc.lib"
".\Debug\de.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
@@ -1945,6 +1949,9 @@ NODEP_CPP_WIN32=\
SOURCE=.\extra\msvc_dbg.c
+msvc_dbg.copied.c : extra\msvc_dbg.c
+ copy extra\msvc_dbg.c msvc_dbg.copied.c
+
!IF "$(CFG)" == "gc - Win32 Release"
DEP_CPP_WIN32=\
@@ -1961,9 +1968,9 @@ NODEP_CPP_WIN32=\
".\th\PCR_ThCtl.h"\
-".\Release\msvc_dbg.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
+".\Release\msvc_dbg.copied.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
-".\Release\msvc_dbg.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
+".\Release\msvc_dbg.copied.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
!ELSEIF "$(CFG)" == "gc - Win32 Debug"
@@ -1982,9 +1989,9 @@ NODEP_CPP_WIN32=\
".\th\PCR_ThCtl.h"\
-".\Debug\msvc_dbg.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
+".\Debug\msvc_dbg.copied.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
-".\Debug\msvc_dbg.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
+".\Debug\msvc_dbg.copied.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
!ENDIF
@@ -2090,15 +2097,15 @@ NODEP_CPP_TEST_=\
!IF "$(CFG)" == "gctest - Win32 Release"
-".\gctest\Release\test.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)"
+".\gctest\Release\test.copied.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)"
!ELSEIF "$(CFG)" == "gctest - Win32 Debug"
-".\gctest\Debug\test.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)"
+".\gctest\Debug\test.copied.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)"
-".\gctest\Debug\test.sbr" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)"
+".\gctest\Debug\test.copied.sbr" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)"
!ENDIF
diff --git a/gc_cpp.cc b/gc_cpp.cc
index 0f6c9d2b..bf880c08 100644
--- a/gc_cpp.cc
+++ b/gc_cpp.cc
@@ -47,11 +47,9 @@ void* operator new( size_t size ) GC_DECL_NEW_THROW {
return GC_MALLOC_UNCOLLECTABLE(size);
}
-#if !defined(__CYGWIN__)
- void operator delete( void* obj ) GC_DECL_DELETE_THROW {
+ void operator delete(void* obj) GC_DECL_DELETE_THROW {
GC_FREE(obj);
}
-#endif /* !__CYGWIN__ */
#ifdef GC_OPERATOR_NEW_ARRAY
void* operator new[]( size_t size ) GC_DECL_NEW_THROW {
diff --git a/gcj_mlc.c b/gcj_mlc.c
index 78950e25..fd06e29e 100644
--- a/gcj_mlc.c
+++ b/gcj_mlc.c
@@ -101,7 +101,7 @@ GC_API void GC_CALL GC_init_gcj_malloc(int mp_index,
/* Use a simple length-based descriptor, thus forcing a fully */
/* conservative scan. */
GC_gcj_kind = GC_new_kind_inner((void **)GC_gcjobjfreelist,
- (0 | GC_DS_LENGTH),
+ /* 0 | */ GC_DS_LENGTH,
TRUE, TRUE);
} else {
GC_gcj_kind = GC_new_kind_inner(
@@ -159,7 +159,7 @@ static void maybe_finalize(void)
GC_INNER void * GC_core_gcj_malloc(size_t lb,
void * ptr_to_struct_containing_descr)
#else
- GC_API void * GC_CALL GC_gcj_malloc(size_t lb,
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_gcj_malloc(size_t lb,
void * ptr_to_struct_containing_descr)
#endif
{
@@ -206,7 +206,7 @@ static void maybe_finalize(void)
/* Similar to GC_gcj_malloc, but add debug info. This is allocated */
/* with GC_gcj_debug_kind. */
-GC_API void * GC_CALL GC_debug_gcj_malloc(size_t lb,
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_gcj_malloc(size_t lb,
void * ptr_to_struct_containing_descr, GC_EXTRA_PARAMS)
{
void * result;
@@ -216,7 +216,8 @@ GC_API void * GC_CALL GC_debug_gcj_malloc(size_t lb,
/* confuse the backtrace. */
LOCK();
maybe_finalize();
- result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
+ result = GC_generic_malloc_inner(SIZET_SAT_ADD(lb, DEBUG_BYTES),
+ GC_gcj_debug_kind);
if (result == 0) {
GC_oom_func oom_fn = GC_oom_fn;
UNLOCK();
@@ -234,7 +235,7 @@ GC_API void * GC_CALL GC_debug_gcj_malloc(size_t lb,
}
/* There is no THREAD_LOCAL_ALLOC for GC_gcj_malloc_ignore_off_page(). */
-GC_API void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t lb,
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t lb,
void * ptr_to_struct_containing_descr)
{
ptr_t op;
diff --git a/headers.c b/headers.c
index 8e92e384..108adf18 100644
--- a/headers.c
+++ b/headers.c
@@ -119,8 +119,7 @@ GC_INNER ptr_t GC_scratch_alloc(size_t bytes)
{
register ptr_t result = scratch_free_ptr;
- bytes += GRANULE_BYTES-1;
- bytes &= ~(GRANULE_BYTES-1);
+ bytes = ROUNDUP_GRANULE_SIZE(bytes);
scratch_free_ptr += bytes;
if ((word)scratch_free_ptr <= (word)GC_scratch_end_ptr) {
return(result);
@@ -130,27 +129,23 @@ GC_INNER ptr_t GC_scratch_alloc(size_t bytes)
if (bytes_to_get <= bytes) {
/* Undo the damage, and get memory directly */
- bytes_to_get = bytes;
-# ifdef USE_MMAP
- bytes_to_get += GC_page_size - 1;
- bytes_to_get &= ~(GC_page_size - 1);
-# endif
+ bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes);
result = (ptr_t)GET_MEM(bytes_to_get);
GC_add_to_our_memory(result, bytes_to_get);
scratch_free_ptr -= bytes;
- GC_scratch_last_end_ptr = result + bytes;
+ if (result != NULL) {
+ GC_scratch_last_end_ptr = result + bytes;
+ }
return(result);
}
+
+ bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes_to_get); /* for safety */
result = (ptr_t)GET_MEM(bytes_to_get);
GC_add_to_our_memory(result, bytes_to_get);
if (result == 0) {
WARN("Out of memory - trying to allocate less\n", 0);
scratch_free_ptr -= bytes;
- bytes_to_get = bytes;
-# ifdef USE_MMAP
- bytes_to_get += GC_page_size - 1;
- bytes_to_get &= ~(GC_page_size - 1);
-# endif
+ bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes);
result = (ptr_t)GET_MEM(bytes_to_get);
GC_add_to_our_memory(result, bytes_to_get);
return result;
diff --git a/src/ia64_save_regs_in_stack.s b/ia64_save_regs_in_stack.s
index 2b81edfa..2b81edfa 100644
--- a/src/ia64_save_regs_in_stack.s
+++ b/ia64_save_regs_in_stack.s
diff --git a/include/cord.h b/include/cord.h
index d3d555b6..f414a916 100644
--- a/include/cord.h
+++ b/include/cord.h
@@ -66,8 +66,8 @@
# elif defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \
|| defined(__CYGWIN__) || defined(__WATCOMC__)
# define CORD_API extern __declspec(dllexport)
-# elif defined(__GNUC__) && (__GNUC__ >= 4 \
- || defined(GC_VISIBILITY_HIDDEN_SET))
+# elif defined(__GNUC__) && !defined(GC_NO_VISIBILITY) \
+ && (__GNUC__ >= 4 || defined(GC_VISIBILITY_HIDDEN_SET))
/* Only matters if used in conjunction with -fvisibility=hidden option. */
# define CORD_API extern __attribute__((__visibility__("default")))
# endif
diff --git a/include/gc.h b/include/gc.h
index 6046b728..02762afb 100644
--- a/include/gc.h
+++ b/include/gc.h
@@ -503,7 +503,20 @@ GC_API size_t GC_CALL GC_size(const void * /* obj_addr */) GC_ATTR_NONNULL(1);
/* The resulting object has the same kind as the original. */
/* If the argument is stubborn, the result will have changes enabled. */
/* It is an error to have changes enabled for the original object. */
-/* Follows ANSI conventions for NULL old_object. */
+/* It does not change the content of the object from its beginning to */
+/* the minimum of old size and new_size_in_bytes; the content above in */
+/* case of object size growth is initialized to zero (not guaranteed */
+/* for atomic object type). The function follows ANSI conventions for */
+/* NULL old_object (i.e., equivalent to GC_malloc regardless of new */
+/* size). If new size is zero (and old_object is non-NULL) then the */
+/* call is equivalent to GC_free (and NULL is returned). If old_object */
+/* is non-NULL, it must have been returned by an earlier call to */
+/* GC_malloc* or GC_realloc. In case of the allocation failure, the */
+/* memory pointed by old_object is untouched (and not freed). */
+/* If the returned pointer is not the same as old_object and both of */
+/* them are non-NULL then old_object is freed. Returns either NULL (in */
+/* case of the allocation failure or zero new size) or pointer to the */
+/* allocated memory. */
GC_API void * GC_CALL GC_realloc(void * /* old_object */,
size_t /* new_size_in_bytes */)
/* 'realloc' attr */ GC_ATTR_ALLOC_SIZE(2);
@@ -729,7 +742,7 @@ GC_API void GC_CALL GC_enable_incremental(void);
/* Does incremental mode write-protect pages? Returns zero or */
/* more of the following, or'ed together: */
-#define GC_PROTECTS_POINTER_HEAP 1 /* May protect non-atomic objs. */
+#define GC_PROTECTS_POINTER_HEAP 1 /* May protect non-atomic objects. */
#define GC_PROTECTS_PTRFREE_HEAP 2
#define GC_PROTECTS_STATIC_DATA 4 /* Currently never. */
#define GC_PROTECTS_STACK 8 /* Probably impractical. */
@@ -1309,7 +1322,7 @@ GC_API void * GC_CALL GC_call_with_stack_base(GC_stack_base_func /* fn */,
/* functions are called to create the thread, e.g. by including gc.h */
/* (which redefines some system functions) before calling the system */
/* thread creation function. Nonetheless, thread cleanup routines */
- /* (eg., pthread key destructor) typically require manual thread */
+ /* (e.g., pthread key destructor) typically require manual thread */
/* registering (and unregistering) if pointers to GC-allocated */
/* objects are manipulated inside. */
/* It is also always done implicitly on some platforms if */
@@ -1494,7 +1507,7 @@ GC_API void GC_CALL GC_register_has_static_roots_callback(
#if defined(GC_WIN32_THREADS) \
&& (!defined(GC_PTHREADS) || defined(GC_BUILD) || defined(WINAPI))
- /* Note: for Cygwin and win32-pthread, this is skipped */
+ /* Note: for Cygwin and pthreads-win32, this is skipped */
/* unless windows.h is included before gc.h. */
# if !defined(GC_NO_THREAD_DECLS) || defined(GC_BUILD)
@@ -1617,14 +1630,24 @@ GC_API int GC_CALL GC_get_force_unmap_on_gcollect(void);
/* THREAD_LOCAL_ALLOC defined and the initial allocation call is not */
/* to GC_malloc() or GC_malloc_atomic(). */
-#ifdef __CYGWIN32__
+#if defined(__CYGWIN32__) || defined(__CYGWIN__)
/* Similarly gnu-win32 DLLs need explicit initialization from the */
/* main program, as does AIX. */
- extern int _data_start__[], _data_end__[], _bss_start__[], _bss_end__[];
-# define GC_DATASTART ((GC_word)_data_start__ < (GC_word)_bss_start__ ? \
- (void *)_data_start__ : (void *)_bss_start__)
-# define GC_DATAEND ((GC_word)_data_end__ > (GC_word)_bss_end__ ? \
- (void *)_data_end__ : (void *)_bss_end__)
+# ifdef __x86_64__
+ /* Cygwin/x64 does not add leading underscore to symbols anymore. */
+ extern int __data_start__[], __data_end__[];
+ extern int __bss_start__[], __bss_end__[];
+# define GC_DATASTART ((GC_word)__data_start__ < (GC_word)__bss_start__ \
+ ? (void *)__data_start__ : (void *)__bss_start__)
+# define GC_DATAEND ((GC_word)__data_end__ > (GC_word)__bss_end__ \
+ ? (void *)__data_end__ : (void *)__bss_end__)
+# else
+ extern int _data_start__[], _data_end__[], _bss_start__[], _bss_end__[];
+# define GC_DATASTART ((GC_word)_data_start__ < (GC_word)_bss_start__ \
+ ? (void *)_data_start__ : (void *)_bss_start__)
+# define GC_DATAEND ((GC_word)_data_end__ > (GC_word)_bss_end__ \
+ ? (void *)_data_end__ : (void *)_bss_end__)
+# endif /* !__x86_64__ */
# define GC_INIT_CONF_ROOTS GC_add_roots(GC_DATASTART, GC_DATAEND); \
GC_gcollect() /* For blacklisting. */
/* Required at least if GC is in a DLL. And doesn't hurt. */
@@ -1633,8 +1656,10 @@ GC_API int GC_CALL GC_get_force_unmap_on_gcollect(void);
# define GC_DATASTART ((void *)((ulong)_data))
# define GC_DATAEND ((void *)((ulong)_end))
# define GC_INIT_CONF_ROOTS GC_add_roots(GC_DATASTART, GC_DATAEND)
+#elif (defined(PLATFORM_ANDROID) || defined(__ANDROID__)) \
+ && !defined(GC_NOT_DLL) && 0
/*
-Enabling this section of code will cause the entire binary section of memory
+Unity: Enabling this section of code will cause the entire binary section of memory
to be pushed as a root, which is not correct. Boehm does this to be conservative
and find static data. This is a bad idea though because on some Android devices
we're seeing some of the binary data become unmapped, so when we go to scan it
@@ -1642,13 +1667,29 @@ we get a signal like this: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR). There is
no need for us to push all of this data as a root, we know where the static
data is already.
*/
-//#elif (defined(PLATFORM_ANDROID) || defined(__ANDROID__)) \
-// && !defined(GC_NOT_DLL)
-// /* Required if GC is built as shared lib with -D IGNORE_DYNAMIC_LOADING. */
-//# pragma weak __data_start
-// extern int __data_start[], _end[];
-//# define GC_INIT_CONF_ROOTS (void)((GC_word)(__data_start) != 0 ? \
-// (GC_add_roots(__data_start, _end), 0) : 0)
+# pragma weak _etext
+# pragma weak __data_start
+# pragma weak __dso_handle
+ extern int _etext[], __data_start[], __dso_handle[];
+# pragma weak __end__
+ extern int __end__[], _end[];
+ /* Explicitly register caller static data roots. Workaround for */
+ /* __data_start: NDK "gold" linker might miss it or place it */
+ /* incorrectly, __dso_handle is an alternative data start reference. */
+ /* Workaround for _end: NDK Clang 3.5+ does not place it at correct */
+ /* offset (as of NDK r10e) but "bfd" linker provides __end__ symbol */
+ /* that could be used instead. */
+# define GC_INIT_CONF_ROOTS \
+ (void)((GC_word)__data_start < (GC_word)_etext \
+ && (GC_word)_etext < (GC_word)__dso_handle \
+ ? (__end__ != 0 \
+ ? (GC_add_roots(__dso_handle, __end__), 0) \
+ : (GC_word)__dso_handle < (GC_word)_end \
+ ? (GC_add_roots(__dso_handle, _end), 0) : 0) \
+ : __data_start != 0 ? (__end__ != 0 \
+ ? (GC_add_roots(__data_start, __end__), 0) \
+ : (GC_word)__data_start < (GC_word)_end \
+ ? (GC_add_roots(__data_start, _end), 0) : 0) : 0)
#else
# define GC_INIT_CONF_ROOTS /* empty */
#endif
diff --git a/include/gc_config_macros.h b/include/gc_config_macros.h
index 2a6b546f..8a82d0f2 100644
--- a/include/gc_config_macros.h
+++ b/include/gc_config_macros.h
@@ -64,7 +64,7 @@
#endif
#if defined(GC_WIN32_PTHREADS) && !defined(GC_WIN32_THREADS)
- /* Using pthreads-w32 library. */
+ /* Using pthreads-win32 library. */
# define GC_WIN32_THREADS
#endif
@@ -94,8 +94,9 @@
# define GC_IRIX_THREADS
# endif
# if defined(__sparc) && !defined(__linux__) \
- || defined(sun) && (defined(i386) || defined(__i386__) \
- || defined(__amd64__))
+ || ((defined(sun) || defined(__sun)) \
+ && (defined(i386) || defined(__i386__) \
+ || defined(__amd64) || defined(__amd64__)))
# define GC_SOLARIS_THREADS
# elif defined(__APPLE__) && defined(__MACH__)
# define GC_DARWIN_THREADS
@@ -211,8 +212,8 @@
# elif defined(__GNUC__)
/* Only matters if used in conjunction with -fvisibility=hidden option. */
-# if defined(GC_BUILD) && (__GNUC__ >= 4 \
- || defined(GC_VISIBILITY_HIDDEN_SET))
+# if defined(GC_BUILD) && !defined(GC_NO_VISIBILITY) \
+ && (__GNUC__ >= 4 || defined(GC_VISIBILITY_HIDDEN_SET))
# define GC_API extern __attribute__((__visibility__("default")))
# endif
# endif
@@ -251,13 +252,17 @@
#ifndef GC_ATTR_ALLOC_SIZE
/* 'alloc_size' attribute improves __builtin_object_size correctness. */
/* Only single-argument form of 'alloc_size' attribute is used. */
-# if !defined(__APPLE__) && defined(__GNUC__) && (__GNUC__ > 4 \
- || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 && !defined(__ICC)) \
- || __clang_major__ > 3 \
- || (__clang_major__ == 3 && __clang_minor__ >= 2))
+# ifdef __clang__
+# if __has_attribute(__alloc_size__)
+# define GC_ATTR_ALLOC_SIZE(argnum) __attribute__((__alloc_size__(argnum)))
+# else
+# define GC_ATTR_ALLOC_SIZE(argnum) /* empty */
+# endif
+# elif __GNUC__ > 4 \
+ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 && !defined(__ICC))
# define GC_ATTR_ALLOC_SIZE(argnum) __attribute__((__alloc_size__(argnum)))
# else
-# define GC_ATTR_ALLOC_SIZE(argnum)
+# define GC_ATTR_ALLOC_SIZE(argnum) /* empty */
# endif
#endif
@@ -316,7 +321,7 @@
# define GC_CAN_SAVE_CALL_STACKS
#endif
-/* If we're on an a platform on which we can't save call stacks, but */
+/* If we're on a platform on which we can't save call stacks, but */
/* gcc is normally used, we go ahead and define GC_ADD_CALLER. */
/* We make this decision independent of whether gcc is actually being */
/* used, in order to keep the interface consistent, and allow mixing */
diff --git a/include/gc_cpp.h b/include/gc_cpp.h
index 6f3fce88..2e4aa1b4 100644
--- a/include/gc_cpp.h
+++ b/include/gc_cpp.h
@@ -21,7 +21,7 @@ C++ Interface to the Boehm Collector
This interface provides access to the Boehm collector. It provides
basic facilities similar to those described in "Safe, Efficient
-Garbage Collection for C++", by John R. Elis and David L. Detlefs
+Garbage Collection for C++", by John R. Ellis and David L. Detlefs
(ftp://ftp.parc.xerox.com/pub/ellis/gc).
All heap-allocated objects are either "collectible" or
@@ -425,12 +425,4 @@ inline void* operator new( size_t size, GC_NS_QUALIFY(GCPlacement) gcp,
}
#endif /* GC_OPERATOR_NEW_ARRAY */
-#if defined(__CYGWIN__)
-# include <new> // for delete throw()
- inline void operator delete(void *p)
- {
- GC_FREE(p);
- }
-#endif
-
#endif /* GC_CPP_H */
diff --git a/include/gc_inline.h b/include/gc_inline.h
index 8d93f44a..db1b2718 100644
--- a/include/gc_inline.h
+++ b/include/gc_inline.h
@@ -42,6 +42,14 @@
# define GC_ASSERT(expr) /* empty */
#endif
+#ifndef GC_PREFETCH_FOR_WRITE
+# define GC_PREFETCH_FOR_WRITE(x) (void)0
+#endif
+
+/* Object kinds; must match PTRFREE, NORMAL in gc_priv.h. */
+#define GC_I_PTRFREE 0
+#define GC_I_NORMAL 1
+
/* Store a pointer to a list of newly allocated objects of kind k and */
/* size lb in *result. The caller must make sure that *result is */
/* traced even if objects are ptrfree. */
@@ -76,14 +84,25 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t /* lb */, int /* k */,
void *my_entry=*my_fl; \
void *next; \
\
- while (GC_EXPECT((GC_word)my_entry \
- <= (num_direct) + GC_TINY_FREELISTS + 1, 0)) { \
+ for (;;) { \
+ if (GC_EXPECT((GC_word)my_entry \
+ > (num_direct) + GC_TINY_FREELISTS + 1, 1)) { \
+ next = *(void **)(my_entry); \
+ result = (void *)my_entry; \
+ *my_fl = next; \
+ init; \
+ GC_PREFETCH_FOR_WRITE(next); \
+ GC_ASSERT(GC_size(result) >= (granules)*GC_GRANULE_BYTES); \
+ GC_ASSERT((kind) == GC_I_PTRFREE \
+ || ((GC_word *)result)[1] == 0); \
+ break; \
+ } \
/* Entry contains counter or NULL */ \
- if ((GC_word)my_entry - 1 < (num_direct)) { \
+ if ((GC_word)my_entry <= (num_direct) && my_entry != 0) { \
/* Small counter value, not NULL */ \
*my_fl = (char *)my_entry + (granules) + 1; \
result = (default_expr); \
- goto out; \
+ break; \
} else { \
/* Large counter or NULL */ \
GC_generic_malloc_many(((granules) == 0? GC_GRANULE_BYTES : \
@@ -92,18 +111,10 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t /* lb */, int /* k */,
my_entry = *my_fl; \
if (my_entry == 0) { \
result = (*GC_get_oom_fn())((granules)*GC_GRANULE_BYTES); \
- goto out; \
+ break; \
} \
} \
} \
- next = *(void **)(my_entry); \
- result = (void *)my_entry; \
- *my_fl = next; \
- init; \
- PREFETCH_FOR_WRITE(next); \
- GC_ASSERT(GC_size(result) >= (granules)*GC_GRANULE_BYTES); \
- GC_ASSERT((kind) == PTRFREE || ((GC_word *)result)[1] == 0); \
- out: ; \
} \
} while (0)
@@ -120,16 +131,16 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t /* lb */, int /* k */,
# define GC_MALLOC_WORDS(result,n,tiny_fl) \
do { \
size_t grans = GC_WORDS_TO_WHOLE_GRANULES(n); \
- GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, \
- NORMAL, GC_malloc(grans*GC_GRANULE_BYTES), \
+ GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, GC_I_NORMAL, \
+ GC_malloc(grans * GC_GRANULE_BYTES), \
*(void **)(result) = 0); \
} while (0)
# define GC_MALLOC_ATOMIC_WORDS(result,n,tiny_fl) \
do { \
size_t grans = GC_WORDS_TO_WHOLE_GRANULES(n); \
- GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, \
- PTRFREE, GC_malloc_atomic(grans*GC_GRANULE_BYTES), \
+ GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, GC_I_PTRFREE, \
+ GC_malloc_atomic(grans * GC_GRANULE_BYTES), \
(void)0 /* no initialization */); \
} while (0)
@@ -137,8 +148,8 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t /* lb */, int /* k */,
# define GC_CONS(result, first, second, tiny_fl) \
do { \
size_t grans = GC_WORDS_TO_WHOLE_GRANULES(2); \
- GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, \
- NORMAL, GC_malloc(grans*GC_GRANULE_BYTES), \
+ GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, GC_I_NORMAL, \
+ GC_malloc(grans * GC_GRANULE_BYTES), \
*(void **)(result) = (void *)(first)); \
((void **)(result))[1] = (void *)(second); \
} while (0)
diff --git a/include/gc_pthread_redirects.h b/include/gc_pthread_redirects.h
index f0ab25e7..0d571e91 100644
--- a/include/gc_pthread_redirects.h
+++ b/include/gc_pthread_redirects.h
@@ -30,38 +30,40 @@
/* facility in thr_keycreate. Alternatively, keep a redundant pointer */
/* to thread specific data on the thread stack. */
-#include <pthread.h>
+#ifndef GC_PTHREAD_REDIRECTS_ONLY
+# include <pthread.h>
-#ifndef GC_NO_DLOPEN
-# include <dlfcn.h>
- GC_API void *GC_dlopen(const char * /* path */, int /* mode */);
-#endif /* !GC_NO_DLOPEN */
+# ifndef GC_NO_DLOPEN
+# include <dlfcn.h>
+ GC_API void *GC_dlopen(const char * /* path */, int /* mode */);
+# endif /* !GC_NO_DLOPEN */
-#ifndef GC_NO_PTHREAD_SIGMASK
-# include <signal.h>
- GC_API int GC_pthread_sigmask(int /* how */, const sigset_t *,
- sigset_t * /* oset */);
-#endif /* !GC_NO_PTHREAD_SIGMASK */
+# ifndef GC_NO_PTHREAD_SIGMASK
+# include <signal.h>
+ GC_API int GC_pthread_sigmask(int /* how */, const sigset_t *,
+ sigset_t * /* oset */);
+# endif /* !GC_NO_PTHREAD_SIGMASK */
-#ifndef GC_PTHREAD_CREATE_CONST
- /* This is used for pthread_create() only. */
-# define GC_PTHREAD_CREATE_CONST const
-#endif
+# ifndef GC_PTHREAD_CREATE_CONST
+ /* This is used for pthread_create() only. */
+# define GC_PTHREAD_CREATE_CONST const
+# endif
-GC_API int GC_pthread_create(pthread_t *,
- GC_PTHREAD_CREATE_CONST pthread_attr_t *,
- void *(*)(void *), void * /* arg */);
-GC_API int GC_pthread_join(pthread_t, void ** /* retval */);
-GC_API int GC_pthread_detach(pthread_t);
+ GC_API int GC_pthread_create(pthread_t *,
+ GC_PTHREAD_CREATE_CONST pthread_attr_t *,
+ void *(*)(void *), void * /* arg */);
+ GC_API int GC_pthread_join(pthread_t, void ** /* retval */);
+ GC_API int GC_pthread_detach(pthread_t);
-#ifndef GC_NO_PTHREAD_CANCEL
- GC_API int GC_pthread_cancel(pthread_t);
-#endif
+# ifndef GC_NO_PTHREAD_CANCEL
+ GC_API int GC_pthread_cancel(pthread_t);
+# endif
-#if defined(GC_PTHREAD_EXIT_ATTRIBUTE) && !defined(GC_PTHREAD_EXIT_DECLARED)
-# define GC_PTHREAD_EXIT_DECLARED
- GC_API void GC_pthread_exit(void *) GC_PTHREAD_EXIT_ATTRIBUTE;
-#endif
+# if defined(GC_PTHREAD_EXIT_ATTRIBUTE) && !defined(GC_PTHREAD_EXIT_DECLARED)
+# define GC_PTHREAD_EXIT_DECLARED
+ GC_API void GC_pthread_exit(void *) GC_PTHREAD_EXIT_ATTRIBUTE;
+# endif
+#endif /* !GC_PTHREAD_REDIRECTS_ONLY */
#if !defined(GC_NO_THREAD_REDIRECTS) && !defined(GC_USE_LD_WRAP)
/* Unless the compiler supports #pragma extern_prefix, the Tru64 */
diff --git a/include/gc_version.h b/include/gc_version.h
index 5551f04e..293c4de2 100644
--- a/include/gc_version.h
+++ b/include/gc_version.h
@@ -30,7 +30,7 @@
/* it to keep the old-style build process working. */
#define GC_TMP_VERSION_MAJOR 7
#define GC_TMP_VERSION_MINOR 4
-#define GC_TMP_VERSION_MICRO 0 /* 7.4.0 */
+#define GC_TMP_VERSION_MICRO 4 /* 7.4.4 */
#ifdef GC_VERSION_MAJOR
# if GC_TMP_VERSION_MAJOR != GC_VERSION_MAJOR \
diff --git a/include/include.am b/include/include.am
index 1b2a557b..0d957341 100644
--- a/include/include.am
+++ b/include/include.am
@@ -44,6 +44,7 @@ dist_noinst_HEADERS += \
include/private/gc_pmark.h \
include/private/gc_priv.h \
include/private/gcconfig.h \
+ include/private/msvc_dbg.h \
include/private/pthread_stop_world.h \
include/private/pthread_support.h \
include/private/specific.h \
diff --git a/include/javaxfc.h b/include/javaxfc.h
index 99eaf9ad..1583a241 100644
--- a/include/javaxfc.h
+++ b/include/javaxfc.h
@@ -33,7 +33,7 @@
* must be prepared to deal with objects that have been finalized in
* spite of the fact that they are still referenced by statically
* allocated pointer variables.
- * 1) It may mean that we get stuck in an infinite loop running
+ * 2) It may mean that we get stuck in an infinite loop running
* finalizers which create new finalizable objects, though that's
* probably unlikely.
* Thus this is not recommended for general use.
diff --git a/include/leak_detector.h b/include/leak_detector.h
index 5540c227..0c27eda0 100644
--- a/include/leak_detector.h
+++ b/include/leak_detector.h
@@ -15,7 +15,7 @@
#ifndef GC_LEAK_DETECTOR_H
#define GC_LEAK_DETECTOR_H
-/* Include leak_detector.h (eg., via GCC --include directive) */
+/* Include leak_detector.h (e.g., via GCC --include directive) */
/* to turn BoehmGC into a Leak Detector. */
#ifndef GC_DEBUG
diff --git a/include/private/darwin_semaphore.h b/include/private/darwin_semaphore.h
index da97b39d..62f185d6 100644
--- a/include/private/darwin_semaphore.h
+++ b/include/private/darwin_semaphore.h
@@ -34,50 +34,47 @@ typedef struct {
} sem_t;
GC_INLINE int sem_init(sem_t *sem, int pshared, int value) {
- int ret;
- if(pshared)
- ABORT("sem_init with pshared set");
+ if (pshared != 0) {
+ errno = EPERM; /* unsupported */
+ return -1;
+ }
sem->value = value;
-
- ret = pthread_mutex_init(&sem->mutex,NULL);
- if(ret < 0) return -1;
- ret = pthread_cond_init(&sem->cond,NULL);
- if(ret < 0) return -1;
+ if (pthread_mutex_init(&sem->mutex, NULL) != 0)
+ return -1;
+ if (pthread_cond_init(&sem->cond, NULL) != 0) {
+ (void)pthread_mutex_destroy(&sem->mutex);
+ return -1;
+ }
return 0;
}
GC_INLINE int sem_post(sem_t *sem) {
- if(pthread_mutex_lock(&sem->mutex) < 0)
- return -1;
+ if (pthread_mutex_lock(&sem->mutex) != 0)
+ return -1;
sem->value++;
- if(pthread_cond_signal(&sem->cond) < 0) {
- pthread_mutex_unlock(&sem->mutex);
- return -1;
+ if (pthread_cond_signal(&sem->cond) != 0) {
+ (void)pthread_mutex_unlock(&sem->mutex);
+ return -1;
}
- if(pthread_mutex_unlock(&sem->mutex) < 0)
- return -1;
- return 0;
+ return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0;
}
GC_INLINE int sem_wait(sem_t *sem) {
- if(pthread_mutex_lock(&sem->mutex) < 0)
- return -1;
- while(sem->value == 0) {
- pthread_cond_wait(&sem->cond,&sem->mutex);
+ if (pthread_mutex_lock(&sem->mutex) != 0)
+ return -1;
+ while (sem->value == 0) {
+ if (pthread_cond_wait(&sem->cond, &sem->mutex) != 0) {
+ (void)pthread_mutex_unlock(&sem->mutex);
+ return -1;
+ }
}
sem->value--;
- if(pthread_mutex_unlock(&sem->mutex) < 0)
- return -1;
- return 0;
+ return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0;
}
GC_INLINE int sem_destroy(sem_t *sem) {
- int ret;
- ret = pthread_cond_destroy(&sem->cond);
- if(ret < 0) return -1;
- ret = pthread_mutex_destroy(&sem->mutex);
- if(ret < 0) return -1;
- return 0;
+ return pthread_cond_destroy(&sem->cond) != 0
+ || pthread_mutex_destroy(&sem->mutex) != 0 ? -1 : 0;
}
#endif
diff --git a/include/private/dbg_mlc.h b/include/private/dbg_mlc.h
index deda69c7..2ffbc5e7 100644
--- a/include/private/dbg_mlc.h
+++ b/include/private/dbg_mlc.h
@@ -157,6 +157,10 @@ typedef struct {
#endif
#if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH)
+# ifdef SHORT_DBG_HDRS
+# error Non-ptr stored in object results in GC_HAS_DEBUG_INFO malfunction
+ /* We may mistakenly conclude that p has a debugging wrapper. */
+# endif
# define GC_HAS_DEBUG_INFO(p) \
((*((word *)p) & 1) && GC_has_other_debug_info(p) > 0)
#else
diff --git a/include/private/gc_hdrs.h b/include/private/gc_hdrs.h
index 89914284..4540ac6b 100644
--- a/include/private/gc_hdrs.h
+++ b/include/private/gc_hdrs.h
@@ -18,7 +18,7 @@
typedef struct hblkhdr hdr;
#if CPP_WORDSZ != 32 && CPP_WORDSZ < 36
- --> Get a real machine.
+# error Get a real machine
#endif
/*
diff --git a/include/private/gc_locks.h b/include/private/gc_locks.h
index 257377fe..213f7529 100644
--- a/include/private/gc_locks.h
+++ b/include/private/gc_locks.h
@@ -83,19 +83,19 @@
/* structure. It also helps if comparisons don't involve a */
/* function call. Hence we introduce platform-dependent macros */
/* to compare pthread_t ids and to map them to integers. */
- /* the mapping to integers does not need to result in different */
+ /* The mapping to integers does not need to result in different */
/* integers for each thread, though that should be true as much */
/* as possible. */
- /* Refine to exclude platforms on which pthread_t is struct */
+ /* Refine to exclude platforms on which pthread_t is struct. */
# if !defined(GC_WIN32_PTHREADS)
# define NUMERIC_THREAD_ID(id) ((unsigned long)(id))
# define THREAD_EQUAL(id1, id2) ((id1) == (id2))
# define NUMERIC_THREAD_ID_UNIQUE
# else
-# define NUMERIC_THREAD_ID(id) ((unsigned long)(id.p))
- /* Using documented internal details of win32-pthread library. */
+# define NUMERIC_THREAD_ID(id) ((unsigned long)(word)(id.p))
+ /* Using documented internal details of pthreads-win32 library. */
/* Faster than pthread_equal(). Should not change with */
- /* future versions of win32-pthread library. */
+ /* future versions of pthreads-win32 library. */
# define THREAD_EQUAL(id1, id2) ((id1.p == id2.p) && (id1.x == id2.x))
# undef NUMERIC_THREAD_ID_UNIQUE
/* Generic definitions based on pthread_equal() always work but */
@@ -197,7 +197,7 @@
# define EXIT_GC() GC_collecting = 0;
GC_INNER void GC_lock(void);
-# elif defined(THREADS)
+# elif defined(THREADS) /* UNITY: Not sure why we need this */
# ifdef GC_ASSERTIONS
extern void GC_set_lock_holder(void);
extern void GC_unset_lock_holder(void);
@@ -218,7 +218,7 @@
# define UNCOND_UNLOCK() GC_unlock()
# endif /* !GC_ASSERTIONS */
-# endif /* GC_PTHREADS with linux_threads.c implementation */
+# endif /* GC_PTHREADS */
GC_EXTERN GC_bool GC_need_to_lock;
# else /* !THREADS */
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index b0a5f65c..1a1a295b 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -90,6 +90,20 @@ typedef char * ptr_t; /* A generic pointer to which we can add */
/* byte displacements and which can be used */
/* for address comparisons. */
+#ifndef SIZE_MAX
+# include <limits.h>
+#endif
+#ifdef SIZE_MAX
+# define GC_SIZE_MAX SIZE_MAX
+#else
+# define GC_SIZE_MAX (~(size_t)0)
+#endif
+
+/* Saturated addition of size_t values. Used to avoid value wrap */
+/* around on overflow. The arguments should have no side effects. */
+#define SIZET_SAT_ADD(a, b) \
+ ((a) < GC_SIZE_MAX - (b) ? (a) + (b) : GC_SIZE_MAX)
+
#ifndef GCCONFIG_H
# include "gcconfig.h"
#endif
@@ -104,7 +118,7 @@ typedef char * ptr_t; /* A generic pointer to which we can add */
/* located in the "extra" folder). */
# if defined(GC_DLL) && defined(__GNUC__) && !defined(MSWIN32) \
&& !defined(MSWINCE) && !defined(CYGWIN32)
-# if __GNUC__ >= 4
+# if (__GNUC__ >= 4) && !defined(GC_NO_VISIBILITY)
/* See the corresponding GC_API definition. */
# define GC_INNER __attribute__((__visibility__("hidden")))
# else
@@ -160,7 +174,7 @@ typedef char * ptr_t; /* A generic pointer to which we can add */
#ifndef GC_API_OSCALL
/* This is used to identify GC routines called by name from OS. */
# if defined(__GNUC__)
-# if __GNUC__ >= 4
+# if (__GNUC__ >= 4) && !defined(GC_NO_VISIBILITY)
/* Same as GC_API if GC_DLL. */
# define GC_API_OSCALL extern __attribute__((__visibility__("default")))
# else
@@ -277,9 +291,9 @@ typedef char * ptr_t; /* A generic pointer to which we can add */
# ifdef LINT2
/* Explicitly instruct the code analysis tool that */
/* GC_all_interior_pointers is assumed to have only 0 or 1 value. */
-# define EXTRA_BYTES (GC_all_interior_pointers? 1 : 0)
+# define EXTRA_BYTES ((size_t)(GC_all_interior_pointers? 1 : 0))
# else
-# define EXTRA_BYTES GC_all_interior_pointers
+# define EXTRA_BYTES (size_t)GC_all_interior_pointers
# endif
# define MAX_EXTRA_BYTES 1
#else
@@ -597,18 +611,16 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc;
# define GC_MACH_THREAD_STATE x86_THREAD_STATE64
# define GC_MACH_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT
# endif
-# else
-# if defined(ARM32)
-# define GC_THREAD_STATE_T arm_thread_state_t
-# define GC_MACH_THREAD_STATE ARM_THREAD_STATE
-# define GC_MACH_THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT
-# elif defined(AARCH64)
+# elif defined(ARM32)
+# define GC_THREAD_STATE_T arm_thread_state_t
+# define GC_MACH_THREAD_STATE ARM_THREAD_STATE
+# define GC_MACH_THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT
+# elif defined(AARCH64)
# define GC_THREAD_STATE_T arm_thread_state64_t
# define GC_MACH_THREAD_STATE ARM_THREAD_STATE64
# define GC_MACH_THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT
-# else
+# else
# error define GC_THREAD_STATE_T
-# endif
# endif
# ifndef GC_MACH_THREAD_STATE
# define GC_MACH_THREAD_STATE MACHINE_THREAD_STATE
@@ -742,7 +754,7 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc;
# elif HBLKSIZE == 16384
# define CPP_LOG_HBLKSIZE 14
# else
- --> fix HBLKSIZE
+# error fix HBLKSIZE
# endif
# undef HBLKSIZE
#endif
@@ -751,11 +763,11 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc;
# define LOG_HBLKSIZE ((size_t)CPP_LOG_HBLKSIZE)
# define HBLKSIZE ((size_t)CPP_HBLKSIZE)
+#define GC_SQRT_SIZE_MAX ((((size_t)1) << (WORDSZ / 2)) - 1)
-/* max size objects supported by freelist (larger objects are */
+/* Max size objects supported by freelist (larger objects are */
/* allocated directly with allchblk(), by rounding to the next */
-/* multiple of HBLKSIZE. */
-
+/* multiple of HBLKSIZE). */
#define CPP_MAXOBJBYTES (CPP_HBLKSIZE/2)
#define MAXOBJBYTES ((size_t)CPP_MAXOBJBYTES)
#define CPP_MAXOBJWORDS BYTES_TO_WORDS(CPP_MAXOBJBYTES)
@@ -779,9 +791,12 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc;
# define HBLKDISPL(objptr) (((size_t) (objptr)) & (HBLKSIZE-1))
+/* Round up allocation size (in bytes) to a multiple of a granule. */
+#define ROUNDUP_GRANULE_SIZE(lb) /* lb should have no side-effect */ \
+ (SIZET_SAT_ADD(lb, GRANULE_BYTES - 1) & ~(GRANULE_BYTES - 1))
/* Round up byte allocation requests to integral number of words, etc. */
-# define ROUNDED_UP_GRANULES(n) \
- BYTES_TO_GRANULES((n) + (GRANULE_BYTES - 1 + EXTRA_BYTES))
+# define ROUNDED_UP_GRANULES(lb) /* lb should have no side-effect */ \
+ BYTES_TO_GRANULES(SIZET_SAT_ADD(lb, GRANULE_BYTES - 1 + EXTRA_BYTES))
# if MAX_EXTRA_BYTES == 0
# define SMALL_OBJ(bytes) EXPECT((bytes) <= (MAXOBJBYTES), TRUE)
# else
@@ -791,7 +806,8 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc;
/* This really just tests bytes <= MAXOBJBYTES - EXTRA_BYTES. */
/* But we try to avoid looking up EXTRA_BYTES. */
# endif
-# define ADD_SLOP(bytes) ((bytes) + EXTRA_BYTES)
+# define ADD_SLOP(lb) /* lb should have no side-effect */ \
+ SIZET_SAT_ADD(lb, EXTRA_BYTES)
# ifndef MIN_WORDS
# define MIN_WORDS 2 /* FIXME: obsolete */
# endif
@@ -941,7 +957,7 @@ struct hblkhdr {
# define LARGE_INV_SZ (1 << 16)
# else
unsigned char hb_large_block;
- short * hb_map; /* Essentially a table of remainders */
+ unsigned short * hb_map; /* Essentially a table of remainders */
/* mod BYTES_TO_GRANULES(hb_sz), except */
/* for large blocks. See GC_obj_map. */
# endif
@@ -1006,9 +1022,11 @@ struct hblk {
# define HBLK_IS_FREE(hdr) (((hdr) -> hb_flags & FREE_BLK) != 0)
-# define OBJ_SZ_TO_BLOCKS(sz) divHBLKSZ((sz) + HBLKSIZE-1)
+# define OBJ_SZ_TO_BLOCKS(lb) divHBLKSZ((lb) + HBLKSIZE-1)
+# define OBJ_SZ_TO_BLOCKS_CHECKED(lb) /* lb should have no side-effect */ \
+ divHBLKSZ(SIZET_SAT_ADD(lb, HBLKSIZE - 1))
/* Size of block (in units of HBLKSIZE) needed to hold objects of */
- /* given sz (in bytes). */
+ /* given lb (in bytes). The checked variant prevents wrap around. */
/* Object free list link */
# define obj_link(p) (*(void **)(p))
@@ -1172,17 +1190,17 @@ struct _GC_arrays {
/* free list for objects */
# define GC_aobjfreelist GC_arrays._aobjfreelist
void *_aobjfreelist[MAXOBJGRANULES+1];
- /* free list for atomic objs */
+ /* free list for atomic objects */
# endif
void *_uobjfreelist[MAXOBJGRANULES+1];
- /* Uncollectible but traced objs */
- /* objects on this and auobjfreelist */
+ /* Uncollectible but traced objects. */
+ /* Objects on this and _auobjfreelist */
/* are always marked, except during */
/* garbage collections. */
# ifdef ATOMIC_UNCOLLECTABLE
# define GC_auobjfreelist GC_arrays._auobjfreelist
void *_auobjfreelist[MAXOBJGRANULES+1];
- /* Atomic uncollectible but traced objs */
+ /* Atomic uncollectible but traced objects. */
# endif
word _composite_in_use; /* Number of bytes in the accessible */
/* composite objects. */
@@ -1205,7 +1223,7 @@ struct _GC_arrays {
/* free list for immutable objects */
# ifdef MARK_BIT_PER_GRANULE
# define GC_obj_map GC_arrays._obj_map
- short * _obj_map[MAXOBJGRANULES+1];
+ unsigned short * _obj_map[MAXOBJGRANULES + 1];
/* If not NULL, then a pointer to a map of valid */
/* object addresses. */
/* _obj_map[sz_in_granules][i] is */
@@ -1335,13 +1353,13 @@ GC_API_PRIV GC_FAR struct _GC_arrays GC_arrays;
#define MAXOBJKINDS 16
GC_EXTERN struct obj_kind {
- void **ok_freelist; /* Array of free listheaders for this kind of object */
- /* Point either to GC_arrays or to storage allocated */
- /* with GC_scratch_alloc. */
+ void **ok_freelist; /* Array of free list headers for this kind of */
+ /* object. Point either to GC_arrays or to */
+ /* storage allocated with GC_scratch_alloc. */
struct hblk **ok_reclaim_list;
- /* List headers for lists of blocks waiting to be */
- /* swept. */
- /* Indexed by object size in granules. */
+ /* List headers for lists of blocks waiting to */
+ /* be swept. Indexed by object size in */
+ /* granules. */
word ok_descriptor; /* Descriptor template for objects in this */
/* block. */
GC_bool ok_relocate_descr;
@@ -1382,7 +1400,7 @@ GC_EXTERN struct obj_kind {
# define endGC_objfreelist (beginGC_objfreelist + sizeof(GC_objfreelist))
extern ptr_t GC_aobjfreelist[MAXOBJGRANULES+1];
- /* free list for atomic (PTRFREE) objs */
+ /* free list for atomic (PTRFREE) objects */
# define beginGC_aobjfreelist ((ptr_t)(&GC_aobjfreelist))
# define endGC_aobjfreelist (beginGC_aobjfreelist + sizeof(GC_aobjfreelist))
#endif /* SEPARATE_GLOBALS */
@@ -1410,7 +1428,19 @@ GC_EXTERN word GC_n_heap_sects; /* Number of separately added heap */
/* sections. */
#endif
-GC_EXTERN word GC_page_size;
+GC_EXTERN size_t GC_page_size;
+
+/* Round up allocation size to a multiple of a page size. */
+/* GC_setpagesize() is assumed to be already invoked. */
+#define ROUNDUP_PAGESIZE(lb) /* lb should have no side-effect */ \
+ (SIZET_SAT_ADD(lb, GC_page_size - 1) & ~(GC_page_size - 1))
+
+/* Same as above but used to make GET_MEM() argument safe. */
+#ifdef MMAP_SUPPORTED
+# define ROUNDUP_PAGESIZE_IF_MMAP(lb) ROUNDUP_PAGESIZE(lb)
+#else
+# define ROUNDUP_PAGESIZE_IF_MMAP(lb) (lb)
+#endif
#if (defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)) && !defined(_XBOX_ONE)
struct _SYSTEM_INFO;
@@ -1620,7 +1650,7 @@ GC_EXTERN void (*GC_push_typed_structures)(void);
/* the typed allocation support if unused. */
GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
- ptr_t arg);
+ volatile ptr_t arg);
#if defined(SPARC) || defined(IA64)
/* Cause all stacked registers to be saved in memory. Return a */
@@ -1832,12 +1862,15 @@ GC_INNER void GC_collect_a_little_inner(int n);
GC_INNER void * GC_generic_malloc_inner(size_t lb, int k);
/* Allocate an object of the given */
/* kind but assuming lock already held. */
-GC_INNER void * GC_generic_malloc_inner_ignore_off_page(size_t lb, int k);
+#if defined(DBG_HDRS_ALL) || defined(GC_GCJ_SUPPORT) \
+ || !defined(GC_NO_FINALIZATION)
+ GC_INNER void * GC_generic_malloc_inner_ignore_off_page(size_t lb, int k);
/* Allocate an object, where */
/* the client guarantees that there */
/* will always be a pointer to the */
/* beginning of the object while the */
/* object is live. */
+#endif
GC_INNER ptr_t GC_allocobj(size_t sz, int kind);
/* Make the indicated */
@@ -2336,6 +2369,14 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str,
# define GC_STATIC_ASSERT(expr) (void)sizeof(char[(expr)? 1 : -1])
#endif
+/* Runtime check for an argument declared as non-null is actually not null. */
+#if defined(__GNUC__) && __GNUC__ >= 4
+ /* Workaround tautological-pointer-compare Clang warning. */
+# define NONNULL_ARG_NOT_NULL(arg) (*(volatile void **)&(arg) != NULL)
+#else
+# define NONNULL_ARG_NOT_NULL(arg) (NULL != (arg))
+#endif
+
#define COND_DUMP_CHECKS \
do { \
GC_ASSERT(GC_compute_large_free_bytes() == GC_large_free_bytes); \
@@ -2372,6 +2413,7 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str,
/* GC_notify_all_builder() is called when GC_fl_builder_count */
/* reaches 0. */
+ GC_INNER void GC_wait_for_markers_init(void);
GC_INNER void GC_acquire_mark_lock(void);
GC_INNER void GC_release_mark_lock(void);
GC_INNER void GC_notify_all_builder(void);
@@ -2391,14 +2433,15 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str,
#endif /* PARALLEL_MARK */
#if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS) && !defined(NACL) \
- && !defined(SIG_SUSPEND)
+ && !defined(GC_DARWIN_THREADS) && !defined(SIG_SUSPEND)
/* We define the thread suspension signal here, so that we can refer */
/* to it in the dirty bit implementation, if necessary. Ideally we */
/* would allocate a (real-time?) signal using the standard mechanism. */
/* unfortunately, there is no standard mechanism. (There is one */
/* in Linux glibc, but it's not exported.) Thus we continue to use */
/* the same hard-coded signals we've always used. */
-# if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS)
+# if (defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS)) \
+ && !defined(GC_USESIGRT_SIGNALS)
# if defined(SPARC) && !defined(SIGPWR)
/* SPARC/Linux doesn't properly define SIGPWR in <signal.h>. */
/* It is aliased to SIGLOST in asm/signal.h, though. */
@@ -2411,12 +2454,10 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str,
# ifndef GC_OPENBSD_UTHREADS
# define SIG_SUSPEND SIGXFSZ
# endif
-# elif !defined(GC_DARWIN_THREADS)
-# if defined(_SIGRTMIN)
-# define SIG_SUSPEND _SIGRTMIN + 6
-# else
-# define SIG_SUSPEND SIGRTMIN + 6
-# endif
+# elif defined(_SIGRTMIN)
+# define SIG_SUSPEND _SIGRTMIN + 6
+# else
+# define SIG_SUSPEND SIGRTMIN + 6
# endif
#endif /* GC_PTHREADS && !SIG_SUSPEND */
@@ -2486,7 +2527,7 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str,
#if defined(NEED_FIND_LIMIT) \
|| (defined(USE_PROC_FOR_LIBRARIES) && defined(THREADS))
- JMP_BUF GC_jmp_buf;
+ GC_EXTERN JMP_BUF GC_jmp_buf;
/* Set up a handler for address faults which will longjmp to */
/* GC_jmp_buf; */
diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h
index c1e9a5c1..a6830263 100644
--- a/include/private/gcconfig.h
+++ b/include/private/gcconfig.h
@@ -203,12 +203,12 @@
# define SEQUENT
# define mach_type_known
# endif
-# if defined(sun) && (defined(i386) || defined(__i386__))
+# if (defined(sun) || defined(__sun)) && (defined(i386) || defined(__i386__))
# define I386
# define SOLARIS
# define mach_type_known
# endif
-# if defined(sun) && defined(__amd64)
+# if (defined(sun) || defined(__sun)) && defined(__amd64)
# define X86_64
# define SOLARIS
# define mach_type_known
@@ -221,16 +221,15 @@
# if defined(ibm032)
# error IBM PC/RT no longer supported.
# endif
-# if defined(sun) && (defined(sparc) || defined(__sparc))
+# if (defined(sun) || defined(__sun)) && (defined(sparc) || defined(__sparc))
# define SPARC
/* Test for SunOS 5.x */
-# include <errno.h>
-# define SOLARIS
+# include <errno.h>
+# define SOLARIS
# define mach_type_known
-# endif
-# if defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \
- && !defined(__OpenBSD__) && !defined(__NetBSD__) \
- && !defined(__FreeBSD__) && !defined(__DragonFly__)
+# elif defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \
+ && !defined(__OpenBSD__) && !defined(__NetBSD__) \
+ && !defined(__FreeBSD__) && !defined(__DragonFly__)
# define SPARC
# define DRSNX
# define mach_type_known
@@ -504,7 +503,11 @@
# define mach_type_known
# endif
# if defined(__CYGWIN32__) || defined(__CYGWIN__)
-# define I386
+# if defined(__LP64__)
+# define X86_64
+# else
+# define I386
+# endif
# define CYGWIN32
# define mach_type_known
# endif
@@ -699,7 +702,7 @@
* LINUX_STACKBOTTOM
* HEURISTIC1
* HEURISTIC2
- * If STACKBOTTOM is defined, then it's value will be used directly as the
+ * If STACKBOTTOM is defined, then its value will be used directly as the
* stack base. If LINUX_STACKBOTTOM is defined, then it will be determined
* with a method appropriate for most Linux systems. Currently we look
* first for __libc_stack_end (currently only if USE_LIBC_PRIVATES is
@@ -740,7 +743,7 @@
* the original main program. The new main program would read something
* like (provided real_main() is not inlined by the compiler):
*
- * # include "gc_private.h"
+ * #include "gc.h"
*
* main(argc, argv, envp)
* int argc;
@@ -768,7 +771,7 @@
* An architecture may define PREFETCH(x) to preload the cache with *x.
* This defaults to GCC built-in operation (or a no-op for other compilers).
*
- * PREFETCH_FOR_WRITE(x) is used if *x is about to be written.
+ * GC_PREFETCH_FOR_WRITE(x) is used if *x is about to be written.
*
* An architecture may also define CLEAR_DOUBLE(x) to be a fast way to
* clear the two words at GC_malloc-aligned address x. By default,
@@ -783,6 +786,7 @@
# if defined(__GNUC__) && ((__GNUC__ >= 3) \
|| (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) \
&& !defined(__INTEL_COMPILER) && !defined(__PATHCC__) \
+ && !defined(__FUJITSU) /* for FX10 system */ \
&& !(defined(POWERPC) && defined(DARWIN)) /* for MacOS X 10.3.9 */ \
&& !defined(RTEMS) \
&& !defined(__clang__) /* since no-op in clang (3.0) */ \
@@ -918,7 +922,14 @@
# define OS_TYPE "LINUX"
/* HEURISTIC1 has been reliably reported to fail for a 32-bit */
/* executable on a 64 bit kernel. */
-# define LINUX_STACKBOTTOM
+# if defined(__bg__)
+ /* The Linux Compute Node Kernel (used on BlueGene systems) */
+ /* does not support LINUX_STACKBOTTOM way. */
+# define HEURISTIC2
+# define NO_PTHREAD_GETATTR_NP
+# else
+# define LINUX_STACKBOTTOM
+# endif
# define DYNAMIC_LOADING
# define SEARCH_FOR_DATA_START
extern int _end[];
@@ -949,12 +960,12 @@
# define USE_MMAP_ANON
# define MPROTECT_VDB
# include <unistd.h>
-# define GETPAGESIZE() getpagesize()
+# define GETPAGESIZE() (unsigned)getpagesize()
# if defined(USE_PPC_PREFETCH) && defined(__GNUC__)
/* The performance impact of prefetches is untested */
# define PREFETCH(x) \
__asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
-# define PREFETCH_FOR_WRITE(x) \
+# define GC_PREFETCH_FOR_WRITE(x) \
__asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
# endif
/* There seems to be some issues with trylock hanging on darwin. */
@@ -1130,7 +1141,7 @@
# define HEURISTIC2
# endif
# include <unistd.h>
-# define GETPAGESIZE() sysconf(_SC_PAGESIZE)
+# define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
/* getpagesize() appeared to be missing from at least one */
/* Solaris 5.4 installation. Weird. */
# define DYNAMIC_LOADING
@@ -1231,7 +1242,7 @@
# ifdef BEOS
# define OS_TYPE "BEOS"
# include <OS.h>
-# define GETPAGESIZE() B_PAGE_SIZE
+# define GETPAGESIZE() (unsigned)B_PAGE_SIZE
extern int etext[];
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
# endif
@@ -1247,8 +1258,16 @@
/* base is a property of the executable, so this should not break */
/* old executables. */
/* HEURISTIC2 probably works, but this appears to be preferable. */
-# include <sys/vm.h>
-# define STACKBOTTOM ((ptr_t) USRSTACK)
+/* Apparently USRSTACK is defined to be USERLIMIT, but in some */
+/* installations that's undefined. We work around this with a */
+/* gross hack: */
+# include <sys/vmparam.h>
+# ifdef USERLIMIT
+ /* This should work everywhere, but doesn't. */
+# define STACKBOTTOM ((ptr_t)USRSTACK)
+# else
+# define HEURISTIC2
+# endif
/* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
/* It appears to be fixed in 2.8 and 2.9. */
# ifdef SOLARIS25_PROC_VDB_BUG_FIXED
@@ -1297,7 +1316,7 @@
# define STACK_GROWS_DOWN
# define HEURISTIC2
# include <unistd.h>
-# define GETPAGESIZE() sysconf(_SC_PAGESIZE)
+# define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
# define DYNAMIC_LOADING
# ifndef USE_MMAP
# define USE_MMAP
@@ -1392,7 +1411,7 @@
# ifdef FORCE_WRITE_PREFETCH
/* Using prefetches for write seems to have a slight negative */
/* impact on performance, at least for a PIII/500. */
-# define PREFETCH_FOR_WRITE(x) \
+# define GC_PREFETCH_FOR_WRITE(x) \
__asm__ __volatile__ ("prefetcht0 %0" : : "m"(*(char *)(x)))
# else
# define NO_PREFETCH_FOR_WRITE
@@ -1400,9 +1419,14 @@
# elif defined(USE_3DNOW_PREFETCH)
# define PREFETCH(x) \
__asm__ __volatile__ ("prefetch %0" : : "m"(*(char *)(x)))
-# define PREFETCH_FOR_WRITE(x) \
+# define GC_PREFETCH_FOR_WRITE(x) \
__asm__ __volatile__ ("prefetchw %0" : : "m"(*(char *)(x)))
# endif
+# if defined(__GLIBC__)
+ /* Workaround lock elision implementation for some glibc. */
+# define GLIBC_2_19_TSX_BUG
+# include <gnu/libc-version.h> /* for gnu_get_libc_version() */
+# endif
# endif
# ifdef CYGWIN32
# define OS_TYPE "CYGWIN32"
@@ -1545,6 +1569,10 @@
# define DATAEND ((ptr_t) (_end))
/* # define MPROTECT_VDB Not quite working yet? */
# define DYNAMIC_LOADING
+# ifndef USE_MMAP
+# define USE_MMAP
+# endif
+# define USE_MMAP_ANON
# endif
# ifdef DARWIN
# define OS_TYPE "DARWIN"
@@ -1561,7 +1589,7 @@
# define USE_MMAP_ANON
# define MPROTECT_VDB
# include <unistd.h>
-# define GETPAGESIZE() getpagesize()
+# define GETPAGESIZE() (unsigned)getpagesize()
/* There seems to be some issues with trylock hanging on darwin. */
/* This should be looked into some more. */
# define NO_PTHREAD_TRYLOCK
@@ -1740,7 +1768,7 @@
# endif
# define DYNAMIC_LOADING
# include <unistd.h>
-# define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
+# define GETPAGESIZE() (unsigned)sysconf(_SC_PAGE_SIZE)
# ifndef __GNUC__
# define PREFETCH(x) do { \
register long addr = (long)(x); \
@@ -1887,7 +1915,7 @@
# define HPUX_STACKBOTTOM
# define DYNAMIC_LOADING
# include <unistd.h>
-# define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
+# define GETPAGESIZE() (unsigned)sysconf(_SC_PAGE_SIZE)
/* The following was empirically determined, and is probably */
/* not very robust. */
/* Note that the backing store base seems to be at a nice */
@@ -1930,18 +1958,29 @@
# ifndef __INTEL_COMPILER
# define PREFETCH(x) \
__asm__ (" lfetch [%0]": : "r"(x))
-# define PREFETCH_FOR_WRITE(x) \
+# define GC_PREFETCH_FOR_WRITE(x) \
__asm__ (" lfetch.excl [%0]": : "r"(x))
# define CLEAR_DOUBLE(x) \
__asm__ (" stf.spill [%0]=f0": : "r"((void *)(x)))
# else
# include <ia64intrin.h>
# define PREFETCH(x) __lfetch(__lfhint_none, (x))
-# define PREFETCH_FOR_WRITE(x) __lfetch(__lfhint_nta, (x))
+# define GC_PREFETCH_FOR_WRITE(x) __lfetch(__lfhint_nta, (x))
# define CLEAR_DOUBLE(x) __stf_spill((void *)(x), 0)
# endif /* __INTEL_COMPILER */
# endif
# endif
+# ifdef CYGWIN32
+# define OS_TYPE "CYGWIN32"
+# define DATASTART ((ptr_t)GC_DATASTART) /* From gc.h */
+# define DATAEND ((ptr_t)GC_DATAEND)
+# undef STACK_GRAN
+# define STACK_GRAN 0x10000
+# ifdef USE_MMAP
+# define NEED_FIND_LIMIT
+# define USE_MMAP_ANON
+# endif
+# endif
# ifdef MSWIN32
/* FIXME: This is a very partial guess. There is no port, yet. */
# define OS_TYPE "MSWIN32"
@@ -2140,7 +2179,7 @@
# define USE_MMAP_ANON
# define MPROTECT_VDB
# include <unistd.h>
-# define GETPAGESIZE() getpagesize()
+# define GETPAGESIZE() (unsigned)getpagesize()
/* FIXME: There seems to be some issues with trylock hanging on */
/* darwin. This should be looked into some more. */
# define NO_PTHREAD_TRYLOCK
@@ -2365,13 +2404,18 @@
extern int etext[];
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
# endif
-# if defined(__GLIBC__)
+# if defined(__GLIBC__) && !defined(__UCLIBC__)
/* At present, there's a bug in GLibc getcontext() on */
/* Linux/x64 (it clears FPU exception mask). We define this */
/* macro to workaround it. */
/* FIXME: This seems to be fixed in GLibc v2.14. */
# define GETCONTEXT_FPU_EXCMASK_BUG
# endif
+# if defined(__GLIBC__)
+ /* Workaround lock elision implementation for some glibc. */
+# define GLIBC_2_19_TSX_BUG
+# include <gnu/libc-version.h> /* for gnu_get_libc_version() */
+# endif
# endif
# ifdef DARWIN
# define OS_TYPE "DARWIN"
@@ -2388,7 +2432,7 @@
# define USE_MMAP_ANON
# define MPROTECT_VDB
# include <unistd.h>
-# define GETPAGESIZE() getpagesize()
+# define GETPAGESIZE() (unsigned)getpagesize()
/* There seems to be some issues with trylock hanging on darwin. */
/* This should be looked into some more. */
# define NO_PTHREAD_TRYLOCK
@@ -2580,6 +2624,16 @@
# define DATAEND (ptr_t)(end)
#endif
+/* Workaround for Android NDK clang 3.5+ (as of NDK r10e) which does */
+/* not provide correct _end symbol. Unfortunately, alternate __end__ */
+/* symbol is provided only by NDK "bfd" linker. */
+#if defined(PLATFORM_ANDROID) && defined(__clang__)
+# undef DATAEND
+# pragma weak __end__
+ extern int __end__[];
+# define DATAEND (__end__ != 0 ? (ptr_t)__end__ : (ptr_t)_end)
+#endif
+
#if defined(PLATFORM_ANDROID) && !defined(THREADS) \
&& !defined(USE_GET_STACKBASE_FOR_MAIN)
/* Always use pthread_attr_getstack on Android ("-lpthread" option is */
@@ -2590,7 +2644,7 @@
#if (defined(SVR4) || defined(PLATFORM_ANDROID) || defined(PLATFORM_TIZEN)) && !defined(GETPAGESIZE)
# include <unistd.h>
-# define GETPAGESIZE() sysconf(_SC_PAGESIZE)
+# define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
#endif
#ifndef GETPAGESIZE
@@ -2598,7 +2652,7 @@
|| defined(NETBSD) || defined(FREEBSD) || defined(HPUX)
# include <unistd.h>
# endif
-# define GETPAGESIZE() getpagesize()
+# define GETPAGESIZE() (unsigned)getpagesize()
#endif
#if defined(SOLARIS) || defined(DRSNX) || defined(UTS4)
@@ -2690,6 +2744,11 @@
# undef USE_MMAP
#endif
+#if defined(LINUX) || defined(FREEBSD) || defined(SOLARIS) || defined(IRIX5) \
+ || ((defined(USE_MMAP) || defined(USE_MUNMAP)) && !defined(USE_WINALLOC))
+# define MMAP_SUPPORTED
+#endif
+
#if defined(GC_DISABLE_INCREMENTAL) || defined(MANUAL_VDB)
# undef GWW_VDB
# undef MPROTECT_VDB
@@ -2748,11 +2807,11 @@
# endif
#endif
-#ifndef PREFETCH_FOR_WRITE
+#ifndef GC_PREFETCH_FOR_WRITE
# if defined(__GNUC__) && __GNUC__ >= 3 && !defined(NO_PREFETCH_FOR_WRITE)
-# define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
+# define GC_PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
# else
-# define PREFETCH_FOR_WRITE(x) (void)0
+# define GC_PREFETCH_FOR_WRITE(x) (void)0
# endif
#endif
@@ -3024,52 +3083,60 @@
/* usually makes it possible to merge consecutively allocated */
/* chunks. It also avoids unintended recursion with */
/* REDIRECT_MALLOC macro defined. */
- /* GET_MEM() returns a HLKSIZE aligned chunk. */
+ /* GET_MEM() argument should be of size_t type and have */
+ /* no side-effect. GET_MEM() returns HLKSIZE-aligned chunk; */
/* 0 is taken to mean failure. */
- /* In the case os USE_MMAP, the argument must also be a */
- /* physical page size. */
+ /* In case of MMAP_SUPPORTED, the argument must also be */
+ /* a multiple of a physical page size. */
/* GET_MEM is currently not assumed to retrieve 0 filled space, */
/* though we should perhaps take advantage of the case in which */
/* does. */
struct hblk; /* See gc_priv.h. */
# if defined(PCR)
char * real_malloc(size_t bytes);
-# define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)(bytes) + GC_page_size) \
+# define GET_MEM(bytes) HBLKPTR(real_malloc(SIZET_SAT_ADD(bytes, \
+ GC_page_size)) \
+ GC_page_size-1)
# elif defined(OS2)
void * os2_alloc(size_t bytes);
-# define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)(bytes) \
- + GC_page_size) + GC_page_size-1)
+# define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc( \
+ SIZET_SAT_ADD(bytes, \
+ GC_page_size)) \
+ + GC_page_size-1)
# elif defined(NEXT) || defined(DOS4GW) || defined(NONSTOP) \
|| (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) \
|| (defined(SOLARIS) && !defined(USE_MMAP)) || defined(RTEMS) \
|| defined(__CC_ARM)
# define GET_MEM(bytes) HBLKPTR((size_t)calloc(1, \
- (size_t)(bytes) + GC_page_size) \
+ SIZET_SAT_ADD(bytes, \
+ GC_page_size)) \
+ GC_page_size - 1)
# elif defined(_XBOX_ONE)
extern void* durango_get_mem (size_t size, size_t page_size);
# define GET_MEM(bytes) (struct hblk *)durango_get_mem(bytes, 0)
# elif defined(MSWIN32) || defined(CYGWIN32)
- ptr_t GC_win32_get_mem(GC_word bytes);
+ ptr_t GC_win32_get_mem(size_t bytes);
# define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
# elif defined(MACOS)
# if defined(USE_TEMPORARY_MEMORY)
Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory);
-# define GET_MEM(bytes) HBLKPTR( \
- GC_MacTemporaryNewPtr((bytes) + GC_page_size, true) \
+# define GET_MEM(bytes) HBLKPTR(GC_MacTemporaryNewPtr( \
+ SIZET_SAT_ADD(bytes, \
+ GC_page_size), true) \
+ GC_page_size-1)
# else
-# define GET_MEM(bytes) HBLKPTR(NewPtrClear((bytes) + GC_page_size) \
+# define GET_MEM(bytes) HBLKPTR(NewPtrClear(SIZET_SAT_ADD(bytes, \
+ GC_page_size)) \
+ GC_page_size-1)
# endif
# elif defined(MSWINCE)
- ptr_t GC_wince_get_mem(GC_word bytes);
+ ptr_t GC_wince_get_mem(size_t bytes);
# define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
# elif defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
- void *GC_amiga_get_mem(size_t size);
-# define GET_MEM(bytes) HBLKPTR((size_t) \
- GC_amiga_get_mem((size_t)(bytes) + GC_page_size) \
+ void *GC_amiga_get_mem(size_t bytes);
+# define GET_MEM(bytes) HBLKPTR((size_t)GC_amiga_get_mem( \
+ SIZET_SAT_ADD(bytes, \
+ GC_page_size)) \
+ GC_page_size-1)
# elif defined(SN_TARGET_PS3)
void *ps3_get_mem(size_t size);
@@ -3087,7 +3154,7 @@
extern void *switch_get_mem (size_t size);
# define GET_MEM(bytes) (struct hblk*) switch_get_mem (bytes)
# else
- ptr_t GC_unix_get_mem(GC_word bytes);
+ ptr_t GC_unix_get_mem(size_t bytes);
# define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
# endif
diff --git a/include/private/thread_local_alloc.h b/include/private/thread_local_alloc.h
index 82fe2987..fff625d3 100644
--- a/include/private/thread_local_alloc.h
+++ b/include/private/thread_local_alloc.h
@@ -82,7 +82,7 @@ typedef struct thread_local_freelists {
# ifdef GC_GCJ_SUPPORT
void * gcj_freelists[TINY_FREELISTS];
# define ERROR_FL ((void *)(word)-1)
- /* Value used for gcj_freelist[-1]; allocation is */
+ /* Value used for gcj_freelists[-1]; allocation is */
/* erroneous. */
# endif
# ifdef ENABLE_DISCLAIM
diff --git a/mach_dep.c b/mach_dep.c
index b5d9515e..86e38f6e 100644
--- a/mach_dep.c
+++ b/mach_dep.c
@@ -219,17 +219,18 @@
/* are somewhere on the stack, and then call fn(arg, ctxt). */
/* ctxt is either a pointer to a ucontext_t we generated, or NULL. */
GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
- ptr_t arg)
+ volatile ptr_t arg)
{
- volatile int dummy;
- void * context = 0;
-
-# if defined(HAVE_PUSH_REGS)
- GC_push_regs();
-# elif defined(UNIX_LIKE) && !defined(NO_GETCONTEXT)
- /* Older versions of Darwin seem to lack getcontext(). */
- /* ARM and MIPS Linux often doesn't support a real */
- /* getcontext(). */
+ volatile int dummy;
+ void * context = 0;
+
+# if defined(HAVE_PUSH_REGS)
+ GC_push_regs();
+# else
+# if defined(UNIX_LIKE) && !defined(NO_GETCONTEXT)
+ /* Older versions of Darwin seem to lack getcontext(). */
+ /* ARM and MIPS Linux often doesn't support a real */
+ /* getcontext(). */
ucontext_t ctxt;
# ifdef GETCONTEXT_FPU_EXCMASK_BUG
/* Workaround a bug (clearing the FPU exception mask) in */
@@ -238,13 +239,20 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
/* We manipulate FPU control word here just not to force the */
/* client application to use -lm linker option. */
unsigned short old_fcw;
+
__asm__ __volatile__ ("fstcw %0" : "=m" (*&old_fcw));
# else
int except_mask = fegetexcept();
# endif
# endif
- if (getcontext(&ctxt) < 0)
- ABORT ("getcontext failed: Use another register retrieval method?");
+
+ if (getcontext(&ctxt) < 0) {
+ WARN("getcontext failed:"
+ " using another register retrieval method...\n", 0);
+ /* E.g., to workaround a bug in Docker ubuntu_32bit. */
+ } else {
+ context = &ctxt;
+ }
# ifdef GETCONTEXT_FPU_EXCMASK_BUG
# ifdef X86_64
__asm__ __volatile__ ("fldcw %0" : : "m" (*&old_fcw));
@@ -260,21 +268,22 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
if (feenableexcept(except_mask) < 0)
ABORT("feenableexcept failed");
# endif
-# endif
- context = &ctxt;
+# endif /* GETCONTEXT_FPU_EXCMASK_BUG */
# if defined(SPARC) || defined(IA64)
/* On a register window machine, we need to save register */
/* contents on the stack for this to work. This may already be */
/* subsumed by the getcontext() call. */
GC_save_regs_ret_val = GC_save_regs_in_stack();
-# endif /* register windows. */
-# elif defined(HAVE_BUILTIN_UNWIND_INIT)
- /* This was suggested by Richard Henderson as the way to */
- /* force callee-save registers and register windows onto */
- /* the stack. */
- __builtin_unwind_init();
-# else /* !HAVE_BUILTIN_UNWIND_INIT && !UNIX_LIKE */
- /* && !HAVE_PUSH_REGS */
+# endif
+ if (NULL == context) /* getcontext failed */
+# endif /* !NO_GETCONTEXT */
+ {
+# if defined(HAVE_BUILTIN_UNWIND_INIT)
+ /* This was suggested by Richard Henderson as the way to */
+ /* force callee-save registers and register windows onto */
+ /* the stack. */
+ __builtin_unwind_init();
+# else
/* Generic code */
/* The idea is due to Parag Patel at HP. */
/* We're not sure whether he would like */
@@ -298,14 +307,16 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
/* SUSV3, setjmp() may or may not save signal mask. */
/* _setjmp won't, but is less portable. */
# endif
-# endif /* !HAVE_PUSH_REGS ... */
- /* FIXME: context here is sometimes just zero. At the moment the */
- /* callees don't really need it. */
- fn(arg, context);
- /* Strongly discourage the compiler from treating the above */
- /* as a tail-call, since that would pop the register */
- /* contents before we get a chance to look at them. */
- GC_noop1((word)(&dummy));
+# endif /* !HAVE_BUILTIN_UNWIND_INIT */
+ }
+# endif /* !HAVE_PUSH_REGS */
+ /* FIXME: context here is sometimes just zero. At the moment the */
+ /* callees don't really need it. */
+ fn(arg, context);
+ /* Strongly discourage the compiler from treating the above */
+ /* as a tail-call, since that would pop the register */
+ /* contents before we get a chance to look at them. */
+ GC_noop1((word)(&dummy));
}
#if defined(ASM_CLEAR_CODE)
diff --git a/malloc.c b/malloc.c
index 4983cdfe..5c378de3 100644
--- a/malloc.c
+++ b/malloc.c
@@ -46,9 +46,8 @@ GC_INNER ptr_t GC_alloc_large(size_t lb, int k, unsigned flags)
ptr_t result;
GC_bool retry = FALSE;
- /* Round up to a multiple of a granule. */
- lb = (lb + GRANULE_BYTES - 1) & ~(GRANULE_BYTES - 1);
- n_blocks = OBJ_SZ_TO_BLOCKS(lb);
+ lb = ROUNDUP_GRANULE_SIZE(lb);
+ n_blocks = OBJ_SZ_TO_BLOCKS_CHECKED(lb);
if (!EXPECT(GC_is_initialized, TRUE)) GC_init();
/* Do our share of marking work */
if (GC_incremental && !GC_dont_gc)
@@ -85,10 +84,11 @@ GC_INNER ptr_t GC_alloc_large(size_t lb, int k, unsigned flags)
STATIC ptr_t GC_alloc_large_and_clear(size_t lb, int k, unsigned flags)
{
ptr_t result = GC_alloc_large(lb, k, flags);
- word n_blocks = OBJ_SZ_TO_BLOCKS(lb);
if (0 == result) return 0;
if (GC_debugging_started || GC_obj_kinds[k].ok_init) {
+ word n_blocks = OBJ_SZ_TO_BLOCKS(lb);
+
/* Clear the whole block, in case of GC_realloc call. */
BZERO(result, n_blocks * HBLKSIZE);
}
@@ -140,17 +140,19 @@ GC_INNER void * GC_generic_malloc_inner(size_t lb, int k)
GC_bytes_allocd += GRANULES_TO_BYTES(lg);
} else {
op = (ptr_t)GC_alloc_large_and_clear(ADD_SLOP(lb), k, 0);
- GC_bytes_allocd += lb;
+ if (op != NULL)
+ GC_bytes_allocd += lb;
}
return op;
}
-/* Allocate a composite object of size n bytes. The caller guarantees */
-/* that pointers past the first page are not relevant. Caller holds */
-/* allocation lock. */
-GC_INNER void * GC_generic_malloc_inner_ignore_off_page(size_t lb, int k)
-{
+#if defined(DBG_HDRS_ALL) || defined(GC_GCJ_SUPPORT) \
+ || !defined(GC_NO_FINALIZATION)
+ /* Allocate a composite object of size n bytes. The caller */
+ /* guarantees that pointers past the first page are not relevant. */
+ GC_INNER void * GC_generic_malloc_inner_ignore_off_page(size_t lb, int k)
+ {
word lb_adjusted;
void * op;
@@ -158,9 +160,11 @@ GC_INNER void * GC_generic_malloc_inner_ignore_off_page(size_t lb, int k)
return(GC_generic_malloc_inner(lb, k));
lb_adjusted = ADD_SLOP(lb);
op = GC_alloc_large_and_clear(lb_adjusted, k, IGNORE_OFF_PAGE);
- GC_bytes_allocd += lb_adjusted;
+ if (op != NULL)
+ GC_bytes_allocd += lb_adjusted;
return op;
-}
+ }
+#endif
#ifdef GC_COLLECT_AT_MALLOC
/* Parameter to force GC at every malloc of size greater or equal to */
@@ -168,7 +172,7 @@ GC_INNER void * GC_generic_malloc_inner_ignore_off_page(size_t lb, int k)
size_t GC_dbg_collect_at_malloc_min_lb = (GC_COLLECT_AT_MALLOC);
#endif
-GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_malloc(size_t lb, int k)
{
void * result;
DCL_LOCK_STATE;
@@ -189,8 +193,6 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
lg = ROUNDED_UP_GRANULES(lb);
lb_rounded = GRANULES_TO_BYTES(lg);
- if (lb_rounded < lb)
- return((*GC_get_oom_fn())(lb));
n_blocks = OBJ_SZ_TO_BLOCKS(lb_rounded);
init = GC_obj_kinds[k].ok_init;
LOCK();
@@ -208,8 +210,8 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
((word *)result)[GRANULES_TO_WORDS(lg)-2] = 0;
# endif
}
+ GC_bytes_allocd += lb_rounded;
}
- GC_bytes_allocd += lb_rounded;
UNLOCK();
if (init && !GC_debugging_started && 0 != result) {
BZERO(result, n_blocks * HBLKSIZE);
@@ -226,7 +228,7 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
#ifdef THREAD_LOCAL_ALLOC
GC_INNER void * GC_core_malloc_atomic(size_t lb)
#else
- GC_API void * GC_CALL GC_malloc_atomic(size_t lb)
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_atomic(size_t lb)
#endif
{
void *op;
@@ -256,7 +258,7 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
#ifdef THREAD_LOCAL_ALLOC
GC_INNER void * GC_core_malloc(size_t lb)
#else
- GC_API void * GC_CALL GC_malloc(size_t lb)
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc(size_t lb)
#endif
{
void *op;
@@ -289,7 +291,7 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
}
/* Allocate lb bytes of pointerful, traced, but not collectible data. */
-GC_API void * GC_CALL GC_malloc_uncollectable(size_t lb)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_uncollectable(size_t lb)
{
void *op;
void **opp;
@@ -309,7 +311,7 @@ GC_API void * GC_CALL GC_malloc_uncollectable(size_t lb)
*opp = obj_link(op);
obj_link(op) = 0;
GC_bytes_allocd += GRANULES_TO_BYTES(lg);
- /* Mark bit ws already set on free list. It will be */
+ /* Mark bit was already set on free list. It will be */
/* cleared only temporarily during a collection, as a */
/* result of the normal free list mark bit clearing. */
GC_non_gc_bytes += GRANULES_TO_BYTES(lg);
@@ -380,7 +382,10 @@ void * malloc(size_t lb)
STATIC void GC_init_lib_bounds(void)
{
+ IF_CANCEL(int cancel_state;)
+
if (GC_libpthread_start != 0) return;
+ DISABLE_CANCEL(cancel_state);
GC_init(); /* if not called yet */
if (!GC_text_mapping("libpthread-",
&GC_libpthread_start, &GC_libpthread_end)) {
@@ -393,23 +398,15 @@ void * malloc(size_t lb)
if (!GC_text_mapping("ld-", &GC_libld_start, &GC_libld_end)) {
WARN("Failed to find ld.so text mapping: Expect crash\n", 0);
}
+ RESTORE_CANCEL(cancel_state);
}
#endif /* GC_LINUX_THREADS */
-#include <limits.h>
-#ifdef SIZE_MAX
-# define GC_SIZE_MAX SIZE_MAX
-#else
-# define GC_SIZE_MAX (~(size_t)0)
-#endif
-
-#define GC_SQRT_SIZE_MAX ((1U << (WORDSZ / 2)) - 1)
-
void * calloc(size_t n, size_t lb)
{
if ((lb | n) > GC_SQRT_SIZE_MAX /* fast initial test */
&& lb && n > GC_SIZE_MAX / lb)
- return NULL;
+ return (*GC_get_oom_fn())(GC_SIZE_MAX); /* n*lb overflow */
# if defined(GC_LINUX_THREADS) /* && !defined(USE_PROC_FOR_LIBRARIES) */
/* libpthread allocated some memory that is only pointed to by */
/* mmapped thread stacks. Make sure it is not collectible. */
diff --git a/mallocx.c b/mallocx.c
index 7fcaa5c2..de66e45b 100644
--- a/mallocx.c
+++ b/mallocx.c
@@ -77,11 +77,18 @@ GC_API void * GC_CALL GC_realloc(void * p, size_t lb)
{
struct hblk * h;
hdr * hhdr;
- size_t sz; /* Current size in bytes */
- size_t orig_sz; /* Original sz in bytes */
+ void * result;
+ size_t sz; /* Current size in bytes */
+ size_t orig_sz; /* Original sz in bytes */
int obj_kind;
if (p == 0) return(GC_malloc(lb)); /* Required by ANSI */
+ if (0 == lb) /* and p != NULL */ {
+# ifndef IGNORE_FREE
+ GC_free(p);
+# endif
+ return NULL;
+ }
h = HBLKPTR(p);
hhdr = HDR(h);
sz = hhdr -> hb_sz;
@@ -118,32 +125,20 @@ GC_API void * GC_CALL GC_realloc(void * p, size_t lb)
BZERO(((ptr_t)p) + lb, orig_sz - lb);
}
return(p);
- } else {
- /* shrink */
- void * result =
- GC_generic_or_special_malloc((word)lb, obj_kind);
-
- if (result == 0) return(0);
- /* Could also return original object. But this */
- /* gives the client warning of imminent disaster. */
- BCOPY(p, result, lb);
-# ifndef IGNORE_FREE
- GC_free(p);
-# endif
- return(result);
}
- } else {
- /* grow */
- void * result =
- GC_generic_or_special_malloc((word)lb, obj_kind);
-
- if (result == 0) return(0);
- BCOPY(p, result, sz);
-# ifndef IGNORE_FREE
- GC_free(p);
-# endif
- return(result);
+ /* shrink */
+ sz = lb;
}
+ result = GC_generic_or_special_malloc((word)lb, obj_kind);
+ if (result != NULL) {
+ /* In case of shrink, it could also return original object. */
+ /* But this gives the client warning of imminent disaster. */
+ BCOPY(p, result, sz);
+# ifndef IGNORE_FREE
+ GC_free(p);
+# endif
+ }
+ return result;
}
# if defined(REDIRECT_MALLOC) && !defined(REDIRECT_REALLOC)
@@ -167,7 +162,8 @@ void * realloc(void * p, size_t lb)
/* Allocate memory such that only pointers to near the */
/* beginning of the object are considered. */
/* We avoid holding allocation lock while we clear the memory. */
-GC_API void * GC_CALL GC_generic_malloc_ignore_off_page(size_t lb, int k)
+GC_API GC_ATTR_MALLOC void * GC_CALL
+ GC_generic_malloc_ignore_off_page(size_t lb, int k)
{
void *result;
size_t lg;
@@ -180,8 +176,6 @@ GC_API void * GC_CALL GC_generic_malloc_ignore_off_page(size_t lb, int k)
return(GC_generic_malloc((word)lb, k));
lg = ROUNDED_UP_GRANULES(lb);
lb_rounded = GRANULES_TO_BYTES(lg);
- if (lb_rounded < lb)
- return((*GC_get_oom_fn())(lb));
n_blocks = OBJ_SZ_TO_BLOCKS(lb_rounded);
init = GC_obj_kinds[k].ok_init;
if (EXPECT(GC_have_errors, FALSE))
@@ -190,40 +184,39 @@ GC_API void * GC_CALL GC_generic_malloc_ignore_off_page(size_t lb, int k)
GC_DBG_COLLECT_AT_MALLOC(lb);
LOCK();
result = (ptr_t)GC_alloc_large(ADD_SLOP(lb), k, IGNORE_OFF_PAGE);
- if (0 != result) {
- if (GC_debugging_started) {
- BZERO(result, n_blocks * HBLKSIZE);
- } else {
-# ifdef THREADS
- /* Clear any memory that might be used for GC descriptors */
- /* before we release the lock. */
- ((word *)result)[0] = 0;
- ((word *)result)[1] = 0;
- ((word *)result)[GRANULES_TO_WORDS(lg)-1] = 0;
- ((word *)result)[GRANULES_TO_WORDS(lg)-2] = 0;
-# endif
- }
- }
- GC_bytes_allocd += lb_rounded;
- if (0 == result) {
+ if (NULL == result) {
GC_oom_func oom_fn = GC_oom_fn;
UNLOCK();
- return((*oom_fn)(lb));
+ return (*oom_fn)(lb);
+ }
+
+ if (GC_debugging_started) {
+ BZERO(result, n_blocks * HBLKSIZE);
} else {
- UNLOCK();
- if (init && !GC_debugging_started) {
- BZERO(result, n_blocks * HBLKSIZE);
- }
- return(result);
+# ifdef THREADS
+ /* Clear any memory that might be used for GC descriptors */
+ /* before we release the lock. */
+ ((word *)result)[0] = 0;
+ ((word *)result)[1] = 0;
+ ((word *)result)[GRANULES_TO_WORDS(lg)-1] = 0;
+ ((word *)result)[GRANULES_TO_WORDS(lg)-2] = 0;
+# endif
}
+ GC_bytes_allocd += lb_rounded;
+ UNLOCK();
+ if (init && !GC_debugging_started) {
+ BZERO(result, n_blocks * HBLKSIZE);
+ }
+ return(result);
}
-GC_API void * GC_CALL GC_malloc_ignore_off_page(size_t lb)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_ignore_off_page(size_t lb)
{
return((void *)GC_generic_malloc_ignore_off_page(lb, NORMAL));
}
-GC_API void * GC_CALL GC_malloc_atomic_ignore_off_page(size_t lb)
+GC_API GC_ATTR_MALLOC void * GC_CALL
+ GC_malloc_atomic_ignore_off_page(size_t lb)
{
return((void *)GC_generic_malloc_ignore_off_page(lb, PTRFREE));
}
@@ -277,6 +270,7 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result)
size_t lg; /* Length in granules. */
signed_word my_bytes_allocd = 0;
struct obj_kind * ok = &(GC_obj_kinds[k]);
+ struct hblk ** rlh;
DCL_LOCK_STATE;
GC_ASSERT(lb != 0 && (lb & (GRANULE_BYTES-1)) == 0);
@@ -303,8 +297,8 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result)
}
/* First see if we can reclaim a page of objects waiting to be */
/* reclaimed. */
- {
- struct hblk ** rlh = ok -> ok_reclaim_list;
+ rlh = ok -> ok_reclaim_list;
+ if (rlh != NULL) {
struct hblk * hbp;
hdr * hhdr;
@@ -433,20 +427,21 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result)
/* Note that the "atomic" version of this would be unsafe, since the */
/* links would not be seen by the collector. */
-GC_API void * GC_CALL GC_malloc_many(size_t lb)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_many(size_t lb)
{
void *result;
- GC_generic_malloc_many((lb + EXTRA_BYTES + GRANULE_BYTES-1)
- & ~(GRANULE_BYTES-1),
- NORMAL, &result);
+ /* Add EXTRA_BYTES and round up to a multiple of a granule. */
+ lb = SIZET_SAT_ADD(lb, EXTRA_BYTES + GRANULE_BYTES - 1)
+ & ~(GRANULE_BYTES - 1);
+
+ GC_generic_malloc_many(lb, NORMAL, &result);
return result;
}
-/* Not well tested nor integrated. */
-/* Debug version is tricky and currently missing. */
#include <limits.h>
-GC_API void * GC_CALL GC_memalign(size_t align, size_t lb)
+/* Debug version is tricky and currently missing. */
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_memalign(size_t align, size_t lb)
{
size_t new_lb;
size_t offset;
@@ -462,7 +457,7 @@ GC_API void * GC_CALL GC_memalign(size_t align, size_t lb)
}
/* We could also try to make sure that the real rounded-up object size */
/* is a multiple of align. That would be correct up to HBLKSIZE. */
- new_lb = lb + align - 1;
+ new_lb = SIZET_SAT_ADD(lb, align - 1);
result = GC_malloc(new_lb);
/* It is OK not to check result for NULL as in that case */
/* GC_memalign returns NULL too since (0 + 0 % align) is 0. */
@@ -470,7 +465,8 @@ GC_API void * GC_CALL GC_memalign(size_t align, size_t lb)
if (offset != 0) {
offset = align - offset;
if (!GC_all_interior_pointers) {
- if (offset >= VALID_OFFSET_SZ) return GC_malloc(HBLKSIZE);
+ GC_STATIC_ASSERT(VALID_OFFSET_SZ <= HBLKSIZE);
+ GC_ASSERT(offset < VALID_OFFSET_SZ);
GC_register_displacement(offset);
}
}
@@ -505,7 +501,8 @@ GC_API int GC_CALL GC_posix_memalign(void **memptr, size_t align, size_t lb)
/* Allocate lb bytes of pointer-free, untraced, uncollectible data */
/* This is normally roughly equivalent to the system malloc. */
/* But it may be useful if malloc is redefined. */
- GC_API void * GC_CALL GC_malloc_atomic_uncollectable(size_t lb)
+ GC_API GC_ATTR_MALLOC void * GC_CALL
+ GC_malloc_atomic_uncollectable(size_t lb)
{
void *op;
void **opp;
@@ -557,7 +554,7 @@ GC_API int GC_CALL GC_posix_memalign(void **memptr, size_t align, size_t lb)
/* provide a version of strdup() that uses the collector to allocate the
copy of the string */
-GC_API char * GC_CALL GC_strdup(const char *s)
+GC_API GC_ATTR_MALLOC char * GC_CALL GC_strdup(const char *s)
{
char *copy;
size_t lb;
@@ -573,7 +570,7 @@ GC_API char * GC_CALL GC_strdup(const char *s)
return copy;
}
-GC_API char * GC_CALL GC_strndup(const char *str, size_t size)
+GC_API GC_ATTR_MALLOC char * GC_CALL GC_strndup(const char *str, size_t size)
{
char *copy;
size_t len = strlen(str); /* str is expected to be non-NULL */
@@ -594,7 +591,7 @@ GC_API char * GC_CALL GC_strndup(const char *str, size_t size)
#ifdef GC_REQUIRE_WCSDUP
# include <wchar.h> /* for wcslen() */
- GC_API wchar_t * GC_CALL GC_wcsdup(const wchar_t *str)
+ GC_API GC_ATTR_MALLOC wchar_t * GC_CALL GC_wcsdup(const wchar_t *str)
{
size_t lb = (wcslen(str) + 1) * sizeof(wchar_t);
wchar_t *copy = GC_malloc_atomic(lb);
diff --git a/mark.c b/mark.c
index 60a1a1e4..4cdc70de 100644
--- a/mark.c
+++ b/mark.c
@@ -48,25 +48,26 @@ GC_INNER unsigned GC_n_mark_procs = GC_RESERVED_MARK_PROCS;
/* It's done here, since we need to deal with mark descriptors. */
GC_INNER struct obj_kind GC_obj_kinds[MAXOBJKINDS] = {
/* PTRFREE */ { &GC_aobjfreelist[0], 0 /* filled in dynamically */,
- 0 | GC_DS_LENGTH, FALSE, FALSE
+ /* 0 | */ GC_DS_LENGTH, FALSE, FALSE
/*, */ OK_DISCLAIM_INITZ },
/* NORMAL */ { &GC_objfreelist[0], 0,
- 0 | GC_DS_LENGTH, /* Adjusted in GC_init for EXTRA_BYTES */
+ /* 0 | */ GC_DS_LENGTH,
+ /* adjusted in GC_init for EXTRA_BYTES */
TRUE /* add length to descr */, TRUE
/*, */ OK_DISCLAIM_INITZ },
/* UNCOLLECTABLE */
{ &GC_uobjfreelist[0], 0,
- 0 | GC_DS_LENGTH, TRUE /* add length to descr */, TRUE
+ /* 0 | */ GC_DS_LENGTH, TRUE /* add length to descr */, TRUE
/*, */ OK_DISCLAIM_INITZ },
# ifdef ATOMIC_UNCOLLECTABLE
/* AUNCOLLECTABLE */
{ &GC_auobjfreelist[0], 0,
- 0 | GC_DS_LENGTH, FALSE /* add length to descr */, FALSE
+ /* 0 | */ GC_DS_LENGTH, FALSE /* add length to descr */, FALSE
/*, */ OK_DISCLAIM_INITZ },
# endif
# ifdef STUBBORN_ALLOC
/*STUBBORN*/ { (void **)&GC_sobjfreelist[0], 0,
- 0 | GC_DS_LENGTH, TRUE /* add length to descr */, TRUE
+ /* 0 | */ GC_DS_LENGTH, TRUE /* add length to descr */, TRUE
/*, */ OK_DISCLAIM_INITZ },
# endif
};
@@ -92,9 +93,9 @@ GC_INNER unsigned GC_n_kinds = GC_N_KINDS_INITIAL_VALUE;
/* INITIAL_MARK_STACK_SIZE * sizeof(mse) should be a */
/* multiple of HBLKSIZE. */
/* The incremental collector actually likes a larger */
- /* size, since it want to push all marked dirty objs */
- /* before marking anything new. Currently we let it */
- /* grow dynamically. */
+ /* size, since it wants to push all marked dirty */
+ /* objects before marking anything new. Currently we */
+ /* let it grow dynamically. */
# endif
STATIC word GC_n_rescuing_pages = 0;
@@ -576,7 +577,15 @@ GC_INNER void GC_invalidate_mark_state(void)
GC_INNER mse * GC_signal_mark_stack_overflow(mse *msp)
{
GC_mark_state = MS_INVALID;
- GC_mark_stack_too_small = TRUE;
+# ifdef PARALLEL_MARK
+ /* We are using a local_mark_stack in parallel mode, so */
+ /* do not signal the global mark stack to be resized. */
+ /* That will be done if required in GC_return_mark_stack. */
+ if (!GC_parallel)
+ GC_mark_stack_too_small = TRUE;
+# else
+ GC_mark_stack_too_small = TRUE;
+# endif
GC_COND_LOG_PRINTF("Mark stack overflow; current size = %lu entries\n",
(unsigned long)GC_mark_stack_size);
return(msp - GC_MARK_STACK_DISCARDS);
@@ -600,9 +609,9 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
mse *mark_stack_limit)
{
signed_word credit = HBLKSIZE; /* Remaining credit for marking work */
- ptr_t current_p; /* Pointer to current candidate ptr. */
- word current; /* Candidate pointer. */
- ptr_t limit; /* (Incl) limit of current candidate range. */
+ ptr_t current_p; /* Pointer to current candidate ptr. */
+ word current; /* Candidate pointer. */
+ ptr_t limit = 0; /* (Incl) limit of current candidate range. */
word descr;
ptr_t greatest_ha = GC_greatest_plausible_heap_addr;
ptr_t least_ha = GC_least_plausible_heap_addr;
@@ -629,20 +638,17 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
if (descr & ((~(WORDS_TO_BYTES(SPLIT_RANGE_WORDS) - 1)) | GC_DS_TAGS)) {
word tag = descr & GC_DS_TAGS;
+ GC_STATIC_ASSERT(GC_DS_TAGS == 0x3);
switch(tag) {
case GC_DS_LENGTH:
/* Large length. */
/* Process part of the range to avoid pushing too much on the */
/* stack. */
GC_ASSERT(descr < (word)GC_greatest_plausible_heap_addr
- - (word)GC_least_plausible_heap_addr);
-# ifdef ENABLE_TRACE
- if ((word)GC_trace_addr >= (word)current_p
- && (word)GC_trace_addr < (word)(current_p + descr)) {
- GC_log_printf("GC #%u: large section; start %p, len %lu\n",
- (unsigned)GC_gc_no, current_p, (unsigned long)descr);
- }
-# endif /* ENABLE_TRACE */
+ - (word)GC_least_plausible_heap_addr
+ || (word)(current_p + descr)
+ <= (word)GC_least_plausible_heap_addr
+ || (word)current_p >= (word)GC_greatest_plausible_heap_addr);
# ifdef PARALLEL_MARK
# define SHARE_BYTES 2048
if (descr > SHARE_BYTES && GC_parallel
@@ -656,10 +662,13 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
# ifdef ENABLE_TRACE
if ((word)GC_trace_addr >= (word)current_p
&& (word)GC_trace_addr < (word)(current_p + descr)) {
- GC_log_printf("GC #%u: splitting (parallel) %p at %p\n",
- (unsigned)GC_gc_no, current_p, current_p + new_size);
+ GC_log_printf("GC #%u: large section; start %p, len %lu,"
+ " splitting (parallel) at %p\n",
+ (unsigned)GC_gc_no, (void *)current_p,
+ (unsigned long)descr,
+ (void *)(current_p + new_size));
}
-# endif /* ENABLE_TRACE */
+# endif
current_p += new_size;
descr -= new_size;
goto retry;
@@ -672,10 +681,12 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
# ifdef ENABLE_TRACE
if ((word)GC_trace_addr >= (word)current_p
&& (word)GC_trace_addr < (word)(current_p + descr)) {
- GC_log_printf("GC #%u: splitting %p at %p\n",
- (unsigned)GC_gc_no, current_p, limit);
+ GC_log_printf("GC #%u: large section; start %p, len %lu,"
+ " splitting at %p\n",
+ (unsigned)GC_gc_no, (void *)current_p,
+ (unsigned long)descr, (void *)limit);
}
-# endif /* ENABLE_TRACE */
+# endif
/* Make sure that pointers overlapping the two ranges are */
/* considered. */
limit += sizeof(word) - ALIGNMENT;
@@ -738,8 +749,8 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
/* word in object. */
ptr_t type_descr = *(ptr_t *)current_p;
/* type_descr is either a valid pointer to the descriptor */
- /* structure, or this object was on a free list. If it */
- /* it was anything but the last object on the free list, */
+ /* structure, or this object was on a free list. */
+ /* If it was anything but the last object on the free list, */
/* we will misinterpret the next object on the free list as */
/* the type descriptor, and get a 0 GC descriptor, which */
/* is ideal. Unfortunately, we need to check for the last */
@@ -749,6 +760,28 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
mark_stack_top--;
continue;
}
+ if ((GC_word)(type_descr) >= (GC_word)GC_least_plausible_heap_addr
+ && (GC_word)(type_descr)
+ <= (GC_word)GC_greatest_plausible_heap_addr) {
+ /* type_descr looks like a pointer into the heap. */
+ /* It could still be the link pointer in a free list */
+ /* though. That's not a problem as long as the offset */
+ /* of the actual descriptor in the pointed to object is */
+ /* within the same object. In that case it will either */
+ /* point at the next free object in the list (if offset */
+ /* is 0) or be zeroed (which we check for below, */
+ /* descr == 0). If the offset is larger than the */
+ /* objects in the block type_descr points to it cannot */
+ /* be a proper pointer. */
+ word offset = ~(descr + (GC_INDIR_PER_OBJ_BIAS
+ - GC_DS_PER_OBJECT - 1));
+ hdr *hhdr;
+ GET_HDR(type_descr, hhdr);
+ if (NULL == hhdr || hhdr->hb_sz - sizeof(word) < offset) {
+ mark_stack_top--;
+ continue;
+ }
+ }
descr = *(word *)(type_descr
- (descr + (GC_INDIR_PER_OBJ_BIAS
- GC_DS_PER_OBJECT)));
@@ -760,9 +793,6 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
continue;
}
goto retry;
- default:
- limit = 0; /* initialized to prevent warning. */
- ABORT_RET("GC_mark_from: bad state");
}
} else /* Small object with length descriptor */ {
mark_stack_top--;
@@ -770,15 +800,16 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
if (descr < sizeof(word))
continue;
# endif
- limit = current_p + (word)descr;
- }
-# ifdef ENABLE_TRACE
+# ifdef ENABLE_TRACE
if ((word)GC_trace_addr >= (word)current_p
- && (word)GC_trace_addr < (word)limit) {
- GC_log_printf("GC #%u: Tracing from %p, length is %lu\n",
- (unsigned)GC_gc_no, current_p, (unsigned long)descr);
+ && (word)GC_trace_addr < (word)(current_p + descr)) {
+ GC_log_printf("GC #%u: small object; start %p, len %lu\n",
+ (unsigned)GC_gc_no, (void *)current_p,
+ (unsigned long)descr);
}
-# endif /* ENABLE_TRACE */
+# endif
+ limit = current_p + (word)descr;
+ }
/* The simple case in which we're scanning a range. */
GC_ASSERT(!((word)current_p & (ALIGNMENT-1)));
credit -= limit - current_p;
@@ -880,6 +911,27 @@ GC_INNER word GC_mark_no = 0;
/* we don't overflow half of it in a single call to */
/* GC_mark_from. */
+/* Wait all markers to finish initialization (i.e. store */
+/* marker_[b]sp, marker_mach_threads, GC_marker_Id). */
+GC_INNER void GC_wait_for_markers_init(void)
+{
+ word count;
+ IF_CANCEL(int cancel_state;)
+
+ if (GC_markers_m1 == 0)
+ return;
+
+ DISABLE_CANCEL(cancel_state);
+ /* Reuse marker lock and builders count to synchronize */
+ /* marker threads startup. */
+ GC_acquire_mark_lock();
+ GC_fl_builder_count += (word)GC_markers_m1;
+ count = GC_fl_builder_count;
+ GC_release_mark_lock();
+ if (count != 0)
+ GC_wait_for_reclaim();
+ RESTORE_CANCEL(cancel_state);
+}
/* Steal mark stack entries starting at mse low into mark stack local */
/* until we either steal mse high, or we have max entries. */
@@ -1028,7 +1080,7 @@ STATIC void GC_mark_local(mse *local_mark_stack, int id)
+ sizeof(mse));
GC_ASSERT((word)global_first_nonempty >= (word)GC_mark_stack &&
(word)global_first_nonempty <=
- (word)AO_load((volatile AO_t *)&GC_mark_stack_top)
+ (word)AO_load_acquire((volatile AO_t *)&GC_mark_stack_top)
+ sizeof(mse));
if ((word)my_first_nonempty < (word)global_first_nonempty) {
my_first_nonempty = global_first_nonempty;
@@ -1727,7 +1779,7 @@ STATIC void GC_push_marked(struct hblk *h, hdr *hhdr)
mse * mark_stack_limit = GC_mark_stack_limit;
/* Some quick shortcuts: */
- if ((0 | GC_DS_LENGTH) == descr) return;
+ if ((/* 0 | */ GC_DS_LENGTH) == descr) return;
if (GC_block_empty(hhdr)/* nothing marked */) return;
GC_n_rescuing_pages++;
GC_objects_are_marked = TRUE;
@@ -1785,7 +1837,7 @@ STATIC void GC_push_marked(struct hblk *h, hdr *hhdr)
mse * GC_mark_stack_top_reg;
mse * mark_stack_limit = GC_mark_stack_limit;
- if ((0 | GC_DS_LENGTH) == descr)
+ if ((/* 0 | */ GC_DS_LENGTH) == descr)
return;
GC_n_rescuing_pages++;
diff --git a/mark_rts.c b/mark_rts.c
index 7c8b324d..9c7fb18a 100644
--- a/mark_rts.c
+++ b/mark_rts.c
@@ -602,7 +602,7 @@ STATIC void GC_push_all_stack_partially_eager(ptr_t bottom, ptr_t top,
GC_push_all_eager(bottom, top);
}
# ifdef TRACE_BUF
- GC_add_trace_entry("GC_push_all_stack", bottom, top);
+ GC_add_trace_entry("GC_push_all_stack", (word)bottom, (word)top);
# endif
}
diff --git a/misc.c b/misc.c
index 71f10ce7..74cf088d 100644
--- a/misc.c
+++ b/misc.c
@@ -232,7 +232,7 @@ GC_API void GC_CALL GC_set_handle_fork(int value GC_ATTR_UNUSED)
/* quantization algorithm (but we precompute it). */
STATIC void GC_init_size_map(void)
{
- int i;
+ size_t i;
/* Map size 0 to something bigger. */
/* This avoids problems at lower levels. */
@@ -370,7 +370,7 @@ GC_API void * GC_CALL GC_clear_stack(void *arg)
/* clearing near the cold end of the stack, a good thing. */
# define GC_SLOP 4000
/* We make GC_high_water this much hotter than we really saw */
- /* saw it, to cover for GC noise etc. above our current frame. */
+ /* it, to cover for GC noise etc. above our current frame. */
# define CLEAR_THRESHOLD 100000
/* We restart the clearing process after this many bytes of */
/* allocation. Otherwise very heavily recursive programs */
@@ -687,7 +687,7 @@ GC_API void GC_CALL GC_get_heap_usage_safe(GC_word *pheap_size,
}
/* At this execution point, GC_setpagesize() and GC_init_win32() */
/* must already be called (for GET_MEM() to work correctly). */
- content = (char *)GET_MEM(len + 1);
+ content = (char *)GET_MEM(ROUNDUP_PAGESIZE_IF_MMAP((size_t)len + 1));
if (content == NULL) {
CloseHandle(hFile);
return; /* allocation failure */
@@ -846,9 +846,9 @@ GC_API void GC_CALL GC_init(void)
# endif
# ifdef GC_INITIAL_HEAP_SIZE
- initial_heap_sz = divHBLKSZ(GC_INITIAL_HEAP_SIZE);
+ initial_heap_sz = GC_INITIAL_HEAP_SIZE;
# else
- initial_heap_sz = (word)MINHINCR;
+ initial_heap_sz = MINHINCR * HBLKSIZE;
# endif
DISABLE_CANCEL(cancel_state);
/* Note that although we are nominally called with the */
@@ -862,9 +862,14 @@ GC_API void GC_CALL GC_init(void)
# ifdef SN_TARGET_PS3
{
pthread_mutexattr_t mattr;
- pthread_mutexattr_init(&mattr);
- pthread_mutex_init(&GC_allocate_ml, &mattr);
- pthread_mutexattr_destroy(&mattr);
+
+ if (0 != pthread_mutexattr_init(&mattr)) {
+ ABORT("pthread_mutexattr_init failed");
+ }
+ if (0 != pthread_mutex_init(&GC_allocate_ml, &mattr)) {
+ ABORT("pthread_mutex_init failed");
+ }
+ (void)pthread_mutexattr_destroy(&mattr);
}
# endif
# endif /* THREADS */
@@ -1165,21 +1170,20 @@ GC_API void GC_CALL GC_init(void)
if (initial_heap_sz <= MINHINCR * HBLKSIZE) {
WARN("Bad initial heap size %s - ignoring it.\n", sz_str);
}
- initial_heap_sz = divHBLKSZ(initial_heap_sz);
}
}
{
char * sz_str = GETENV("GC_MAXIMUM_HEAP_SIZE");
if (sz_str != NULL) {
word max_heap_sz = GC_parse_mem_size_arg(sz_str);
- if (max_heap_sz < initial_heap_sz * HBLKSIZE) {
+ if (max_heap_sz < initial_heap_sz) {
WARN("Bad maximum heap size %s - ignoring it.\n", sz_str);
}
if (0 == GC_max_retries) GC_max_retries = 2;
GC_set_max_heap_size(max_heap_sz);
}
}
- if (!GC_expand_hp_inner(initial_heap_sz)) {
+ if (!GC_expand_hp_inner(divHBLKSZ(initial_heap_sz))) {
GC_err_printf("Can't start up: not enough memory\n");
EXIT();
} else {
@@ -1622,8 +1626,8 @@ GC_API void GC_CALL GC_enable_incremental(void)
#define BUFSZ 1024
-#ifdef NO_VSNPRINTF
- /* In case this function is missing (eg., in DJGPP v2.0.3). */
+#if defined(DJGPP) || defined(__STRICT_ANSI__)
+ /* vsnprintf is missing in DJGPP (v2.0.3) */
# define GC_VSNPRINTF(buf, bufsz, format, args) vsprintf(buf, format, args)
#elif defined(_MSC_VER)
# ifdef MSWINCE
@@ -1737,7 +1741,7 @@ GC_API void GC_CALLBACK GC_ignore_warn_proc(char *msg, GC_word arg)
GC_API void GC_CALL GC_set_warn_proc(GC_warn_proc p)
{
DCL_LOCK_STATE;
- GC_ASSERT(p != 0);
+ GC_ASSERT(NONNULL_ARG_NOT_NULL(p));
# ifdef GC_WIN32_THREADS
# ifdef CYGWIN32
/* Need explicit GC_INIT call */
@@ -1825,7 +1829,7 @@ GC_API GC_warn_proc GC_CALL GC_get_warn_proc(void)
GC_API void GC_CALL GC_set_abort_func(GC_abort_func fn)
{
DCL_LOCK_STATE;
- GC_ASSERT(fn != 0);
+ GC_ASSERT(NONNULL_ARG_NOT_NULL(fn));
LOCK();
GC_on_abort = fn;
UNLOCK();
@@ -1888,18 +1892,22 @@ GC_API void ** GC_CALL GC_new_free_list(void)
GC_API unsigned GC_CALL GC_new_kind_inner(void **fl, GC_word descr,
int adjust, int clear)
{
- unsigned result = GC_n_kinds++;
+ unsigned result = GC_n_kinds;
- if (GC_n_kinds > MAXOBJKINDS) ABORT("Too many kinds");
- GC_obj_kinds[result].ok_freelist = fl;
- GC_obj_kinds[result].ok_reclaim_list = 0;
- GC_obj_kinds[result].ok_descriptor = descr;
- GC_obj_kinds[result].ok_relocate_descr = adjust;
- GC_obj_kinds[result].ok_init = clear;
-# ifdef ENABLE_DISCLAIM
+ if (result < MAXOBJKINDS) {
+ GC_n_kinds++;
+ GC_obj_kinds[result].ok_freelist = fl;
+ GC_obj_kinds[result].ok_reclaim_list = 0;
+ GC_obj_kinds[result].ok_descriptor = descr;
+ GC_obj_kinds[result].ok_relocate_descr = adjust;
+ GC_obj_kinds[result].ok_init = (GC_bool)clear;
+# ifdef ENABLE_DISCLAIM
GC_obj_kinds[result].ok_mark_unconditionally = FALSE;
GC_obj_kinds[result].ok_disclaim_proc = 0;
-# endif
+# endif
+ } else {
+ ABORT("Too many kinds");
+ }
return result;
}
@@ -1916,10 +1924,14 @@ GC_API unsigned GC_CALL GC_new_kind(void **fl, GC_word descr, int adjust,
GC_API unsigned GC_CALL GC_new_proc_inner(GC_mark_proc proc)
{
- unsigned result = GC_n_mark_procs++;
+ unsigned result = GC_n_mark_procs;
- if (GC_n_mark_procs > MAX_MARK_PROCS) ABORT("Too many mark procedures");
- GC_mark_procs[result] = proc;
+ if (result < MAX_MARK_PROCS) {
+ GC_n_mark_procs++;
+ GC_mark_procs[result] = proc;
+ } else {
+ ABORT("Too many mark procedures");
+ }
return result;
}
@@ -2107,7 +2119,7 @@ GC_API GC_word GC_CALL GC_get_gc_no(void)
GC_API void GC_CALL GC_set_oom_fn(GC_oom_func fn)
{
- GC_ASSERT(fn != 0);
+ GC_ASSERT(NONNULL_ARG_NOT_NULL(fn));
DCL_LOCK_STATE;
LOCK();
GC_oom_fn = fn;
diff --git a/new_hblk.c b/new_hblk.c
index 05c4abff..ac6a118d 100644
--- a/new_hblk.c
+++ b/new_hblk.c
@@ -58,7 +58,7 @@
p[3] = 0;
p += 4;
for (; (word)p < (word)lim; p += 4) {
- PREFETCH_FOR_WRITE((ptr_t)(p+64));
+ GC_PREFETCH_FOR_WRITE((ptr_t)(p + 64));
p[0] = (word)(p-4);
p[1] = 0;
CLEAR_DOUBLE(p+2);
@@ -92,7 +92,7 @@
p[4] = (word)p;
p += 8;
for (; (word)p < (word)lim; p += 8) {
- PREFETCH_FOR_WRITE((ptr_t)(p+64));
+ GC_PREFETCH_FOR_WRITE((ptr_t)(p + 64));
p[0] = (word)(p-4);
p[4] = (word)p;
};
@@ -116,10 +116,10 @@ GC_INNER ptr_t GC_build_fl(struct hblk *h, size_t sz, GC_bool clear,
/* If we were more serious about it, these should go inside */
/* the loops. But write prefetches usually don't seem to */
/* matter much. */
- PREFETCH_FOR_WRITE((ptr_t)h);
- PREFETCH_FOR_WRITE((ptr_t)h + 128);
- PREFETCH_FOR_WRITE((ptr_t)h + 256);
- PREFETCH_FOR_WRITE((ptr_t)h + 378);
+ GC_PREFETCH_FOR_WRITE((ptr_t)h);
+ GC_PREFETCH_FOR_WRITE((ptr_t)h + 128);
+ GC_PREFETCH_FOR_WRITE((ptr_t)h + 256);
+ GC_PREFETCH_FOR_WRITE((ptr_t)h + 378);
# ifndef SMALL_CONFIG
/* Handle small objects sizes more efficiently. For larger objects */
/* the difference is less significant. */
diff --git a/obj_map.c b/obj_map.c
index c935bf3f..9fdeb0af 100644
--- a/obj_map.c
+++ b/obj_map.c
@@ -51,13 +51,13 @@ GC_INNER void GC_register_displacement_inner(size_t offset)
GC_INNER GC_bool GC_add_map_entry(size_t granules)
{
unsigned displ;
- short * new_map;
+ unsigned short * new_map;
if (granules > BYTES_TO_GRANULES(MAXOBJBYTES)) granules = 0;
if (GC_obj_map[granules] != 0) {
return(TRUE);
}
- new_map = (short *)GC_scratch_alloc(MAP_LEN * sizeof(short));
+ new_map = (unsigned short *)GC_scratch_alloc(MAP_LEN * sizeof(short));
if (new_map == 0) return(FALSE);
GC_COND_LOG_PRINTF(
"Adding block map for size of %u granules (%u bytes)\n",
@@ -68,7 +68,7 @@ GC_INNER void GC_register_displacement_inner(size_t offset)
}
} else {
for (displ = 0; displ < BYTES_TO_GRANULES(HBLKSIZE); displ++) {
- new_map[displ] = (short)(displ % granules);
+ new_map[displ] = (unsigned short)(displ % granules);
}
}
GC_obj_map[granules] = new_map;
diff --git a/os_dep.c b/os_dep.c
index c5f9bb00..b5267253 100644
--- a/os_dep.c
+++ b/os_dep.c
@@ -16,36 +16,6 @@
#include "private/gc_priv.h"
-#if defined(LINUX) && !defined(POWERPC) && !defined(NO_SIGCONTEXT_H)
-# include <linux/version.h>
-# if (LINUX_VERSION_CODE <= 0x10400)
- /* Ugly hack to get struct sigcontext_struct definition. Required */
- /* for some early 1.3.X releases. Will hopefully go away soon. */
- /* in some later Linux releases, asm/sigcontext.h may have to */
- /* be included instead. */
-# define __KERNEL__
-# include <asm/signal.h>
-# undef __KERNEL__
-# else
- /* Kernels prior to 2.1.1 defined struct sigcontext_struct instead of */
- /* struct sigcontext. libc6 (glibc2) uses "struct sigcontext" in */
- /* prototypes, so we have to include the top-level sigcontext.h to */
- /* make sure the former gets defined to be the latter if appropriate. */
-# include <features.h>
-# if 2 <= __GLIBC__
-# if 2 == __GLIBC__ && 0 == __GLIBC_MINOR__
- /* glibc 2.1 no longer has sigcontext.h. But signal.h */
- /* has the right declaration for glibc 2.1. */
-# include <sigcontext.h>
-# endif /* 0 == __GLIBC_MINOR__ */
-# else /* __GLIBC__ < 2 */
- /* libc5 doesn't have <sigcontext.h>: go directly with the kernel */
- /* one. Check LINUX_VERSION_CODE to see which we should reference. */
-# include <asm/sigcontext.h>
-# endif /* __GLIBC__ < 2 */
-# endif
-#endif /* LINUX && !POWERPC */
-
#if !defined(OS2) && !defined(PCR) && !defined(AMIGA) && !defined(MACOS) \
&& !defined(MSWINCE) && !defined(__CC_ARM) && !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2)
# include <sys/types.h>
@@ -103,11 +73,6 @@
# include <malloc.h> /* for locking */
#endif
-#if defined(LINUX) || defined(FREEBSD) || defined(SOLARIS) || defined(IRIX5) \
- || ((defined(USE_MMAP) || defined(USE_MUNMAP)) && !defined(USE_WINALLOC))
-# define MMAP_SUPPORTED
-#endif
-
#if defined(MMAP_SUPPORTED) || defined(ADD_HEAP_GUARD_PAGES)
# if defined(USE_MUNMAP) && !defined(USE_MMAP)
# error "invalid config - USE_MUNMAP requires USE_MMAP"
@@ -169,8 +134,8 @@ STATIC ssize_t GC_repeat_read(int fd, char *buf, size_t count)
#ifdef THREADS
/* Determine the length of a file by incrementally reading it into a */
- /* This would be silly to use on a file supporting lseek, but Linux */
- /* /proc files usually do not. */
+ /* buffer. This would be silly to use it on a file supporting lseek, */
+ /* but Linux /proc files usually do not. */
STATIC size_t GC_get_file_len(int f)
{
size_t total = 0;
@@ -309,30 +274,29 @@ GC_INNER char * GC_get_maps(void)
char **prot, unsigned int *maj_dev,
char **mapping_name)
{
- char *start_start, *end_start, *maj_dev_start;
- char *p;
- char *endp;
+ unsigned char *start_start, *end_start, *maj_dev_start;
+ unsigned char *p; /* unsigned for isspace, isxdigit */
if (buf_ptr == NULL || *buf_ptr == '\0') {
return NULL;
}
- p = buf_ptr;
+ p = (unsigned char *)buf_ptr;
while (isspace(*p)) ++p;
start_start = p;
GC_ASSERT(isxdigit(*start_start));
- *start = (ptr_t)strtoul(start_start, &endp, 16); p = endp;
+ *start = (ptr_t)strtoul((char *)start_start, (char **)&p, 16);
GC_ASSERT(*p=='-');
++p;
end_start = p;
GC_ASSERT(isxdigit(*end_start));
- *end = (ptr_t)strtoul(end_start, &endp, 16); p = endp;
+ *end = (ptr_t)strtoul((char *)end_start, (char **)&p, 16);
GC_ASSERT(isspace(*p));
while (isspace(*p)) ++p;
GC_ASSERT(*p == 'r' || *p == '-');
- *prot = p;
+ *prot = (char *)p;
/* Skip past protection field to offset field */
while (!isspace(*p)) ++p; while (isspace(*p)) ++p;
GC_ASSERT(isxdigit(*p));
@@ -340,16 +304,16 @@ GC_INNER char * GC_get_maps(void)
while (!isspace(*p)) ++p; while (isspace(*p)) ++p;
maj_dev_start = p;
GC_ASSERT(isxdigit(*maj_dev_start));
- *maj_dev = strtoul(maj_dev_start, NULL, 16);
+ *maj_dev = strtoul((char *)maj_dev_start, NULL, 16);
if (mapping_name == 0) {
while (*p && *p++ != '\n');
} else {
while (*p && *p != '\n' && *p != '/' && *p != '[') p++;
- *mapping_name = p;
+ *mapping_name = (char *)p;
while (*p && *p++ != '\n');
}
- return p;
+ return (char *)p;
}
#endif /* REDIRECT_MALLOC || DYNAMIC_LOADING || IA64 || ... */
@@ -446,13 +410,16 @@ GC_INNER char * GC_get_maps(void)
/* define data_start as a weak symbol. The latter is technically */
/* broken, since the user program may define data_start, in which */
/* case we lose. Nonetheless, we try both, preferring __data_start.*/
- /* We assume gcc-compatible pragmas. */
+ /* We assume gcc-compatible pragmas. */
# pragma weak __data_start
- extern int __data_start[];
# pragma weak data_start
- extern int data_start[];
+ extern int __data_start[], data_start[];
+# ifdef PLATFORM_ANDROID
+# pragma weak _etext
+# pragma weak __dso_handle
+ extern int _etext[], __dso_handle[];
+# endif
# endif /* LINUX */
- extern int _end[];
ptr_t GC_data_start = NULL;
@@ -460,16 +427,31 @@ GC_INNER char * GC_get_maps(void)
GC_INNER void GC_init_linux_data_start(void)
{
+ ptr_t data_end = DATAEND;
+
# if (defined(LINUX) || defined(HURD)) && !defined(IGNORE_PROG_DATA_START)
/* Try the easy approaches first: */
+# ifdef PLATFORM_ANDROID
+ /* Workaround for "gold" (default) linker (as of Android NDK r10e). */
+ if ((word)__data_start < (word)_etext
+ && (word)_etext < (word)__dso_handle) {
+ GC_data_start = (ptr_t)(__dso_handle);
+# ifdef DEBUG_ADD_DEL_ROOTS
+ GC_log_printf(
+ "__data_start is wrong; using __dso_handle as data start\n");
+# endif
+ GC_ASSERT((word)GC_data_start <= (word)data_end);
+ return;
+ }
+# endif
if ((ptr_t)__data_start != 0) {
GC_data_start = (ptr_t)(__data_start);
- GC_ASSERT((word)GC_data_start <= (word)_end);
+ GC_ASSERT((word)GC_data_start <= (word)data_end);
return;
}
if ((ptr_t)data_start != 0) {
GC_data_start = (ptr_t)(data_start);
- GC_ASSERT((word)GC_data_start <= (word)_end);
+ GC_ASSERT((word)GC_data_start <= (word)data_end);
return;
}
# ifdef DEBUG_ADD_DEL_ROOTS
@@ -480,11 +462,11 @@ GC_INNER char * GC_get_maps(void)
if (GC_no_dls) {
/* Not needed, avoids the SIGSEGV caused by */
/* GC_find_limit which complicates debugging. */
- GC_data_start = (ptr_t)_end; /* set data root size to 0 */
+ GC_data_start = data_end; /* set data root size to 0 */
return;
}
- GC_data_start = GC_find_limit((ptr_t)(_end), FALSE);
+ GC_data_start = GC_find_limit(data_end, FALSE);
}
#endif /* SEARCH_FOR_DATA_START */
@@ -559,6 +541,8 @@ GC_INNER char * GC_get_maps(void)
struct sigaction act;
size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
+
+ GC_ASSERT((word)bound >= pgsz);
GC_ASSERT(I_HOLD_LOCK());
act.sa_handler = GC_fault_handler_openbsd;
@@ -570,11 +554,11 @@ GC_INNER char * GC_get_maps(void)
if (sigsetjmp(GC_jmp_buf_openbsd, 1) == 0) {
result = (ptr_t)((word)p & ~(pgsz-1));
for (;;) {
- result += pgsz;
- if ((word)result >= (word)bound) {
+ if ((word)result >= (word)bound - pgsz) {
result = bound;
break;
}
+ result += pgsz; /* no overflow expected */
GC_noop1((word)(*result));
}
}
@@ -597,6 +581,8 @@ GC_INNER char * GC_get_maps(void)
struct sigaction act;
size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
+
+ GC_ASSERT((word)bound >= pgsz);
GC_ASSERT(I_HOLD_LOCK());
act.sa_handler = GC_fault_handler_openbsd;
@@ -609,10 +595,10 @@ GC_INNER char * GC_get_maps(void)
result = (ptr_t)((word)p & ~(pgsz-1));
if (sigsetjmp(GC_jmp_buf_openbsd, 1) != 0 || firstpass) {
firstpass = 0;
- result += pgsz;
- if ((word)result >= (word)bound) {
+ if ((word)result >= (word)bound - pgsz) {
result = bound;
} else {
+ result += pgsz; /* no overflow expected */
GC_noop1((word)(*result));
}
}
@@ -706,7 +692,7 @@ struct o32_obj {
# endif /* OS/2 */
/* Find the page size */
-GC_INNER word GC_page_size = 0;
+GC_INNER size_t GC_page_size = 0;
#if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
# ifndef VER_PLATFORM_WIN32_CE
@@ -722,7 +708,7 @@ GC_INNER word GC_page_size = 0;
GC_INNER void GC_setpagesize(void)
{
GetSystemInfo(&GC_sysinfo);
- GC_page_size = GC_sysinfo.dwPageSize;
+ GC_page_size = (size_t)GC_sysinfo.dwPageSize;
# if defined(MSWINCE) && !defined(_WIN32_WCE_EMULATION)
{
OSVERSIONINFO verInfo;
@@ -775,10 +761,17 @@ GC_INNER word GC_page_size = 0;
GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *sb)
{
- ptr_t trunc_sp = (ptr_t)((word)GC_approx_sp() & ~(GC_page_size - 1));
+ ptr_t trunc_sp;
+ word size;
+
+ /* Set page size if it is not ready (so client can use this */
+ /* function even before GC is initialized). */
+ if (!GC_page_size) GC_setpagesize();
+
+ trunc_sp = (ptr_t)((word)GC_approx_sp() & ~(GC_page_size - 1));
/* FIXME: This won't work if called from a deeply recursive */
/* client code (and the committed stack space has grown). */
- word size = GC_get_writable_length(trunc_sp, 0);
+ size = GC_get_writable_length(trunc_sp, 0);
GC_ASSERT(size != 0);
sb -> mem_base = trunc_sp + size;
return GC_SUCCESS;
@@ -788,11 +781,15 @@ GC_INNER word GC_page_size = 0;
/* gcc version of boehm-gc). */
GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *sb)
{
- void * _tlsbase;
+# ifdef X86_64
+ sb -> mem_base = ((NT_TIB*)NtCurrentTeb())->StackBase;
+# else
+ void * _tlsbase;
- __asm__ ("movl %%fs:4, %0"
- : "=r" (_tlsbase));
- sb -> mem_base = _tlsbase;
+ __asm__ ("movl %%fs:4, %0"
+ : "=r" (_tlsbase));
+ sb -> mem_base = _tlsbase;
+# endif
return GC_SUCCESS;
}
# endif /* CYGWIN32 */
@@ -802,7 +799,7 @@ GC_INNER word GC_page_size = 0;
GC_INNER void GC_setpagesize(void)
{
# if defined(MPROTECT_VDB) || defined(PROC_VDB) || defined(USE_MMAP)
- GC_page_size = GETPAGESIZE();
+ GC_page_size = (size_t)GETPAGESIZE();
if (!GC_page_size) ABORT("getpagesize failed");
# else
/* It's acceptable to fake it. */
@@ -842,6 +839,7 @@ GC_INNER word GC_page_size = 0;
# define GC_AMIGA_SB
# include "extra/AmigaOS.c"
# undef GC_AMIGA_SB
+# define GET_MAIN_STACKBASE_SPECIAL
# endif /* AMIGA */
# if defined(NEED_FIND_LIMIT) || defined(UNIX_LIKE)
@@ -908,6 +906,8 @@ GC_INNER word GC_page_size = 0;
/* Some tools to implement HEURISTIC2 */
# define MIN_PAGE_SIZE 256 /* Smallest conceivable page size, bytes */
+ GC_INNER JMP_BUF GC_jmp_buf;
+
STATIC void GC_fault_handler(int sig GC_ATTR_UNUSED)
{
LONGJMP(GC_jmp_buf, 1);
@@ -950,6 +950,8 @@ GC_INNER word GC_page_size = 0;
/* static since it's only called with the */
/* allocation lock held. */
+ GC_ASSERT(up ? (word)bound >= MIN_PAGE_SIZE
+ : (word)bound <= ~(word)MIN_PAGE_SIZE);
GC_ASSERT(I_HOLD_LOCK());
GC_setup_temporary_fault_handler();
if (SETJMP(GC_jmp_buf) == 0) {
@@ -957,14 +959,13 @@ GC_INNER word GC_page_size = 0;
& ~(MIN_PAGE_SIZE-1));
for (;;) {
if (up) {
- result += MIN_PAGE_SIZE;
- if ((word)result >= (word)bound) {
+ if ((word)result >= (word)bound - MIN_PAGE_SIZE) {
result = bound;
break;
}
+ result += MIN_PAGE_SIZE; /* no overflow expected */
} else {
- result -= MIN_PAGE_SIZE;
- if ((word)result <= (word)bound) {
+ if ((word)result <= (word)bound + MIN_PAGE_SIZE) {
result = bound - MIN_PAGE_SIZE;
/* This is to compensate */
/* further result increment (we */
@@ -973,6 +974,7 @@ GC_INNER word GC_page_size = 0;
/* by setjmp otherwise). */
break;
}
+ result -= MIN_PAGE_SIZE; /* no underflow expected */
}
GC_noop1((word)(*result));
}
@@ -1191,13 +1193,13 @@ GC_INNER word GC_page_size = 0;
if (pthread_getattr_np(pthread_self(), &attr) == 0) {
if (pthread_attr_getstack(&attr, &stackaddr, &size) == 0
&& stackaddr != NULL) {
- pthread_attr_destroy(&attr);
+ (void)pthread_attr_destroy(&attr);
# ifdef STACK_GROWS_DOWN
stackaddr = (char *)stackaddr + size;
# endif
return (ptr_t)stackaddr;
}
- pthread_attr_destroy(&attr);
+ (void)pthread_attr_destroy(&attr);
}
WARN("pthread_getattr_np or pthread_attr_getstack failed"
" for main thread\n", 0);
@@ -1274,7 +1276,7 @@ GC_INNER word GC_page_size = 0;
if (pthread_attr_getstack(&attr, &(b -> mem_base), &size) != 0) {
ABORT("pthread_attr_getstack failed");
}
- pthread_attr_destroy(&attr);
+ (void)pthread_attr_destroy(&attr);
# ifdef STACK_GROWS_DOWN
b -> mem_base = (char *)(b -> mem_base) + size;
# endif
@@ -1527,6 +1529,7 @@ void GC_register_data_segments(void)
GC_add_roots_inner((ptr_t)O32_BASE(seg),
(ptr_t)(O32_BASE(seg)+O32_SIZE(seg)), FALSE);
}
+ (void)fclose(myexefile);
}
# else /* !OS2 */
@@ -1655,27 +1658,25 @@ void GC_register_data_segments(void)
GC_INNER void GC_init_win32(void)
{
-# if !defined(MSWINRT) && !defined(_XBOX_ONE)
- /* Set GC_wnt. If we're running under win32s, assume that no DLLs */
- /* will be loaded. I doubt anyone still runs win32s, but... */
- /* GetVersion is deprecated as of Windows 8.1 */
-#pragma warning( push )
-#pragma warning( disable : 4996 )
+# if defined(_WIN64) || (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(MSWINRT) || defined(_XBOX_ONE)
+ /* MS Visual Studio 2013 deprecates GetVersion, but on the other */
+ /* hand it cannot be used to target pre-Win2K. */
+ GC_wnt = TRUE;
+# else
+ /* Set GC_wnt. If we're running under win32s, assume that no */
+ /* DLLs will be loaded. I doubt anyone still runs win32s, but... */
DWORD v = GetVersion();
-#pragma warning( pop )
+
GC_wnt = !(v & 0x80000000);
GC_no_win32_dlls |= ((!GC_wnt) && (v & 0xff) <= 3);
-# ifdef USE_MUNMAP
- if (GC_no_win32_dlls) {
- /* Turn off unmapping for safety (since may not work well with */
- /* GlobalAlloc). */
- GC_unmap_threshold = 0;
- }
-# endif
-# else
- GC_no_win32_dlls = FALSE;
- GC_wnt = TRUE;
-# endif
+# endif
+# ifdef USE_MUNMAP
+ if (GC_no_win32_dlls) {
+ /* Turn off unmapping for safety (since may not work well with */
+ /* GlobalAlloc). */
+ GC_unmap_threshold = 0;
+ }
+# endif
}
/* Return the smallest address a such that VirtualQuery */
@@ -2046,7 +2047,7 @@ void GC_register_data_segments(void)
#endif
#if !defined(_XBOX_ONE)
-STATIC ptr_t GC_unix_mmap_get_mem(word bytes)
+STATIC ptr_t GC_unix_mmap_get_mem(size_t bytes)
{
void *result;
static ptr_t last_addr = HEAP_START;
@@ -2064,8 +2065,9 @@ STATIC ptr_t GC_unix_mmap_get_mem(word bytes)
# endif
if (zero_fd == -1)
ABORT("Could not open /dev/zero");
+ if (fcntl(zero_fd, F_SETFD, FD_CLOEXEC) == -1)
+ WARN("Could not set FD_CLOEXEC for /dev/zero\n", 0);
- fcntl(zero_fd, F_SETFD, FD_CLOEXEC);
initialized = TRUE;
}
# endif
@@ -2084,7 +2086,7 @@ STATIC ptr_t GC_unix_mmap_get_mem(word bytes)
/* Oops. We got the end of the address space. This isn't */
/* usable by arbitrary C code, since one-past-end pointers */
/* don't work, so we discard it and try again. */
- munmap(result, (size_t)(-GC_page_size) - (size_t)result);
+ munmap(result, ~GC_page_size - (size_t)result + 1);
/* Leave last page mapped, so we can't repeat. */
return GC_unix_mmap_get_mem(bytes);
}
@@ -2101,13 +2103,13 @@ STATIC ptr_t GC_unix_mmap_get_mem(word bytes)
# endif /* MMAP_SUPPORTED */
#if defined(USE_MMAP)
- ptr_t GC_unix_get_mem(word bytes)
+ ptr_t GC_unix_get_mem(size_t bytes)
{
return GC_unix_mmap_get_mem(bytes);
}
#else /* !USE_MMAP */
-STATIC ptr_t GC_unix_sbrk_get_mem(word bytes)
+STATIC ptr_t GC_unix_sbrk_get_mem(size_t bytes)
{
ptr_t result;
# ifdef IRIX5
@@ -2124,7 +2126,7 @@ STATIC ptr_t GC_unix_sbrk_get_mem(word bytes)
goto out;
}
if (lsbs != 0) {
- if((ptr_t)sbrk(GC_page_size - lsbs) == (ptr_t)(-1)) {
+ if((ptr_t)sbrk((SBRK_ARG_T)GC_page_size - lsbs) == (ptr_t)(-1)) {
result = 0;
goto out;
}
@@ -2148,7 +2150,7 @@ STATIC ptr_t GC_unix_sbrk_get_mem(word bytes)
return(result);
}
-ptr_t GC_unix_get_mem(word bytes)
+ptr_t GC_unix_get_mem(size_t bytes)
{
# if defined(MMAP_SUPPORTED)
/* By default, we try both sbrk and mmap, in that order. */
@@ -2209,7 +2211,7 @@ void* durango_get_mem (size_t size, size_t page_size)
#endif
#ifdef MSWINCE
- ptr_t GC_wince_get_mem(word bytes)
+ ptr_t GC_wince_get_mem(size_t bytes)
{
ptr_t result = 0; /* initialized to prevent warning. */
word i;
@@ -2229,8 +2231,9 @@ void* durango_get_mem (size_t size, size_t page_size)
if (i == GC_n_heap_bases) {
/* Reserve more pages */
- word res_bytes = (bytes + GC_sysinfo.dwAllocationGranularity-1)
- & ~(GC_sysinfo.dwAllocationGranularity-1);
+ size_t res_bytes =
+ SIZET_SAT_ADD(bytes, (size_t)GC_sysinfo.dwAllocationGranularity-1)
+ & ~((size_t)GC_sysinfo.dwAllocationGranularity-1);
/* If we ever support MPROTECT_VDB here, we will probably need to */
/* ensure that res_bytes is strictly > bytes, so that VirtualProtect */
/* never spans regions. It seems to be OK for a VirtualFree */
@@ -2280,7 +2283,7 @@ void* durango_get_mem (size_t size, size_t page_size)
# define GC_mem_top_down 0
# endif /* !GC_USE_MEM_TOP_DOWN */
- ptr_t GC_win32_get_mem(word bytes)
+ ptr_t GC_win32_get_mem(size_t bytes)
{
ptr_t result;
@@ -2292,8 +2295,8 @@ void* durango_get_mem (size_t size, size_t page_size)
/* VirtualAlloc doesn't like PAGE_EXECUTE_READWRITE. */
/* There are also unconfirmed rumors of other */
/* problems, so we dodge the issue. */
- result = (ptr_t) GlobalAlloc(0, bytes + HBLKSIZE);
- result = (ptr_t)(((word)result + HBLKSIZE - 1) & ~(HBLKSIZE-1));
+ result = (ptr_t)(((word)GlobalAlloc(0, SIZET_SAT_ADD(bytes, HBLKSIZE))
+ + HBLKSIZE - 1) & ~(HBLKSIZE - 1));
} else
# endif
/* else */ {
@@ -2322,12 +2325,13 @@ void* durango_get_mem (size_t size, size_t page_size)
/* available. Otherwise we waste resources or possibly */
/* cause VirtualAlloc to fail (observed in Windows 2000 */
/* SP2). */
- result = (ptr_t) VirtualAlloc(NULL, bytes + VIRTUAL_ALLOC_PAD,
- GetWriteWatch_alloc_flag
+ result = (ptr_t) VirtualAlloc(NULL,
+ SIZET_SAT_ADD(bytes, VIRTUAL_ALLOC_PAD),
+ GetWriteWatch_alloc_flag
| (MEM_COMMIT | MEM_RESERVE)
| GC_mem_top_down,
- GC_pages_executable ? PAGE_EXECUTE_READWRITE :
- PAGE_READWRITE);
+ GC_pages_executable ? PAGE_EXECUTE_READWRITE :
+ PAGE_READWRITE);
# undef IGNORE_PAGES_EXECUTABLE
}
# endif /* USE_WINALLOC */
@@ -2464,6 +2468,10 @@ GC_INNER void GC_unmap(ptr_t start, size_t bytes)
zero_fd, 0/* offset */);
if (result != (void *)start_addr)
ABORT("mmap(PROT_NONE) failed");
+# ifdef LINT2
+ /* Explicitly store the resource handle to a global variable. */
+ GC_noop1((word)result);
+# endif
}
GC_unmapped_bytes += len;
# endif
@@ -2498,6 +2506,9 @@ GC_INNER void GC_remap(ptr_t start, size_t bytes)
ABORT("VirtualAlloc remapping failed");
}
}
+# ifdef LINT2
+ GC_noop1((word)result);
+# endif
GC_unmapped_bytes -= alloc_len;
start_addr += alloc_len;
len -= alloc_len;
@@ -2507,12 +2518,15 @@ GC_INNER void GC_remap(ptr_t start, size_t bytes)
{
# ifdef NACL
/* NaCl does not expose mprotect, but mmap should work fine. */
- void *mmap_result = mmap(start_addr, len, (PROT_READ | PROT_WRITE)
+ void *result = mmap(start_addr, len, (PROT_READ | PROT_WRITE)
| (GC_pages_executable ? PROT_EXEC : 0),
MAP_PRIVATE | MAP_FIXED | OPT_MAP_ANON,
zero_fd, 0 /* offset */);
- if (mmap_result != (void *)start_addr)
+ if (result != (void *)start_addr)
ABORT("mmap as mprotect failed");
+# ifdef LINT2
+ GC_noop1((word)result);
+# endif
# else
if (mprotect(start_addr, len, (PROT_READ | PROT_WRITE)
| (GC_pages_executable ? PROT_EXEC : 0)) != 0) {
@@ -2570,8 +2584,11 @@ GC_INNER void GC_unmap_gap(ptr_t start1, size_t bytes1, ptr_t start2,
zero_fd, 0/* offset */);
if (result != (void *)start_addr)
ABORT("mmap(PROT_NONE) failed");
+# ifdef LINT2
+ GC_noop1((word)result);
+# endif
+ GC_unmapped_bytes += len;
}
- GC_unmapped_bytes += len;
# endif
}
@@ -3178,7 +3195,7 @@ GC_API GC_push_other_roots_proc GC_CALL GC_get_push_other_roots(void)
char * addr = (char *) (exc_info -> ExceptionRecord
-> ExceptionInformation[1]);
# endif
- unsigned i;
+ size_t i;
if (SIG_OK && CODE_OK) {
register struct hblk * h =
@@ -3685,8 +3702,7 @@ ssize_t read(int fd, void *buf, size_t nbyte)
GC_INNER void GC_dirty_init(void)
{
- int fd;
- char buf[30];
+ char buf[40];
if (GC_bytes_allocd != 0 || GC_bytes_allocd_before_gc != 0) {
memset(GC_written_pages, 0xff, sizeof(page_hash_table));
@@ -3695,19 +3711,14 @@ GC_INNER void GC_dirty_init(void)
(unsigned long)(GC_bytes_allocd + GC_bytes_allocd_before_gc));
}
- (void)snprintf(buf, sizeof(buf), "/proc/%ld", (long)getpid());
+ (void)snprintf(buf, sizeof(buf), "/proc/%ld/pagedata", (long)getpid());
buf[sizeof(buf) - 1] = '\0';
- fd = open(buf, O_RDONLY);
- if (fd < 0) {
- ABORT("/proc open failed");
- }
- GC_proc_fd = syscall(SYS_ioctl, fd, PIOCOPENPD, 0);
- close(fd);
- syscall(SYS_fcntl, GC_proc_fd, F_SETFD, FD_CLOEXEC);
+ GC_proc_fd = open(buf, O_RDONLY);
if (GC_proc_fd < 0) {
- WARN("/proc ioctl(PIOCOPENPD) failed", 0);
- return;
+ ABORT("/proc open failed");
}
+ if (syscall(SYS_fcntl, GC_proc_fd, F_SETFD, FD_CLOEXEC) == -1)
+ WARN("Could not set FD_CLOEXEC for /proc\n", 0);
GC_dirty_maintained = TRUE;
GC_proc_buf = GC_scratch_alloc(GC_proc_buf_size);
@@ -3787,7 +3798,7 @@ GC_INNER void GC_read_dirty(void)
bufp = (char *)(((word)bufp + (sizeof(long)-1)) & ~(sizeof(long)-1));
}
# ifdef DEBUG_DIRTY_BITS
- GC_log_printf("Proc VDB read done.\n");
+ GC_log_printf("Proc VDB read done\n");
# endif
/* Update GC_written_pages. */
@@ -4153,7 +4164,7 @@ STATIC void *GC_mprotect_thread(void *arg)
ABORT("Got more than 8 SIGBUSs in a row!");
} else {
GC_sigbus_count++;
- WARN("Ignoring SIGBUS.\n", 0);
+ WARN("Ignoring SIGBUS\n", 0);
}
}
#endif /* BROKEN_EXCEPTION_HANDLING */
@@ -4184,7 +4195,7 @@ GC_INNER void GC_dirty_init(void)
" virtual dirty bit implementation\n");
# ifdef BROKEN_EXCEPTION_HANDLING
WARN("Enabling workarounds for various darwin "
- "exception handling bugs.\n", 0);
+ "exception handling bugs\n", 0);
# endif
GC_dirty_maintained = TRUE;
if (GC_page_size % HBLKSIZE != 0) {
@@ -4231,7 +4242,7 @@ GC_INNER void GC_dirty_init(void)
/* This will call the real pthread function, not our wrapper */
if (pthread_create(&thread, &attr, GC_mprotect_thread, NULL) != 0)
ABORT("pthread_create failed");
- pthread_attr_destroy(&attr);
+ (void)pthread_attr_destroy(&attr);
/* Setup the sigbus handler for ignoring the meaningless SIGBUSs */
# ifdef BROKEN_EXCEPTION_HANDLING
@@ -4362,7 +4373,7 @@ catch_exception_raise(mach_port_t exception_port GC_ATTR_UNUSED,
kern_return_t r;
char *addr;
struct hblk *h;
- unsigned int i;
+ size_t i;
thread_state_flavor_t flavor = DARWIN_EXC_STATE;
mach_msg_type_number_t exc_state_count = DARWIN_EXC_STATE_COUNT;
DARWIN_EXC_STATE_T exc_state;
@@ -4629,8 +4640,10 @@ GC_INNER void GC_save_callers(struct callinfo info[NFRAMES])
for (; !((word)fp HOTTER_THAN (word)frame)
&& !((word)GC_stackbottom HOTTER_THAN (word)fp)
&& nframes < NFRAMES;
- fp = (struct frame *)((long) fp -> FR_SAVFP + BIAS), nframes++) {
- register int i;
+ fp = (struct frame *)((long) fp -> FR_SAVFP + BIAS), nframes++) {
+# if NARGS > 0
+ register int i;
+# endif
info[nframes].ci_pc = fp->FR_SAVPC;
# if NARGS > 0
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
index 642ffdf2..b805c024 100644
--- a/pthread_stop_world.c
+++ b/pthread_stop_world.c
@@ -59,7 +59,7 @@ int GC_nacl_thread_used[MAX_NACL_GC_THREADS];
# elif defined(__SIGRTMAX)
# define NSIG (__SIGRTMAX+1)
# else
- --> please fix it
+# error define NSIG
# endif
# endif /* NSIG */
@@ -129,22 +129,26 @@ STATIC volatile AO_t GC_world_is_stopped = FALSE;
* Note that we can't just stop a thread; we need it to save its stack
* pointer(s) and acknowledge.
*/
-
#ifndef SIG_THR_RESTART
-# if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) \
- || defined(GC_NETBSD_THREADS)
-# ifdef _SIGRTMIN
-# define SIG_THR_RESTART _SIGRTMIN + 5
-# else
-# define SIG_THR_RESTART SIGRTMIN + 5
-# endif
-# else
+# if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) \
+ || defined(GC_NETBSD_THREADS) || defined(GC_USESIGRT_SIGNALS)
+# ifdef _SIGRTMIN
+# define SIG_THR_RESTART _SIGRTMIN + 5
+# else
+# define SIG_THR_RESTART SIGRTMIN + 5
+# endif
+# else
# define SIG_THR_RESTART SIGXCPU
-# endif
+# endif
#endif
-STATIC int GC_sig_suspend = SIG_SUSPEND;
-STATIC int GC_sig_thr_restart = SIG_THR_RESTART;
+#define SIGNAL_UNSET (-1)
+ /* Since SIG_SUSPEND and/or SIG_THR_RESTART could represent */
+ /* a non-constant expression (e.g., in case of SIGRTMIN), */
+ /* actual signal numbers are determined by GC_stop_init() */
+ /* unless manually set (before GC initialization). */
+STATIC int GC_sig_suspend = SIGNAL_UNSET;
+STATIC int GC_sig_thr_restart = SIGNAL_UNSET;
GC_API void GC_CALL GC_set_suspend_signal(int sig)
{
@@ -162,21 +166,24 @@ GC_API void GC_CALL GC_set_thr_restart_signal(int sig)
GC_API int GC_CALL GC_get_suspend_signal(void)
{
- return GC_sig_suspend;
+ return GC_sig_suspend != SIGNAL_UNSET ? GC_sig_suspend : SIG_SUSPEND;
}
GC_API int GC_CALL GC_get_thr_restart_signal(void)
{
- return GC_sig_thr_restart;
+ return GC_sig_thr_restart != SIGNAL_UNSET
+ ? GC_sig_thr_restart : SIG_THR_RESTART;
}
#ifdef GC_EXPLICIT_SIGNALS_UNBLOCK
- /* Some targets (eg., Solaris) might require this to be called when */
+ /* Some targets (e.g., Solaris) might require this to be called when */
/* doing thread registering from the thread destructor. */
GC_INNER void GC_unblock_gc_signals(void)
{
sigset_t set;
sigemptyset(&set);
+ GC_ASSERT(GC_sig_suspend != SIGNAL_UNSET);
+ GC_ASSERT(GC_sig_thr_restart != SIGNAL_UNSET);
sigaddset(&set, GC_sig_suspend);
sigaddset(&set, GC_sig_thr_restart);
if (pthread_sigmask(SIG_UNBLOCK, &set, NULL) != 0)
@@ -864,6 +871,13 @@ GC_INNER void GC_stop_init(void)
# if !defined(GC_OPENBSD_UTHREADS) && !defined(NACL)
struct sigaction act;
+ if (SIGNAL_UNSET == GC_sig_suspend)
+ GC_sig_suspend = SIG_SUSPEND;
+ if (SIGNAL_UNSET == GC_sig_thr_restart)
+ GC_sig_thr_restart = SIG_THR_RESTART;
+ if (GC_sig_suspend == GC_sig_thr_restart)
+ ABORT("Cannot use same signal for thread suspend and resume");
+
if (sem_init(&GC_suspend_ack_sem, GC_SEM_INIT_PSHARED, 0) != 0)
ABORT("sem_init failed");
# ifdef GC_NETBSD_THREADS_WORKAROUND
@@ -897,8 +911,6 @@ GC_INNER void GC_stop_init(void)
act.sa_handler = GC_suspend_handler;
# endif
/* act.sa_restorer is deprecated and should not be initialized. */
- if (GC_sig_suspend == GC_sig_thr_restart)
- ABORT("Cannot use same signal for thread suspend and resume");
if (sigaction(GC_sig_suspend, &act, NULL) != 0) {
ABORT("Cannot set SIG_SUSPEND handler");
}
diff --git a/pthread_support.c b/pthread_support.c
index f57dbe1c..73a12c74 100644
--- a/pthread_support.c
+++ b/pthread_support.c
@@ -27,23 +27,6 @@
* all flavors of pthread support code into this file.
*/
-/*
- * Linux_threads.c now also includes some code to support HPUX and
- * OSF1 (Compaq Tru64 Unix, really). The OSF1 support is based on Eric Benson's
- * patch.
- *
- * Eric also suggested an alternate basis for a lock implementation in
- * his code:
- * + #elif defined(OSF1)
- * + unsigned long GC_allocate_lock = 0;
- * + msemaphore GC_allocate_semaphore;
- * + # define GC_TRY_LOCK() \
- * + ((msem_lock(&GC_allocate_semaphore, MSEM_IF_NOWAIT) == 0) \
- * + ? (GC_allocate_lock = 1) \
- * + : 0)
- * + # define GC_LOCK_TAKEN GC_allocate_lock
- */
-
#if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS)
# include <stdlib.h>
# include <pthread.h>
@@ -371,6 +354,12 @@ STATIC void * GC_mark_thread(void * id)
marker_mach_threads[(word)id] = mach_thread_self();
# endif
+ /* Inform start_mark_threads() about completion of marker data init. */
+ GC_acquire_mark_lock();
+ if (0 == --GC_fl_builder_count)
+ GC_notify_all_builder();
+ GC_release_mark_lock();
+
for (;; ++my_mark_no) {
/* GC_mark_no is passed only to allow GC_help_marker to terminate */
/* promptly. This is important if it were called from the signal */
@@ -407,6 +396,7 @@ start_mark_threads(void)
pthread_attr_t attr;
GC_ASSERT(I_DONT_HOLD_LOCK());
+ GC_ASSERT(GC_fl_builder_count == 0);
# ifdef CAN_HANDLE_FORK
if (available_markers_m1 <= 0 || GC_parallel) return;
/* Skip if parallel markers disabled or already started. */
@@ -444,7 +434,8 @@ start_mark_threads(void)
}
}
GC_markers_m1 = i;
- pthread_attr_destroy(&attr);
+ (void)pthread_attr_destroy(&attr);
+ GC_wait_for_markers_init();
GC_COND_LOG_PRINTF("Started %d mark helper threads\n", GC_markers_m1);
}
@@ -1030,6 +1021,10 @@ static void fork_child_proc(void)
ptr_t *startp, ptr_t *endp);
#endif
+#ifdef PARALLEL_MARK
+ static void setup_mark_lock(void);
+#endif
+
/* We hold the allocation lock. */
GC_INNER void GC_thr_init(void)
{
@@ -1107,30 +1102,31 @@ GC_INNER void GC_thr_init(void)
available_markers_m1 = 0; /* but use only one marker */
# endif
} else {
-# ifdef PARALLEL_MARK
- {
- char * markers_string = GETENV("GC_MARKERS");
- int markers_m1;
-
- if (markers_string != NULL) {
- markers_m1 = atoi(markers_string) - 1;
- if (markers_m1 >= MAX_MARKERS) {
- WARN("Limiting number of mark threads\n", 0);
- markers_m1 = MAX_MARKERS - 1;
- }
- } else {
- markers_m1 = GC_nprocs - 1;
-# ifdef GC_MIN_MARKERS
- /* This is primarily for targets without getenv(). */
- if (markers_m1 < GC_MIN_MARKERS - 1)
- markers_m1 = GC_MIN_MARKERS - 1;
-# endif
- if (markers_m1 >= MAX_MARKERS)
- markers_m1 = MAX_MARKERS - 1; /* silently limit the value */
- }
- available_markers_m1 = markers_m1;
- }
-# endif
+# ifdef PARALLEL_MARK
+ {
+ char * markers_string = GETENV("GC_MARKERS");
+ int markers;
+
+ if (markers_string != NULL) {
+ markers = atoi(markers_string);
+ if (markers <= 0 || markers > MAX_MARKERS) {
+ WARN("Too big or invalid number of mark threads: %" WARN_PRIdPTR
+ "; using maximum threads\n", (signed_word)markers);
+ markers = MAX_MARKERS;
+ }
+ } else {
+ markers = GC_nprocs;
+# ifdef GC_MIN_MARKERS
+ /* This is primarily for targets without getenv(). */
+ if (markers < GC_MIN_MARKERS)
+ markers = GC_MIN_MARKERS;
+# endif
+ if (markers > MAX_MARKERS)
+ markers = MAX_MARKERS; /* silently limit the value */
+ }
+ available_markers_m1 = markers - 1;
+ }
+# endif
}
GC_COND_LOG_PRINTF("Number of processors = %d\n", GC_nprocs);
# ifdef PARALLEL_MARK
@@ -1142,6 +1138,7 @@ GC_INNER void GC_thr_init(void)
} else {
/* Disable true incremental collection, but generational is OK. */
GC_time_limit = GC_TIME_UNLIMITED;
+ setup_mark_lock();
/* If we are using a parallel marker, actually start helper threads. */
start_mark_threads();
}
@@ -1183,7 +1180,8 @@ GC_INNER void GC_init_parallel(void)
fudged_set = *set;
sig_suspend = GC_get_suspend_signal();
GC_ASSERT(sig_suspend >= 0);
- sigdelset(&fudged_set, sig_suspend);
+ if (sigdelset(&fudged_set, sig_suspend) != 0)
+ ABORT("sigdelset failed");
set = &fudged_set;
}
return(REAL_FUNC(pthread_sigmask)(how, set, oset));
@@ -1367,13 +1365,13 @@ GC_API int GC_CALL GC_unregister_my_thread(void)
/* resources or id anyway. */
GC_INNER_PTHRSTART void GC_thread_exit_proc(void *arg)
{
+ IF_CANCEL(int cancel_state;)
+ DCL_LOCK_STATE;
+
# ifdef DEBUG_THREADS
GC_log_printf("Called GC_thread_exit_proc on %p, gc_thread = %p\n",
(void *)((GC_thread)arg)->id, arg);
# endif
- IF_CANCEL(int cancel_state;)
- DCL_LOCK_STATE;
-
LOCK();
DISABLE_CANCEL(cancel_state);
GC_wait_for_gc_completion(FALSE);
@@ -1704,14 +1702,17 @@ GC_API int WRAP_FUNC(pthread_create)(pthread_t *new_thread,
{
size_t stack_size = 0;
if (NULL != attr) {
- pthread_attr_getstacksize(attr, &stack_size);
+ if (pthread_attr_getstacksize(attr, &stack_size) != 0)
+ ABORT("pthread_attr_getstacksize failed");
}
if (0 == stack_size) {
pthread_attr_t my_attr;
- pthread_attr_init(&my_attr);
- pthread_attr_getstacksize(&my_attr, &stack_size);
- pthread_attr_destroy(&my_attr);
+ if (pthread_attr_init(&my_attr) != 0)
+ ABORT("pthread_attr_init failed");
+ if (pthread_attr_getstacksize(&my_attr, &stack_size) != 0)
+ ABORT("pthread_attr_getstacksize failed");
+ (void)pthread_attr_destroy(&my_attr);
}
/* On Solaris 10, with default attr initialization, */
/* stack_size remains 0. Fudge it. */
@@ -2010,9 +2011,60 @@ GC_INNER void GC_lock(void)
static pthread_cond_t builder_cv = PTHREAD_COND_INITIALIZER;
+#ifdef GLIBC_2_19_TSX_BUG
+ /* Parse string like <major>[.<minor>[<tail>]] and return major value. */
+ static int parse_version(int *pminor, const char *pverstr) {
+ char *endp;
+ unsigned long value = strtoul(pverstr, &endp, 10);
+ int major = (int)value;
+
+ if (major < 0 || (char *)pverstr == endp || (unsigned)major != value) {
+ /* Parse error */
+ return -1;
+ }
+ if (*endp != '.') {
+ /* No minor part. */
+ *pminor = -1;
+ } else {
+ value = strtoul(endp + 1, &endp, 10);
+ *pminor = (int)value;
+ if (*pminor < 0 || (unsigned)(*pminor) != value) {
+ return -1;
+ }
+ }
+ return major;
+ }
+#endif /* GLIBC_2_19_TSX_BUG */
+
+static void setup_mark_lock(void)
+{
+# ifdef GLIBC_2_19_TSX_BUG
+ pthread_mutexattr_t mattr;
+ int glibc_minor = -1;
+ int glibc_major = parse_version(&glibc_minor, gnu_get_libc_version());
+
+ if (glibc_major > 2 || (glibc_major == 2 && glibc_minor >= 19)) {
+ /* TODO: disable this workaround for glibc with fixed TSX */
+ /* This disables lock elision to workaround a bug in glibc 2.19+ */
+ if (0 != pthread_mutexattr_init(&mattr)) {
+ ABORT("pthread_mutexattr_init failed");
+ }
+ if (0 != pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_NORMAL)) {
+ ABORT("pthread_mutexattr_settype failed");
+ }
+ if (0 != pthread_mutex_init(&mark_mutex, &mattr)) {
+ ABORT("pthread_mutex_init failed");
+ }
+ (void)pthread_mutexattr_destroy(&mattr);
+ }
+# endif
+}
+
GC_INNER void GC_acquire_mark_lock(void)
{
- GC_ASSERT(GC_mark_lock_holder != NUMERIC_THREAD_ID(pthread_self()));
+# ifdef NUMERIC_THREAD_ID_UNIQUE
+ GC_ASSERT(GC_mark_lock_holder != NUMERIC_THREAD_ID(pthread_self()));
+# endif
GC_generic_lock(&mark_mutex);
SET_MARK_LOCK_HOLDER;
}
diff --git a/ptr_chck.c b/ptr_chck.c
index 011b27ef..e86378e9 100644
--- a/ptr_chck.c
+++ b/ptr_chck.c
@@ -178,7 +178,7 @@ void (GC_CALLBACK *GC_is_visible_print_proc)(void * p) =
/* Check that p is visible */
/* to the collector as a possibly pointer containing location. */
-/* If it isn't invoke *GC_is_visible_print_proc. */
+/* If it isn't, invoke *GC_is_visible_print_proc. */
/* Returns the argument in all cases. May erroneously succeed */
/* in hard cases. (This is intended for debugging use with */
/* untyped allocations. The idea is that it should be possible, though */
diff --git a/src/sparc_mach_dep.S b/sparc_mach_dep.S
index d204dc43..d204dc43 100644
--- a/src/sparc_mach_dep.S
+++ b/sparc_mach_dep.S
diff --git a/src/sparc_netbsd_mach_dep.s b/sparc_netbsd_mach_dep.s
index 14feb15e..14feb15e 100644
--- a/src/sparc_netbsd_mach_dep.s
+++ b/sparc_netbsd_mach_dep.s
diff --git a/src/sparc_sunos4_mach_dep.s b/sparc_sunos4_mach_dep.s
index 923f5eaa..923f5eaa 100644
--- a/src/sparc_sunos4_mach_dep.s
+++ b/sparc_sunos4_mach_dep.s
diff --git a/specific.c b/specific.c
index 3657fbad..ba23e47d 100644
--- a/specific.c
+++ b/specific.c
@@ -26,12 +26,14 @@ static const tse invalid_tse = {INVALID_QTID, 0, 0, INVALID_THREADID};
GC_INNER int GC_key_create_inner(tsd ** key_ptr)
{
int i;
+ int ret;
tsd * result = (tsd *)MALLOC_CLEAR(sizeof(tsd));
/* A quick alignment check, since we need atomic stores */
GC_ASSERT((word)(&invalid_tse.next) % sizeof(tse *) == 0);
if (0 == result) return ENOMEM;
- pthread_mutex_init(&(result -> lock), NULL);
+ ret = pthread_mutex_init(&result->lock, NULL);
+ if (ret != 0) return ret;
for (i = 0; i < TS_CACHE_SIZE; ++i) {
result -> cache[i] = (/* no const */ tse *)&invalid_tse;
}
diff --git a/stubborn.c b/stubborn.c
index 82f11389..cc5d08ae 100644
--- a/stubborn.c
+++ b/stubborn.c
@@ -24,7 +24,7 @@
void GC_dirty(ptr_t p);
- GC_API void * GC_CALL GC_malloc_stubborn(size_t lb)
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_stubborn(size_t lb)
{
return(GC_malloc(lb));
}
@@ -40,7 +40,7 @@
#else /* !MANUAL_VDB */
- GC_API void * GC_CALL GC_malloc_stubborn(size_t lb)
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_stubborn(size_t lb)
{
return(GC_malloc(lb));
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 0f4d455f..a24872c9 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -17,3 +17,4 @@
ADD_DEFINITIONS(-DGC_NOT_DLL)
ADD_EXECUTABLE(gctest WIN32 test.c)
TARGET_LINK_LIBRARIES(gctest gc-lib)
+ADD_TEST(NAME gctest COMMAND gctest)
diff --git a/tests/disclaim_bench.c b/tests/disclaim_bench.c
index 5159829c..a2fc3972 100644
--- a/tests/disclaim_bench.c
+++ b/tests/disclaim_bench.c
@@ -53,7 +53,7 @@ testobj_t testobj_new(int model)
case 0:
obj = GC_MALLOC(sizeof(struct testobj_s));
if (obj != NULL)
- GC_register_finalizer_no_order(obj, testobj_finalize,
+ GC_REGISTER_FINALIZER_NO_ORDER(obj, testobj_finalize,
&free_count, NULL, NULL);
break;
case 1:
@@ -91,9 +91,6 @@ int main(int argc, char **argv)
GC_INIT();
GC_init_finalized_malloc();
-
- keep_arr = GC_MALLOC(sizeof(void *)*KEEP_CNT);
-
if (argc == 2 && strcmp(argv[1], "--help") == 0) {
fprintf(stderr,
"Usage: %s [FINALIZATION_MODEL]\n"
@@ -112,15 +109,21 @@ int main(int argc, char **argv)
model_max = 2;
}
+ keep_arr = GC_MALLOC(sizeof(void *) * KEEP_CNT);
+ if (NULL == keep_arr) {
+ fprintf(stderr, "Out of memory!\n");
+ exit(3);
+ }
+
printf("\t\t\tfin. ratio time/s time/fin.\n");
for (model = model_min; model <= model_max; ++model) {
double t = 0.0;
- free_count = 0;
-
# ifdef CLOCK_TYPE
CLOCK_TYPE tI, tF;
+
GET_TIME(tI);
# endif
+ free_count = 0;
for (i = 0; i < ALLOC_CNT; ++i) {
int k = rand() % KEEP_CNT;
keep_arr[k] = testobj_new(model);
@@ -131,11 +134,11 @@ int main(int argc, char **argv)
t = MS_TIME_DIFF(tF, tI)*1e-3;
# endif
- if (model < 2)
- printf("%20s: %12.4lf %12lg %12lg\n", model_str[model],
+ if (model < 2 && free_count > 0)
+ printf("%20s: %12.4f %12g %12g\n", model_str[model],
free_count/(double)ALLOC_CNT, t, t/free_count);
else
- printf("%20s: %12.4lf %12lg %12s\n",
+ printf("%20s: %12.4f %12g %12s\n",
model_str[model], 0.0, t, "N/A");
}
return 0;
diff --git a/tests/disclaim_test.c b/tests/disclaim_test.c
index 7bba6fb8..a59c2361 100644
--- a/tests/disclaim_test.c
+++ b/tests/disclaim_test.c
@@ -25,6 +25,7 @@
# include "config.h"
#endif
+#undef GC_NO_THREAD_REDIRECTS
#include "gc_disclaim.h"
#define my_assert(e) \
diff --git a/tests/initsecondarythread.c b/tests/initsecondarythread.c
index 5f214050..73cc298d 100644
--- a/tests/initsecondarythread.c
+++ b/tests/initsecondarythread.c
@@ -74,6 +74,7 @@ int main(void)
/* GC_INIT() must be called from main thread only. */
GC_INIT();
# endif
+ (void)GC_get_parallel(); /* linking fails if no threads support */
# ifdef GC_PTHREADS
if ((code = pthread_create (&t, NULL, thread, NULL)) != 0) {
fprintf(stderr, "Thread creation failed %d\n", code);
diff --git a/tests/test.c b/tests/test.c
index 34c6307b..a06df7ec 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -28,6 +28,7 @@
# define GC_DEBUG
#endif
+#undef GC_NO_THREAD_REDIRECTS
#include "gc.h"
#ifndef NTHREADS /* Number of additional threads to fork. */
@@ -96,6 +97,8 @@
# ifndef NO_TEST_HANDLE_FORK
# include <unistd.h>
+# include <sys/types.h>
+# include <sys/wait.h>
# ifdef HANDLE_FORK
# define INIT_FORK_SUPPORT GC_set_handle_fork(1)
/* Causes abort in GC_init on pthread_atfork failure. */
@@ -116,7 +119,7 @@
# include <stdarg.h>
-#define CHECH_GCLIB_VERSION \
+#define CHECK_GCLIB_VERSION \
if (GC_get_version() != ((GC_VERSION_MAJOR<<16) \
| (GC_VERSION_MINOR<<8) \
| GC_VERSION_MICRO)) { \
@@ -135,7 +138,7 @@
#endif
#define GC_COND_INIT() \
- INIT_FORK_SUPPORT; GC_OPT_INIT; CHECH_GCLIB_VERSION; INIT_PRINT_STATS
+ INIT_FORK_SUPPORT; GC_OPT_INIT; CHECK_GCLIB_VERSION; INIT_PRINT_STATS
#define CHECK_OUT_OF_MEMORY(p) \
if ((p) == NULL) { \
@@ -155,7 +158,7 @@ int realloc_count = 0;
void GC_amiga_free_all_mem(void);
void Amiga_Fail(void){GC_amiga_free_all_mem();abort();}
-# define FAIL (void)Amiga_Fail()
+# define FAIL Amiga_Fail()
void *GC_amiga_gctest_malloc_explicitly_typed(size_t lb, GC_descr d){
void *ret=GC_malloc_explicitly_typed(lb,d);
if(ret==NULL){
@@ -188,7 +191,7 @@ int realloc_count = 0;
#else /* !AMIGA_FASTALLOC */
# if defined(PCR) || defined(LINT2)
-# define FAIL (void)abort()
+# define FAIL abort()
# else
# define FAIL ABORT("Test failed")
# endif
@@ -358,7 +361,7 @@ sexpr reverse1(sexpr x, sexpr y)
sexpr reverse(sexpr x)
{
# ifdef TEST_WITH_SYSTEM_MALLOC
- malloc(100000);
+ GC_noop1(GC_HIDE_POINTER(malloc(100000)));
# endif
return( reverse1(x, nil) );
}
@@ -412,6 +415,10 @@ sexpr uncollectable_ints(int low, int up)
void check_ints(sexpr list, int low, int up)
{
+ if (is_nil(list)) {
+ GC_printf("list is nil\n");
+ FAIL;
+ }
if (SEXPR_TO_INT(car(car(list))) != low) {
GC_printf(
"List reversal produced incorrect list - collector is broken\n");
@@ -1148,6 +1155,10 @@ void run_one_test(void)
CLOCK_TYPE reverse_time;
CLOCK_TYPE tree_time;
unsigned long time_diff;
+# ifndef NO_TEST_HANDLE_FORK
+ pid_t pid;
+ int wstatus;
+# endif
# ifdef FIND_LEAK
GC_printf(
@@ -1222,6 +1233,7 @@ void run_one_test(void)
FAIL;
}
z = GC_malloc(8);
+ CHECK_OUT_OF_MEMORY(z);
GC_PTR_STORE(z, x);
if (*z != x) {
GC_printf("GC_PTR_STORE failed: %p != %p\n", (void *)(*z), (void *)x);
@@ -1309,10 +1321,23 @@ void run_one_test(void)
GC_free(GC_malloc_atomic(0));
# ifndef NO_TEST_HANDLE_FORK
GC_atfork_prepare();
- if (fork() != 0) {
+ pid = fork();
+ if (pid != 0) {
GC_atfork_parent();
+ if (pid == -1) {
+ GC_printf("Process fork failed\n");
+ FAIL;
+ }
if (print_stats)
- GC_log_printf("Forked child process (or failed)\n");
+ GC_log_printf("Forked child process\n");
+ if (waitpid(pid, &wstatus, 0) == -1) {
+ GC_printf("Wait for child process failed\n");
+ FAIL;
+ }
+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
+ GC_printf("Child process failed, status= 0x%x\n", wstatus);
+ FAIL;
+ }
} else {
GC_atfork_child();
if (print_stats)
@@ -1499,7 +1524,7 @@ void check_heap_stats(void)
(unsigned long)GC_get_total_bytes());
GC_printf("Final heap size is %lu bytes\n",
(unsigned long)GC_get_heap_size());
- if (GC_get_total_bytes() < n_tests *
+ if (GC_get_total_bytes() < (size_t)n_tests *
# ifdef VERY_SMALL_CONFIG
2700000
# else
@@ -1852,11 +1877,17 @@ int main(void)
# endif
GC_COND_INIT();
- pthread_attr_init(&attr);
+ if ((code = pthread_attr_init(&attr)) != 0) {
+ GC_printf("pthread_attr_init failed, error=%d\n", code);
+ FAIL;
+ }
# if defined(GC_IRIX_THREADS) || defined(GC_FREEBSD_THREADS) \
|| defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS) \
|| defined(GC_OPENBSD_THREADS)
- pthread_attr_setstacksize(&attr, 1000000);
+ if ((code = pthread_attr_setstacksize(&attr, 1000 * 1024)) != 0) {
+ GC_printf("pthread_attr_setstacksize failed, error=%d\n", code);
+ FAIL;
+ }
# endif
n_tests = 0;
# if (defined(MPROTECT_VDB)) && !defined(REDIRECT_MALLOC) \
@@ -1894,7 +1925,7 @@ int main(void)
}
check_heap_stats();
(void)fflush(stdout);
- pthread_attr_destroy(&attr);
+ (void)pthread_attr_destroy(&attr);
# ifdef PTW32_STATIC_LIB
pthread_win32_thread_detach_np ();
pthread_win32_process_detach_np ();
diff --git a/tests/thread_leak_test.c b/tests/thread_leak_test.c
index 845de00e..8fedbd15 100644
--- a/tests/thread_leak_test.c
+++ b/tests/thread_leak_test.c
@@ -7,6 +7,7 @@
# define GC_THREADS
#endif
+#undef GC_NO_THREAD_REDIRECTS
#include "leak_detector.h"
#ifdef GC_PTHREADS
diff --git a/tests/threadkey_test.c b/tests/threadkey_test.c
index f87530e3..859f53fd 100644
--- a/tests/threadkey_test.c
+++ b/tests/threadkey_test.c
@@ -11,6 +11,9 @@
#include "gc.h"
+#include <stdio.h>
+#include <stdlib.h>
+
#if (!defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) \
|| defined(__native_client__)) && !defined(SKIP_THREADKEY_TEST)
/* FIXME: Skip this test on Solaris for now. The test may fail on */
@@ -21,8 +24,6 @@
#ifdef SKIP_THREADKEY_TEST
-#include <stdio.h>
-
int main (void)
{
printf("threadkey_test skipped\n");
@@ -91,7 +92,11 @@ int main (void)
void *res;
if (GC_pthread_create (&t, NULL, entry, NULL) == 0
&& (i & 1) != 0) {
- (void)GC_pthread_join(t, &res);
+ int code = GC_pthread_join(t, &res);
+ if (code != 0) {
+ fprintf(stderr, "Thread join failed %d\n", code);
+ exit(2);
+ }
}
}
return 0;
diff --git a/thread_local_alloc.c b/thread_local_alloc.c
index a35b0c3f..a9f9f27f 100644
--- a/thread_local_alloc.c
+++ b/thread_local_alloc.c
@@ -144,7 +144,7 @@ GC_INNER void GC_destroy_thread_local(GC_tlfs p)
GC_bool GC_is_thread_tsd_valid(void *tsd);
#endif
-GC_API void * GC_CALL GC_malloc(size_t bytes)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc(size_t bytes)
{
size_t granules = ROUNDED_UP_GRANULES(bytes);
void *tsd;
@@ -152,13 +152,16 @@ GC_API void * GC_CALL GC_malloc(size_t bytes)
void **tiny_fl;
# if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_WIN32_SPECIFIC)
+ {
GC_key_t k = GC_thread_key;
+
if (EXPECT(0 == k, FALSE)) {
/* We haven't yet run GC_init_parallel. That means */
/* we also aren't locking, so this is fairly cheap. */
return GC_core_malloc(bytes);
}
tsd = GC_getspecific(k);
+ }
# else
tsd = GC_getspecific(GC_thread_key);
# endif
@@ -181,7 +184,7 @@ GC_API void * GC_CALL GC_malloc(size_t bytes)
return result;
}
-GC_API void * GC_CALL GC_malloc_atomic(size_t bytes)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_atomic(size_t bytes)
{
size_t granules = ROUNDED_UP_GRANULES(bytes);
void *tsd;
@@ -237,7 +240,7 @@ GC_API void * GC_CALL GC_malloc_atomic(size_t bytes)
/* incremental GC should be enabled before we fork a second thread. */
/* Unlike the other thread local allocation calls, we assume that the */
/* collector has been explicitly initialized. */
-GC_API void * GC_CALL GC_gcj_malloc(size_t bytes,
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_gcj_malloc(size_t bytes,
void * ptr_to_struct_containing_descr)
{
if (EXPECT(GC_incremental, FALSE)) {
diff --git a/tools/if_not_there.c b/tools/if_not_there.c
index c0f095d0..652126d4 100644
--- a/tools/if_not_there.c
+++ b/tools/if_not_there.c
@@ -16,8 +16,14 @@ int main(int argc, char **argv)
DIR * d;
#endif /* __DJGPP__ */
if (argc < 3) goto Usage;
- if ((f = fopen(argv[1], "rb")) != 0
- || (f = fopen(argv[1], "r")) != 0) {
+
+ f = fopen(argv[1], "rb");
+ if (f != NULL) {
+ fclose(f);
+ return(0);
+ }
+ f = fopen(argv[1], "r");
+ if (f != NULL) {
fclose(f);
return(0);
}
diff --git a/tools/setjmp_t.c b/tools/setjmp_t.c
index 1d9a1ad0..07247415 100644
--- a/tools/setjmp_t.c
+++ b/tools/setjmp_t.c
@@ -60,24 +60,29 @@ struct {
char * a_b;
} a;
-int * nested_sp(void)
+word nested_sp(void)
{
volatile word sp;
sp = (word)(&sp);
- return (int *)sp;
+ return sp;
}
+/* To prevent nested_sp inlining. */
+word (*volatile nested_sp_fn)(void) = nested_sp;
+
+int g(int x);
+
int main(void)
{
volatile word sp;
- long ps = GETPAGESIZE();
+ unsigned ps = GETPAGESIZE();
jmp_buf b;
register int x = (int)strlen("a"); /* 1, slightly disguised */
static int y = 0;
sp = (word)(&sp);
printf("This appears to be a %s running %s\n", MACH_TYPE, OS_TYPE);
- if ((word)nested_sp() < sp) {
+ if (nested_sp_fn() < sp) {
printf("Stack appears to grow down, which is the default.\n");
printf("A good guess for STACKBOTTOM on this machine is 0x%lx.\n",
((unsigned long)sp + ps) & ~(ps-1));
@@ -90,7 +95,7 @@ int main(void)
printf("Note that this may vary between machines of ostensibly\n");
printf("the same architecture (e.g. Sun 3/50s and 3/80s).\n");
printf("On many machines the value is not fixed.\n");
- printf("A good guess for ALIGNMENT on this machine is %ld.\n",
+ printf("A good guess for ALIGNMENT on this machine is %lu.\n",
(unsigned long)((word)(&(a.a_b)) - (word)(&a)));
printf("The following is a very dubious test of one root marking"
@@ -136,6 +141,7 @@ int main(void)
# ifdef PARALLEL_MARK
printf("Parallel marking enabled.\n");
# endif
+ (void)g(x);
return(0);
}
diff --git a/typd_mlc.c b/typd_mlc.c
index 00f78ce5..12bdd8ac 100644
--- a/typd_mlc.c
+++ b/typd_mlc.c
@@ -41,8 +41,6 @@
#define TYPD_EXTRA_BYTES (sizeof(word) - EXTRA_BYTES)
-STATIC GC_bool GC_explicit_typing_initialized = FALSE;
-
STATIC int GC_explicit_kind = 0;
/* Object kind for objects with indirect */
/* (possibly extended) descriptors. */
@@ -100,6 +98,18 @@ STATIC size_t GC_avail_descr = 0; /* Next available slot. */
STATIC int GC_typed_mark_proc_index = 0; /* Indices of my mark */
STATIC int GC_array_mark_proc_index = 0; /* procedures. */
+#if !defined(AO_HAVE_load_acquire) && defined(GC_FORCE_INCLUDE_ATOMIC_OPS)
+# include "atomic_ops.h"
+#endif
+
+STATIC
+# ifdef AO_HAVE_load_acquire
+ AO_t
+# else
+ GC_bool
+# endif
+ GC_explicit_typing_initialized = FALSE;
+
STATIC void GC_push_typed_structures_proc(void)
{
GC_push_all((ptr_t)&GC_ext_descriptors,
@@ -344,19 +354,11 @@ STATIC mse * GC_typed_mark_proc(word * addr, mse * mark_stack_ptr,
STATIC mse * GC_array_mark_proc(word * addr, mse * mark_stack_ptr,
mse * mark_stack_limit, word env);
-/* Caller does not hold allocation lock. */
STATIC void GC_init_explicit_typing(void)
{
- register unsigned i;
- DCL_LOCK_STATE;
+ unsigned i;
GC_STATIC_ASSERT(sizeof(struct LeafDescriptor) % sizeof(word) == 0);
- LOCK();
- if (GC_explicit_typing_initialized) {
- UNLOCK();
- return;
- }
- GC_explicit_typing_initialized = TRUE;
/* Set up object kind with simple indirect descriptor. */
GC_eobjfreelist = (ptr_t *)GC_new_free_list_inner();
GC_explicit_kind = GC_new_kind_inner(
@@ -372,10 +374,10 @@ STATIC void GC_init_explicit_typing(void)
(void **)GC_arobjfreelist,
GC_MAKE_PROC(GC_array_mark_proc_index, 0),
FALSE, TRUE);
- for (i = 0; i < WORDSZ/2; i++) {
+ GC_bm_table[0] = GC_DS_BITMAP;
+ for (i = 1; i < WORDSZ/2; i++) {
GC_bm_table[i] = (((word)-1) << (WORDSZ - i)) | GC_DS_BITMAP;
}
- UNLOCK();
}
STATIC mse * GC_typed_mark_proc(word * addr, mse * mark_stack_ptr,
@@ -537,9 +539,26 @@ GC_API GC_descr GC_CALL GC_make_descriptor(const GC_word * bm, size_t len)
GC_descr result;
signed_word i;
# define HIGH_BIT (((word)1) << (WORDSZ - 1))
+ DCL_LOCK_STATE;
- if (!EXPECT(GC_explicit_typing_initialized, TRUE))
- GC_init_explicit_typing();
+# if defined(THREADS) && defined(AO_HAVE_load_acquire)
+ if (!EXPECT(AO_load_acquire(
+ (volatile AO_t *)&GC_explicit_typing_initialized),
+ TRUE))
+# endif
+ {
+ LOCK();
+# if defined(THREADS) && defined(AO_HAVE_load_acquire)
+ if (!GC_explicit_typing_initialized)
+# else
+ if (!EXPECT(GC_explicit_typing_initialized, TRUE))
+# endif
+ {
+ GC_init_explicit_typing();
+ GC_explicit_typing_initialized = TRUE;
+ }
+ UNLOCK();
+ }
while (last_set_bit >= 0 && !GC_get_bit(bm, last_set_bit))
last_set_bit--;
@@ -581,15 +600,17 @@ GC_API GC_descr GC_CALL GC_make_descriptor(const GC_word * bm, size_t len)
}
}
-GC_API void * GC_CALL GC_malloc_explicitly_typed(size_t lb, GC_descr d)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_explicitly_typed(size_t lb,
+ GC_descr d)
{
ptr_t op;
ptr_t * opp;
size_t lg;
DCL_LOCK_STATE;
- lb += TYPD_EXTRA_BYTES;
- if(SMALL_OBJ(lb)) {
+ GC_ASSERT(GC_explicit_typing_initialized);
+ lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES);
+ if (SMALL_OBJ(lb)) {
GC_DBG_COLLECT_AT_MALLOC(lb);
lg = GC_size_map[lb];
opp = &(GC_eobjfreelist[lg]);
@@ -617,16 +638,17 @@ GC_API void * GC_CALL GC_malloc_explicitly_typed(size_t lb, GC_descr d)
return((void *) op);
}
-GC_API void * GC_CALL GC_malloc_explicitly_typed_ignore_off_page(size_t lb,
- GC_descr d)
+GC_API GC_ATTR_MALLOC void * GC_CALL
+ GC_malloc_explicitly_typed_ignore_off_page(size_t lb, GC_descr d)
{
ptr_t op;
ptr_t * opp;
size_t lg;
DCL_LOCK_STATE;
- lb += TYPD_EXTRA_BYTES;
- if( SMALL_OBJ(lb) ) {
+ GC_ASSERT(GC_explicit_typing_initialized);
+ lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES);
+ if (SMALL_OBJ(lb)) {
GC_DBG_COLLECT_AT_MALLOC(lb);
lg = GC_size_map[lb];
opp = &(GC_eobjfreelist[lg]);
@@ -654,8 +676,8 @@ GC_API void * GC_CALL GC_malloc_explicitly_typed_ignore_off_page(size_t lb,
return((void *) op);
}
-GC_API void * GC_CALL GC_calloc_explicitly_typed(size_t n, size_t lb,
- GC_descr d)
+GC_API GC_ATTR_MALLOC void * GC_CALL GC_calloc_explicitly_typed(size_t n,
+ size_t lb, GC_descr d)
{
ptr_t op;
ptr_t * opp;
@@ -666,18 +688,23 @@ GC_API void * GC_CALL GC_calloc_explicitly_typed(size_t n, size_t lb,
struct LeafDescriptor leaf;
DCL_LOCK_STATE;
- descr_type = GC_make_array_descriptor((word)n, (word)lb, d,
- &simple_descr, &complex_descr, &leaf);
+ GC_ASSERT(GC_explicit_typing_initialized);
+ descr_type = GC_make_array_descriptor((word)n, (word)lb, d, &simple_descr,
+ &complex_descr, &leaf);
+ if ((lb | n) > GC_SQRT_SIZE_MAX /* fast initial check */
+ && lb > 0 && n > GC_SIZE_MAX / lb)
+ return (*GC_get_oom_fn())(GC_SIZE_MAX); /* n*lb overflow */
+ lb *= n;
switch(descr_type) {
case NO_MEM: return(0);
- case SIMPLE: return(GC_malloc_explicitly_typed(n*lb, simple_descr));
+ case SIMPLE:
+ return GC_malloc_explicitly_typed(lb, simple_descr);
case LEAF:
- lb *= n;
- lb += sizeof(struct LeafDescriptor) + TYPD_EXTRA_BYTES;
+ lb = SIZET_SAT_ADD(lb,
+ sizeof(struct LeafDescriptor) + TYPD_EXTRA_BYTES);
break;
case COMPLEX:
- lb *= n;
- lb += TYPD_EXTRA_BYTES;
+ lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES);
break;
}
if( SMALL_OBJ(lb) ) {
@@ -726,9 +753,7 @@ GC_API void * GC_CALL GC_calloc_explicitly_typed(size_t n, size_t lb,
# endif
{
/* Couldn't register it due to lack of memory. Punt. */
- /* This will probably fail too, but gives the recovery code */
- /* a chance. */
- return(GC_malloc(n*lb));
+ return (*GC_get_oom_fn())(lb);
}
}
return((void *) op);
diff --git a/win32_threads.c b/win32_threads.c
index 321426e0..6b802bb4 100644
--- a/win32_threads.c
+++ b/win32_threads.c
@@ -68,20 +68,11 @@
# include <unistd.h>
# endif
-#else
-
-# ifdef MSWINCE
- /* Force DONT_USE_SIGNALANDWAIT implementation of PARALLEL_MARK */
- /* for WinCE (since Win32 SignalObjectAndWait() is missing). */
-# ifndef DONT_USE_SIGNALANDWAIT
-# define DONT_USE_SIGNALANDWAIT
-# endif
-# else
-# include <process.h> /* For _beginthreadex, _endthreadex */
-# include <errno.h> /* for errno, EAGAIN */
-# endif
+#elif !defined(MSWINCE)
+# include <process.h> /* For _beginthreadex, _endthreadex */
+# include <errno.h> /* for errno, EAGAIN */
-#endif
+#endif /* !GC_PTHREADS && !MSWINCE */
/* DllMain-based thread registration is currently incompatible */
/* with thread-local allocation, pthreads and WinCE. */
@@ -1676,10 +1667,15 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
# if defined(GC_PTHREADS) && !defined(GC_PTHREADS_PARAMARK)
/* Use pthread-based parallel mark implementation. */
-# define GC_PTHREADS_PARAMARK
+
+ /* Workaround a deadlock in winpthreads-3.0b internals (observed */
+ /* with MinGW 32/64). */
+# if !defined(__MINGW32__)
+# define GC_PTHREADS_PARAMARK
+# endif
# endif
-# if !defined(GC_PTHREADS_PARAMARK) && defined(DONT_USE_SIGNALANDWAIT)
+# if !defined(GC_PTHREADS_PARAMARK)
STATIC HANDLE GC_marker_cv[MAX_MARKERS - 1] = {0};
/* Events with manual reset (one for each */
/* mark helper). */
@@ -1694,12 +1690,10 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
/* GC_mark_thread() is the same as in pthread_support.c */
# ifdef GC_PTHREADS_PARAMARK
STATIC void * GC_mark_thread(void * id)
+# elif defined(MSWINCE)
+ STATIC DWORD WINAPI GC_mark_thread(LPVOID id)
# else
-# ifdef MSWINCE
- STATIC DWORD WINAPI GC_mark_thread(LPVOID id)
-# else
- STATIC unsigned __stdcall GC_mark_thread(void * id)
-# endif
+ STATIC unsigned __stdcall GC_mark_thread(void * id)
# endif
{
word my_mark_no = 0;
@@ -1709,10 +1703,16 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
# ifdef IA64
marker_bsp[(word)id] = GC_save_regs_in_stack();
# endif
-# if !defined(GC_PTHREADS_PARAMARK) && defined(DONT_USE_SIGNALANDWAIT)
+# if !defined(GC_PTHREADS_PARAMARK)
GC_marker_Id[(word)id] = GetCurrentThreadId();
# endif
+ /* Inform start_mark_threads() about completion of marker data init. */
+ GC_acquire_mark_lock();
+ if (0 == --GC_fl_builder_count)
+ GC_notify_all_builder();
+ GC_release_mark_lock();
+
for (;; ++my_mark_no) {
if (my_mark_no - GC_mark_no > (word)2) {
/* resynchronize if we get far off, e.g. because GC_mark_no */
@@ -1741,8 +1741,9 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
# ifdef GC_PTHREADS_PARAMARK
# include <pthread.h>
-# ifndef NUMERIC_THREAD_ID
-# define NUMERIC_THREAD_ID(id) (unsigned long)GC_PTHREAD_PTRVAL(id)
+# if defined(GC_ASSERTIONS) && !defined(NUMERIC_THREAD_ID)
+# define NUMERIC_THREAD_ID(id) (unsigned long)(word)GC_PTHREAD_PTRVAL(id)
+ /* Id not guaranteed to be unique. */
# endif
/* start_mark_threads is the same as in pthread_support.c except */
@@ -1761,6 +1762,7 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
pthread_t new_thread;
GC_ASSERT(I_DONT_HOLD_LOCK());
+ GC_ASSERT(GC_fl_builder_count == 0);
# ifdef CAN_HANDLE_FORK
if (available_markers_m1 <= 0 || GC_parallel) return;
/* Skip if parallel markers disabled or already started. */
@@ -1774,13 +1776,14 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
marker_last_stack_min[i] = ADDR_LIMIT;
if (0 != pthread_create(&new_thread, &attr,
GC_mark_thread, (void *)(word)i)) {
- WARN("Marker thread creation failed.\n", 0);
+ WARN("Marker thread creation failed\n", 0);
/* Don't try to create other marker threads. */
break;
}
}
GC_markers_m1 = i;
- pthread_attr_destroy(&attr);
+ (void)pthread_attr_destroy(&attr);
+ GC_wait_for_markers_init();
GC_COND_LOG_PRINTF("Started %d mark helper threads\n", GC_markers_m1);
}
@@ -1810,7 +1813,9 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
GC_INNER void GC_acquire_mark_lock(void)
{
- GC_ASSERT(GC_mark_lock_holder != NUMERIC_THREAD_ID(pthread_self()));
+# ifdef NUMERIC_THREAD_ID_UNIQUE
+ GC_ASSERT(GC_mark_lock_holder != NUMERIC_THREAD_ID(pthread_self()));
+# endif
if (pthread_mutex_lock(&mark_mutex) != 0) {
ABORT("pthread_mutex_lock failed");
}
@@ -1902,17 +1907,16 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
unsigned thread_id;
# endif
-# ifdef DONT_USE_SIGNALANDWAIT
- /* Initialize GC_marker_cv[] fully before starting the */
- /* first helper thread. */
- for (i = 0; i < GC_markers_m1; ++i) {
- if ((GC_marker_cv[i] = CreateEvent(NULL /* attrs */,
+ GC_ASSERT(GC_fl_builder_count == 0);
+ /* Initialize GC_marker_cv[] fully before starting the */
+ /* first helper thread. */
+ for (i = 0; i < GC_markers_m1; ++i) {
+ if ((GC_marker_cv[i] = CreateEvent(NULL /* attrs */,
TRUE /* isManualReset */,
FALSE /* initialState */,
NULL /* name (A/W) */)) == (HANDLE)0)
- ABORT("CreateEvent failed");
- }
-# endif
+ ABORT("CreateEvent failed");
+ }
for (i = 0; i < GC_markers_m1; ++i) {
marker_last_stack_min[i] = ADDR_LIMIT;
@@ -1946,14 +1950,11 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
}
/* Adjust GC_markers_m1 (and free unused resources) if failed. */
-# ifdef DONT_USE_SIGNALANDWAIT
- while (GC_markers_m1 > i) {
- GC_markers_m1--;
- CloseHandle(GC_marker_cv[GC_markers_m1]);
- }
-# else
- GC_markers_m1 = i;
-# endif
+ while (GC_markers_m1 > i) {
+ GC_markers_m1--;
+ CloseHandle(GC_marker_cv[GC_markers_m1]);
+ }
+ GC_wait_for_markers_init();
GC_COND_LOG_PRINTF("Started %d mark helper threads\n", GC_markers_m1);
if (i == 0) {
CloseHandle(mark_cv);
@@ -1973,16 +1974,11 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
} while (0)
# endif /* GC_ASSERTIONS */
-# ifdef DONT_USE_SIGNALANDWAIT
- STATIC /* volatile */ LONG GC_mark_mutex_state = 0;
+ STATIC /* volatile */ LONG GC_mark_mutex_state = 0;
/* Mutex state: 0 - unlocked, */
/* 1 - locked and no other waiters, */
/* -1 - locked and waiters may exist. */
/* Accessed by InterlockedExchange(). */
-# else
- STATIC volatile AO_t GC_mark_mutex_waitcnt = 0;
- /* Number of waiters + 1; 0 - unlocked. */
-# endif
/* #define LOCK_STATS */
# ifdef LOCK_STATS
@@ -1993,21 +1989,13 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
GC_INNER void GC_acquire_mark_lock(void)
{
GC_ASSERT(GC_mark_lock_holder != GetCurrentThreadId());
-# ifdef DONT_USE_SIGNALANDWAIT
- if (InterlockedExchange(&GC_mark_mutex_state, 1 /* locked */) != 0)
-# else
- if (AO_fetch_and_add1_acquire(&GC_mark_mutex_waitcnt) != 0)
-# endif
- {
+ if (InterlockedExchange(&GC_mark_mutex_state, 1 /* locked */) != 0) {
# ifdef LOCK_STATS
(void)AO_fetch_and_add1(&GC_block_count);
# endif
-# ifdef DONT_USE_SIGNALANDWAIT
- /* Repeatedly reset the state and wait until acquire the lock. */
- while (InterlockedExchange(&GC_mark_mutex_state,
- -1 /* locked_and_has_waiters */) != 0)
-# endif
- {
+ /* Repeatedly reset the state and wait until acquire the lock. */
+ while (InterlockedExchange(&GC_mark_mutex_state,
+ -1 /* locked_and_has_waiters */) != 0) {
if (WaitForSingleObject(mark_mutex_event, INFINITE) == WAIT_FAILED)
ABORT("WaitForSingleObject failed");
}
@@ -2025,17 +2013,11 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
GC_INNER void GC_release_mark_lock(void)
{
UNSET_MARK_LOCK_HOLDER;
-# ifdef DONT_USE_SIGNALANDWAIT
- if (InterlockedExchange(&GC_mark_mutex_state, 0 /* unlocked */) < 0)
-# else
- GC_ASSERT(AO_load(&GC_mark_mutex_waitcnt) != 0);
- if (AO_fetch_and_sub1_release(&GC_mark_mutex_waitcnt) > 1)
-# endif
- {
- /* wake a waiter */
- if (SetEvent(mark_mutex_event) == FALSE)
- ABORT("SetEvent failed");
- }
+ if (InterlockedExchange(&GC_mark_mutex_state, 0 /* unlocked */) < 0) {
+ /* wake a waiter */
+ if (SetEvent(mark_mutex_event) == FALSE)
+ ABORT("SetEvent failed");
+ }
}
/* In GC_wait_for_reclaim/GC_notify_all_builder() we emulate POSIX */
@@ -2070,115 +2052,41 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
ABORT("SetEvent failed");
}
-# ifdef DONT_USE_SIGNALANDWAIT
-
- /* mark_cv is used (for waiting) by a non-helper thread. */
-
- GC_INNER void GC_wait_marker(void)
- {
- HANDLE event = mark_cv;
- DWORD thread_id = GetCurrentThreadId();
- int i = GC_markers_m1;
-
- while (i-- > 0) {
- if (GC_marker_Id[i] == thread_id) {
- event = GC_marker_cv[i];
- break;
- }
- }
-
- if (ResetEvent(event) == FALSE)
- ABORT("ResetEvent failed");
- GC_release_mark_lock();
- if (WaitForSingleObject(event, INFINITE) == WAIT_FAILED)
- ABORT("WaitForSingleObject failed");
- GC_acquire_mark_lock();
- }
+ /* mark_cv is used (for waiting) by a non-helper thread. */
- GC_INNER void GC_notify_all_marker(void)
- {
- DWORD thread_id = GetCurrentThreadId();
- int i = GC_markers_m1;
+ GC_INNER void GC_wait_marker(void)
+ {
+ HANDLE event = mark_cv;
+ DWORD thread_id = GetCurrentThreadId();
+ int i = GC_markers_m1;
- while (i-- > 0) {
- /* Notify every marker ignoring self (for efficiency). */
- if (SetEvent(GC_marker_Id[i] != thread_id ? GC_marker_cv[i] :
- mark_cv) == FALSE)
- ABORT("SetEvent failed");
+ while (i-- > 0) {
+ if (GC_marker_Id[i] == thread_id) {
+ event = GC_marker_cv[i];
+ break;
}
}
-# else /* DONT_USE_SIGNALANDWAIT */
-
- /* For GC_wait_marker/GC_notify_all_marker() the above technique */
- /* does not work because they are used with different checked */
- /* conditions in different places (and, in addition, notifying is */
- /* done after leaving critical section) and this could result in */
- /* a signal losing between checking for a particular condition */
- /* and calling WaitForSingleObject. So, we use PulseEvent() and */
- /* NT SignalObjectAndWait() (which atomically sets mutex event to */
- /* signaled state and starts waiting on condvar). A special */
- /* case here is GC_mark_mutex_waitcnt == 1 (i.e. nobody waits for */
- /* mark lock at this moment) - we don't change it (otherwise we */
- /* may lose a signal sent between decrementing mark_mutex_waitcnt */
- /* and calling WaitForSingleObject). */
-
-# ifdef MSWINCE
- /* SignalObjectAndWait() is missing in WinCE (for now), so you */
- /* should supply its emulation (externally) to use this code. */
- WINBASEAPI DWORD WINAPI SignalObjectAndWait(HANDLE, HANDLE, DWORD,
- BOOL);
-# define signalObjectAndWait_func SignalObjectAndWait
-# else
- typedef DWORD (WINAPI * SignalObjectAndWait_type)(HANDLE, HANDLE,
- DWORD, BOOL);
- static SignalObjectAndWait_type signalObjectAndWait_func = 0;
-# endif
-
- GC_INNER void GC_wait_marker(void)
- {
- /* Here we assume that GC_wait_marker() is always called */
- /* from a while(check_cond) loop. */
- AO_t waitcnt;
- GC_ASSERT(mark_cv != 0);
-
- /* We inline GC_release_mark_lock() to have atomic */
- /* unlock-and-wait action here. */
- UNSET_MARK_LOCK_HOLDER;
- if ((waitcnt = AO_load(&GC_mark_mutex_waitcnt)) > 1) {
- (void)AO_fetch_and_sub1_release(&GC_mark_mutex_waitcnt);
- } else {
- GC_ASSERT(AO_load(&GC_mark_mutex_waitcnt) != 0);
- }
-
- /* The state of mark_cv is non-signaled here. */
- if (signalObjectAndWait_func(mark_mutex_event /* hObjectToSignal */,
- mark_cv /* hObjectToWaitOn */,
- INFINITE /* timeout */,
- FALSE /* isAlertable */) == WAIT_FAILED)
- ABORT("SignalObjectAndWait failed");
- /* The state of mark_cv is non-signaled here again. */
-
- if (waitcnt > 1) {
- GC_acquire_mark_lock();
- } else {
- GC_ASSERT(GC_mark_mutex_waitcnt != 0);
- /* Acquire mark lock */
- if (WaitForSingleObject(mark_mutex_event, INFINITE) == WAIT_FAILED)
- ABORT("WaitForSingleObject failed");
- GC_ASSERT(GC_mark_lock_holder == NO_THREAD);
- SET_MARK_LOCK_HOLDER;
- }
- }
+ if (ResetEvent(event) == FALSE)
+ ABORT("ResetEvent failed");
+ GC_release_mark_lock();
+ if (WaitForSingleObject(event, INFINITE) == WAIT_FAILED)
+ ABORT("WaitForSingleObject failed");
+ GC_acquire_mark_lock();
+ }
- GC_INNER void GC_notify_all_marker(void)
- {
- GC_ASSERT(mark_cv != 0);
- if (PulseEvent(mark_cv) == FALSE)
- ABORT("PulseEvent failed");
+ GC_INNER void GC_notify_all_marker(void)
+ {
+ DWORD thread_id = GetCurrentThreadId();
+ int i = GC_markers_m1;
+
+ while (i-- > 0) {
+ /* Notify every marker ignoring self (for efficiency). */
+ if (SetEvent(GC_marker_Id[i] != thread_id ? GC_marker_cv[i] :
+ mark_cv) == FALSE)
+ ABORT("SetEvent failed");
}
-
-# endif /* !DONT_USE_SIGNALANDWAIT */
+ }
# endif /* ! GC_PTHREADS_PARAMARK */
@@ -2456,19 +2364,20 @@ GC_INNER void GC_thr_init(void)
# if defined(PARALLEL_MARK)
{
char * markers_string = GETENV("GC_MARKERS");
- int markers_m1;
+ int markers;
if (markers_string != NULL) {
- markers_m1 = atoi(markers_string) - 1;
- if (markers_m1 >= MAX_MARKERS) {
- WARN("Limiting number of mark threads\n", 0);
- markers_m1 = MAX_MARKERS - 1;
+ markers = atoi(markers_string);
+ if (markers <= 0 || markers > MAX_MARKERS) {
+ WARN("Too big or invalid number of mark threads: %" WARN_PRIdPTR
+ "; using maximum threads\n", (signed_word)markers);
+ markers = MAX_MARKERS;
}
} else {
# ifdef MSWINCE
/* There is no GetProcessAffinityMask() in WinCE. */
/* GC_sysinfo is already initialized. */
- markers_m1 = (int)GC_sysinfo.dwNumberOfProcessors - 1;
+ markers = (int)GC_sysinfo.dwNumberOfProcessors;
# else
# ifdef _WIN64
DWORD_PTR procMask = 0;
@@ -2485,35 +2394,22 @@ GC_INNER void GC_thr_init(void)
ncpu++;
} while ((procMask &= procMask - 1) != 0);
}
- markers_m1 = ncpu - 1;
+ markers = ncpu;
# endif
# ifdef GC_MIN_MARKERS
/* This is primarily for testing on systems without getenv(). */
- if (markers_m1 < GC_MIN_MARKERS - 1)
- markers_m1 = GC_MIN_MARKERS - 1;
+ if (markers < GC_MIN_MARKERS)
+ markers = GC_MIN_MARKERS;
# endif
- if (markers_m1 >= MAX_MARKERS)
- markers_m1 = MAX_MARKERS - 1; /* silently limit the value */
+ if (markers > MAX_MARKERS)
+ markers = MAX_MARKERS; /* silently limit the value */
}
- available_markers_m1 = markers_m1;
+ available_markers_m1 = markers - 1;
}
/* Check whether parallel mode could be enabled. */
{
-# if !defined(GC_PTHREADS_PARAMARK) && !defined(MSWINCE) \
- && !defined(DONT_USE_SIGNALANDWAIT)
- HMODULE hK32;
- /* SignalObjectAndWait() API call works only under NT. */
-# endif
- if (GC_win32_dll_threads || available_markers_m1 <= 0
-# if !defined(GC_PTHREADS_PARAMARK) && !defined(MSWINCE) \
- && !defined(DONT_USE_SIGNALANDWAIT)
- || GC_wnt == FALSE
- || (hK32 = GetModuleHandle(TEXT("kernel32.dll"))) == (HMODULE)0
- || (signalObjectAndWait_func = (SignalObjectAndWait_type)
- GetProcAddress(hK32, "SignalObjectAndWait")) == 0
-# endif
- ) {
+ if (GC_win32_dll_threads || available_markers_m1 <= 0) {
/* Disable parallel marking. */
GC_parallel = FALSE;
GC_COND_LOG_PRINTF(
@@ -2581,15 +2477,14 @@ GC_INNER void GC_thr_init(void)
# ifndef GC_WIN32_PTHREADS
while ((t = GC_lookup_pthread(pthread_id)) == 0)
Sleep(10);
-# endif
-
- result = pthread_join(pthread_id, retval);
-
-# ifdef GC_WIN32_PTHREADS
- /* win32_pthreads id are unique */
+ result = pthread_join(pthread_id, retval);
+# else
+ result = pthread_join(pthread_id, retval);
+ /* pthreads-win32 id are unique (not recycled) */
t = GC_lookup_pthread(pthread_id);
if (NULL == t) ABORT("Thread not registered");
# endif
+
LOCK();
GC_delete_gc_thread_no_free(t);
GC_INTERNAL_FREE(t);
@@ -2604,7 +2499,7 @@ GC_INNER void GC_thr_init(void)
}
/* Cygwin-pthreads calls CreateThread internally, but it's not easily */
- /* interceptible by us..., so intercept pthread_create instead. */
+ /* interceptable by us..., so intercept pthread_create instead. */
GC_API int GC_pthread_create(pthread_t *new_thread,
GC_PTHREAD_CREATE_CONST pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg)
@@ -2876,7 +2771,7 @@ GC_INNER void GC_init_parallel(void)
#if defined(USE_PTHREAD_LOCKS)
/* Support for pthread locking code. */
- /* Pthread_mutex_try_lock may not win here, */
+ /* pthread_mutex_trylock may not win here, */
/* due to builtin support for spinning first? */
GC_INNER volatile GC_bool GC_collecting = 0;
diff --git a/windows-untested/vc60/gc.dsp b/windows-untested/vc60/gc.dsp
index 762a2220..fafcc9c7 100644
--- a/windows-untested/vc60/gc.dsp
+++ b/windows-untested/vc60/gc.dsp
@@ -172,7 +172,7 @@ SOURCE=..\..\misc.c
# End Source File
# Begin Source File
-SOURCE=..\..\msvc_dbg.c
+SOURCE=..\..\extra\msvc_dbg.c
# End Source File
# Begin Source File
@@ -293,7 +293,7 @@ SOURCE=..\..\include\leak_detector.h
# End Source File
# Begin Source File
-SOURCE=..\..\msvc_dbg.h
+SOURCE=..\..\include\private\msvc_dbg.h
# End Source File
# Begin Source File
diff --git a/windows-untested/vc60/libgc.dsp b/windows-untested/vc60/libgc.dsp
index f7d77df5..fdac64e2 100644
--- a/windows-untested/vc60/libgc.dsp
+++ b/windows-untested/vc60/libgc.dsp
@@ -165,7 +165,7 @@ SOURCE=..\..\misc.c
# End Source File
# Begin Source File
-SOURCE=..\..\msvc_dbg.c
+SOURCE=..\..\extra\msvc_dbg.c
# End Source File
# Begin Source File
@@ -246,7 +246,7 @@ SOURCE=..\..\include\leak_detector.h
# End Source File
# Begin Source File
-SOURCE=..\..\msvc_dbg.h
+SOURCE=..\..\include\private\msvc_dbg.h
# End Source File
# Begin Source File
diff --git a/windows-untested/vc60/libgcmt.dsp b/windows-untested/vc60/libgcmt.dsp
index 72d3658c..e31e2680 100644
--- a/windows-untested/vc60/libgcmt.dsp
+++ b/windows-untested/vc60/libgcmt.dsp
@@ -165,7 +165,7 @@ SOURCE=..\..\misc.c
# End Source File
# Begin Source File
-SOURCE=..\..\msvc_dbg.c
+SOURCE=..\..\extra\msvc_dbg.c
# End Source File
# Begin Source File
@@ -210,7 +210,7 @@ SOURCE=..\..\win32_threads.c
# PROP Default_Filter "h;hh;hpp;hxx;hm;inl"
# Begin Source File
-SOURCE=..\..\msvc_dbg.h
+SOURCE=..\..\include\private\msvc_dbg.h
# End Source File
# Begin Source File
diff --git a/windows-untested/vc70/gc.vcproj b/windows-untested/vc70/gc.vcproj
index 9f18300e..0cb02fa2 100644
--- a/windows-untested/vc70/gc.vcproj
+++ b/windows-untested/vc70/gc.vcproj
@@ -198,7 +198,7 @@
RelativePath="..\..\misc.c">
</File>
<File
- RelativePath="..\..\msvc_dbg.c">
+ RelativePath="..\..\extra\msvc_dbg.c">
</File>
<File
RelativePath="..\..\new_hblk.c">
@@ -301,7 +301,7 @@
RelativePath="..\..\include\leak_detector.h">
</File>
<File
- RelativePath="..\..\msvc_dbg.h">
+ RelativePath="..\..\include\private\msvc_dbg.h">
</File>
<File
RelativePath="..\..\include\new_gc_alloc.h">
diff --git a/windows-untested/vc70/libgc.vcproj b/windows-untested/vc70/libgc.vcproj
index 56847eb9..efacacc1 100644
--- a/windows-untested/vc70/libgc.vcproj
+++ b/windows-untested/vc70/libgc.vcproj
@@ -164,7 +164,7 @@
RelativePath="..\..\misc.c">
</File>
<File
- RelativePath="..\..\msvc_dbg.c">
+ RelativePath="..\..\extra\msvc_dbg.c">
</File>
<File
RelativePath="..\..\new_hblk.c">
@@ -237,7 +237,7 @@
RelativePath="..\..\include\leak_detector.h">
</File>
<File
- RelativePath="..\..\msvc_dbg.h">
+ RelativePath="..\..\include\private\msvc_dbg.h">
</File>
<File
RelativePath="..\..\include\new_gc_alloc.h">
diff --git a/windows-untested/vc70/libgcmt.vcproj b/windows-untested/vc70/libgcmt.vcproj
index ab574007..a1015c77 100644
--- a/windows-untested/vc70/libgcmt.vcproj
+++ b/windows-untested/vc70/libgcmt.vcproj
@@ -164,7 +164,7 @@
RelativePath="..\..\misc.c">
</File>
<File
- RelativePath="..\..\msvc_dbg.c">
+ RelativePath="..\..\extra\msvc_dbg.c">
</File>
<File
RelativePath="..\..\new_hblk.c">
@@ -210,7 +210,7 @@
Name="Header Files"
Filter="h;hh;hpp;hxx;hm;inl">
<File
- RelativePath="..\..\msvc_dbg.h">
+ RelativePath="..\..\include\private\msvc_dbg.h">
</File>
<File
RelativePath="..\stdafx.h">
diff --git a/windows-untested/vc71/gc.vcproj b/windows-untested/vc71/gc.vcproj
index af5598f8..50cdb5ec 100644
--- a/windows-untested/vc71/gc.vcproj
+++ b/windows-untested/vc71/gc.vcproj
@@ -538,7 +538,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\..\msvc_dbg.c">
+ RelativePath="..\..\extra\msvc_dbg.c">
<FileConfiguration
Name="Release|Win32">
<Tool
@@ -821,7 +821,7 @@
RelativePath="..\..\include\leak_detector.h">
</File>
<File
- RelativePath="..\..\msvc_dbg.h">
+ RelativePath="..\..\include\private\msvc_dbg.h">
</File>
<File
RelativePath="..\..\include\new_gc_alloc.h">
diff --git a/windows-untested/vc71/libgc.vcproj b/windows-untested/vc71/libgc.vcproj
index f0cc9086..6e369c8a 100644
--- a/windows-untested/vc71/libgc.vcproj
+++ b/windows-untested/vc71/libgc.vcproj
@@ -502,7 +502,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\..\msvc_dbg.c">
+ RelativePath="..\..\extra\msvc_dbg.c">
<FileConfiguration
Name="Release|Win32">
<Tool
@@ -755,7 +755,7 @@
RelativePath="..\..\include\leak_detector.h">
</File>
<File
- RelativePath="..\..\msvc_dbg.h">
+ RelativePath="..\..\include\private\msvc_dbg.h">
</File>
<File
RelativePath="..\..\include\new_gc_alloc.h">
diff --git a/windows-untested/vc71/libgcmt.vcproj b/windows-untested/vc71/libgcmt.vcproj
index 1005eb97..83f899ae 100644
--- a/windows-untested/vc71/libgcmt.vcproj
+++ b/windows-untested/vc71/libgcmt.vcproj
@@ -502,7 +502,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\..\msvc_dbg.c">
+ RelativePath="..\..\extra\msvc_dbg.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
@@ -728,7 +728,7 @@
Name="Header Files"
Filter="h;hh;hpp;hxx;hm;inl">
<File
- RelativePath="..\..\msvc_dbg.h">
+ RelativePath="..\..\include\private\msvc_dbg.h">
</File>
<File
RelativePath="..\stdafx.h">