OSDN Git Service

2001-04-04 Hans Boehm <hans_boehm@hp.com>
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Apr 2001 00:14:18 +0000 (00:14 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Apr 2001 00:14:18 +0000 (00:14 +0000)
* finalize.c:
- Accomodate finalization requests for static objects.
  (Will be required by hash synchronization.  May be needed
  in some configurations now.)

* gc_priv.h:
- Define MIN_WORDS.  All allocation requests are rounded
  up to at least this size.  Removes a subtle assumption that
  Java objects have a 2 word header.

* gcconfig.h:
- Adjust Linux/IA64 configuration for non-ancient kernels.
  (Necessary fix for IA64.)

* linux_threads.c:
- Fix syntax error in currently unused code.  Will be needed
  for Linux/PA-RISC.

* malloc.c:
- Handle MIN_WORDS.

* misc.c:
- Handle MIN_WORDS.
- Change stack cleaning code to typically clear about one tenth
  the memory it used to in the threads configuration.  Occasionally
  still clear more.  (This is really a fix for a long-standing
  and fairly significant performance bug with threads.)

* os_dep.c:
- Fix the code for finding the beginning of the data segment under
  Linux.  I believe this is necessary for some IA64 Linux
  distributions.  It will also helo other platforms, though those
  may additionally require a gcconfig.h adjustment.  (This basically
  works around the absence of a data_start or __data_start
  definition in glibc.)

* test.c:
- Handle rounding due to MIN_WORDS.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41102 138bc75d-0d04-0410-961f-82ee72b054a4

boehm-gc/ChangeLog
boehm-gc/finalize.c
boehm-gc/gc_priv.h
boehm-gc/gcconfig.h
boehm-gc/gcj_mlc.c
boehm-gc/linux_threads.c
boehm-gc/malloc.c
boehm-gc/misc.c
boehm-gc/os_dep.c
boehm-gc/test.c

index e5636d9..31b8ebe 100644 (file)
@@ -1,3 +1,44 @@
+2001-04-04  Hans Boehm  <hans_boehm@hp.com>
+
+       * finalize.c:
+       - Accomodate finalization requests for static objects.
+         (Will be required by hash synchronization.  May be needed
+         in some configurations now.)
+
+       * gc_priv.h:
+       - Define MIN_WORDS.  All allocation requests are rounded
+         up to at least this size.  Removes a subtle assumption that
+         Java objects have a 2 word header.
+
+       * gcconfig.h:
+       - Adjust Linux/IA64 configuration for non-ancient kernels.
+         (Necessary fix for IA64.)
+
+       * linux_threads.c:
+       - Fix syntax error in currently unused code.  Will be needed
+         for Linux/PA-RISC.
+
+       * malloc.c:
+       - Handle MIN_WORDS.
+
+       * misc.c:
+       - Handle MIN_WORDS.
+       - Change stack cleaning code to typically clear about one tenth
+         the memory it used to in the threads configuration.  Occasionally
+         still clear more.  (This is really a fix for a long-standing
+         and fairly significant performance bug with threads.)
+
+       * os_dep.c:
+       - Fix the code for finding the beginning of the data segment under
+         Linux.  I believe this is necessary for some IA64 Linux
+         distributions.  It will also helo other platforms, though those
+         may additionally require a gcconfig.h adjustment.  (This basically
+         works around the absence of a data_start or __data_start
+         definition in glibc.)
+
+       * test.c:
+       - Handle rounding due to MIN_WORDS.
+
 2001-03-22  Tom Tromey  <tromey@redhat.com>
 
        * Makefile.am (gctest_LDFLAGS): Use -shared-libgcc.
index e70a9ff..7ff6798 100644 (file)
@@ -324,6 +324,7 @@ finalization_mark_proc * mp;
     struct finalizable_object * curr_fo, * prev_fo;
     int index;
     struct finalizable_object *new_fo;
+    hdr *hhdr;
     DCL_LOCK_STATE;
 
 #   ifdef THREADS
@@ -402,6 +403,19 @@ finalization_mark_proc * mp;
 #      endif
         return;
     }
+    GET_HDR(base, hhdr);
+    if (0 == hhdr) {
+      /* We won't collect it, hence finalizer wouldn't be run. */
+      /* This is changed for gcj, but it will be in version 6.0 of the */
+      /* standard collector distribution.  It costs virtually nothing  */
+      /* here, but it's expensive to check in the hash synchronization */
+      /* code, where it matters.               -HB                     */
+#     ifdef THREADS
+          UNLOCK();
+         ENABLE_SIGNALS();
+#     endif
+      return;
+    }
 #   ifdef THREADS
       new_fo = (struct finalizable_object *)
        GC_generic_malloc_inner(sizeof(struct finalizable_object),NORMAL);
@@ -413,7 +427,7 @@ finalization_mark_proc * mp;
         new_fo -> fo_hidden_base = (word)HIDE_POINTER(base);
        new_fo -> fo_fn = fn;
        new_fo -> fo_client_data = (ptr_t)cd;
