OSDN Git Service

compiler: Use less memory for array/slice literals.
[pf3gnuchains/gcc-fork.git] / boehm-gc / mark_rts.c
index f663dcd..94eb0dd 100644 (file)
@@ -22,7 +22,7 @@
 struct roots {
        ptr_t r_start;
        ptr_t r_end;
- #     if !defined(MSWIN32) && !defined(MSWINCE)
+ #     if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32)
          struct roots * r_next;
  #     endif
        GC_bool r_tmp;
@@ -87,7 +87,7 @@ ptr_t p;
     return(FALSE);
 }
 
-#if !defined(MSWIN32) && !defined(MSWINCE)
+#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32)
 /* 
 #   define LOG_RT_SIZE 6
 #   define RT_SIZE (1 << LOG_RT_SIZE)  -- Power of 2, may be != MAX_ROOT_SETS
@@ -139,7 +139,7 @@ struct roots *p;
     GC_root_index[h] = p;
 }
 
-# else /* MSWIN32 || MSWINCE */
+# else /* MSWIN32 || MSWINCE || CYGWIN32 */
 
 #   define add_roots_to_index(p)
 
@@ -175,7 +175,7 @@ GC_bool tmp;
 {
     struct roots * old;
     
-#   if defined(MSWIN32) || defined(MSWINCE)
+#   if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
       /* Spend the time to ensure that there are no overlapping        */
       /* or adjacent intervals.                                        */
       /* This could be done faster with e.g. a                 */
@@ -244,7 +244,7 @@ GC_bool tmp;
     GC_static_roots[n_root_sets].r_start = (ptr_t)b;
     GC_static_roots[n_root_sets].r_end = (ptr_t)e;
     GC_static_roots[n_root_sets].r_tmp = tmp;
-#   if !defined(MSWIN32) && !defined(MSWINCE)
+#   if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32)
       GC_static_roots[n_root_sets].r_next = 0;
 #   endif
     add_roots_to_index(GC_static_roots + n_root_sets);
@@ -263,7 +263,7 @@ void GC_clear_roots GC_PROTO((void))
     roots_were_cleared = TRUE;
     n_root_sets = 0;
     GC_root_size = 0;
-#   if !defined(MSWIN32) && !defined(MSWINCE)
+#   if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32)
     {
        register int i;
        
@@ -275,35 +275,74 @@ void GC_clear_roots GC_PROTO((void))
 }
 
 /* Internal use only; lock held.       */
+static void GC_remove_root_at_pos(i) 
+int i;
+{
+    GC_root_size -= (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
+    GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
+    GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
+    GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
+    n_root_sets--;
+}
+
+#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32)
+static void GC_rebuild_root_index()
+{
+    register int i;
+       
+    for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
+    for (i = 0; i < n_root_sets; i++)
+       add_roots_to_index(GC_static_roots + i);
+}
+#endif
+
+/* Internal use only; lock held.       */
 void GC_remove_tmp_roots()
 {
     register int i;
     
     for (i = 0; i < n_root_sets; ) {
        if (GC_static_roots[i].r_tmp) {
-           GC_root_size -=
-               (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
-           GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
-           GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
-           GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
-           n_root_sets--;
+            GC_remove_root_at_pos(i);
        } else {
            i++;
-       }
     }
-#   if !defined(MSWIN32) && !defined(MSWINCE)
-    {
-       register int i;
-       
-       for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
-       for (i = 0; i < n_root_sets; i++)
-               add_roots_to_index(GC_static_roots + i);
     }
-#   endif
+    #if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32)
+    GC_rebuild_root_index();
+    #endif
+}
+
+#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32)
+void GC_remove_roots(b, e)
+char * b; char * e;
+{
+    DCL_LOCK_STATE;
     
+    DISABLE_SIGNALS();
+    LOCK();
+    GC_remove_roots_inner(b, e);
+    UNLOCK();
+    ENABLE_SIGNALS();
+}
+
+/* Should only be called when the lock is held */
+void GC_remove_roots_inner(b,e)
+char * b; char * e;
+{
+    int i;
+    for (i = 0; i < n_root_sets; ) {
+       if (GC_static_roots[i].r_start >= (ptr_t)b && GC_static_roots[i].r_end <= (ptr_t)e) {
+            GC_remove_root_at_pos(i);
+       } else {
+           i++;
+       }
+    }
+    GC_rebuild_root_index();
 }
+#endif /* !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) */
 
-#if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION)
+#if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION) || defined(CYGWIN32)
 /* Workaround for the OS mapping and unmapping behind our back:                */
 /* Is the address p in one of the temporary static root sections?      */
 GC_bool GC_is_tmp_root(p)
@@ -325,16 +364,25 @@ ptr_t p;
     }
     return(FALSE);
 }
-#endif /* MSWIN32 || _WIN32_WCE_EMULATION */
+#endif /* MSWIN32 || _WIN32_WCE_EMULATION || defined(CYGWIN32) */
 
 ptr_t GC_approx_sp()
 {
-    word dummy;
+    VOLATILE word dummy;
 
+    dummy = 42;        /* Force stack to grow if necessary.    Otherwise the   */
+               /* later accesses might cause the kernel to think we're */
+               /* doing something wrong.                               */
 #   ifdef _MSC_VER
 #     pragma warning(disable:4172)
 #   endif
-    return((ptr_t)(&dummy));
+#ifdef __GNUC__
+    /* Eliminate a warning from GCC about taking the address of a
+       local variable.  */
+    return __builtin_frame_address (0);
+#else
+    return ((ptr_t)(&dummy));
+#endif /* __GNUC__ */
 #   ifdef _MSC_VER
 #     pragma warning(default:4172)
 #   endif
@@ -509,7 +557,7 @@ void GC_push_gc_structures GC_PROTO((void))
 void GC_cond_register_dynamic_libraries()
 {
 # if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
-     || defined(PCR)) && !defined(SRC_M3)
+     || defined(CYGWIN32) || defined(PCR)) && !defined(SRC_M3)
     GC_remove_tmp_roots();
     if (!GC_no_dls) GC_register_dynamic_libraries();
 # else
@@ -573,8 +621,11 @@ ptr_t cold_gc_frame;
 
      /* Mark thread local free lists, even if their mark       */
      /* descriptor excludes the link field.                    */
+     /* If the world is not stopped, this is unsafe.  It is    */
+     /* also unnecessary, since we will do this again with the */
+     /* world stopped.                                         */
 #      ifdef THREAD_LOCAL_ALLOC
-         GC_mark_thread_local_free_lists();
+         if (GC_world_stopped) GC_mark_thread_local_free_lists();
 #      endif
 
     /*