From: Ivan Maidanski Date: Wed, 1 Aug 2012 05:42:36 +0000 (+0400) Subject: Fix all address-of-dummy operations by adding volatile X-Git-Tag: gc7_4_0~240 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d6acbda;p=gc Fix all address-of-dummy operations by adding volatile * alloc.c (min_bytes_allocd, GC_stopped_mark): Use volatile for 'dummy' local variable (used to get 'sp' value) to prevent any harmful optimizations (e.g., some Mac OS X clang releases might turn a conditional expression that uses 'dummy' address into a constant). * dyn_load.c (GC_cond_add_roots): Likewise. * mach_dep.c (GC_with_callee_saves_pushed): Likewise. * misc.c (GC_clear_stack_inner, GC_init, GC_call_with_stack_base): Likewise. * os_dep.c (GC_get_stack_base, GC_get_main_stack_base, async_set_pht_entry_from_index): Likewise. * pthread_stop_world.c (nacl_pre_syscall_hook, __nacl_suspend_thread_if_needed): Likewise. * pthread_support.c (GC_thr_init): Likewise. * ptr_chck.c (GC_on_stack): Likewise. * tools/setjmp_t.c (main): Likewise. * win32_threads.c (GC_push_stack_for): Likewise. * dyn_load.c (dummy): Change variable type from char to int. * include/private/gcconfig.h: Update comment about GC_stackbottom initialization. * os_dep.c (GC_get_stack_base): Remove 'sp' local variable. * os_dep.c (GC_get_main_stack_base): Define and use volatile 'dummy' variable (instead of 'result') to get 'sp' value (revert part of commit bddc75f). * os_dep.c (GC_get_stack_base): Add missing cast of 'dummy' address (only if NEED_FIND_LIMIT). * pthread_stop_world.c (GC_suspend_handler_inner): Define and use volatile 'dummy' variable (instead of 'me') to get 'sp' value (revert part of commit 31fc0f6). * pthread_stop_world.c (nacl_pre_syscall_hook, __nacl_suspend_thread_if_needed): Rename 'local_dummy' to 'dummy' local variable. --- diff --git a/alloc.c b/alloc.c index 3cfcd831..e0fbe0b3 100644 --- a/alloc.c +++ b/alloc.c @@ -200,7 +200,8 @@ GC_API GC_stop_func GC_CALL GC_get_stop_func(void) /* collections to amortize the collection cost. */ static word min_bytes_allocd(void) { - int dummy; /* GC_stackbottom is used only for a single-threaded case. */ + volatile int dummy; + /* GC_stackbottom is used only for a single-threaded case. */ # ifdef STACK_GROWS_UP word stack_size = (ptr_t)(&dummy) - GC_stackbottom; # else @@ -591,7 +592,7 @@ GC_API int GC_CALL GC_collect_a_little(void) STATIC GC_bool GC_stopped_mark(GC_stop_func stop_func) { unsigned i; - int dummy; + volatile int dummy; # ifndef SMALL_CONFIG CLOCK_TYPE start_time = 0; /* initialized to prevent warning. */ CLOCK_TYPE current_time; diff --git a/dyn_load.c b/dyn_load.c index bab89709..2f9fec2d 100644 --- a/dyn_load.c +++ b/dyn_load.c @@ -863,9 +863,10 @@ GC_INNER void GC_register_dynamic_libraries(void) if ((word)curr_base < (word)limit) GC_add_roots_inner(curr_base, limit, TRUE); # else - char dummy; + volatile int dummy; char * stack_top = (char *) ((word)(&dummy) & ~(GC_sysinfo.dwAllocationGranularity-1)); + if (base == limit) return; if ((word)limit > (word)stack_top && (word)base < (word)GC_stackbottom) { diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 5a1453c5..98c2df08 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -664,7 +664,7 @@ * int argc; * char **argv, **envp; * { - * int dummy; + * volatile int dummy; * * GC_stackbottom = (ptr_t)(&dummy); * return(real_main(argc, argv, envp)); diff --git a/mach_dep.c b/mach_dep.c index fc7dd8cf..0760d362 100644 --- a/mach_dep.c +++ b/mach_dep.c @@ -219,7 +219,7 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *), ptr_t arg) { - word dummy; + volatile int dummy; void * context = 0; # if defined(HAVE_PUSH_REGS) diff --git a/misc.c b/misc.c index c4237796..b98e4196 100644 --- a/misc.c +++ b/misc.c @@ -301,9 +301,11 @@ GC_INNER void GC_extend_size_map(size_t i) /* file, so this error would be caught by the linker. */ void * GC_clear_stack_inner(void *arg, ptr_t limit) { - word dummy[CLEAR_SIZE]; + volatile word dummy[CLEAR_SIZE]; + /* volatile prevents the following condition to */ + /* be 'optimized' to TRUE constant. */ - BZERO(dummy, CLEAR_SIZE*sizeof(word)); + BZERO((/* no volatile */ void *)dummy, sizeof(dummy)); if ((word)(&dummy[0]) COOLER_THAN (word)limit) { (void) GC_clear_stack_inner(arg, limit); } @@ -720,7 +722,7 @@ GC_API void GC_CALL GC_init(void) { /* LOCK(); -- no longer does anything this early. */ # if !defined(THREADS) && defined(GC_ASSERTIONS) - word dummy; + volatile int dummy; # endif word initial_heap_sz; IF_CANCEL(int cancel_state;) @@ -1636,7 +1638,7 @@ GC_API void * GC_CALL GC_call_with_alloc_lock(GC_fn_type fn, void *client_data) GC_API void * GC_CALL GC_call_with_stack_base(GC_stack_base_func fn, void *arg) { - int dummy; + volatile int dummy; struct GC_stack_base base; base.mem_base = (void *)&dummy; diff --git a/os_dep.c b/os_dep.c index b9343053..1311c8a7 100644 --- a/os_dep.c +++ b/os_dep.c @@ -768,9 +768,8 @@ GC_INNER word GC_page_size = 0; GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *sb) { - int dummy; - ptr_t sp = (ptr_t)(&dummy); - ptr_t trunc_sp = (ptr_t)((word)sp & ~(GC_page_size - 1)); + volatile int dummy; + ptr_t trunc_sp = (ptr_t)((word)(&dummy) & ~(GC_page_size - 1)); /* FIXME: This won't work if called from a deeply recursive */ /* client code (and the committed stack space has grown). */ word size = GC_get_writable_length(trunc_sp, 0); @@ -1172,13 +1171,19 @@ GC_INNER word GC_page_size = 0; ptr_t GC_get_main_stack_base(void) { - ptr_t result; /* also used as "dummy" to get the approx. sp value */ +# if defined(GC_ASSERTIONS) \ + || (!defined(STACKBOTTOM) \ + && (defined(HEURISTIC1) || defined(HEURISTIC2))) + volatile int dummy; +# endif + ptr_t result; # if defined(LINUX) && !defined(NACL) \ && (defined(USE_GET_STACKBASE_FOR_MAIN) \ || (defined(THREADS) && !defined(REDIRECT_MALLOC))) pthread_attr_t attr; void *stackaddr; size_t size; + if (pthread_getattr_np(pthread_self(), &attr) == 0) { if (pthread_attr_getstack(&attr, &stackaddr, &size) == 0 && stackaddr != NULL) { @@ -1199,10 +1204,10 @@ GC_INNER word GC_page_size = 0; # define STACKBOTTOM_ALIGNMENT_M1 ((word)STACK_GRAN - 1) # ifdef HEURISTIC1 # ifdef STACK_GROWS_DOWN - result = (ptr_t)((((word)(&result)) + STACKBOTTOM_ALIGNMENT_M1) + result = (ptr_t)((((word)(&dummy)) + STACKBOTTOM_ALIGNMENT_M1) & ~STACKBOTTOM_ALIGNMENT_M1); # else - result = (ptr_t)(((word)(&result)) & ~STACKBOTTOM_ALIGNMENT_M1); + result = (ptr_t)(((word)(&dummy)) & ~STACKBOTTOM_ALIGNMENT_M1); # endif # endif /* HEURISTIC1 */ # ifdef LINUX_STACKBOTTOM @@ -1213,18 +1218,18 @@ GC_INNER word GC_page_size = 0; # endif # ifdef HEURISTIC2 # ifdef STACK_GROWS_DOWN - result = GC_find_limit((ptr_t)(&result), TRUE); + result = GC_find_limit((ptr_t)(&dummy), TRUE); # ifdef HEURISTIC2_LIMIT if ((word)result > (word)HEURISTIC2_LIMIT - && (word)(&result) < (word)HEURISTIC2_LIMIT) { + && (word)(&dummy) < (word)HEURISTIC2_LIMIT) { result = HEURISTIC2_LIMIT; } # endif # else - result = GC_find_limit((ptr_t)(&result), FALSE); + result = GC_find_limit((ptr_t)(&dummy), FALSE); # ifdef HEURISTIC2_LIMIT if ((word)result < (word)HEURISTIC2_LIMIT - && (word)(&result) > (word)HEURISTIC2_LIMIT) { + && (word)(&dummy) > (word)HEURISTIC2_LIMIT) { result = HEURISTIC2_LIMIT; } # endif @@ -1235,7 +1240,7 @@ GC_INNER word GC_page_size = 0; result = (ptr_t)(signed_word)(-sizeof(ptr_t)); # endif # endif - GC_ASSERT((word)(&result) HOTTER_THAN (word)result); + GC_ASSERT((word)(&dummy) HOTTER_THAN (word)result); return(result); } # define GET_MAIN_STACKBASE_SPECIAL @@ -1301,7 +1306,7 @@ GC_INNER word GC_page_size = 0; GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *b) { # ifdef GC_ASSERTIONS - int dummy; + volatile int dummy; # endif /* pthread_get_stackaddr_np() should return stack bottom (highest */ /* stack address plus 1). */ @@ -1344,8 +1349,12 @@ GC_INNER word GC_page_size = 0; GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *b) { +# ifdef GC_ASSERTIONS + volatile int dummy; +# endif stack_t s; pthread_t self = pthread_self(); + if (self == stackbase_main_self) { /* If the client calls GC_get_stack_base() from the main thread */ @@ -1363,7 +1372,7 @@ GC_INNER word GC_page_size = 0; ABORT("thr_stksegment failed"); } /* s.ss_sp holds the pointer to the stack bottom. */ - GC_ASSERT((word)(&s) HOTTER_THAN (word)s.ss_sp); + GC_ASSERT((word)(&dummy) HOTTER_THAN (word)s.ss_sp); if (!stackbase_main_self && thr_main() != 0) { @@ -1399,7 +1408,7 @@ GC_INNER word GC_page_size = 0; /* FIXME - Implement better strategies here. */ GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *b) { - int dummy; + volatile int dummy; IF_CANCEL(int cancel_state;) DCL_LOCK_STATE; @@ -1411,7 +1420,7 @@ GC_INNER word GC_page_size = 0; b -> reg_base = GC_find_limit(GC_save_regs_in_stack(), FALSE); # endif # else - b -> mem_base = GC_find_limit(&dummy, FALSE); + b -> mem_base = GC_find_limit((ptr_t)(&dummy), FALSE); # endif RESTORE_CANCEL(cancel_state); UNLOCK(); @@ -1436,10 +1445,14 @@ GC_INNER word GC_page_size = 0; /* This is always called from the main thread. Default implementation. */ ptr_t GC_get_main_stack_base(void) { +# ifdef GC_ASSERTIONS + volatile int dummy; +# endif struct GC_stack_base sb; + if (GC_get_stack_base(&sb) != GC_SUCCESS) ABORT("GC_get_stack_base failed"); - GC_ASSERT((word)(&sb) HOTTER_THAN (word)sb.mem_base); + GC_ASSERT((word)(&dummy) HOTTER_THAN (word)sb.mem_base); return (ptr_t)sb.mem_base; } #endif /* !GET_MAIN_STACKBASE_SPECIAL */ @@ -3079,7 +3092,7 @@ GC_API GC_push_other_roots_proc GC_CALL GC_get_push_other_roots(void) static void async_set_pht_entry_from_index(volatile page_hash_table db, size_t index) { - unsigned int update_dummy; + volatile int update_dummy; currently_updating = (word)(&update_dummy); set_pht_entry_from_index(db, index); /* If we get contention in the 10 or so instruction window here, */ diff --git a/pthread_stop_world.c b/pthread_stop_world.c index 11f7573c..b69aed61 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -222,6 +222,9 @@ STATIC void GC_suspend_handler_inner(ptr_t sig_arg, void *context); STATIC void GC_suspend_handler_inner(ptr_t sig_arg, void * context GC_ATTR_UNUSED) { +# ifndef SPARC + volatile int dummy; +# endif pthread_t self = pthread_self(); GC_thread me; IF_CANCEL(int cancel_state;) @@ -259,7 +262,7 @@ STATIC void GC_suspend_handler_inner(ptr_t sig_arg, # ifdef SPARC me -> stop_info.stack_ptr = GC_save_regs_in_stack(); # else - me -> stop_info.stack_ptr = (ptr_t)(&me); + me -> stop_info.stack_ptr = (ptr_t)(&dummy); # endif # ifdef IA64 me -> backing_store_ptr = GC_save_regs_in_stack(); @@ -679,19 +682,21 @@ GC_INNER void GC_stop_world(void) GC_API_OSCALL void nacl_pre_syscall_hook(void) { - int local_dummy = 0; + volatile int dummy; + if (GC_nacl_thread_idx != -1) { NACL_STORE_REGS(); - GC_nacl_gc_thread_self->stop_info.stack_ptr = (ptr_t)(&local_dummy); + GC_nacl_gc_thread_self->stop_info.stack_ptr = (ptr_t)(&dummy); GC_nacl_thread_parked[GC_nacl_thread_idx] = 1; } } GC_API_OSCALL void __nacl_suspend_thread_if_needed(void) { + volatile int dummy; + if (GC_nacl_park_threads_now) { pthread_t self = pthread_self(); - int local_dummy = 0; /* Don't try to park the thread parker. */ if (GC_nacl_thread_parker == self) @@ -706,7 +711,7 @@ GC_INNER void GC_stop_world(void) /* so don't bother storing registers again, the GC has a set. */ if (!GC_nacl_thread_parked[GC_nacl_thread_idx]) { NACL_STORE_REGS(); - GC_nacl_gc_thread_self->stop_info.stack_ptr = (ptr_t)(&local_dummy); + GC_nacl_gc_thread_self->stop_info.stack_ptr = (ptr_t)(&dummy); } GC_nacl_thread_parked[GC_nacl_thread_idx] = 1; while (GC_nacl_park_threads_now) { diff --git a/pthread_support.c b/pthread_support.c index acd4b664..e6884d59 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -995,7 +995,7 @@ STATIC void GC_fork_child_proc(void) GC_INNER void GC_thr_init(void) { # ifndef GC_DARWIN_THREADS - int dummy; + volatile int dummy; # endif if (GC_thr_initialized) return; GC_thr_initialized = TRUE; diff --git a/ptr_chck.c b/ptr_chck.c index 068eb189..fd88c162 100644 --- a/ptr_chck.c +++ b/ptr_chck.c @@ -163,7 +163,7 @@ void (GC_CALLBACK *GC_is_visible_print_proc)(void * p) = /* Could p be a stack address? */ STATIC GC_bool GC_on_stack(ptr_t p) { - int dummy; + volatile int dummy; # ifdef STACK_GROWS_DOWN if ((word)p >= (word)(&dummy) && (word)p < (word)GC_stackbottom) { return(TRUE); diff --git a/tools/setjmp_t.c b/tools/setjmp_t.c index fc54844a..b3bc2a29 100644 --- a/tools/setjmp_t.c +++ b/tools/setjmp_t.c @@ -69,7 +69,7 @@ int * nested_sp(void) int main(void) { - int dummy; + volatile int dummy; long ps = GETPAGESIZE(); jmp_buf b; register int x = (int)strlen("a"); /* 1, slightly disguised */ diff --git a/win32_threads.c b/win32_threads.c index bf2bc644..b95cd2b7 100644 --- a/win32_threads.c +++ b/win32_threads.c @@ -1334,14 +1334,14 @@ static GC_bool may_be_in_stack(ptr_t s) STATIC word GC_push_stack_for(GC_thread thread, DWORD me) { - int dummy; + volatile int dummy; ptr_t sp, stack_min; struct GC_traced_stack_sect_s *traced_stack_sect = thread -> traced_stack_sect; if (thread -> id == me) { GC_ASSERT(thread -> thread_blocked_sp == NULL); - sp = (ptr_t) &dummy; + sp = (ptr_t)(&dummy); } else if ((sp = thread -> thread_blocked_sp) == NULL) { /* Use saved sp value for blocked threads. */ /* For unblocked threads call GetThreadContext(). */