-       new_fo -> fo_object_size = GC_size(base);
+       new_fo -> fo_object_size = hhdr -> hb_sz;
        new_fo -> fo_mark_proc = mp;
        fo_set_next(new_fo, fo_head[index]);
        GC_fo_entries++;
index c0fa5d6..314eced 100644 (file)
@@ -890,6 +890,18 @@ extern GC_warn_proc GC_current_warn_proc;
 #   define SMALL_OBJ(bytes) ((bytes) <= WORDS_TO_BYTES(MAXOBJSZ))
 #   define ADD_SLOP(bytes) (bytes)
 # endif
+# ifndef MIN_WORDS
+    /* MIN_WORDS is the size of the smallest allocated object. */
+    /* 1 and 2 are the only valid values.                      */
+    /* 2 must be used if:                                      */
+    /* - GC_gcj_malloc can be used for objects of requested    */
+    /*   size smaller than 2 words                             */
+#   if defined(GC_GCJ_SUPPORT)
+#     define MIN_WORDS 2       /* Smallest allocated object.   */
+#   else
+#     define MIN_WORDS 1
+#   endif
+# endif
 
 
 /*
index 4cab9c7..84a4b3c 100644 (file)
 #       define CPP_WORDSZ 64
        /* This should really be done through /proc, but that   */
        /* requires we run on an IA64 kernel.                   */
-#       define STACKBOTTOM ((ptr_t) 0xa000000000000000l)
+       /* The following works on NUE and older kernels:        */
+/* #       define STACKBOTTOM ((ptr_t) 0xa000000000000000l)    */
+       /* This does not work on NUE:                           */
+#       define LINUX_STACKBOTTOM
        /* We also need the base address of the register stack  */
-       /* backing store.  There is probably a better way to    */
-       /* get that, too ...                                    */
-#      define BACKING_STORE_BASE ((ptr_t) 0x9fffffff80000000l)
+       /* backing store.  There should be a better way to get  */
+       /* this:                                                */
+#      define APPROX_BS_BASE ((word)GC_stackbottom-0x80000000)
+       /* We round to the next multiple of 1 MB, to compensate */
+       /* for the fact that the stack base is displaced by     */
+       /* the environment, etc.                                */
+#      define BACKING_STORE_BASE \
+               (ptr_t)((APPROX_BS_BASE + 0xfffff) & ~0xfffff)
+
 #      if 1
 #          define SEARCH_FOR_DATA_START
 #          define DATASTART GC_data_start
index d7b912c..519c5cb 100644 (file)
@@ -267,7 +267,6 @@ DCL_LOCK_STATE;
         } else {
             *opp = obj_link(op);
             GC_words_allocd += lw;
-            FASTUNLOCK();
         }
        *(void **)op = ptr_to_struct_containing_descr;
        UNLOCK();
index cac5237..2c856f5 100644 (file)
@@ -611,7 +611,7 @@ void * GC_start_routine(void * arg)
        /* Needs to be plausible, since an asynchronous stack mark      */
        /* should not crash.                                            */
 #   else
