From e4209b16e78bb50386a5f4cf545211e7249e35cd Mon Sep 17 00:00:00 2001 From: hboehm Date: Wed, 6 Jun 2007 19:49:20 +0000 Subject: [PATCH] 2007-06-06 Hans Boehm (Really mostly Romano Paolo Tenca) * 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 | 5 +++ NT_X64_STATIC_THREADS_MAKEFILE | 74 ++++++++++++++++++++++++++++++++++++ include/gc.h | 15 ++++++-- include/private/gcconfig.h | 25 ++++++++++-- tests/test.c | 86 ++++++++++++++++-------------------------- tests/test_cpp.cc | 6 ++- 6 files changed, 149 insertions(+), 62 deletions(-) create mode 100644 NT_X64_STATIC_THREADS_MAKEFILE diff --git a/NT_STATIC_THREADS_MAKEFILE b/NT_STATIC_THREADS_MAKEFILE index b52ed67..d0f9127 100644 --- a/NT_STATIC_THREADS_MAKEFILE +++ b/NT_STATIC_THREADS_MAKEFILE @@ -6,6 +6,11 @@ MY_CPU=X86 CPU=$(MY_CPU) !include +# 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 index 0000000..31ca3db --- /dev/null +++ b/NT_X64_STATIC_THREADS_MAKEFILE @@ -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 + +# 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; + diff --git a/include/gc.h b/include/gc.h index f3c7725..ea11fff 100644 --- a/include/gc.h +++ b/include/gc.h @@ -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 +#ifdef __cplusplus + extern "C" { +#endif /* * All threads must be created using GC_CreateThread or GC_beginthreadex, * or must explicitly call GC_register_my_thread, diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 615dd7a..20f35bc 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -374,8 +374,12 @@ # 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) @@ -988,8 +992,7 @@ # 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 @@ -1958,6 +1961,20 @@ # 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) diff --git a/tests/test.c b/tests/test.c index 70bd7c5..6c7a6ce 100644 --- a/tests/test.c +++ b/tests/test.c @@ -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 diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc index 9a7af1c..695f951 100644 --- a/tests/test_cpp.cc +++ b/tests/test_cpp.cc @@ -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 -- 2.7.4