From 353e1a000a7e29928266ec3aa2b16e49b266fca3 Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Thu, 29 Mar 2012 01:37:33 +0200 Subject: [PATCH] Let ASSERT_LIVE_IS_ALLOWED take an argument to print the last unallowed live object --- lily/context-def.cc | 2 +- lily/context-mod.cc | 2 +- lily/grob-smob.cc | 2 +- lily/include/smobs.hh | 33 +++++++++++++++++++++++---------- lily/lily-lexer.cc | 2 +- lily/music-function.cc | 2 +- lily/prob.cc | 2 +- lily/skyline.cc | 4 ++-- lily/undead.cc | 31 +++++++++++++++++++++++++++++++ scm/lily.scm | 8 ++++++++ 10 files changed, 70 insertions(+), 18 deletions(-) diff --git a/lily/context-def.cc b/lily/context-def.cc index f2d7e2e137..b4e1e2567c 100644 --- a/lily/context-def.cc +++ b/lily/context-def.cc @@ -100,7 +100,7 @@ Context_def::print_smob (SCM smob, SCM port, scm_print_state *) 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); diff --git a/lily/context-mod.cc b/lily/context-mod.cc index 460d18bcfd..cb6cf83562 100644 --- a/lily/context-mod.cc +++ b/lily/context-mod.cc @@ -53,7 +53,7 @@ Context_mod::print_smob (SCM smob, SCM port, scm_print_state *) 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); diff --git a/lily/grob-smob.cc b/lily/grob-smob.cc index e695cdda0c..853546a886 100644 --- a/lily/grob-smob.cc +++ b/lily/grob-smob.cc @@ -31,7 +31,7 @@ IMPLEMENT_TYPE_P (Grob, "ly:grob?"); 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_); diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh index c550754910..22a4d18309 100644 --- a/lily/include/smobs.hh +++ b/lily/include/smobs.hh @@ -153,19 +153,32 @@ void protect_smob (SCM smob, SCM *prot_cons); void unprotect_smob (SCM smob, SCM *prot_cons); extern bool parsed_objects_should_be_dead; +class parsed_dead { + static vector 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 diff --git a/lily/lily-lexer.cc b/lily/lily-lexer.cc index 7f017a437b..1bbc5b8167 100644 --- a/lily/lily-lexer.cc +++ b/lily/lily-lexer.cc @@ -372,7 +372,7 @@ IMPLEMENT_DEFAULT_EQUAL_P (Lily_lexer); 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); diff --git a/lily/music-function.cc b/lily/music-function.cc index 85b2157576..b9159fe3a7 100644 --- a/lily/music-function.cc +++ b/lily/music-function.cc @@ -83,6 +83,6 @@ Musicfunction::mark_smob (SCM s) { Musicfunction *p = Musicfunction::unsmob (s); scm_gc_mark (p->signature_); - ASSERT_LIVE_IS_ALLOWED (); + ASSERT_LIVE_IS_ALLOWED (s); return p->function_; } diff --git a/lily/prob.cc b/lily/prob.cc index 53b562c270..367d1616a7 100644 --- a/lily/prob.cc +++ b/lily/prob.cc @@ -119,7 +119,7 @@ Prob::derived_mark () const 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_); diff --git a/lily/skyline.cc b/lily/skyline.cc index 2a1e54f5f5..0250fc07f4 100644 --- a/lily/skyline.cc +++ b/lily/skyline.cc @@ -661,9 +661,9 @@ IMPLEMENT_TYPE_P (Skyline, "ly:skyline?"); 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; } diff --git a/lily/undead.cc b/lily/undead.cc index 9ba0878e3c..a3387ea9e9 100644 --- a/lily/undead.cc +++ b/lily/undead.cc @@ -69,3 +69,34 @@ LY_DEFINE (ly_get_undead, "ly:get-undead", 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::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 (); +} diff --git a/scm/lily.scm b/scm/lily.scm index 64c403b074..190670045c 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -642,6 +642,10 @@ messages into errors.") (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))) @@ -832,6 +836,10 @@ PIDs or the number of the process." (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)) -- 2.39.2