Alpha patch from Jeff Sturm:
authorTom Tromey <tromey@cygnus.com>
Mon, 21 Jun 1999 15:39:02 +0000 (15:39 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Mon, 21 Jun 1999 15:39:02 +0000 (15:39 +0000)
* os_dep.c (GC_init_linuxalpha): New function.
* misc.c: Initialize for alpha linux.
* gc_priv.h (GC_test_and_set): Define for alpha.
* config.h: Don't assume __data_start on alpha.

From-SVN: r27670

boehm-gc/ChangeLog
boehm-gc/config.h
boehm-gc/gc_priv.h
boehm-gc/misc.c
boehm-gc/os_dep.c

index 279a2f3..af461ba 100644 (file)
@@ -1,5 +1,11 @@
 1999-06-21  Tom Tromey  <tromey@cygnus.com>
 
+       Alpha patch from Jeff Sturm:
+       * os_dep.c (GC_init_linuxalpha): New function.
+       * misc.c: Initialize for alpha linux.
+       * gc_priv.h (GC_test_and_set): Define for alpha.
+       * config.h: Don't assume __data_start on alpha.
+
        * Makefile.in: Rebuilt.
        * Makefile.am (libgcjgc_la_LDFLAGS): Use -version-info, not
        -release.
index 6aaf503..89110a6 100644 (file)
 #       define CPP_WORDSZ 64
 #       define STACKBOTTOM ((ptr_t) 0x120000000)
 #       ifdef __ELF__
-            extern int __data_start;
-#           define DATASTART &__data_start
+#           define DATASTART GC_data_start
+#           define USE_PROC
 #           define DYNAMIC_LOADING
 #       else
 #           define DATASTART ((ptr_t) 0x140000000)
index 888e46e..cc8b147 100644 (file)
@@ -442,10 +442,32 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
                : "0"(1), "m"(*(addr)));
          return oldval;
        }
+       inline static void GC_clear(volatile unsigned int *addr) {
+          *(addr) = 0;
+       }
+#    elif defined(__alpha__)
+       inline static int GC_test_and_set(volatile unsigned int *addr) {
+        long oldval, temp;
+
+        __asm__ __volatile__(
+              "1:\tldl_l %0,%3\n"
+              "\tbne %0,2f\n"
+              "\tor $31,1,%1\n"
+              "\tstl_c %1,%2\n"
+              "\tbeq %1,1b\n"
+              "2:\tmb\n"
+              : "=&r"(oldval), "=&r"(temp), "=m"(*(addr))
+              : "m"(*(addr))
+              : "memory");
+        return (int)oldval;
+       }
+       inline static void GC_clear(volatile unsigned int *addr) {
+          __asm__ __volatile__("mb": : :"memory");
+          *(addr) = 0;
+       }
 #    else
        -- > Need implementation of GC_test_and_set()
 #    endif
-#    define GC_clear(addr) (*(addr) = 0)
 
      extern volatile unsigned int GC_allocate_lock;
        /* This is not a mutex because mutexes that obey the (optional)     */
index 72c87b0..70f583f 100644 (file)
@@ -436,6 +436,9 @@ void GC_init_inner()
 #   if defined(LINUX) && defined(POWERPC)
        GC_init_linuxppc();
 #   endif
+#   if defined(LINUX) && defined(ALPHA)
+      GC_init_linuxalpha();
+#   endif
 #   ifdef SOLARIS_THREADS
        GC_thr_init();
        /* We need dirty bits in order to find live stack sections.     */
index f05e94d..29cf8ff 100644 (file)
@@ -68,7 +68,7 @@
 #   define NEED_FIND_LIMIT
 # endif
 
-# if defined(LINUX) && defined(POWERPC)
+# if defined(LINUX) && (defined(POWERPC) || defined(ALPHA))
 #   define NEED_FIND_LIMIT
 # endif
 
   }
 #endif
 
+#if defined(LINUX) && defined(ALPHA)
+  ptr_t GC_data_start;
+
+  void GC_init_linuxalpha()
+  {
+# ifdef USE_PROC
+    FILE *fp = fopen("/proc/self/maps", "r");
+
+    if (fp) {
+      extern void *_etext;
+      ptr_t stacktop = 0, stackbottom = 0;
+      ptr_t textstart = 0, textend = 0;
+      ptr_t datastart = 0, dataend = 0;
+      ptr_t bssstart = 0, bssend = 0;
+
+      while (!feof(fp)) {
+        ptr_t start, end, offset;
+        unsigned short major, minor;
+        char r, w, x, p;
+        unsigned int inode;
+
+        int n = fscanf(fp, "%lx-%lx %c%c%c%c %lx %hx:%hx %d",
+          &start, &end, &r, &w, &x, &p, &offset, &major, &minor, &inode);
+        if (n < 10) break;
+
+        /*
+         * If local variable lies within segment, it is stack.
+         * Else if segment lies below _end and is executable,
+         * it is text.  Otherwise, if segment start lies between
+         * _etext and _end and segment is writable and is mapped
+         * to the executable image it is data, otherwise bss.
+         */
+         if (start < (ptr_t)&fp && end > (ptr_t)&fp && w == 'w') {
+           stacktop = start;
+           stackbottom = end;
+         } else if (start < (ptr_t)&_end && w == '-' && x == 'x') {
+           textstart = start;
+           textend = end;
+         } else if (start >= (ptr_t)&_etext &&
+                      start < (ptr_t)&_end && w == 'w') {
+           if (inode > 0) {
+             datastart = start;
+             dataend = end;
+           } else {
+             bssstart = start;
+             bssend = end;
+           }
+         }
+
+         //printf("%016lx-%016lx %c%c%c%c %016lx %02hx:%02hx %d\n",
+         //      start, end, r, w, x, p, offset, major, minor, inode);
+
+         while (fgetc(fp) != '\n') ;
+       }
+       fclose(fp);
+
+       //fprintf(stderr, "text:  %lx-%lx\n", textstart, textend);
+       //fprintf(stderr, "data:  %lx-%lx\n", datastart, dataend);
+       //fprintf(stderr, "bss:   %lx-%lx\n", bssstart, bssend);
+       //fprintf(stderr, "stack: %lx-%lx\n", stacktop, stackbottom);
+
+       GC_data_start = datastart;
+     } else {
+# endif
+       extern ptr_t GC_find_limit();
+       extern int _edata;
+       /* This may need to be environ, without the underscore, for */
+       /* some versions.  */
+       GC_data_start = GC_find_limit((ptr_t)&_edata, FALSE);
+# ifdef USE_PROC
+     }
+# endif
+     //fprintf(stderr, "GC_data_start = %p\n", GC_data_start);
+  }
+#endif
+
 # ifdef ECOS
 
 # ifndef ECOS_GC_MEMORY_SIZE