OSDN Git Service

2003-03-03 Hans Boehm <Hans.Boehm@hp.com>
authorhboehm <hboehm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 Mar 2003 19:34:11 +0000 (19:34 +0000)
committerhboehm <hboehm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 Mar 2003 19:34:11 +0000 (19:34 +0000)
* 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
boehm-gc/alloc.c
boehm-gc/dyn_load.c
boehm-gc/include/private/gc_priv.h
boehm-gc/include/private/gcconfig.h
boehm-gc/mark_rts.c
boehm-gc/misc.c

index 64ff38f..a33943e 100644 (file)
@@ -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
index 8a413b2..f2e5af0 100644 (file)
@@ -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);
index d3ef572..f7b88f0 100644 (file)
@@ -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 */
+
index 5465c78..dac604f 100644 (file)
@@ -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 */
index f71bb98..af0d2e4 100644 (file)
 #   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; \
index 628cba2..f663dcd 100644 (file)
@@ -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) {
index f607973..891cdc7 100644 (file)
 #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();