mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
Allow the SMOB mark procedures to be called when libgc uses parallel markers.
Fixes <http://bugs.gnu.org/13611>. Reported by Mike Gran <spk121@yahoo.com>. * libguile/smob.c (current_mark_stack_pointer, current_mark_stack_limit): New variables. (smob_mark): Use CURRENT_MARK_STACK_POINTER and CURRENT_MARK_STACK_LIMIT instead of the same-named fields of `SCM_I_CURRENT_THREAD'. (scm_gc_mark): Likewise. (scm_smob_prehistory): Initialize CURRENT_MARK_STACK_LIMIT and CURRENT_MARK_STACK_POINTER. * libguile/threads.h (scm_i_thread): Add comment that `current_mark_stack_ptr' and `current_mark_stack_limit' are no longer used.
This commit is contained in:
parent
0f595d7d1d
commit
01b69e79f6
2 changed files with 29 additions and 27 deletions
|
@ -1,4 +1,5 @@
|
||||||
/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2003, 2004, 2006, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
/* Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2004, 2006,
|
||||||
|
* 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -284,6 +285,10 @@ scm_make_smob (scm_t_bits tc)
|
||||||
/* The GC kind used for SMOB types that provide a custom mark procedure. */
|
/* The GC kind used for SMOB types that provide a custom mark procedure. */
|
||||||
static int smob_gc_kind;
|
static int smob_gc_kind;
|
||||||
|
|
||||||
|
/* Mark stack pointer and limit, used by `scm_gc_mark'. */
|
||||||
|
static scm_i_pthread_key_t current_mark_stack_pointer;
|
||||||
|
static scm_i_pthread_key_t current_mark_stack_limit;
|
||||||
|
|
||||||
|
|
||||||
/* The generic SMOB mark procedure that gets called for SMOBs allocated
|
/* The generic SMOB mark procedure that gets called for SMOBs allocated
|
||||||
with smob_gc_kind. */
|
with smob_gc_kind. */
|
||||||
|
@ -322,14 +327,14 @@ smob_mark (GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
|
||||||
{
|
{
|
||||||
SCM obj;
|
SCM obj;
|
||||||
|
|
||||||
SCM_I_CURRENT_THREAD->current_mark_stack_ptr = mark_stack_ptr;
|
scm_i_pthread_setspecific (current_mark_stack_pointer, mark_stack_ptr);
|
||||||
SCM_I_CURRENT_THREAD->current_mark_stack_limit = mark_stack_limit;
|
scm_i_pthread_setspecific (current_mark_stack_limit, mark_stack_limit);
|
||||||
|
|
||||||
/* Invoke the SMOB's mark procedure, which will in turn invoke
|
/* Invoke the SMOB's mark procedure, which will in turn invoke
|
||||||
`scm_gc_mark ()', which may modify `current_mark_stack_ptr'. */
|
`scm_gc_mark', which may modify `current_mark_stack_pointer'. */
|
||||||
obj = scm_smobs[smobnum].mark (cell);
|
obj = scm_smobs[smobnum].mark (cell);
|
||||||
|
|
||||||
mark_stack_ptr = SCM_I_CURRENT_THREAD->current_mark_stack_ptr;
|
mark_stack_ptr = scm_i_pthread_getspecific (current_mark_stack_pointer);
|
||||||
|
|
||||||
if (SCM_NIMP (obj))
|
if (SCM_NIMP (obj))
|
||||||
/* Mark the returned object. */
|
/* Mark the returned object. */
|
||||||
|
@ -337,42 +342,35 @@ smob_mark (GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
|
||||||
mark_stack_ptr,
|
mark_stack_ptr,
|
||||||
mark_stack_limit, NULL);
|
mark_stack_limit, NULL);
|
||||||
|
|
||||||
SCM_I_CURRENT_THREAD->current_mark_stack_limit = NULL;
|
scm_i_pthread_setspecific (current_mark_stack_pointer, NULL);
|
||||||
SCM_I_CURRENT_THREAD->current_mark_stack_ptr = NULL;
|
scm_i_pthread_setspecific (current_mark_stack_limit, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mark_stack_ptr;
|
return mark_stack_ptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark object O. We assume that this function is only called during the
|
/* Mark object O. We assume that this function is only called during the mark
|
||||||
mark phase, i.e., from within `smob_mark ()' or one of its
|
phase, i.e., from within `smob_mark' or one of its descendants. */
|
||||||
descendents. */
|
|
||||||
void
|
void
|
||||||
scm_gc_mark (SCM o)
|
scm_gc_mark (SCM o)
|
||||||
{
|
{
|
||||||
#define CURRENT_MARK_PTR \
|
|
||||||
((struct GC_ms_entry *)(SCM_I_CURRENT_THREAD->current_mark_stack_ptr))
|
|
||||||
#define CURRENT_MARK_LIMIT \
|
|
||||||
((struct GC_ms_entry *)(SCM_I_CURRENT_THREAD->current_mark_stack_limit))
|
|
||||||
|
|
||||||
if (SCM_NIMP (o))
|
if (SCM_NIMP (o))
|
||||||
{
|
{
|
||||||
/* At this point, the `current_mark_*' fields of the current thread
|
void *mark_stack_ptr, *mark_stack_limit;
|
||||||
must be defined (they are set in `smob_mark ()'). */
|
|
||||||
register struct GC_ms_entry *mark_stack_ptr;
|
|
||||||
|
|
||||||
if (!CURRENT_MARK_PTR)
|
mark_stack_ptr = scm_i_pthread_getspecific (current_mark_stack_pointer);
|
||||||
|
mark_stack_limit = scm_i_pthread_getspecific (current_mark_stack_limit);
|
||||||
|
|
||||||
|
if (mark_stack_ptr == NULL)
|
||||||
/* The function was not called from a mark procedure. */
|
/* The function was not called from a mark procedure. */
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
mark_stack_ptr = GC_MARK_AND_PUSH (SCM2PTR (o),
|
mark_stack_ptr = GC_MARK_AND_PUSH (SCM2PTR (o),
|
||||||
CURRENT_MARK_PTR, CURRENT_MARK_LIMIT,
|
mark_stack_ptr, mark_stack_limit,
|
||||||
NULL);
|
NULL);
|
||||||
SCM_I_CURRENT_THREAD->current_mark_stack_ptr = mark_stack_ptr;
|
scm_i_pthread_setspecific (current_mark_stack_pointer, mark_stack_ptr);
|
||||||
}
|
}
|
||||||
#undef CURRENT_MARK_PTR
|
|
||||||
#undef CURRENT_MARK_LIMIT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -473,6 +471,9 @@ scm_smob_prehistory ()
|
||||||
{
|
{
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
|
scm_i_pthread_key_create (¤t_mark_stack_pointer, NULL);
|
||||||
|
scm_i_pthread_key_create (¤t_mark_stack_limit, NULL);
|
||||||
|
|
||||||
smob_gc_kind = GC_new_kind (GC_new_free_list (),
|
smob_gc_kind = GC_new_kind (GC_new_free_list (),
|
||||||
GC_MAKE_PROC (GC_new_proc (smob_mark), 0),
|
GC_MAKE_PROC (GC_new_proc (smob_mark), 0),
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
#ifndef SCM_THREADS_H
|
#ifndef SCM_THREADS_H
|
||||||
#define SCM_THREADS_H
|
#define SCM_THREADS_H
|
||||||
|
|
||||||
/* Copyright (C) 1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
|
/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2006,
|
||||||
|
* 2007, 2008, 2009, 2011, 2013 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -71,8 +72,8 @@ typedef struct scm_i_thread {
|
||||||
scm_i_pthread_cond_t sleep_cond;
|
scm_i_pthread_cond_t sleep_cond;
|
||||||
int sleep_fd, sleep_pipe[2];
|
int sleep_fd, sleep_pipe[2];
|
||||||
|
|
||||||
/* Information about the Boehm-GC mark stack during the mark phase. This
|
/* XXX: These two fields used to hold information about the BDW-GC
|
||||||
is used by `scm_gc_mark ()'. */
|
mark stack during the mark phase. They are no longer used. */
|
||||||
void *current_mark_stack_ptr;
|
void *current_mark_stack_ptr;
|
||||||
void *current_mark_stack_limit;
|
void *current_mark_stack_limit;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue