This is the mail archive of the java-patches@sourceware.cygnus.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch [boehm-gc]: support for mingw32


Here are the patches needed to build boehm-gc for mingw32 (win32).  The
Makefile is not quite ready, since boehm-gc must be built as a DLL on
this target... at this point I can either tame libtool or continue
creating the DLL by hand.  Otherwise it is ready for use.

Win32 now has working I/O, working GC, and partly working threads.

Hans Boehm has already accepted most of these (.c and .h) changes into
his source tree.  The exception is some of the private functions (e.g.
GC_generic_malloc) which aren't supposed to be called from outside
boehm-gc anyway.

I made a trivial change to Makefile.in (I know, I know, don't do
that...) I can omit that if you'd prefer.  Likewise, I rebuilt
configure, but might be on a different version of autoconf.

-- 
Jeff Sturm
jsturm@sigma6.com


2000-04-14  Jeff Sturm  <jsturm@sigma6.com>

	* Makefile.am: Added win32_threads.c.
	* Makefile.in: Likewise.

	* configure.in: Define WIN32_THREADS for win32 targets.
	* configure: Rebuilt.

	* gc.h: Define GC_API for __MINGW32__.
	* gc_mark.h (GC_n_mark_procs, GC_find_start,
	GC_signal_mark_stack_overflow): Declare with GC_API.
	* gc_priv.h (GC_obj_kinds, GC_n_kinds,
	GC_least_plausible_heap_addr,
	GC_greatest_plausible_heap_addr,
	GC_add_to_black_list_normal,
	GC_generic_malloc,
	GC_generic_malloc_ignore_off_page,
	GC_generic_malloc_inner,
	GC_find_header): Declare with GC_API.
	* gcconfig.h: Recognize __MINGW32__ machine type.
	* mach_dep.c (GC_push_regs): Don't use MSVC assember syntax
	for mingw32.
	* test.c (GC_BUILD): Undefine, since this object is not part of
	the GC library.
	Use main, not WinMain entry point for mingw32.
	(main): Don't use thread code when NTEST == 0.
	* win32_threads.c: Don't include <windows.h> (already in gc.h).
	(struct thread_entry): Remove `context' member.
	(GC_current_stackbottom): Remove function.
	(GC_get_lo_stack_addr): Add `static' qualifier.
	Use GC_push_all_stack for current thread.  Allocate `context'
	variable on stack, not in data segment.
	(DllMain): Don't zero-out context.
Index: Makefile.am
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/Makefile.am,v
retrieving revision 1.14
diff -u -r1.14 Makefile.am
--- Makefile.am	1999/12/13 20:15:51	1.14
+++ Makefile.am	2000/04/14 20:08:17
@@ -31,7 +31,8 @@
 irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c \
 misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c	\
 real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c \
-solaris_threads.h stubborn.c typd_mlc.c version.h weakpointer.h
+solaris_threads.h stubborn.c typd_mlc.c version.h weakpointer.h \
+win32_threads.c
 libgcjgc_la_LIBADD = @addobjs@
 libgcjgc_la_DEPENDENCIES = @addobjs@
 libgcjgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir)
Index: Makefile.in
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/Makefile.in,v
retrieving revision 1.16
diff -u -r1.16 Makefile.in
--- Makefile.in	1999/12/13 20:15:51	1.16
+++ Makefile.in	2000/04/14 20:08:17
@@ -114,7 +114,8 @@
 irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c \
 misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c	\
 real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c \
-solaris_threads.h stubborn.c typd_mlc.c version.h weakpointer.h
+solaris_threads.h stubborn.c typd_mlc.c version.h weakpointer.h \
+win32_threads.c
 
 libgcjgc_la_LIBADD = @addobjs@
 libgcjgc_la_DEPENDENCIES = @addobjs@
@@ -203,7 +204,7 @@
 linux_threads.lo malloc.lo mallocx.lo mark.lo mark_rts.lo misc.lo \
 new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo ptr_chck.lo \
 real_malloc.lo reclaim.lo solaris_pthreads.lo solaris_threads.lo \
-stubborn.lo typd_mlc.lo
+stubborn.lo typd_mlc.lo win32_threads.lo
 check_PROGRAMS =  gctest$(EXEEXT)
 gctest_OBJECTS =  test.o
 gctest_DEPENDENCIES =  ./libgcjgc.la
Index: configure
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/configure,v
retrieving revision 1.19
diff -u -r1.19 configure
--- configure	1999/12/13 20:15:51	1.19
+++ configure	2000/04/14 20:08:18
@@ -1514,7 +1514,7 @@
   if { (eval echo configure:1515: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
-      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+      *.c | *.o | *.obj) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
@@ -2016,7 +2016,7 @@
   if { (eval echo configure:2017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
-      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+      *.c | *.o | *.obj) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
@@ -2113,7 +2113,13 @@
     esac
     THREADLIB=-lpthread
     ;;
- decosf1 | irix | mach | os2 | solaris | win32 | dce | vxworks)
+  win32)
+	cat >> confdefs.h <<\EOF
+#define WIN32_THREADS 1
+EOF
+
+    ;;
+ decosf1 | irix | mach | os2 | solaris | dce | vxworks)
     { echo "configure: error: thread package $THREADS not yet supported" 1>&2; exit 1; }
     ;;
  *)
Index: configure.in
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/configure.in,v
retrieving revision 1.16
diff -u -r1.16 configure.in
--- configure.in	1999/11/04 17:25:07	1.16
+++ configure.in	2000/04/14 20:08:18
@@ -84,7 +84,10 @@
     esac
     THREADLIB=-lpthread
     ;;
- decosf1 | irix | mach | os2 | solaris | win32 | dce | vxworks)
+  win32)
+	AC_DEFINE(WIN32_THREADS)
+    ;;
+ decosf1 | irix | mach | os2 | solaris | dce | vxworks)
     AC_MSG_ERROR(thread package $THREADS not yet supported)
     ;;
  *)
Index: gc.h
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/gc.h,v
retrieving revision 1.5
diff -u -r1.5 gc.h
--- gc.h	2000/02/14 21:53:27	1.5
+++ gc.h	2000/04/14 20:08:19
@@ -35,6 +35,14 @@
 #include "libgc_globals.h"
 #endif
 
+#if defined(__MINGW32__) && defined(WIN32_THREADS)
+# ifdef GC_BUILD
+#   define GC_API __declspec(dllexport)
+# else
+#   define GC_API __declspec(dllimport)
+# endif
+#endif
+
 #if defined(_MSC_VER) && defined(_DLL)
 # ifdef GC_BUILD
 #   define GC_API __declspec(dllexport)
Index: gc_mark.h
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/gc_mark.h,v
retrieving revision 1.3
diff -u -r1.3 gc_mark.h
--- gc_mark.h	1999/11/01 23:15:51	1.3
+++ gc_mark.h	2000/04/14 20:08:19
@@ -49,7 +49,7 @@
 extern mark_proc GC_mark_procs[MAX_MARK_PROCS];
 */
 
-extern word GC_n_mark_procs;
+GC_API word GC_n_mark_procs;
 
 /* Object descriptors on mark stack or in objects.  Low order two	*/
 /* bits are tags distinguishing among the following 4 possibilities	*/
@@ -98,9 +98,9 @@
 
 extern mse * GC_mark_stack;
 
-word GC_find_start();
+GC_API word GC_find_start();
 
-mse * GC_signal_mark_stack_overflow();
+GC_API mse * GC_signal_mark_stack_overflow();
 
 # ifdef GATHERSTATS
 #   define ADD_TO_ATOMIC(sz) GC_atomic_in_use += (sz)
Index: gc_priv.h
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/gc_priv.h,v
retrieving revision 1.9
diff -u -r1.9 gc_priv.h
--- gc_priv.h	1999/11/04 17:25:07	1.9
+++ gc_priv.h	2000/04/14 20:08:20
@@ -1263,7 +1263,7 @@
 /* Object kinds: */
 # define MAXOBJKINDS 16
 
-extern struct obj_kind {
+GC_API struct obj_kind {
    ptr_t *ok_freelist;	/* Array of free listheaders for this kind of object */
    			/* Point either to GC_arrays or to storage allocated */
    			/* with GC_scratch_alloc.			     */
@@ -1297,7 +1297,7 @@
 #   define IS_UNCOLLECTABLE(k) ((k) == UNCOLLECTABLE)
 # endif
 
-extern int GC_n_kinds;
+GC_API int GC_n_kinds;
 
 GC_API word GC_fo_entries;
 
@@ -1352,8 +1352,8 @@
 
 extern GC_bool GC_debugging_started;	/* GC_debug_malloc has been called. */ 
 
-extern ptr_t GC_least_plausible_heap_addr;
-extern ptr_t GC_greatest_plausible_heap_addr;
+GC_API ptr_t GC_least_plausible_heap_addr;
+GC_API ptr_t GC_greatest_plausible_heap_addr;
 			/* Bounds on the heap.  Guaranteed valid	*/
 			/* Likely to include future heap expansion.	*/
 			
@@ -1524,7 +1524,7 @@
 /* Black listing: */
 void GC_bl_init(); 	
 # ifndef ALL_INTERIOR_POINTERS
-    void GC_add_to_black_list_normal(/* bits, maybe source */);
+    GC_API void GC_add_to_black_list_normal(/* bits, maybe source */);
 			/* Register bits as a possible future false	*/
 			/* reference from the heap or static data	*/
 #   ifdef PRINT_BLACK_LIST
@@ -1640,7 +1640,7 @@
 				/* collection work, if appropriate.	*/
 				/* A unit is an amount appropriate for  */
 				/* HBLKSIZE bytes of allocation.	*/
-ptr_t GC_generic_malloc(/* bytes, kind */);
+GC_API ptr_t GC_generic_malloc(/* bytes, kind */);
 				/* Allocate an object of the given	*/
 				/* kind.  By default, there are only	*/
 				/* a few kinds: composite(pointerfree), */
@@ -1650,17 +1650,17 @@
 				/* internals to add more, e.g. to	*/
 				/* communicate object layout info	*/
 				/* to the collector.			*/
-ptr_t GC_generic_malloc_ignore_off_page(/* bytes, kind */);
+GC_API ptr_t GC_generic_malloc_ignore_off_page(/* bytes, kind */);
 				/* As above, but pointers past the 	*/
 				/* first page of the resulting object	*/
 				/* are ignored.				*/
-ptr_t GC_generic_malloc_inner(/* bytes, kind */);
+GC_API ptr_t GC_generic_malloc_inner(/* bytes, kind */);
 				/* Ditto, but I already hold lock, etc.	*/
-ptr_t GC_generic_malloc_words_small GC_PROTO((size_t words, int kind));
+GC_API ptr_t GC_generic_malloc_words_small GC_PROTO((size_t words, int kind));
 				/* As above, but size in units of words */
 				/* Bypasses MERGE_SIZES.  Assumes	*/
 				/* words <= MAXOBJSZ.			*/
-ptr_t GC_generic_malloc_inner_ignore_off_page(/* bytes, kind */);
+GC_API ptr_t GC_generic_malloc_inner_ignore_off_page(/* bytes, kind */);
 				/* Allocate an object, where		*/
 				/* the client guarantees that there	*/
 				/* will always be a pointer to the 	*/
@@ -1683,7 +1683,7 @@
 				/* Remove the header for block h.	*/
 void GC_remove_counts(/*h, sz*/);
 				/* Remove forwarding counts for h.	*/
-hdr * GC_find_header(/*p*/);	/* Debugging only.			*/
+GC_API hdr * GC_find_header(/*p*/);	/* Debugging only.			*/
 
 void GC_finalize();	/* Perform all indicated finalization actions	*/
 			/* on unmarked objects.				*/
Index: gcconfig.h
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/gcconfig.h,v
retrieving revision 1.9
diff -u -r1.9 gcconfig.h
--- gcconfig.h	2000/01/29 01:17:03	1.9
+++ gcconfig.h	2000/04/14 20:08:20
@@ -255,6 +255,11 @@
 #   define CYGWIN32
 #   define mach_type_known
 # endif
+# if defined(__MINGW32__)
+#   define I386
+#   define MSWIN32
+#   define mach_type_known
+# endif
 # if defined(__BORLANDC__)
 #   define I386
 #   define MSWIN32
Index: mach_dep.c
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/mach_dep.c,v
retrieving revision 1.5
diff -u -r1.5 mach_dep.c
--- mach_dep.c	1999/11/01 23:15:51	1.5
+++ mach_dep.c	2000/04/14 20:08:21
@@ -199,7 +199,8 @@
 #	endif	/* __MWERKS__ */
 #   endif	/* MACOS */
 
-#       if defined(I386) &&!defined(OS2) &&!defined(SVR4) &&!defined(MSWIN32) \
+#       if defined(I386) &&!defined(OS2) &&!defined(SVR4) \
+	&& (defined(__MINGW32__) || !defined(MSWIN32)) \
 	&& !defined(SCO) && !defined(SCO_ELF) \
  	&& !(defined(LINUX)       && defined(__ELF__)) \
 	&& !(defined(__FreeBSD__) && defined(__ELF__)) \
@@ -230,7 +231,8 @@
 	  asm("pushl %ebx");  asm("call GC_push_one"); asm("addl $4,%esp");
 #	endif
 
-#       if defined(I386) && defined(MSWIN32) && !defined(USE_GENERIC)
+#       if defined(I386) && defined(MSWIN32) && !defined(__MINGW32__)
+	&& !defined(USE_GENERIC)
 	/* I386 code, Microsoft variant		*/
 	  __asm  push eax
 	  __asm  call GC_push_one
Index: test.c
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/test.c,v
retrieving revision 1.3
diff -u -r1.3 test.c
--- test.c	1999/11/01 23:15:51	1.3
+++ test.c	2000/04/14 20:08:21
@@ -15,6 +15,8 @@
 /* An incomplete test for the garbage collector.  		*/
 /* Some more obscure entry points are not tested at all.	*/
 
+#undef GC_BUILD
+
 # if defined(mips) && defined(SYSTYPE_BSD43)
     /* MIPS RISCOS 4 */
 # else
@@ -836,7 +838,7 @@
     	char *y = (char *)(size_t)fail_proc1;
 #   endif
     DCL_LOCK_STATE;
-    
+
 #   ifdef FIND_LEAK
 	(void)GC_printf0(
 		"This test program is not designed for leak detection mode\n");
@@ -1032,7 +1034,7 @@
 #if !defined(PCR) && !defined(SOLARIS_THREADS) && !defined(WIN32_THREADS) \
   && !defined(IRIX_THREADS) && !defined(LINUX_THREADS) \
   && !defined(HPUX_THREADS) || defined(LINT)
-#ifdef MSWIN32
+#if defined(MSWIN32) && !defined(__MINGW32__)
   int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int n)
 #else
   int main()
@@ -1100,7 +1102,7 @@
   return 0;
 }
 
-#define NTEST 2 
+#define NTEST 2
 
 int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int n)
 {
@@ -1114,6 +1116,7 @@
 # endif
   InitializeCriticalSection(&incr_cs);
   (void) GC_set_warn_proc(warn_proc);
+#if NTEST > 0
   for (i = 0; i < NTEST; i++) {
     h[i] = (HANDLE)_beginthreadex(NULL, 0, thr_run_one_test, 0, 0, &thread_id);
     if (h[i] == (HANDLE)-1) {
@@ -1121,12 +1124,15 @@
       FAIL;
     }
   }
+#endif
   run_one_test();
+#if NTEST > 0
   for (i = 0; i < NTEST; i++)
     if (WaitForSingleObject(h[i], INFINITE) != WAIT_OBJECT_0) {
       (void)GC_printf1("Thread wait failed %lu\n", (unsigned long)GetLastError());
       FAIL;
     }
+#endif
   check_heap_stats();
   (void)fflush(stdout);
   return(0);
Index: win32_threads.c
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/win32_threads.c,v
retrieving revision 1.3
diff -u -r1.3 win32_threads.c
--- win32_threads.c	1999/11/01 23:15:51	1.3
+++ win32_threads.c	2000/04/14 20:08:21
@@ -2,9 +2,6 @@
 
 #include "gc_priv.h"
 
-#define STRICT
-#include <windows.h>
-
 #define MAX_THREADS 64
 
 struct thread_entry {
@@ -14,7 +11,6 @@
   void *stack;		/* The cold end of the stack.   */
 			/* 0 ==> entry not valid.	*/
 			/* !in_use ==> stack == 0	*/
-  CONTEXT context;
   GC_bool suspended;
 };
 
@@ -50,18 +46,8 @@
     }
   GC_please_stop = FALSE;
 }
-
-ptr_t GC_current_stackbottom()
-{
-  DWORD thread_id = GetCurrentThreadId();
-  int i;
-  for (i = 0; i < MAX_THREADS; i++)
-    if (thread_table[i].stack && thread_table[i].id == thread_id)
-      return thread_table[i].stack;
-  ABORT("no thread table entry for current thread");
-}
 
-ptr_t GC_get_lo_stack_addr(ptr_t s)
+static ptr_t GC_get_lo_stack_addr(ptr_t s)
 {
     ptr_t bottom;
     MEMORY_BASIC_INFORMATION info;
@@ -79,25 +65,28 @@
   int i;
   for (i = 0; i < MAX_THREADS; i++)
     if (thread_table[i].stack) {
+#ifdef GC_DEBUG
       ptr_t bottom = GC_get_lo_stack_addr(thread_table[i].stack);
+#endif
       if (thread_table[i].id == thread_id)
-	GC_push_all(&i, thread_table[i].stack);
+	GC_push_all_stack(&i, thread_table[i].stack);
       else {
-	thread_table[i].context.ContextFlags
-			= (CONTEXT_INTEGER|CONTEXT_CONTROL);
-	if (!GetThreadContext(thread_table[i].handle,
-	    		      &thread_table[i].context))
+	CONTEXT context;
+	context.ContextFlags = (CONTEXT_INTEGER|CONTEXT_CONTROL);
+	if (!GetThreadContext(thread_table[i].handle, &context))
 	  ABORT("GetThreadContext failed");
-	if (thread_table[i].context.Esp >= (DWORD)thread_table[i].stack
-	    || thread_table[i].context.Esp < (DWORD)bottom)
+#ifdef GC_DEBUG
+	if (context.Esp >= (DWORD)thread_table[i].stack
+	    || context.Esp < (DWORD)bottom)
 	    ABORT("Thread stack pointer out of range");
-	GC_push_one ((word) thread_table[i].context.Edi);
-    	GC_push_one ((word) thread_table[i].context.Esi);
-    	GC_push_one ((word) thread_table[i].context.Ebx);
-    	GC_push_one ((word) thread_table[i].context.Edx);
-    	GC_push_one ((word) thread_table[i].context.Ecx);
-    	GC_push_one ((word) thread_table[i].context.Eax);
-	GC_push_all_stack(thread_table[i].context.Esp, thread_table[i].stack);
+#endif
+	GC_push_one ((word) context.Edi);
+    	GC_push_one ((word) context.Esi);
+    	GC_push_one ((word) context.Ebx);
+    	GC_push_one ((word) context.Edx);
+    	GC_push_one ((word) context.Ecx);
+    	GC_push_one ((word) context.Eax);
+	GC_push_all_stack(context.Esp, thread_table[i].stack);
       }
     }
 }
@@ -198,7 +187,6 @@
       thread_table[i].stack = 0;
       thread_table[i].in_use = FALSE;
       CloseHandle(thread_table[i].handle);
-      BZERO(&thread_table[i].context, sizeof(CONTEXT));
       UNLOCK();
     }
     break;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]