summaryrefslogtreecommitdiff
path: root/finalize.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2011-07-26 17:49:27 +0400
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 17:49:27 +0400
commitcab07051b9609b90d82db8c4586988a804a25264 (patch)
tree98eb408f4e958f983450dad080f567702d67bd74 /finalize.c
parent1b159c5602737076356b862a8d2205bb13b34909 (diff)
downloadbdwgc-cab07051b9609b90d82db8c4586988a804a25264.tar.gz
gc6.3alpha5 tarball importgc6_3alpha5
Diffstat (limited to 'finalize.c')
-rw-r--r--finalize.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/finalize.c b/finalize.c
index 3b9d9f5e..e103228c 100644
--- a/finalize.c
+++ b/finalize.c
@@ -807,8 +807,37 @@ void (* GC_finalizer_notifier)() = (void (*) GC_PROTO((void)))0;
static GC_word last_finalizer_notification = 0;
+#ifdef KEEP_BACK_PTRS
+void GC_generate_random_backtrace_no_gc(void);
+#endif
+
void GC_notify_or_invoke_finalizers GC_PROTO((void))
{
+ /* This is a convenient place to generate backtraces if appropriate, */
+ /* since that code is not callable with the allocation lock. */
+# ifdef KEEP_BACK_PTRS
+ if (GC_backtraces > 0) {
+ static word last_back_trace_gc_no = 3; /* Skip early ones. */
+ long i;
+
+ LOCK();
+ if (GC_gc_no > last_back_trace_gc_no) {
+ /* Stops when GC_gc_no wraps; that's OK. */
+ last_back_trace_gc_no = (word)(-1); /* disable others. */
+ for (i = 0; i < GC_backtraces; ++i) {
+ /* FIXME: This tolerates concurrent heap mutation, */
+ /* which may cause occasional mysterious results. */
+ /* We need to release the GC lock, since GC_print_callers */
+ /* acquires it. It probably shouldn't. */
+ UNLOCK();
+ GC_generate_random_backtrace_no_gc();
+ LOCK();
+ }
+ last_back_trace_gc_no = GC_gc_no;
+ }
+ UNLOCK();
+ }
+# endif
if (GC_finalize_now == 0) return;
if (!GC_finalize_on_demand) {
(void) GC_invoke_finalizers();