From 9b87a1524d2a8086943ef3b0c240b1dc693cd744 Mon Sep 17 00:00:00 2001 From: hboehm Date: Wed, 9 Feb 2005 21:33:02 +0000 Subject: [PATCH] * allchblk.c (GC_allochblk_nth): Dont overlook available space if GC disabled, correctly convert GC_finalizer_mem_freed to byte, total_size to words. * dyn_load.c (win32 GC_register_dynamic_libraries): Consider only MEM_IMAGE regions. * mach_dep.c (GC_with_callee_saves_pushed): separate into new function, and indent appropriately. * mark_rts.c (GC_approx_sp): Access stack. * pthread_stop_world.c: (GC_suspend_handler): Explicitly push callee-saves registers when appropriate. (GC_stop_world): Handle EINTR from sem_wait (sync with Mono GC). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94776 138bc75d-0d04-0410-961f-82ee72b054a4 --- boehm-gc/ChangeLog | 14 +++++ boehm-gc/allchblk.c | 10 ++-- boehm-gc/dyn_load.c | 10 +++- boehm-gc/mach_dep.c | 123 +++++++++++++++++++++++------------------- boehm-gc/mark_rts.c | 5 +- boehm-gc/pthread_stop_world.c | 24 ++++++++- 6 files changed, 125 insertions(+), 61 deletions(-) diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index 5bb9d45a435..b9c7c46ae05 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,17 @@ +2005-02-07 Hans Boehm + + * allchblk.c (GC_allochblk_nth): Dont overlook available space if + GC disabled, correctly convert GC_finalizer_mem_freed to byte, + total_size to words. + * dyn_load.c (win32 GC_register_dynamic_libraries): Consider only + MEM_IMAGE regions. + * mach_dep.c (GC_with_callee_saves_pushed): separate into new function, + and indent appropriately. + * mark_rts.c (GC_approx_sp): Access stack. + * pthread_stop_world.c: (GC_suspend_handler): Explicitly push + callee-saves registers when appropriate. + (GC_stop_world): Handle EINTR from sem_wait (sync with Mono GC). + 2005-01-01 Bryce McKinlay * configure.ac (AC_CONFIG_HEADERS): Build both include/gc_config.h diff --git a/boehm-gc/allchblk.c b/boehm-gc/allchblk.c index 793c468b928..f9c31e04527 100644 --- a/boehm-gc/allchblk.c +++ b/boehm-gc/allchblk.c @@ -590,8 +590,9 @@ int n; GET_HDR(hbp, hhdr); size_avail = hhdr->hb_sz; if (size_avail < size_needed) continue; - if (!GC_use_entire_heap - && size_avail != size_needed + if (size_avail != size_needed + && !GC_use_entire_heap + && !GC_dont_gc && USED_HEAP_SIZE >= GC_requested_heapsize && !TRUE_INCREMENTAL && GC_should_collect()) { # ifdef USE_MUNMAP @@ -608,7 +609,8 @@ int n; /* If we are deallocating lots of memory from */ /* finalizers, fail and collect sooner rather */ /* than later. */ - if (GC_finalizer_mem_freed > (GC_heapsize >> 4)) { + if (WORDS_TO_BYTES(GC_finalizer_mem_freed) + > (GC_heapsize >> 4)) { continue; } # endif /* !USE_MUNMAP */ @@ -698,7 +700,7 @@ int n; struct hblk * h; struct hblk * prev = hhdr -> hb_prev; - GC_words_wasted += total_size; + GC_words_wasted += BYTES_TO_WORDS(total_size); GC_large_free_bytes -= total_size; GC_remove_from_fl(hhdr, n); for (h = hbp; h < limit; h++) { diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c index 9bd9e060688..dfe0a3c87e8 100644 --- a/boehm-gc/dyn_load.c +++ b/boehm-gc/dyn_load.c @@ -735,6 +735,10 @@ void GC_register_dynamic_libraries() # define HAVE_REGISTER_MAIN_STATIC_DATA + /* The frame buffer testing code is dead in this version. */ + /* We leave it here temporarily in case the switch to just */ + /* testing for MEM_IMAGE sections causes un expected */ + /* problems. */ GC_bool GC_warn_fb = TRUE; /* Warn about traced likely */ /* graphics memory. */ GC_bool GC_disallow_ignore_fb = FALSE; @@ -856,7 +860,11 @@ void GC_register_dynamic_libraries() && (protect == PAGE_EXECUTE_READWRITE || protect == PAGE_READWRITE) && !GC_is_heap_base(buf.AllocationBase) - && !is_frame_buffer(p, buf.RegionSize)) { + /* This used to check for + * !is_frame_buffer(p, buf.RegionSize, buf.Type) + * instead of just checking for MEM_IMAGE. + * If something breaks, change it back. */ + && buf.Type == MEM_IMAGE) { # ifdef DEBUG_VIRTUALQUERY GC_dump_meminfo(&buf); # endif diff --git a/boehm-gc/mach_dep.c b/boehm-gc/mach_dep.c index 327e11ca690..5412b8b54fd 100644 --- a/boehm-gc/mach_dep.c +++ b/boehm-gc/mach_dep.c @@ -400,64 +400,79 @@ void GC_push_regs() } #endif /* !USE_GENERIC_PUSH_REGS && !USE_ASM_PUSH_REGS */ +void GC_with_callee_saves_pushed(fn, arg) +void (*fn)(); +ptr_t arg; +{ + word dummy; + +# if defined(USE_GENERIC_PUSH_REGS) +# ifdef HAVE_BUILTIN_UNWIND_INIT + /* This was suggested by Richard Henderson as the way to */ + /* force callee-save registers and register windows onto */ + /* the stack. */ + __builtin_unwind_init(); +# else /* !HAVE_BUILTIN_UNWIND_INIT */ + /* Generic code */ + /* The idea is due to Parag Patel at HP. */ + /* We're not sure whether he would like */ + /* to be he acknowledged for it or not. */ + jmp_buf regs; + register word * i = (word *) regs; + register ptr_t lim = (ptr_t)(regs) + (sizeof regs); + + /* Setjmp doesn't always clear all of the buffer. */ + /* That tends to preserve garbage. Clear it. */ + for (; (char *)i < lim; i++) { + *i = 0; + } +# if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \ + || defined(UTS4) || defined(LINUX) || defined(EWS4800) + (void) setjmp(regs); +# else + (void) _setjmp(regs); + /* We don't want to mess with signals. According to */ + /* SUSV3, setjmp() may or may not save signal mask. */ + /* _setjmp won't, but is less portable. */ +# endif +# endif /* !HAVE_BUILTIN_UNWIND_INIT */ +# elif defined(PTHREADS) && !defined(MSWIN32) /* !USE_GENERIC_PUSH_REGS */ + /* We may still need this to save thread contexts. */ + /* This should probably be used in all Posix/non-gcc */ + /* settings. We defer that change to minimize risk. */ + ucontext_t ctxt; + getcontext(&ctxt); +# else /* Shouldn't be needed */ + ABORT("Unexpected call to GC_with_callee_saves_pushed"); +# endif +# if (defined(SPARC) && !defined(HAVE_BUILTIN_UNWIND_INIT)) \ + || defined(IA64) + /* On a register window machine, we need to save register */ + /* contents on the stack for this to work. The setjmp */ + /* is probably not needed on SPARC, since pointers are */ + /* only stored in windowed or scratch registers. It is */ + /* needed on IA64, since some non-windowed registers are */ + /* preserved. */ + { + GC_save_regs_ret_val = GC_save_regs_in_stack(); + /* On IA64 gcc, could use __builtin_ia64_flushrs() and */ + /* __builtin_ia64_flushrs(). The latter will be done */ + /* implicitly by __builtin_unwind_init() for gcc3.0.1 */ + /* and later. */ + } +# endif + fn(arg); + /* Strongly discourage the compiler from treating the above */ + /* as a tail-call, since that would pop the register */ + /* contents before we get a chance to look at them. */ + GC_noop1((word)(&dummy)); +} + #if defined(USE_GENERIC_PUSH_REGS) void GC_generic_push_regs(cold_gc_frame) ptr_t cold_gc_frame; { - { - word dummy; - -# ifdef HAVE_BUILTIN_UNWIND_INIT - /* This was suggested by Richard Henderson as the way to */ - /* force callee-save registers and register windows onto */ - /* the stack. */ - __builtin_unwind_init(); -# else /* !HAVE_BUILTIN_UNWIND_INIT */ - /* Generic code */ - /* The idea is due to Parag Patel at HP. */ - /* We're not sure whether he would like */ - /* to be he acknowledged for it or not. */ - jmp_buf regs; - register word * i = (word *) regs; - register ptr_t lim = (ptr_t)(regs) + (sizeof regs); - - /* Setjmp doesn't always clear all of the buffer. */ - /* That tends to preserve garbage. Clear it. */ - for (; (char *)i < lim; i++) { - *i = 0; - } -# if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \ - || defined(UTS4) || defined(LINUX) || defined(EWS4800) - (void) setjmp(regs); -# else - (void) _setjmp(regs); - /* We don't want to mess with signals. According to */ - /* SUSV3, setjmp() may or may not save signal mask. */ - /* _setjmp won't, but is less portable. */ -# endif -# endif /* !HAVE_BUILTIN_UNWIND_INIT */ -# if (defined(SPARC) && !defined(HAVE_BUILTIN_UNWIND_INIT)) \ - || defined(IA64) - /* On a register window machine, we need to save register */ - /* contents on the stack for this to work. The setjmp */ - /* is probably not needed on SPARC, since pointers are */ - /* only stored in windowed or scratch registers. It is */ - /* needed on IA64, since some non-windowed registers are */ - /* preserved. */ - { - GC_save_regs_ret_val = GC_save_regs_in_stack(); - /* On IA64 gcc, could use __builtin_ia64_flushrs() and */ - /* __builtin_ia64_flushrs(). The latter will be done */ - /* implicitly by __builtin_unwind_init() for gcc3.0.1 */ - /* and later. */ - } -# endif - GC_push_current_stack(cold_gc_frame); - /* Strongly discourage the compiler from treating the above */ - /* as a tail-call, since that would pop the register */ - /* contents before we get a chance to look at them. */ - GC_noop1((word)(&dummy)); - } + GC_with_callee_saves_pushed(GC_push_current_stack, cold_gc_frame); } #endif /* USE_GENERIC_PUSH_REGS */ diff --git a/boehm-gc/mark_rts.c b/boehm-gc/mark_rts.c index 55eb5d54339..4074879a71a 100644 --- a/boehm-gc/mark_rts.c +++ b/boehm-gc/mark_rts.c @@ -368,8 +368,11 @@ ptr_t p; ptr_t GC_approx_sp() { - word dummy; + VOLATILE word dummy; + dummy = 42; /* Force stack to grow if necessary. Otherwise the */ + /* later accesses might cause the kernel to think we're */ + /* doing something wrong. */ # ifdef _MSC_VER # pragma warning(disable:4172) # endif diff --git a/boehm-gc/pthread_stop_world.c b/boehm-gc/pthread_stop_world.c index 832c49ca81e..b5e7faed5ab 100644 --- a/boehm-gc/pthread_stop_world.c +++ b/boehm-gc/pthread_stop_world.c @@ -101,8 +101,28 @@ word GC_stop_count; /* Incremented at the beginning of GC_stop_world. */ sem_t GC_suspend_ack_sem; +void GC_suspend_handler_inner(ptr_t sig_arg); + +#if defined(IA64) || defined(HP_PA) +extern void GC_with_callee_saves_pushed(); + void GC_suspend_handler(int sig) { + GC_with_callee_saves_pushed(GC_suspend_handler_inner, (ptr_t)(word)sig); +} + +#else +/* We believe that in all other cases the full context is already */ +/* in the signal handler frame. */ +void GC_suspend_handler(int sig) +{ + GC_suspend_handler_inner((ptr_t)(word)sig); +} +#endif + +void GC_suspend_handler_inner(ptr_t sig_arg) +{ + int sig = (int)(word)sig_arg; int dummy; pthread_t my_thread = pthread_self(); GC_thread me; @@ -369,9 +389,11 @@ void GC_stop_world() } } for (i = 0; i < n_live_threads; i++) { - if (0 != (code = sem_wait(&GC_suspend_ack_sem))) { + while (0 != (code = sem_wait(&GC_suspend_ack_sem))) { + if (errno != EINTR) { GC_err_printf1("Sem_wait returned %ld\n", (unsigned long)code); ABORT("sem_wait for handler failed"); + } } } # ifdef PARALLEL_MARK -- 2.11.0