From 0c67eea30c500aad72b41360a5268d3190085d08 Mon Sep 17 00:00:00 2001
From: hboehm <hboehm@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 3 Mar 2003 19:34:11 +0000
Subject: [PATCH] 2003-03-03  Hans Boehm  <Hans.Boehm@hp.com> 	* mark_rts.c
 (GC_cond_register_dynamic_libraries): add. 	(GC_push_roots): explicitly
 mark free list headers, register 	dynamic libraries only if
 !REGISTER_LIBRARIES_EARLY. 	* alloc.c (GC_stopped_mark): Conditionally
 call 	GC_cond_register_dynamic_libraries(). 	(GC_collect_a_little_inner,
 GC_try_to_collect_inner): Check GC_dont_gc. 	* dyn_load.c
 (GC_register_main_static_data): define. 	(GC_register_dyn_libraries
 (Linux /proc, Linux ELF versions)): 	no longer skip main data. 	*
 misc.c (GC_REGISTER_MAIN_STATIC_DATA): define. 	(GC_init_inner): Make
 main data registration conditional. 	* include/private/gc_priv.h
 (GC_register_main_static_data): declare. 	* include/private/gcconfig.h
 (REGISTER_LIBRARIES_EARLY): define 	for LINUX.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63727 138bc75d-0d04-0410-961f-82ee72b054a4
---
 boehm-gc/ChangeLog                  | 16 +++++++++
 boehm-gc/alloc.c                    |  5 +++
 boehm-gc/dyn_load.c                 | 54 ++++++++++++++++++++++-------
 boehm-gc/include/private/gc_priv.h  |  5 +++
 boehm-gc/include/private/gcconfig.h |  9 +++++
 boehm-gc/mark_rts.c                 | 40 ++++++++++++++++-----
 boehm-gc/misc.c                     | 12 +++++--
 7 files changed, 118 insertions(+), 23 deletions(-)

diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index 64ff38f169cf..a33943e8518e 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,19 @@
+2003-03-03  Hans Boehm  <Hans.Boehm@hp.com>
+	* mark_rts.c (GC_cond_register_dynamic_libraries): add.
+	(GC_push_roots): explicitly mark free list headers, register
+	dynamic libraries only if !REGISTER_LIBRARIES_EARLY.
+	* alloc.c (GC_stopped_mark): Conditionally call
+	GC_cond_register_dynamic_libraries().
+	(GC_collect_a_little_inner, GC_try_to_collect_inner): Check GC_dont_gc.
+	* dyn_load.c (GC_register_main_static_data): define.
+	(GC_register_dyn_libraries (Linux /proc, Linux ELF versions)):
+	no longer skip main data.
+	* misc.c (GC_REGISTER_MAIN_STATIC_DATA): define.
+	(GC_init_inner): Make main data registration conditional.
+	* include/private/gc_priv.h (GC_register_main_static_data): declare.
+	* include/private/gcconfig.h (REGISTER_LIBRARIES_EARLY): define
+	for LINUX.
+
 2003-02-20  Alexandre Oliva  <aoliva@redhat.com>
 
 	* configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to
