SCM
Context_def::mark_smob (SCM smob)
{
- ASSERT_LIVE_IS_ALLOWED ();
+ ASSERT_LIVE_IS_ALLOWED (smob);
Context_def *me = (Context_def *) SCM_CELL_WORD_1 (smob);
SCM
Context_mod::mark_smob (SCM smob)
{
- ASSERT_LIVE_IS_ALLOWED ();
+ ASSERT_LIVE_IS_ALLOWED (smob);
Context_mod *me = (Context_mod *) SCM_CELL_WORD_1 (smob);
SCM
Grob::mark_smob (SCM ses)
{
- ASSERT_LIVE_IS_ALLOWED ();
+ ASSERT_LIVE_IS_ALLOWED (ses);
Grob *s = (Grob *) SCM_CELL_WORD_1 (ses);
scm_gc_mark (s->immutable_property_alist_);
void unprotect_smob (SCM smob, SCM *prot_cons);
extern bool parsed_objects_should_be_dead;
+class parsed_dead {
+ static vector<parsed_dead *> elements;
+ SCM data;
+ SCM readout_one () {
+ SCM res = data;
+ data = SCM_UNDEFINED;
+ return res;
+ }
+public:
+ parsed_dead () : data (SCM_UNDEFINED)
+ {
+ elements.push_back (this);
+ }
+ void checkin (SCM arg) { data = arg; }
+ static SCM readout ();
+};
#ifndef NDEBUG
-#define ASSERT_LIVE_IS_ALLOWED() \
- do { \
- static bool passed_here_once;\
- if (parsed_objects_should_be_dead && !passed_here_once) { \
- ::programming_error (string ("Parsed object should be dead: ") + __PRETTY_FUNCTION__ ); \
- passed_here_once = true;\
- } \
- } \
- while (0)
+#define ASSERT_LIVE_IS_ALLOWED(arg) \
+ do { \
+ static parsed_dead pass_here; \
+ if (parsed_objects_should_be_dead) \
+ pass_here.checkin (arg); \
+ } while (0)
#else
-#define ASSERT_LIVE_IS_ALLOWED() do { } \
+#define ASSERT_LIVE_IS_ALLOWED(arg) do { } \
while (0)
#endif
SCM
Lily_lexer::mark_smob (SCM s)
{
- ASSERT_LIVE_IS_ALLOWED ();
+ ASSERT_LIVE_IS_ALLOWED (s);
Lily_lexer *lexer = (Lily_lexer *) SCM_CELL_WORD_1 (s);
{
Musicfunction *p = Musicfunction::unsmob (s);
scm_gc_mark (p->signature_);
- ASSERT_LIVE_IS_ALLOWED ();
+ ASSERT_LIVE_IS_ALLOWED (s);
return p->function_;
}
SCM
Prob::mark_smob (SCM smob)
{
- ASSERT_LIVE_IS_ALLOWED ();
+ ASSERT_LIVE_IS_ALLOWED (smob);
Prob *system = (Prob *) SCM_CELL_WORD_1 (smob);
scm_gc_mark (system->mutable_property_alist_);
IMPLEMENT_DEFAULT_EQUAL_P (Skyline);
SCM
-Skyline::mark_smob (SCM)
+Skyline::mark_smob (SCM s)
{
- ASSERT_LIVE_IS_ALLOWED ();
+ ASSERT_LIVE_IS_ALLOWED (s);
return SCM_EOL;
}
LY_ASSERT_SMOB (Undead, undead, 1);
return Undead::unsmob (undead)->object ();
}
+
+// '
+// These are not protected since the means of protecting them would be
+// problematic to trigger during the mark pass where the array element
+// references get set. However, they get set only when in the mark
+// pass when checking for parsed elements that should be dead, and we
+// query and clear them immediately afterwards. So there should be no
+// way in which the references would have become unprotected in the
+// mean time.
+
+vector<parsed_dead *> parsed_dead::elements;
+
+SCM
+parsed_dead::readout ()
+{
+ SCM result = SCM_EOL;
+ for (vsize i = 0; i < elements.size (); i++) {
+ SCM elt = elements[i]->readout_one ();
+ if (!SCM_UNBNDP (elt))
+ result = scm_cons (elt, result);
+ }
+ return result;
+}
+
+LY_DEFINE (ly_parsed_undead_list_x, "ly:parsed-undead-list!",
+ 0, 0, 0, (),
+ "Return the list of objects that have been found live"
+ " that should have been dead, and clear that list.")
+{
+ return parsed_dead::readout ();
+}
(ly:set-option 'debug-gc-assert-parsed-dead #t)
(gc)
(ly:set-option 'debug-gc-assert-parsed-dead #f)
+ (for-each
+ (lambda (x)
+ (ly:programming-error "Parsed object should be dead: ~a" x))
+ (ly:parsed-undead-list!))
(set! stats (gc-live-object-stats))
(ly:progress "Dumping live object statistics.\n")
(dump-live-object-stats outfile)))
(ly:set-option 'debug-gc-assert-parsed-dead #t)
(gc)
(ly:set-option 'debug-gc-assert-parsed-dead #f)
+ (for-each
+ (lambda (x)
+ (ly:programming-error "Parsed object should be dead: ~a" x))
+ (ly:parsed-undead-list!))
(if (ly:get-option 'debug-gc)
(dump-gc-protects)
(ly:reset-all-fonts))