From: hboehm Date: Mon, 23 Jul 2007 21:01:46 +0000 (+0000) Subject: 2007-07-23 Hans Boehm X-Git-Tag: gc7_1alpha2~28 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=03fd483a45856f6a1ea12544b19c51fa9a57a6d5;p=gc 2007-07-23 Hans Boehm * alloc.c (GC_stopped_mark): Call GC_add_current_malloc_heap() while world is still running. * os_dep.c (GC_is_heap_base): Don't call GC_add_current_malloc_heap() with world stopped. * include/gc.h (GC_INIT for cygwin): Always call GC_add_roots. * misc.c (GC_init/GC_init_inner): Perform all work in GC_init_inner. * Makefile.direct: Expand -DUSE_MUNMAP comment. 2007-07-23 Hans Boehm (really Jim Marshall) * include/gc.h: Define uintptr_t explicitly for VC++6. * msvc_dbg.c (GetModuleBase): Revert to strcat if strcat_s doesn't exist. --- diff --git a/ChangeLog b/ChangeLog index 8982eedf..e36da7a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2007-07-23 Hans Boehm + + * alloc.c (GC_stopped_mark): Call GC_add_current_malloc_heap() + while world is still running. + * os_dep.c (GC_is_heap_base): Don't call GC_add_current_malloc_heap() + with world stopped. + * include/gc.h (GC_INIT for cygwin): Always call GC_add_roots. + * misc.c (GC_init/GC_init_inner): Perform all work in + GC_init_inner. + * Makefile.direct: Expand -DUSE_MUNMAP comment. + +2007-07-23 Hans Boehm (really Jim Marshall) + + * include/gc.h: Define uintptr_t explicitly for VC++6. + * msvc_dbg.c (GetModuleBase): Revert to strcat if strcat_s doesn't + exist. + 2007-07-02 Hans Boehm * version.h, configure.ac, doc/README: Change to version 7.1alpha1. diff --git a/Makefile.direct b/Makefile.direct index 40195a56..3d611aa7 100644 --- a/Makefile.direct +++ b/Makefile.direct @@ -183,7 +183,8 @@ HOSTCFLAGS=$(CFLAGS) # -DUSE_MUNMAP causes memory to be returned to the OS under the right # circumstances. This currently disables VM-based incremental collection. # This is currently experimental, and works only under some Unix, -# Linux and Windows versions. +# Linux and Windows versions. Requires -DUSE_MMAP, even under Windows, +# where USE_MMAP doesn't do anything. # -DMMAP_STACKS (for Solaris threads) Use mmap from /dev/zero rather than # GC_scratch_alloc() to get stack memory. # -DPRINT_BLACK_LIST Whenever a black list entry is added, i.e. whenever diff --git a/alloc.c b/alloc.c index 94a968e0..ac5fa16d 100644 --- a/alloc.c +++ b/alloc.c @@ -448,6 +448,9 @@ GC_bool GC_stopped_mark(GC_stop_func stop_func) if (GC_print_stats) GET_TIME(start_time); +# if !defined(REDIRECT_MALLOC) && (defined(MSWIN32) || defined(MSWINCE)) + GC_add_current_malloc_heap(); +# endif # if defined(REGISTER_LIBRARIES_EARLY) GC_cond_register_dynamic_libraries(); # endif diff --git a/include/gc.h b/include/gc.h index cc950888..ec15bbd2 100644 --- a/include/gc.h +++ b/include/gc.h @@ -1037,6 +1037,9 @@ GC_register_has_static_roots_callback DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); +# if defined(_MSC_VER) && _MSC_VER >= 1200 && !defined(_UINTPTR_T_DEFINED) + typedef unsigned long uintptr_t; +# endif GC_API uintptr_t GC_beginthreadex( void *security, unsigned stack_size, @@ -1097,13 +1100,9 @@ GC_API void GC_use_DllMain(void); # define GC_MIN(x,y) ((x) < (y) ? (x) : (y)) # define GC_DATASTART ((void *) GC_MIN(_data_start__, _bss_start__)) # define GC_DATAEND ((void *) GC_MAX(_data_end__, _bss_end__)) -# if defined(GC_DLL) -# define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); \ +# define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); \ GC_gcollect(); /* For blacklisting. */} -# else - /* Main program init not required */ -# define GC_INIT() { GC_init(); } -# endif + /* Required at least if GC is in dll. And doesn't hurt. */ # endif # if defined(_AIX) extern int _data[], _end[]; diff --git a/misc.c b/misc.c index 37e50933..d846e9d5 100644 --- a/misc.c +++ b/misc.c @@ -405,46 +405,12 @@ GC_bool GC_is_initialized = FALSE; extern void GC_init_parallel(void); # endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */ +/* FIXME: The GC_init/GC_init_inner distinction should go away. */ void GC_init(void) { - DCL_LOCK_STATE; - -#if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) - if (!GC_is_initialized) { - BOOL (WINAPI *pfn) (LPCRITICAL_SECTION, DWORD) = NULL; - HMODULE hK32 = GetModuleHandleA("kernel32.dll"); - if (hK32) - pfn = (BOOL (WINAPI *) (LPCRITICAL_SECTION, DWORD)) - GetProcAddress (hK32, - "InitializeCriticalSectionAndSpinCount"); - if (pfn) - pfn(&GC_allocate_ml, 4000); - else - InitializeCriticalSection (&GC_allocate_ml); - } -#endif /* MSWIN32 */ - - LOCK(); + /* LOCK(); -- no longer does anything this early. */ GC_init_inner(); - UNLOCK(); - -# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC) - /* Make sure marker threads and started and thread local */ - /* allocation is initialized, in case we didn't get */ - /* called from GC_init_parallel(); */ - { - GC_init_parallel(); - } -# endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */ - -# if defined(DYNAMIC_LOADING) && defined(DARWIN) - { - /* This must be called WITHOUT the allocation lock held - and before any threads are created */ - extern void GC_init_dyld(); - GC_init_dyld(); - } -# endif + /* UNLOCK(); */ } #if defined(MSWIN32) || defined(MSWINCE) @@ -510,6 +476,28 @@ void GC_init_inner() word initial_heap_sz = (word)MINHINCR; if (GC_is_initialized) return; + + /* Note that although we are nominally called with the */ + /* allocation lock held, the allocation lock is now */ + /* only really acquired once a second thread is forked.*/ + /* And the initialization code needs to run before */ + /* then. Thus we really don't hold any locks, and can */ + /* in fact safely initialize them here. */ + GC_ASSERT(!GC_need_to_lock); +# if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) + if (!GC_is_initialized) { + BOOL (WINAPI *pfn) (LPCRITICAL_SECTION, DWORD) = NULL; + HMODULE hK32 = GetModuleHandleA("kernel32.dll"); + if (hK32) + pfn = (BOOL (WINAPI *) (LPCRITICAL_SECTION, DWORD)) + GetProcAddress (hK32, + "InitializeCriticalSectionAndSpinCount"); + if (pfn) + pfn(&GC_allocate_ml, 4000); + else + InitializeCriticalSection (&GC_allocate_ml); + } +#endif /* MSWIN32 */ # if defined(MSWIN32) || defined(MSWINCE) InitializeCriticalSection(&GC_write_cs); # endif @@ -765,6 +753,26 @@ void GC_init_inner() GC_register_finalizer_no_order); } # endif + + /* The rest of this again assumes we don't really hold */ + /* the allocation lock. */ +# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC) + /* Make sure marker threads and started and thread local */ + /* allocation is initialized, in case we didn't get */ + /* called from GC_init_parallel(); */ + { + GC_init_parallel(); + } +# endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */ + +# if defined(DYNAMIC_LOADING) && defined(DARWIN) + { + /* This must be called WITHOUT the allocation lock held + and before any threads are created */ + extern void GC_init_dyld(); + GC_init_dyld(); + } +# endif } void GC_enable_incremental(void) diff --git a/msvc_dbg.c b/msvc_dbg.c index b172025b..2420a44b 100644 --- a/msvc_dbg.c +++ b/msvc_dbg.c @@ -77,7 +77,12 @@ static ULONG_ADDR CALLBACK GetModuleBase(HANDLE hProcess, ULONG_ADDR dwAddress) // Save and restore current directory around SymLoadModule, see KB article Q189780 GetCurrentDirectoryA(sizeof(curDir), curDir); GetModuleFileNameA(NULL, exePath, sizeof(exePath)); +#if defined(_MSC_VER) && _MSC_VER == 1200 + /* use strcat for VC6 */ + strcat(exePath, "\\.."); +#else strcat_s(exePath, sizeof(exePath), "\\.."); +#endif /* _MSC_VER >= 1200 */ SetCurrentDirectoryA(exePath); #ifdef _DEBUG GetCurrentDirectoryA(sizeof(exePath), exePath); diff --git a/os_dep.c b/os_dep.c index bb8fa08f..8f838254 100644 --- a/os_dep.c +++ b/os_dep.c @@ -1528,12 +1528,6 @@ void GC_register_data_segments(void) unsigned i; # ifndef REDIRECT_MALLOC - static word last_gc_no = (word)(-1); - - if (last_gc_no != GC_gc_no) { - GC_add_current_malloc_heap(); - last_gc_no = GC_gc_no; - } if (GC_root_size > GC_max_root_size) GC_max_root_size = GC_root_size; if (GC_is_malloc_heap_base(p)) return TRUE; # endif