diff --git a/boehm-gc/alloc.c b/boehm-gc/alloc.c
index 8a413b275f88..f2e5af057203 100644
--- a/boehm-gc/alloc.c
+++ b/boehm-gc/alloc.c
@@ -306,6 +306,7 @@ void GC_maybe_gc()
 GC_bool GC_try_to_collect_inner(stop_func)
 GC_stop_func stop_func;
 {
+    if (GC_dont_gc) return FALSE;
     if (GC_incremental && GC_collection_in_progress()) {
 #   ifdef CONDPRINT
       if (GC_print_stats) {
@@ -386,6 +387,7 @@ int n;
 {
     register int i;
     
+    if (GC_dont_gc) return;
     if (GC_incremental && GC_collection_in_progress()) {
     	for (i = GC_deficit; i < GC_RATE*n; i++) {
     	    if (GC_mark_some((ptr_t)0)) {
@@ -446,6 +448,9 @@ GC_stop_func stop_func;
 	CLOCK_TYPE start_time, current_time;
 #   endif
 	
+#   if defined(REGISTER_LIBRARIES_EARLY)
+        GC_cond_register_dynamic_libraries();
+#   endif
     STOP_WORLD();
 #   ifdef PRINTTIMES
 	GET_TIME(start_time);
diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c
index d3ef572be687..f7b88f00dabd 100644
--- a/boehm-gc/dyn_load.c
+++ b/boehm-gc/dyn_load.c
@@ -355,10 +355,6 @@ void GC_register_dynamic_libraries()
 		/* Stack mapping; discard	*/
 		continue;
 	    }
-	    if (start <= datastart && end > datastart && maj_dev != 0) {
-		/* Main data segment; discard	*/
-		continue;
-	    }
 #	    ifdef THREADS
 	      if (GC_segment_is_thread_stack(start, end)) continue;
 #	    endif
@@ -384,6 +380,13 @@ void GC_register_dynamic_libraries()
      }
 }
 
+/* We now take care of the main data segment ourselves: */
+GC_bool GC_register_main_static_data()
+{
+  return FALSE;
+}
+  
+# define HAVE_REGISTER_MAIN_STATIC_DATA
 //
 //  parse_map_entry parses an entry from /proc/self/maps so we can
 //  locate all writable data segments that belong to shared libraries.
@@ -469,13 +472,6 @@ static int GC_register_dynlib_callback(info, size, ptr)
       + sizeof (info->dlpi_phnum))
     return -1;
 
-  /* Skip the first object - it is the main program.  */
-  if (*(int *)ptr == 0)
-    {
-      *(int *)ptr = 1;
-      return 0;
-    }
-
   p = info->dlpi_phdr;
   for( i = 0; i < (int)(info->dlpi_phnum); ((i++),(p++)) ) {
     switch( p->p_type ) {
@@ -510,6 +506,14 @@ GC_bool GC_register_dynamic_libraries_dl_iterate_phdr()
   }
 }
 
+/* Do we need to separately register the main static data segment? */
+GC_bool GC_register_main_static_data()
+{
+  return (dl_iterate_phdr == 0);
+}
+
+#define HAVE_REGISTER_MAIN_STATIC_DATA
+
 # else /* !LINUX || version(glibc) < 2.2.4 */
 
 /* Dynamic loading code for Linux running ELF. Somewhat tested on
@@ -775,10 +779,23 @@ void GC_register_dynamic_libraries()
     }
 # endif
 
-# ifndef MSWINCE
+# ifdef MSWINCE
+  /* Do we need to separately register the main static data segment? */
+  GC_bool GC_register_main_static_data()
+  {
+    return FALSE;
+  }
+# else /* win32 */
   extern GC_bool GC_no_win32_dlls;
-# endif
+
+  GC_bool GC_register_main_static_data()
+  {
+    return GC_no_win32_dlls;
+  }
+# endif /* win32 */
   
+# define HAVE_REGISTER_MAIN_STATIC_DATA
+
   void GC_register_dynamic_libraries()
   {
     MEMORY_BASIC_INFORMATION buf;
@@ -1079,4 +1096,15 @@ void GC_register_dynamic_libraries(){}
 int GC_no_dynamic_loading;
 
 #endif /* !PCR */
+
 #endif /* !DYNAMIC_LOADING */
+
+#ifndef HAVE_REGISTER_MAIN_STATIC_DATA
+
+/* Do we need to separately register the main static data segment? */
+GC_bool GC_register_main_static_data()
+{
+  return TRUE;
+}
+#endif /* HAVE_REGISTER_MAIN_STATIC_DATA */
+
diff --git a/boehm-gc/include/private/gc_priv.h b/boehm-gc/include/private/gc_priv.h
index 5465c78b6e41..dac604f2a117 100644
--- a/boehm-gc/include/private/gc_priv.h
+++ b/boehm-gc/include/private/gc_priv.h
@@ -1462,6 +1462,11 @@ GC_bool GC_is_tmp_root GC_PROTO((ptr_t p));
 # endif
 void GC_register_dynamic_libraries GC_PROTO((void));
   		/* Add dynamic library data sections to the root set. */
+
+GC_bool GC_register_main_static_data GC_PROTO((void));
+               /* We need to register the main data segment.  Returns  */
+               /* TRUE unless this is done implicitly as part of       */
+               /* dynamic library registration.                        */
   
 /* Machine dependent startup routines */
 ptr_t GC_get_stack_base GC_PROTO((void));	/* Cold end of stack */
diff --git a/boehm-gc/include/private/gcconfig.h b/boehm-gc/include/private/gcconfig.h
index f71bb9813ed7..af0d2e4ec490 100644
--- a/boehm-gc/include/private/gcconfig.h
+++ b/boehm-gc/include/private/gcconfig.h
@@ -1801,6 +1801,15 @@
 #   define CACHE_LINE_SIZE 32	/* Wild guess	*/
 # endif
 
+# ifdef LINUX
+#   define REGISTER_LIBRARIES_EARLY
+    /* We sometimes use dl_iterate_phdr, which may acquire an internal	*/
+    /* lock.  This isn't safe after the world has stopped.  So we must	*/
+    /* call GC_register_dynamic_libraries before stopping the world.	*/
+    /* For performance reasons, this may be beneficial on other		*/
+    /* platforms as well, though it should be avoided in win32.		*/
+# endif /* LINUX */
+
 # ifndef CLEAR_DOUBLE
 #   define CLEAR_DOUBLE(x) \
 	((word*)x)[0] = 0; \
diff --git a/boehm-gc/mark_rts.c b/boehm-gc/mark_rts.c
index 628cba289aca..f663dcd55c34 100644
--- a/boehm-gc/mark_rts.c
+++ b/boehm-gc/mark_rts.c
@@ -506,6 +506,17 @@ void GC_push_gc_structures GC_PROTO((void))
   void GC_mark_thread_local_free_lists();
 #endif
 
+void GC_cond_register_dynamic_libraries()
+{
+# if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
+     || defined(PCR)) && !defined(SRC_M3)
+    GC_remove_tmp_roots();
+    if (!GC_no_dls) GC_register_dynamic_libraries();
+# else
+    GC_no_dls = TRUE;
+# endif
+}
+
 /*
  * Call the mark routines (GC_tl_push for a single pointer, GC_push_conditional
  * on groups of pointers) on every top level accessible pointer.
@@ -519,19 +530,20 @@ void GC_push_roots(all, cold_gc_frame)
 GC_bool all;
 ptr_t cold_gc_frame;
 {
-    register int i;
+    int i;
+    int kind;
 
     /*
      * Next push static data.  This must happen early on, since it's
      * not robust against mark stack overflow.
      */
-     /* Reregister dynamic libraries, in case one got added.	*/
-#      if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
-	   || defined(PCR)) && !defined(SRC_M3)
-         GC_remove_tmp_roots();
-         if (!GC_no_dls) GC_register_dynamic_libraries();
-#      else
-	 GC_no_dls = TRUE;
+     /* Reregister dynamic libraries, in case one got added.		*/
+     /* There is some argument for doing this as late as possible,	*/
+     /* especially on win32, where it can change asynchronously.	*/
+     /* In those cases, we do it here.  But on other platforms, it's	*/
+     /* not safe with the world stopped, so we do it earlier.		*/
+#      if !defined(REGISTER_LIBRARIES_EARLY)
+         GC_cond_register_dynamic_libraries();
 #      endif
 
      /* Mark everything in static data areas                             */
@@ -541,6 +553,18 @@ ptr_t cold_gc_frame;
 			     GC_static_roots[i].r_end, all);
        }
 