-      me -> stack_end = (ptr_t)(((word)(&dummy) & ~(GC_page_size - 1));
+      me -> stack_end = (ptr_t)((word)(&dummy) & ~(GC_page_size - 1));
       me -> stack_ptr = me -> stack_end + 0x10;
 #   endif
     /* This is dubious, since we may be more than a page into the stack, */
index a5a93ad..c922224 100644 (file)
@@ -52,7 +52,7 @@ register ptr_t *opp;
          lw = GC_size_map[lb];
 #      else
          lw = ALIGNED_WORDS(lb);
-         if (lw == 0) lw = 1;
+         if (lw == 0) lw = MIN_WORDS;
 #       endif
        opp = &(kind -> ok_freelist[lw]);
         if( (op = *opp) == 0 ) {
index dd42961..1e1ada5 100644 (file)
@@ -107,13 +107,17 @@ extern signed_word GC_mem_found;
     {
        register unsigned i;
 
-       /* Map size 0 to 1.  This avoids problems at lower levels. */
-         GC_size_map[0] = 1;
+       /* Map size 0 to something bigger.                         */
+        /* This avoids problems at lower levels.                  */
        /* One word objects don't have to be 2 word aligned.       */
-         for (i = 1; i < sizeof(word); i++) {
-             GC_size_map[i] = 1;
+         for (i = 0; i < sizeof(word); i++) {
+             GC_size_map[i] = MIN_WORDS;
          }
-         GC_size_map[sizeof(word)] = ROUNDED_UP_WORDS(sizeof(word));
+#        if MIN_WORDS > 1
+           GC_size_map[sizeof(word)] = MIN_WORDS;
+#        else
+           GC_size_map[sizeof(word)] = ROUNDED_UP_WORDS(sizeof(word));
+#        endif
        for (i = sizeof(word) + 1; i <= 8 * sizeof(word); i++) {
 #           ifdef ALIGN_DOUBLE
              GC_size_map[i] = (ROUNDED_UP_WORDS(i) + 1) & (~1);
@@ -202,10 +206,10 @@ extern signed_word GC_mem_found;
  */
 word GC_stack_last_cleared = 0;        /* GC_no when we last did this */
 # ifdef THREADS
-#   define CLEAR_SIZE 2048
-# else
-#   define CLEAR_SIZE 213
+#   define BIG_CLEAR_SIZE 2048 /* Clear this much now and then.        */
+#   define SMALL_CLEAR_SIZE 256 /* Clear this much every time.         */
 # endif
+# define CLEAR_SIZE 213  /* Granularity for GC_clear_stack_inner */
 # define DEGRADE_RATE 50
 
 word GC_min_sp;                /* Coolest stack pointer value from which we've */
@@ -262,10 +266,12 @@ ptr_t arg;
 {
     register word sp = (word)GC_approx_sp();  /* Hotter than actual sp */
 #   ifdef THREADS
-        word dummy[CLEAR_SIZE];
-#   else
-       register word limit;
+        word dummy[SMALL_CLEAR_SIZE];
+       unsigned random_no = 0;  /* Should be more random than it is ... */
+                                /* Used to occasionally clear a bigger  */
+                                /* chunk.                               */
 #   endif
+    register word limit;
     
 #   define SLOP 400
        /* Extra bytes we clear every time.  This clears our own        */
@@ -283,7 +289,14 @@ ptr_t arg;
        /* thus more junk remains accessible, thus the heap gets        */
        /* larger ...                                                   */
 # ifdef THREADS
-    BZERO(dummy, CLEAR_SIZE*sizeof(word));
+    if (++random_no % 13 == 0) {
+       limit = sp;
+       MAKE_HOTTER(limit, BIG_CLEAR_SIZE*sizeof(word));
+       return GC_lear_stack_inner(arg, limit);
+    } else {
+       BZERO(dummy, SMALL_CLEAR_SIZE*sizeof(word));
+       return arg;
+    }
 # else
     if (GC_gc_no > GC_stack_last_cleared) {
         /* Start things over, so we clear the entire stack again */
index 87f84e7..a192d35 100644 (file)
 #endif
 
 #if defined(SEARCH_FOR_DATA_START)
-  /* The following doesn't work if the GC is in a dynamic library.     */
   /* The I386 case can be handled without a search.  The Alpha case    */
   /* used to be handled differently as well, but the rules changed     */
   /* for recent Linux versions.  This seems to be the easiest way to   */
   /* cover all versions.                                               */
-  ptr_t GC_data_start;
 
-  extern char * GC_copyright[];  /* Any data symbol would do. */
+# ifdef LINUX
+#   pragma weak __data_start
+    extern int __data_start;
+#   pragma weak data_start
+    extern int data_start;
+# endif /* LINUX */
+  extern int _end;
+
+  ptr_t GC_data_start;
 
   void GC_init_linux_data_start()
   {
     extern ptr_t GC_find_limit();
 
-    GC_data_start = GC_find_limit((ptr_t)GC_copyright, FALSE);
+#   ifdef LINUX
+      /* Try the easy approaches first:        */
+      if (&__data_start != 0) {
+         GC_data_start = (ptr_t)(&__data_start);
+         return;
+      }
+      if (&data_start != 0) {
+         GC_data_start = (ptr_t)(&data_start);
+         return;
+      }
+#   endif /* LINUX */
+    GC_data_start = GC_find_limit((ptr_t)(&_end), FALSE);
   }
 #endif
 
index 96a5415..9254fa8 100644 (file)
@@ -958,17 +958,17 @@ void run_one_test()
                "This test program is not designed for leak detection mode\n");
        (void)GC_printf0("Expect lots of problems.\n");
 #   endif
-    if (GC_size(GC_malloc(7)) != 8
+    if (GC_size(GC_malloc(7)) != 8 &&
+       GC_size(GC_malloc(7)) != MIN_WORDS * sizeof(GC_word)
        || GC_size(GC_malloc(15)) != 16) {
            (void)GC_printf0("GC_size produced unexpected results\n");
            FAIL;
     }
-    if (GC_size(GC_malloc(0)) != 4 && GC_size(GC_malloc(0)) != 8) {
+    if (GC_size(GC_malloc(0)) != MIN_WORDS * sizeof(GC_word)) {
        (void)GC_printf0("GC_malloc(0) failed\n");
            FAIL;
     }
-    if (GC_size(GC_malloc_uncollectable(0)) != 4
-        && GC_size(GC_malloc_uncollectable(0)) != 8) {
+    if (GC_size(GC_malloc_uncollectable(0)) != MIN_WORDS * sizeof(GC_word)) {
        (void)GC_printf0("GC_malloc_uncollectable(0) failed\n");
            FAIL;
     }