2007-06-06 Hans Boehm <Hans.Boehm@hp.com> (Really mostly Romano Paolo Tenca)
authorhboehm <hboehm>
Wed, 6 Jun 2007 19:49:20 +0000 (19:49 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:40 +0000 (21:06 +0400)
* include/gc.h: (GC_word, GC_signed_word): Fix win64 definitions.
Don't include windows.h in an extern "C" context.
* include/private/gcconfig.h: Fix win64/X86_64 configuration.
* tests/test.c: Eliminate more old style function definitions.
Cleanup pointer and integer casts for win64.
* tests/test_cpp.cc: Don't include gc_priv.h.
* NT_STATIC_THREADS_MAKEFILE: Restrict suffixes for VC++ 2005.
* NT_X64_STATIC_THREADS_MAKEFILE: New.

NT_STATIC_THREADS_MAKEFILE
NT_X64_STATIC_THREADS_MAKEFILE [new file with mode: 0644]
include/gc.h
include/private/gcconfig.h
tests/test.c
tests/test_cpp.cc

index b52ed67..d0f9127 100644 (file)
@@ -6,6 +6,11 @@ MY_CPU=X86
 CPU=$(MY_CPU)
 !include <ntwin32.mak>
 
+# Make sure that .cc is not viewed as a suffix.  It is for VC++2005, but
+# not earlier versions.  We can deal with either, but not inconsistency.
+.SUFFIXES:
+.SUFFIXES: .obj .cpp .c
+
 # Atomic_ops installation directory.  For win32, the source directory
 # should do, since we only need the headers.
 # We assume this was manually unpacked, since I'm not sure there is
diff --git a/NT_X64_STATIC_THREADS_MAKEFILE b/NT_X64_STATIC_THREADS_MAKEFILE
new file mode 100644 (file)
index 0000000..31ca3db
--- /dev/null
@@ -0,0 +1,74 @@
+# Makefile for Windows NT.  Assumes Microsoft compiler.
+# DLLs are included in the root set under NT, but not under win32S.
+# Use "nmake nodebug=1 all" for optimized versions of library, gctest and editor.
+
+MY_CPU=AMD64
+CPU=$(MY_CPU)
+!include <ntwin32.mak>
+
+# Make sure that .cc is not viewed as a suffix.  It is for VC++2005, but
+# not earlier versions.  We can deal with either, but not inconsistency.
+.SUFFIXES:
+.SUFFIXES: .obj .cpp .c
+
+# Atomic_ops installation directory.  For win32, the source directory
+# should do, since we only need the headers.
+# We assume this was manually unpacked, since I'm not sure there is
+# a Windows standard command line tool to do this.
+AO_VERSION=1.2
+AO_SRC_DIR=libatomic_ops-$(AO_VERSION)/src
+AO_INCLUDE_DIR=$(AO_SRC_DIR)
+
+OBJS= alloc.obj reclaim.obj allchblk.obj misc.obj mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj obj_map.obj blacklst.obj finalize.obj new_hblk.obj dbg_mlc.obj malloc.obj stubborn.obj dyn_load.obj typd_mlc.obj ptr_chck.obj gc_cpp.obj mallocx.obj win32_threads.obj msvc_dbg.obj thread_local_alloc.obj
+
+all: gctest.exe cord\de.exe test_cpp.exe
+
+.c.obj:
+       $(cc) $(cdebug) $(cflags) $(cvarsmt) -Iinclude -I$(AO_INCLUDE_DIR) -DALL_INTERIOR_POINTERS -D__STDC__ -DGC_NOT_DLL -DGC_WIN32_THREADS -DTHREAD_LOCAL_ALLOC $*.c /Fo$*.obj /wd4107 -D_CRT_SECURE_NO_DEPRECATE
+# Disable "may not be initialized" warnings.  They're too approximate.
+# Disable crt security warnings, since unfortunately they warn about all sorts
+# of safe uses of strncpy.  It would be nice to leave the rest enabled.
+
+.cpp.obj:
+       $(cc) $(cdebug) $(cflags) $(cvarsmt) -Iinclude -I$(AO_INCLUDE_DIR) -DALL_INTERIOR_POINTERS -DGC_NOT_DLL $*.CPP -DGC_WIN32_THREADS -DTHREAD_LOCAL_ALLOC /Fo$*.obj
+
+$(OBJS) tests\test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h include\private\gc_locks.h include\private\gc_pmark.h include\gc_mark.h include\private\msvc_dbg.h
+
+gc.lib: $(OBJS)
+       lib /MACHINE:X64 /out:gc.lib $(OBJS)
+
+gctest.exe: tests\test.obj gc.lib
+#  This produces a "GUI" applications that opens no windows and writes to the log file
+#  "gc.log".  This was done to make the result runnable under win32s and
+#  should be fixed.
+       $(link) -debugtype:cv $(guiflags) -stack:131072 -out:$*.exe tests\test.obj $(guilibs) gc.lib
+
+cord\de_win.rbj: cord\de_win.res
+       cvtres /MACHINE:$(MY_CPU) /OUT:cord\de_win.rbj cord\de_win.res
+
+cord\de.obj cord\de_win.obj: include\cord.h include\private\cord_pos.h cord\de_win.h cord\de_cmds.h
+
+cord\de_win.res: cord\de_win.rc cord\de_win.h cord\de_cmds.h
+       $(rc) $(rcvars) -r -fo cord\de_win.res cord\de_win.rc
+
+# Cord/de is a real win32 gui application.
+cord\de.exe: cord\cordbscs.obj cord\cordxtra.obj cord\de.obj cord\de_win.obj cord\de_win.rbj gc.lib
+       $(link) -debugtype:cv $(guiflags) -stack:16384 -out:cord\de.exe  cord\cordbscs.obj cord\cordxtra.obj cord\de.obj cord\de_win.obj cord\de_win.rbj gc.lib $(guilibs)
+
+gc_cpp.obj: include\gc_cpp.h include\gc.h
+
+gc_cpp.cpp: gc_cpp.cc
+       copy gc_cpp.cc gc_cpp.cpp
+
+test_cpp.cpp: tests\test_cpp.cc
+       copy tests\test_cpp.cc test_cpp.cpp
+
+# This generates the C++ test executable.  The executable expects
+# a single numeric argument, which is the number of iterations.
+# The output appears in the file "gc.log".
+test_cpp.exe: test_cpp.obj include\gc_cpp.h include\gc.h gc.lib
+       $(link) -debugtype:cv $(guiflags) -stack:16384 -out:test_cpp.exe test_cpp.obj gc.lib $(guilibs)
+
+AO_SCR_DIR:
+               tar xvfz $(AO_SRC_DIR).tar.gz;
+
index f3c7725..ea11fff 100644 (file)
@@ -52,8 +52,8 @@
   /* Win64 isn't really supported yet, but this is the first step. And */
   /* it might cause error messages to show up in more plausible places.        */
   /* This needs basetsd.h, which is included by windows.h.             */
-  typedef ULONG_PTR GC_word;
-  typedef LONG_PTR GC_word;
+  typedef unsigned long long GC_word;
+  typedef long long GC_signed_word;
 #endif
 
 /* Public read-only variables */
@@ -1003,10 +1003,19 @@ GC_register_has_static_roots_callback
   (int (*callback)(const char *, void *, size_t));
 
 
-#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) \
+#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) \
+       && !defined(__CYGWIN__) \
        && !defined(GC_PTHREADS)
+
+#ifdef __cplusplus
+    }  /* Including windows.h in an extern "C" context no longer works. */
+#endif
+
 # include <windows.h>
 