+     /* Mark all free list header blocks, if those were allocated from	*/
+     /* the garbage collected heap.  This makes sure they don't 	*/
+     /* disappear if we are not marking from static data.  It also 	*/
+     /* saves us the trouble of scanning them, and possibly that of	*/
+     /* marking the freelists.						*/
+       for (kind = 0; kind < GC_n_kinds; kind++) {
+	 GC_PTR base = GC_base(GC_obj_kinds[kind].ok_freelist);
+	 if (0 != base) {
+	   GC_set_mark_bit(base);
+	 }
+       }
+       
      /* Mark from GC internal roots if those might otherwise have	*/
      /* been excluded.							*/
        if (GC_no_dls || roots_were_cleared) {
diff --git a/boehm-gc/misc.c b/boehm-gc/misc.c
index f6079732fbfc..891cdc722b75 100644
--- a/boehm-gc/misc.c
+++ b/boehm-gc/misc.c
@@ -75,6 +75,14 @@
 #undef STACKBASE
 #endif
 
+/* Dont unnecessarily call GC_register_main_static_data() in case      */
+/* dyn_load.c isn't linked in.                                         */
+#ifdef DYNAMIC_LOADING
+# define GC_REGISTER_MAIN_STATIC_DATA() GC_register_main_static_data()
+#else
+# define GC_REGISTER_MAIN_STATIC_DATA() TRUE
+#endif
+
 GC_FAR struct _GC_arrays GC_arrays /* = { 0 } */;
 
 
@@ -572,7 +580,7 @@ void GC_init_inner()
  	GC_init_win32();
 #   endif
 #   if defined(SEARCH_FOR_DATA_START)
-	GC_init_linux_data_start();
+	if (GC_REGISTER_MAIN_STATIC_DATA()) GC_init_linux_data_start();
 #   endif
 #   if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
 	GC_init_netbsd_elf();
@@ -619,7 +627,7 @@ void GC_init_inner()
     
     /* Add initial guess of root sets.  Do this first, since sbrk(0)	*/
     /* might be used.							*/
-      GC_register_data_segments();
+      if (GC_REGISTER_MAIN_STATIC_DATA()) GC_register_data_segments();
     GC_init_headers();
     GC_bl_init();
     GC_mark_init();
-- 
GitLab