From: ivmai Date: Sat, 26 Sep 2009 21:10:54 +0000 (+0000) Subject: 2009-09-26 Ivan Maidanski X-Git-Tag: gc7_2alpha4~85 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7225f60941c19b023a87b44e950463555de55ef1;p=gc 2009-09-26 Ivan Maidanski * Makefile.direct: Document EMPTY_GETENV_RESULTS. * gcj_mlc.c (GC_clear_stack): Remove declaration. * malloc.c (GC_clear_stack): Ditto. * mallocx.c (GC_clear_stack): Ditto. * typd_mlc.c (GC_clear_stack): Ditto. * gcj_mlc.c (GENERAL_MALLOC, GENERAL_MALLOC_IOP): Rename to GENERAL_MALLOC_INNER and GENERAL_MALLOC_INNER_IOP, respectively; remove "lb" unnecessary cast to word. * include/private/gc_priv.h (GC_clear_stack): Add declaration. * include/private/gc_priv.h (GENERAL_MALLOC, GENERAL_MALLOC_IOP): Move common declaration from typd_mlc.c and malloc.c; remove unnecessary result and "lb" parameter casts. * include/private/thread_local_alloc.h: Guard against duplicate header file inclusion. * os_dep.c (USE_MUNMAP): Replace "-->" with an error directive for the case when USE_MMAP is not defined. * pthread_support.c (GC_is_thread_tsd_valid): New internal function (only if GC_ASSERTIONS and THREAD_LOCAL_ALLOC); move the code from thread-local GC_malloc(); add FIXME for the condition. * win32_threads.c (GC_is_thread_tsd_valid): Ditto. * thread_local_alloc.c (GC_gcjobjfreelist): Change the type (to match that of its definition). * thread_local_alloc.c (GC_destroy_thread_local): Add a cast for GC_gcjobjfreelist. * thread_local_alloc.c (GC_lookup_thread, GC_lookup_thread_inner): Remove unused declaration; don't include pthread.h. * thread_local_alloc.c (GC_is_thread_tsd_valid): New declaration (only if GC_ASSERTIONS). * thread_local_alloc.c (GC_malloc): Use GC_is_thread_tsd_valid() instead of GC_lookup_thread(). * win32_threads.c (GC_lookup_thread_inner): Define as STATIC. * win32_threads.c (UNPROTECT): Rename to UNPROTECT_THREAD (to have id different from that in os_dep.c). --- diff --git a/ChangeLog b/ChangeLog index 655e8333..b7032379 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,39 @@ +2009-09-26 Ivan Maidanski + + * Makefile.direct: Document EMPTY_GETENV_RESULTS. + * gcj_mlc.c (GC_clear_stack): Remove declaration. + * malloc.c (GC_clear_stack): Ditto. + * mallocx.c (GC_clear_stack): Ditto. + * typd_mlc.c (GC_clear_stack): Ditto. + * gcj_mlc.c (GENERAL_MALLOC, GENERAL_MALLOC_IOP): Rename to + GENERAL_MALLOC_INNER and GENERAL_MALLOC_INNER_IOP, respectively; + remove "lb" unnecessary cast to word. + * include/private/gc_priv.h (GC_clear_stack): Add declaration. + * include/private/gc_priv.h (GENERAL_MALLOC, GENERAL_MALLOC_IOP): + Move common declaration from typd_mlc.c and malloc.c; remove + unnecessary result and "lb" parameter casts. + * include/private/thread_local_alloc.h: Guard against duplicate + header file inclusion. + * os_dep.c (USE_MUNMAP): Replace "-->" with an error directive for + the case when USE_MMAP is not defined. + * pthread_support.c (GC_is_thread_tsd_valid): New internal + function (only if GC_ASSERTIONS and THREAD_LOCAL_ALLOC); move the + code from thread-local GC_malloc(); add FIXME for the condition. + * win32_threads.c (GC_is_thread_tsd_valid): Ditto. + * thread_local_alloc.c (GC_gcjobjfreelist): Change the type (to + match that of its definition). + * thread_local_alloc.c (GC_destroy_thread_local): Add a cast for + GC_gcjobjfreelist. + * thread_local_alloc.c (GC_lookup_thread, GC_lookup_thread_inner): + Remove unused declaration; don't include pthread.h. + * thread_local_alloc.c (GC_is_thread_tsd_valid): New declaration + (only if GC_ASSERTIONS). + * thread_local_alloc.c (GC_malloc): Use GC_is_thread_tsd_valid() + instead of GC_lookup_thread(). + * win32_threads.c (GC_lookup_thread_inner): Define as STATIC. + * win32_threads.c (UNPROTECT): Rename to UNPROTECT_THREAD (to have + id different from that in os_dep.c). + 2009-09-26 Ivan Maidanski * allchblk.c (GC_enough_large_bytes_left): Replace "inline static" diff --git a/Makefile.direct b/Makefile.direct index 5fa2cddf..35930918 100644 --- a/Makefile.direct +++ b/Makefile.direct @@ -290,6 +290,8 @@ HOSTCFLAGS=$(CFLAGS) # I don't know of a reason to disable this, except possibly if the # resulting process runs as a privileged user. (This is on by default for # WinCE.) +# -DEMPTY_GETENV_RESULTS Define to workaround a reputed Wine bug in getenv +# (getenv() may return an empty string instead of NULL for a missing entry). # -DUSE_GLOBAL_ALLOC. Win32 only. Use GlobalAlloc instead of # VirtualAlloc to allocate the heap. May be needed to work around # a Windows NT/2000 issue. Incompatible with USE_MUNMAP. diff --git a/gcj_mlc.c b/gcj_mlc.c index 4eedfe24..189c25aa 100644 --- a/gcj_mlc.c +++ b/gcj_mlc.c @@ -121,12 +121,10 @@ GC_API void GC_CALL GC_init_gcj_malloc(int mp_index, UNLOCK(); } -void * GC_clear_stack(void *); +#define GENERAL_MALLOC_INNER(lb,k) \ + GC_clear_stack(GC_generic_malloc_inner(lb, k)) -#define GENERAL_MALLOC(lb,k) \ - GC_clear_stack(GC_generic_malloc_inner((word)lb, k)) - -#define GENERAL_MALLOC_IOP(lb,k) \ +#define GENERAL_MALLOC_INNER_IOP(lb,k) \ GC_clear_stack(GC_generic_malloc_inner_ignore_off_page(lb, k)) /* We need a mechanism to release the lock and invoke finalizers. */ @@ -170,7 +168,7 @@ static void maybe_finalize(void) op = *opp; if(EXPECT(op == 0, 0)) { maybe_finalize(); - op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind); + op = (ptr_t)GENERAL_MALLOC_INNER((word)lb, GC_gcj_kind); if (0 == op) { GC_oom_func oom_fn = GC_oom_fn; UNLOCK(); @@ -186,7 +184,7 @@ static void maybe_finalize(void) } else { LOCK(); maybe_finalize(); - op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind); + op = (ptr_t)GENERAL_MALLOC_INNER((word)lb, GC_gcj_kind); if (0 == op) { GC_oom_func oom_fn = GC_oom_fn; UNLOCK(); @@ -245,7 +243,7 @@ GC_API void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t lb, LOCK(); if( (op = *opp) == 0 ) { maybe_finalize(); - op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind); + op = (ptr_t)GENERAL_MALLOC_INNER_IOP(lb, GC_gcj_kind); if (0 == op) { GC_oom_func oom_fn = GC_oom_fn; UNLOCK(); @@ -258,7 +256,7 @@ GC_API void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t lb, } else { LOCK(); maybe_finalize(); - op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind); + op = (ptr_t)GENERAL_MALLOC_INNER_IOP(lb, GC_gcj_kind); if (0 == op) { GC_oom_func oom_fn = GC_oom_fn; UNLOCK(); diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 7dde6503..cda6fe8c 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1755,6 +1755,15 @@ ptr_t GC_allocobj(size_t sz, int kind); /* free list nonempty, and return its */ /* head. Sz is in granules. */ +void * GC_clear_stack(void *); /* in misc.c, behaves like identity. */ + +/* We make the GC_clear_stack() call a tail one, hoping to get more of */ +/* the stack. */ +#define GENERAL_MALLOC(lb,k) \ + GC_clear_stack(GC_generic_malloc(lb, k)) +#define GENERAL_MALLOC_IOP(lb,k) \ + GC_clear_stack(GC_generic_malloc_ignore_off_page(lb, k)) + /* Allocation routines that bypass the thread local cache. */ /* Used internally. */ #ifdef THREAD_LOCAL_ALLOC diff --git a/include/private/thread_local_alloc.h b/include/private/thread_local_alloc.h index 15cf37e5..e07880f4 100644 --- a/include/private/thread_local_alloc.h +++ b/include/private/thread_local_alloc.h @@ -19,6 +19,9 @@ /* implementation also exports GC_malloc and friends, which */ /* are declared in gc.h. */ +#ifndef GC_THREAD_LOCAL_ALLOC_H +#define GC_THREAD_LOCAL_ALLOC_H + #include "private/gc_priv.h" #if defined(THREAD_LOCAL_ALLOC) @@ -154,3 +157,5 @@ GC_key_t GC_thread_key; /* if necessary. */ #endif /* THREAD_LOCAL_ALLOC */ + +#endif /* GC_THREAD_LOCAL_ALLOC_H */ diff --git a/malloc.c b/malloc.c index e41802e8..5d147d0d 100644 --- a/malloc.c +++ b/malloc.c @@ -21,7 +21,6 @@ # include #endif -extern void * GC_clear_stack(void *); /* in misc.c, behaves like identity */ void GC_extend_size_map(size_t); /* in misc.c. */ /* Allocate reclaim list for kind: */ @@ -199,12 +198,6 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k) } } - -#define GENERAL_MALLOC(lb,k) \ - GC_clear_stack(GC_generic_malloc(lb, k)) -/* We make the GC_clear_stack_call a tail call, hoping to get more of */ -/* the stack. */ - /* Allocate lb bytes of atomic (pointerfree) data */ #ifdef THREAD_LOCAL_ALLOC void * GC_core_malloc_atomic(size_t lb) diff --git a/mallocx.c b/mallocx.c index b5481763..a3336923 100644 --- a/mallocx.c +++ b/mallocx.c @@ -24,8 +24,6 @@ #include #include "private/gc_priv.h" -void * GC_clear_stack(void *); /* in misc.c, behaves like identity */ - /* Some externally visible but unadvertised variables to allow access to */ /* free lists from inlined allocators without including gc_priv.h */ /* or introducing dependencies on internal data structure layouts. */ diff --git a/os_dep.c b/os_dep.c index 2b61f69f..93e452ac 100644 --- a/os_dep.c +++ b/os_dep.c @@ -106,7 +106,7 @@ #if defined(MMAP_SUPPORTED) || defined(ADD_HEAP_GUARD_PAGES) # if defined(USE_MUNMAP) && !defined(USE_MMAP) - --> USE_MUNMAP requires USE_MMAP +# error "invalid config - USE_MUNMAP requires USE_MMAP" # endif # include # include diff --git a/pthread_support.c b/pthread_support.c index 54439926..b2d9518a 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -497,6 +497,21 @@ unsigned *GC_check_finalizer_nested(void) return &me->finalizer_nested; } +#if defined(GC_ASSERTIONS) && defined(THREAD_LOCAL_ALLOC) + /* This is called from thread-local GC_malloc(). */ + GC_bool GC_is_thread_tsd_valid(void *tsd) + { + char *me; + LOCK(); + me = (char *)GC_lookup_thread(pthread_self()); + UNLOCK(); + /* FIXME: We can check tsd more correctly (since now we have access */ + /* to the right declarations). This old algorithm (moved from */ + /* thread_local_alloc.c) checks only that it's close. */ + return((char *)tsd > me && (char *)tsd < me + 1000); + } +#endif + #ifdef HANDLE_FORK /* Remove all entries from the GC_threads table, except the */ /* one for the current thread. We need to do this in the child */ diff --git a/thread_local_alloc.c b/thread_local_alloc.c index f45b08da..0045e1ed 100644 --- a/thread_local_alloc.c +++ b/thread_local_alloc.c @@ -111,7 +111,7 @@ void GC_init_thread_local(GC_tlfs p) } #ifdef GC_GCJ_SUPPORT - extern void ** GC_gcjobjfreelist; + extern ptr_t * GC_gcjobjfreelist; #endif /* We hold the allocator lock. */ @@ -125,18 +125,13 @@ void GC_destroy_thread_local(GC_tlfs p) return_freelists(p -> ptrfree_freelists, GC_aobjfreelist); return_freelists(p -> normal_freelists, GC_objfreelist); # ifdef GC_GCJ_SUPPORT - return_freelists(p -> gcj_freelists, GC_gcjobjfreelist); + return_freelists(p -> gcj_freelists, (void **)GC_gcjobjfreelist); # endif } -#if defined(GC_ASSERTIONS) && defined(GC_PTHREADS) && !defined(CYGWIN32) \ - && !defined(GC_WIN32_PTHREADS) -# include - extern char * GC_lookup_thread(pthread_t id); -#endif - -#if defined(GC_ASSERTIONS) && defined(GC_WIN32_THREADS) - void * /*GC_thread*/ GC_lookup_thread_inner(unsigned /*DWORD*/ thread_id); +#ifdef GC_ASSERTIONS + /* Defined in pthread_support.c or win32_threads.c. */ + GC_bool GC_is_thread_tsd_valid(void *tsd); #endif GC_API void * GC_CALL GC_malloc(size_t bytes) @@ -163,20 +158,9 @@ GC_API void * GC_CALL GC_malloc(size_t bytes) } # endif GC_ASSERT(GC_is_initialized); -# ifdef GC_ASSERTIONS - /* We can't check tsd correctly, since we don't have access to */ - /* the right declarations. But we can check that it's close. */ - LOCK(); - { -# if defined(GC_WIN32_THREADS) - char * me = (char *)GC_lookup_thread_inner(GetCurrentThreadId()); -# else - char * me = GC_lookup_thread(pthread_self()); -# endif - GC_ASSERT((char *)tsd > me && (char *)tsd < me + 1000); - } - UNLOCK(); -# endif + + GC_ASSERT(GC_is_thread_tsd_valid(tsd)); + tiny_fl = ((GC_tlfs)tsd) -> normal_freelists; GC_FAST_MALLOC_GRANS(result, granules, tiny_fl, DIRECT_GRANULES, NORMAL, GC_core_malloc(bytes), obj_link(result)=0); diff --git a/typd_mlc.c b/typd_mlc.c index 9530aafe..82bd92dc 100644 --- a/typd_mlc.c +++ b/typd_mlc.c @@ -577,14 +577,6 @@ GC_API GC_descr GC_CALL GC_make_descriptor(GC_bitmap bm, size_t len) } } -void * GC_clear_stack(void *); - -#define GENERAL_MALLOC(lb,k) \ - (void *)GC_clear_stack(GC_generic_malloc((word)lb, k)) - -#define GENERAL_MALLOC_IOP(lb,k) \ - (void *)GC_clear_stack(GC_generic_malloc_ignore_off_page(lb, k)) - GC_API void * GC_CALL GC_malloc_explicitly_typed(size_t lb, GC_descr d) { ptr_t op; diff --git a/win32_threads.c b/win32_threads.c index 939b846a..cb4805d8 100644 --- a/win32_threads.c +++ b/win32_threads.c @@ -509,7 +509,7 @@ GC_INLINE LONG GC_get_max_thread_index(void) /* This version assumes that either GC_win32_dll_threads is set, or */ /* we hold the allocator lock. */ /* Also used (for assertion checking only) from thread_local_alloc.c. */ -GC_thread GC_lookup_thread_inner(DWORD thread_id) +STATIC GC_thread GC_lookup_thread_inner(DWORD thread_id) { # ifndef GC_NO_DLLMAIN if (GC_win32_dll_threads) { @@ -569,20 +569,35 @@ unsigned *GC_check_finalizer_nested(void) return &me->finalizer_nested; } +#if defined(GC_ASSERTIONS) && defined(THREAD_LOCAL_ALLOC) + /* This is called from thread-local GC_malloc(). */ + GC_bool GC_is_thread_tsd_valid(void *tsd) + { + char *me; + LOCK(); + me = (char *)GC_lookup_thread_inner(GetCurrentThreadId()); + UNLOCK(); + /* FIXME: We can check tsd more correctly (since now we have access */ + /* to the right declarations). This old algorithm (moved from */ + /* thread_local_alloc.c) checks only that it's close. */ + return((char *)tsd > me && (char *)tsd < me + 1000); + } +#endif + /* Make sure thread descriptor t is not protected by the VDB */ /* implementation. */ /* Used to prevent write faults when the world is (partially) stopped, */ /* since it may have been stopped with a system lock held, and that */ /* lock may be required for fault handling. */ #if defined(MPROTECT_VDB) -# define UNPROTECT(t) \ +# define UNPROTECT_THREAD(t) \ if (GC_dirty_maintained && !GC_win32_dll_threads && \ t != &first_thread) { \ GC_ASSERT(SMALL_OBJ(GC_size(t))); \ GC_remove_protection(HBLKPTR(t), 1, FALSE); \ } #else -# define UNPROTECT(t) +# define UNPROTECT_THREAD(t) #endif /* If a thread has been joined, but we have not yet */ @@ -923,7 +938,7 @@ STATIC void GC_suspend(GC_thread t) /* appears there's a race here. */ DWORD exitCode; # endif - UNPROTECT(t); + UNPROTECT_THREAD(t); # ifndef MSWINCE if (GetExitCodeThread(t -> handle, &exitCode) && exitCode != STILL_ACTIVE) { @@ -941,7 +956,7 @@ STATIC void GC_suspend(GC_thread t) # if defined(MPROTECT_VDB) /* Acquire the spin lock we use to update dirty bits. */ /* Threads shouldn't get stopped holding it. But we may */ - /* acquire and release it in the UNPROTECT call. */ + /* acquire and release it in the UNPROTECT_THREAD call. */ while (AO_test_and_set_acquire(&GC_fault_handler_lock) == AO_TS_SET) { /* empty */ } @@ -1054,7 +1069,7 @@ void GC_start_world(void) && t -> id != thread_id) { if (ResumeThread(THREAD_HANDLE(t)) == (DWORD)-1) ABORT("ResumeThread failed"); - UNPROTECT(t); + UNPROTECT_THREAD(t); t -> suspended = FALSE; } } @@ -1183,14 +1198,14 @@ STATIC void GC_push_stack_for(GC_thread thread) if (thread -> last_stack_min == ADDR_LIMIT) { stack_min = GC_get_stack_min(activation_frame != NULL ? (ptr_t)activation_frame : thread -> stack_base); - UNPROTECT(thread); + UNPROTECT_THREAD(thread); thread -> last_stack_min = stack_min; } else { /* First, adjust the latest known minimum stack address if we */ /* are inside GC_call_with_gc_active(). */ if (activation_frame != NULL && thread -> last_stack_min > (ptr_t)activation_frame) { - UNPROTECT(thread); + UNPROTECT_THREAD(thread); thread -> last_stack_min = (ptr_t)activation_frame; } @@ -1214,7 +1229,7 @@ STATIC void GC_push_stack_for(GC_thread thread) stack_min = GC_get_stack_min(thread -> stack_base); } # endif - UNPROTECT(thread); + UNPROTECT_THREAD(thread); thread -> last_stack_min = stack_min; } } @@ -1414,7 +1429,7 @@ void GC_get_next_stack(char *start, char *limit, /* Remember current stack_min value. */ if (thread != NULL) { - UNPROTECT(thread); + UNPROTECT_THREAD(thread); } *plast_stack_min = *lo; }