+#ifdef __cplusplus
+    extern "C" {
+#endif
   /*
    * All threads must be created using GC_CreateThread or GC_beginthreadex,
    * or must explicitly call GC_register_my_thread,
index 615dd7a..20f35bc 100644 (file)
 # else
 #   if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \
         || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
-#     define I386
-#     define MSWIN32   /* or Win32s */
+#     if defined(__LP64__) || defined(_WIN64)
+#      define X86_64
+#     else
+#       define I386
+#     endif
+#     define MSWIN32   /* or Win64 */
 #     define mach_type_known
 #   endif
 #   if defined(_MSC_VER) && defined(_M_IA64)
 # ifdef I386
 #   define MACH_TYPE "I386"
 #   if defined(__LP64__) || defined(_WIN64)
-#     define CPP_WORDSZ 64
-#     define ALIGNMENT 8
+#     error This should be handled as X86_64
 #   else
 #     define CPP_WORDSZ 32
 #     define ALIGNMENT 4
 #        define HEAP_START DATAEND
 #       endif
 #   endif
+#   ifdef MSWIN32
+#      define OS_TYPE "MSWIN32"
+               /* STACKBOTTOM and DATASTART are handled specially in   */
+               /* os_dep.c.                                            */
+#       if !defined(__WATCOMC__)
+#        define MPROTECT_VDB
+         /* We also avoided doing this in the past with GC_WIN32_THREADS */
+         /* Hopefully that's fixed.                                      */
+#      endif
+#      if _MSC_VER >= 1300  /* .NET, i.e. > VisualStudio 6     */
+#         define GWW_VDB
+#      endif
+#       define DATAEND  /* not needed */
+#   endif
 # endif
 
 #if defined(LINUX) && defined(USE_MMAP)
index 70bd7c5..6c7a6ce 100644 (file)
@@ -137,7 +137,8 @@ struct SEXPR {
 
 typedef struct SEXPR * sexpr;
 
-# define INT_TO_SEXPR(x) ((sexpr)(unsigned long)(x))
+# define INT_TO_SEXPR(x) ((sexpr)(GC_word)(x))
+# define SEXPR_TO_INT(x) ((int)(GC_word)(x))
 
 # undef nil
 # define nil (INT_TO_SEXPR(0))
@@ -153,13 +154,11 @@ int extra_count = 0;        /* Amount of space wasted in cons node */
 # ifdef VERY_SMALL_CONFIG
 #   define cons small_cons
 # else
-sexpr cons (x, y)
-sexpr x;
-sexpr y;
+sexpr cons (sexpr x, sexpr y)
 {
-    register sexpr r;
-    register int *p;
-    register int my_extra = extra_count;
+    sexpr r;
+    int *p;
+    int my_extra = extra_count;
     
     stubborn_count++;
     r = (sexpr) GC_MALLOC_STUBBORN(sizeof(struct SEXPR) + my_extra);
@@ -173,7 +172,7 @@ sexpr y;
            (void)GC_printf("Found nonzero at %p - allocator is broken\n", p);
            FAIL;
         }
-        *p = (13 << 12) + ((p - (int *)r) & 0xfff);
+        *p = (int)((13 << 12) + ((p - (int *)r) & 0xfff));
     }
 #   ifdef AT_END
        r = (sexpr)((char *)r + (my_extra & ~7));
@@ -233,11 +232,9 @@ struct GC_ms_entry * fake_gcj_mark_proc(word * addr,
 #endif /* GC_GCJ_SUPPORT */
 
 
-sexpr small_cons (x, y)
-sexpr x;
-sexpr y;
+sexpr small_cons (sexpr x, sexpr y)
 {
-    register sexpr r;
+    sexpr r;
     
     collectable_count++;
     r = (sexpr) GC_MALLOC(sizeof(struct SEXPR));
@@ -250,11 +247,9 @@ sexpr y;
     return(r);
 }
 
-sexpr small_cons_uncollectable (x, y)
-sexpr x;
-sexpr y;
+sexpr small_cons_uncollectable (sexpr x, sexpr y)
 {
-    register sexpr r;
+    sexpr r;
     
     uncollectable_count++;
     r = (sexpr) GC_MALLOC_UNCOLLECTABLE(sizeof(struct SEXPR));
@@ -263,16 +258,14 @@ sexpr y;
         exit(1);
     }
     r -> sexpr_car = x;
-    r -> sexpr_cdr = (sexpr)(~(unsigned long)y);
+    r -> sexpr_cdr = (sexpr)(~(GC_word)y);
     return(r);
 }
 
 #ifdef GC_GCJ_SUPPORT
 
 
-sexpr gcj_cons(x, y)
-sexpr x;
-sexpr y;
+sexpr gcj_cons(sexpr x, sexpr y)
 {
     GC_word * r;
     sexpr result;
@@ -293,8 +286,7 @@ sexpr y;
 #endif
 
 /* Return reverse(x) concatenated with y */
-sexpr reverse1(x, y)
-sexpr x, y;
+sexpr reverse1(sexpr x, sexpr y)
 {
     if (is_nil(x)) {
         return(y);
@@ -303,8 +295,7 @@ sexpr x, y;
     }
 }
 
-sexpr reverse(x)
-sexpr x;
+sexpr reverse(sexpr x)
 {
 #   ifdef TEST_WITH_SYSTEM_MALLOC
       malloc(100000);
@@ -312,8 +303,7 @@ sexpr x;
     return( reverse1(x, nil) );
 }
 
-sexpr ints(low, up)
-int low, up;
+sexpr ints(int low, int up)
 {
     if (low > up) {
        return(nil);
@@ -324,8 +314,7 @@ int low, up;
 
 #ifdef GC_GCJ_SUPPORT
 /* Return reverse(x) concatenated with y */
-sexpr gcj_reverse1(x, y)
-sexpr x, y;
+sexpr gcj_reverse1(sexpr x, sexpr y)
 {
     if (is_nil(x)) {
         return(y);
@@ -334,14 +323,12 @@ sexpr x, y;
     }
 }
 
-sexpr gcj_reverse(x)
-sexpr x;
+sexpr gcj_reverse(sexpr x)
 {
     return( gcj_reverse1(x, nil) );
 }
 
-sexpr gcj_ints(low, up)
-int low, up;
+sexpr gcj_ints(int low, int up)
 {
     if (low > up) {
        return(nil);
@@ -353,8 +340,7 @@ int low, up;
 
 /* To check uncollectable allocation we build lists with disguised cdr */
 /* pointers, and make sure they don't go away.                         */
-sexpr uncollectable_ints(low, up)
-int low, up;
+sexpr uncollectable_ints(int low, int up)
 {
     if (low > up) {
        return(nil);
@@ -364,11 +350,9 @@ int low, up;
     }
 }
 
-void check_ints(list, low, up)
-sexpr list;
-int low, up;
+void check_ints(sexpr list, int low, int up)
 {
-    if ((int)(GC_word)(car(car(list))) != low) {
+    if (SEXPR_TO_INT(car(car(list))) != low) {
         (void)GC_printf(
            "List reversal produced incorrect list - collector is broken\n");
         FAIL;
@@ -383,13 +367,11 @@ int low, up;
     }
 }
 
-# define UNCOLLECTABLE_CDR(x) (sexpr)(~(unsigned long)(cdr(x)))
+# define UNCOLLECTABLE_CDR(x) (sexpr)(~(GC_word)(cdr(x)))
 
-void check_uncollectable_ints(list, low, up)
-sexpr list;
-int low, up;
+void check_uncollectable_ints(sexpr list, int low, int up)
 {
-    if ((int)(GC_word)(car(car(list))) != low) {
+    if (SEXPR_TO_INT(car(car(list))) != low) {
         (void)GC_printf(
            "Uncollectable list corrupted - collector is broken\n");
         FAIL;
@@ -410,7 +392,7 @@ void print_int_list(sexpr x)
     if (is_nil(x)) {
         (void)GC_printf("NIL\n");
     } else {
-        (void)GC_printf("(%ld)", (long)(car(car(x))));
+        (void)GC_printf("(%d)", SEXPR_TO_INT(car(car(x))));
         if (!is_nil(cdr(x))) {
             (void)GC_printf(", ");
             (void)print_int_list(cdr(x));
@@ -431,7 +413,7 @@ void check_marks_int_list(sexpr x)
         (void)GC_printf("NIL\n");
     } else {
         if (!GC_is_marked((ptr_t)car(x))) GC_printf("[unm car:%p]", car(x));
-        (void)GC_printf("(%ld)", (long)(car(car(x))));
+        (void)GC_printf("(%d)", SEXPR_TO_INT(car(car(x))));
         if (!is_nil(cdr(x))) {
             (void)GC_printf(", ");
             (void)check_marks_int_list(cdr(x));
@@ -692,8 +674,7 @@ size_t counter = 0;
 
 int live_indicators_count = 0;
 
-tn * mktree(n)
-int n;
+tn * mktree(int n)
 {
     tn * result = (tn *)GC_MALLOC(sizeof(tn));
     
@@ -778,9 +759,7 @@ int n;
     return(result);
 }
 
-void chktree(t,n)
-tn *t;
-int n;
+void chktree(tn *t, int n)
 {
     if (n == 0 && t != 0) {
         (void)GC_printf("Clobbered a leaf - collector is broken\n");
@@ -844,10 +823,9 @@ void * alloc8bytes()
 #   define alloc8bytes() GC_MALLOC_ATOMIC(8)
 #endif
 
-void alloc_small(n)
-int n;
+void alloc_small(int n)
 {
-    register int i;
+    int i;
     
     for (i = 0; i < n; i += 8) {
         atomic_count++;
@@ -874,7 +852,7 @@ int n;
 void tree_test()
 {
     tn * root;
-    register int i;
+    int i;
     
     root = mktree(TREE_HEIGHT);
 #   ifndef VERY_SMALL_CONFIG
index 9a7af1c..695f951 100644 (file)
@@ -37,7 +37,11 @@ few minutes to complete.
 #   include "gc_alloc.h"
 #endif
 extern "C" {
-#include "private/gc_priv.h"
+# include "private/gcconfig.h"
+  GC_API void GC_printf(const char *format, ...);
+  /* Use GC private output to reach the same log file.  */
+  /* Don't include gc_priv.h, since that may include Windows system    */
+  /* header files that don't take kindly to this context.              */
 }
 #ifdef MSWIN32
 #   include <windows.h>