summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhboehm <hboehm@138bc75d-0d04-0410-961f-82ee72b054a4>2005-02-09 21:33:02 +0000
committerhboehm <hboehm@138bc75d-0d04-0410-961f-82ee72b054a4>2005-02-09 21:33:02 +0000
commit9b87a1524d2a8086943ef3b0c240b1dc693cd744 (patch)
tree740a513131a2bfd49e69843a563d9ce978424f93
parent8024da994207870f456c6d8dc2a1bd312b008861 (diff)
downloadgcc-9b87a1524d2a8086943ef3b0c240b1dc693cd744.tar.gz
* 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
-rw-r--r--boehm-gc/ChangeLog14
-rw-r--r--boehm-gc/allchblk.c10
-rw-r--r--boehm-gc/dyn_load.c10
-rw-r--r--boehm-gc/mach_dep.c123
-rw-r--r--boehm-gc/mark_rts.c5
-rw-r--r--boehm-gc/pthread_stop_world.c24
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 <Hans.Boehm@hp.com>
+
+ * 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 <mckinlay@redhat.com>
* 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