From: hanwen <hanwen>
Date: Sun, 24 Jul 2005 15:30:03 +0000 (+0000)
Subject: (DECLARE_BASE_SMOBS): add methods
X-Git-Tag: release/2.6.4~17^2~187
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=b7f56c6ce7e67a3d122d1b6a5e4970572a0fd112;p=lilypond.git

(DECLARE_BASE_SMOBS): add methods
protect() and unprotect(). Use throughout.
---

diff --git a/ChangeLog b/ChangeLog
index 839dd0d793..0bd8d57804 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-07-24  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+
+	* lily/smobs.cc (protect_smob): experiment: O(1) GC (un)protection.
+
+	* lily/include/smobs.hh (DECLARE_BASE_SMOBS): add methods
+	protect() and unprotect(). Use throughout.
+
 2005-07-24  Nicolas Sceaux  <nicolas.sceaux@free.fr>
 
 	* Documentation/topdocs/NEWS.tely: new item for \displayLilyMusic
diff --git a/lily/all-font-metrics.cc b/lily/all-font-metrics.cc
index 8c4d40ffc8..c4a2c61676 100644
--- a/lily/all-font-metrics.cc
+++ b/lily/all-font-metrics.cc
@@ -43,12 +43,12 @@ All_font_metrics::All_font_metrics (String path)
 
 All_font_metrics::~All_font_metrics ()
 {
-  scm_gc_unprotect_object (afm_dict_->self_scm ());
-  scm_gc_unprotect_object (tfm_dict_->self_scm ());
-  scm_gc_unprotect_object (otf_dict_->self_scm ());
+  afm_dict_->unprotect ();
+  tfm_dict_->unprotect ();
+  otf_dict_->unprotect ();
 
 #if HAVE_PANGO_FT2
-  scm_gc_unprotect_object (pango_dict_->self_scm ());
+  pango_dict_->unprotect ();
   g_object_unref (pango_ft2_fontmap_);
 #endif
 }
@@ -83,7 +83,7 @@ All_font_metrics::find_pango_font (PangoFontDescription *description,
 				       output_scale);
       val = pf->self_scm ();
       pango_dict_->set (key, val);
-      scm_gc_unprotect_object (val);
+      pf->unprotect ();
 
       if (be_verbose_global)
 	progress_indication ("]");
@@ -158,7 +158,7 @@ All_font_metrics::find_afm (String name)
 	progress_indication ("]");
 
       afm_dict_->set (sname, val);
-      scm_gc_unprotect_object (val);
+      unsmob_metrics (val)->unprotect ();
 
       Adobe_font_metric *afm
 	= dynamic_cast<Adobe_font_metric *> (unsmob_metrics (val));
@@ -224,7 +224,7 @@ All_font_metrics::find_otf (String name)
       unsmob_metrics (val)->description_ = scm_cons (name_string,
 						     scm_make_real (1.0));
       otf_dict_->set (sname, val);
-      scm_gc_unprotect_object (val);
+      unsmob_metrics (val)->unprotect ();
     }
 
   return dynamic_cast<Open_type_font *> (unsmob_metrics (val));
@@ -266,7 +266,7 @@ All_font_metrics::find_tfm (String name)
       unsmob_metrics (val)->description_ = scm_cons (name_string,
 						     scm_make_real (1.0));
       tfm_dict_->set (sname, val);
-      scm_gc_unprotect_object (val);
+      unsmob_metrics (val)->unprotect ();
     }
 
   return dynamic_cast<Tex_font_metric *> (unsmob_metrics (val));
diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc
index 8123101852..e27aad488a 100644
--- a/lily/auto-beam-engraver.cc
+++ b/lily/auto-beam-engraver.cc
@@ -177,17 +177,13 @@ Auto_beam_engraver::create_beam ()
   if (to_boolean (get_property ("skipTypesetting")))
     return 0;
 
+  for (int i = 0; i < stems_->size (); i++)
+    if (Stem::get_beam ((*stems_)[i]))
+      return 0;
+
   Spanner *beam = new Spanner (beam_settings_, context ()->get_grob_key ("Beam"));
   for (int i = 0; i < stems_->size (); i++)
     {
-      /*
-	watch out for stem tremolos and abbreviation beams
-      */
-      if (Stem::get_beam ((*stems_)[i]))
-	{
-	  scm_gc_unprotect_object (beam->self_scm ());
-	  return 0;
-	}
       Beam::add_stem (beam, (*stems_)[i]);
     }
 
@@ -306,6 +302,7 @@ Auto_beam_engraver::finalize ()
 void
 Auto_beam_engraver::acknowledge_beam (Grob_info info)
 {
+  (void)info;
   check_bar_property ();
   if (stems_)
     {
@@ -316,6 +313,7 @@ Auto_beam_engraver::acknowledge_beam (Grob_info info)
 void
 Auto_beam_engraver::acknowledge_bar_line (Grob_info info)
 {
+  (void)info;
   check_bar_property ();
   if (stems_)
     end_beam ();
@@ -324,6 +322,7 @@ Auto_beam_engraver::acknowledge_bar_line (Grob_info info)
 void
 Auto_beam_engraver::acknowledge_rest (Grob_info info)
 {
+  (void)info;
   check_bar_property ();
   if (stems_)
     end_beam ();
diff --git a/lily/book-scheme.cc b/lily/book-scheme.cc
index 03e10af05d..541269be61 100644
--- a/lily/book-scheme.cc
+++ b/lily/book-scheme.cc
@@ -30,8 +30,9 @@ LY_DEFINE (ly_make_book, "ly:make-book",
 
   book->scores_ = scm_append (scm_list_2 (scores, book->scores_));
 
+  
   SCM x = book->self_scm ();
-  scm_gc_unprotect_object (x);
+  book->unprotect ();
   return x;
 }
 
@@ -58,7 +59,7 @@ LY_DEFINE (ly_parser_print_book, "ly:book-process",
   if (pb)
     {
       pb->output (output);
-      scm_gc_unprotect_object (pb->self_scm ());
+      pb->unprotect ();
     }
 
   return SCM_UNSPECIFIED;
diff --git a/lily/book.cc b/lily/book.cc
index 0994c84a0e..a6279b531c 100644
--- a/lily/book.cc
+++ b/lily/book.cc
@@ -93,11 +93,10 @@ Book::process (Output_def *default_paper,
   Output_def *scaled_bookdef = scale_output_def (paper, scale);
 
   Object_key *key = new Lilypond_general_key (0, user_key_, 0);
-  SCM scm_key = key->self_scm ();
-  scm_gc_unprotect_object (scm_key);
-
+  SCM scm_key = key->unprotect ();
+  
   paper_book->paper_ = scaled_bookdef;
-  scm_gc_unprotect_object (scaled_bookdef->self_scm ());
+  scaled_bookdef->unprotect ();
 
   paper_book->header_ = header_;
 
diff --git a/lily/completion-note-heads-engraver.cc b/lily/completion-note-heads-engraver.cc
index 4553428417..6f8bab9337 100644
--- a/lily/completion-note-heads-engraver.cc
+++ b/lily/completion-note-heads-engraver.cc
@@ -291,7 +291,7 @@ Completion_heads_engraver::stop_translation_timestep ()
 
   for (int i = scratch_note_events_.size (); i--;)
     {
-      scm_gc_unprotect_object (scratch_note_events_[i]->self_scm ());
+      scratch_note_events_[i]->unprotect ();
     }
 
   scratch_note_events_.clear ();
diff --git a/lily/context-def.cc b/lily/context-def.cc
index 8adf44f715..1650076669 100644
--- a/lily/context-def.cc
+++ b/lily/context-def.cc
@@ -331,7 +331,7 @@ Context_def::instantiate (SCM ops, Object_key const *key)
 	    }
 
 	  tr->daddy_context_ = context;
-	  scm_gc_unprotect_object (str);
+	  tr->unprotect ();
 	}
     }
 
@@ -352,7 +352,7 @@ Context_def::instantiate (SCM ops, Object_key const *key)
   g->context_ = context;
   context->aliases_ = context_aliases_;
 
-  scm_gc_unprotect_object (g->self_scm ());
+  g->unprotect ();
 
   context->accepts_list_ = get_accepted (ops);
     
@@ -363,18 +363,14 @@ SCM
 Context_def::clone_scm () const
 {
   Context_def *t = new Context_def (*this);
-  SCM x = t->self_scm ();
-  scm_gc_unprotect_object (x);
-  return x;
+  return t->unprotect ();
 }
 
 SCM
 Context_def::make_scm ()
 {
   Context_def *t = new Context_def;
-  SCM x = t->self_scm ();
-  scm_gc_unprotect_object (x);
-  return x;
+  return t->unprotect ();
 }
 
 void
diff --git a/lily/context.cc b/lily/context.cc
index d1b5cd56e0..c977cc4e2e 100644
--- a/lily/context.cc
+++ b/lily/context.cc
@@ -67,7 +67,7 @@ Context::add_context (Context *t)
     {
       t->init_ = true;
 
-      scm_gc_unprotect_object (ts);
+      t->unprotect ();
       Context_def *td = unsmob_context_def (t->definition_);
 
       /* This cannot move before add_context (), because \override
@@ -101,11 +101,16 @@ Context::Context (Object_key const *key)
   definition_ = SCM_EOL;
 
   smobify_self ();
-  properties_scm_ = (new Scheme_hash_table)->self_scm ();
-  scm_gc_unprotect_object (properties_scm_);
+  
+  Scheme_hash_table *tab = new Scheme_hash_table;
+  properties_scm_ =   tab->unprotect ();
 
+  /*
+   UGH UGH
+   const correctness.
+  */
   if (key_)
-    scm_gc_unprotect_object (key_->self_scm ());
+    ((Object_key*)key)->unprotect ();
 }
 
 /* TODO:  this shares code with find_create_context ().  */
diff --git a/lily/folded-repeat-iterator.cc b/lily/folded-repeat-iterator.cc
index 3963c5dd4b..97dd639dd9 100644
--- a/lily/folded-repeat-iterator.cc
+++ b/lily/folded-repeat-iterator.cc
@@ -113,7 +113,7 @@ Folded_repeat_iterator::enter_alternative ()
       alternative_iter_ = s;
       alternative_iter_->construct_children ();
 
-      scm_gc_unprotect_object (s->self_scm ());
+      s->unprotect ();
     }
 }
 
diff --git a/lily/global-context-scheme.cc b/lily/global-context-scheme.cc
index 8b77fab5c6..914b1c7d3b 100644
--- a/lily/global-context-scheme.cc
+++ b/lily/global-context-scheme.cc
@@ -86,5 +86,5 @@ LY_DEFINE (ly_run_translator, "ly:run-translator",
   if (be_verbose_global)
     message (_f ("elapsed time: %.2f seconds", timer.read ()));
 
-  return scm_gc_unprotect_object (trans->self_scm ());
+  return trans->unprotect ();
 }
diff --git a/lily/grob.cc b/lily/grob.cc
index d91e62342a..b43ed15409 100644
--- a/lily/grob.cc
+++ b/lily/grob.cc
@@ -67,7 +67,9 @@ Grob::Grob (SCM basicprops,
     We always get a new key object for a new grob.
   */
   if (key_)
-    scm_gc_unprotect_object (key_->self_scm ());
+    {
+      ((Object_key*)key_)->unprotect ();
+    }
   SCM meta = get_property ("meta");
   if (scm_is_pair (meta))
     {
@@ -137,7 +139,9 @@ Grob::Grob (Grob const &s, int copy_index)
 
   smobify_self ();
   if (key_)
-    scm_gc_unprotect_object (key_->self_scm ());
+    {
+      ((Object_key*)key_)->unprotect ();
+    }
 }
 
 Grob::~Grob ()
diff --git a/lily/include/ly-smobs.icc b/lily/include/ly-smobs.icc
index 45ba7ebf2d..3a02164952 100644
--- a/lily/include/ly-smobs.icc
+++ b/lily/include/ly-smobs.icc
@@ -51,7 +51,7 @@
   {									\
     CL *s = (CL *) SCM_CELL_WORD_1 (ses);				\
     delete s;								\
-    scm_gc_unregister_collectable_memory (s, sizeof (CL), #CL " smob");	\
+    /*    scm_gc_unregister_collectable_memory (s, sizeof (CL), #CL " smob"); */ \
     return SMOB_FREE_RETURN_VAL (CL);					\
   }									\
 									\
@@ -64,20 +64,30 @@
     CL *ptr = new CL (*this);						\
     SCM s;								\
     s = scm_cons (SCM_PACK (CL::smob_tag_), SCM_PACK (ptr));		\
-    scm_gc_register_collectable_memory ((CL *)this, sizeof (CL), #CL " smob"); \
+    /*    scm_gc_register_collectable_memory ((CL *)this, sizeof (CL), #CL " smob");*/ \
 									\
     return s;								\
   }
 
 #define IMPLEMENT_SMOBS(CL)						\
   IMPLEMENT_BASE_SMOBS (CL)						\
-    void								\
+  void								\
   CL::smobify_self ()							\
   {									\
-    SCM s = unprotected_smobify_self ();				\
-    scm_gc_protect_object (s);						\
+    self_scm_ = unprotected_smobify_self ();				\
+    protection_cons_ = SCM_EOL;\
+    protect();\
+  }\
+  void\
+  CL::protect(){					\
+    protect_smob (self_scm_, &protection_cons_);\
+  }\
+  SCM\
+  CL::unprotect ()\
+  {\
+    unprotect_smob (&protection_cons_);\
+    return self_scm_;\
   }									\
-									\
   SCM									\
   CL::unprotected_smobify_self ()					\
   {									\
@@ -92,7 +102,7 @@
     SCM s;								\
     SCM_NEWSMOB (s, CL::smob_tag_, this);				\
     self_scm_ = s;							\
-    scm_gc_register_collectable_memory (this, sizeof (CL), #CL " smob"); \
+    /* scm_gc_register_collectable_memory (this, sizeof (CL), #CL " smob");*/ \
     return s;								\
   }
 
diff --git a/lily/include/music-iterator.hh b/lily/include/music-iterator.hh
index 29d67bbeb8..6d2587e577 100644
--- a/lily/include/music-iterator.hh
+++ b/lily/include/music-iterator.hh
@@ -97,9 +97,8 @@ bool is_child_context (Context *me, Context *child);
 			     (),					\
 			     "")					\
   {									\
-    SCM val = (new Class)->self_scm ();					\
-    scm_gc_unprotect_object (val);					\
-    return val;								\
+    Class *c = (new Class);\
+    return c->unprotect();\
   }
 
 DECLARE_UNSMOB (Music_iterator, iterator);
diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh
index c563f6df19..429aca960b 100644
--- a/lily/include/smobs.hh
+++ b/lily/include/smobs.hh
@@ -120,7 +120,10 @@
   private:					\
   void smobify_self ();				\
   SCM self_scm_;				\
+  SCM protection_cons_; \
   public:					\
+  SCM unprotect();\
+  void protect();\
   SCM self_scm () const { return self_scm_; }	\
   private:
 
@@ -133,5 +136,8 @@
 
 #define DECLARE_TYPE_P(CL) extern SCM CL ## _type_p_proc
 
+void protect_smob (SCM smob, SCM *prot_cons);
+void unprotect_smob (SCM *prot_cons);
+
 #endif /* SMOBS_HH */
 
diff --git a/lily/key-engraver.cc b/lily/key-engraver.cc
index b1fee20684..d5b4c3acb7 100644
--- a/lily/key-engraver.cc
+++ b/lily/key-engraver.cc
@@ -107,6 +107,7 @@ Key_engraver::try_music (Music *ev)
 void
 Key_engraver::acknowledge_clef (Grob_info info)
 {
+  (void)info;
   SCM c = get_property ("createKeyOnClefChange");
   if (to_boolean (c))
     {
@@ -117,6 +118,7 @@ Key_engraver::acknowledge_clef (Grob_info info)
 void
 Key_engraver::acknowledge_bar_line (Grob_info info)
 {
+  (void)info;
   if (scm_is_pair (get_property ("keySignature")))
     {
       create_key (true);
diff --git a/lily/lily-parser-scheme.cc b/lily/lily-parser-scheme.cc
index 5563f7dea5..b25888d689 100644
--- a/lily/lily-parser-scheme.cc
+++ b/lily/lily-parser-scheme.cc
@@ -118,7 +118,7 @@ LY_DEFINE (ly_parse_file, "ly:parse-file",
       parser->parse_file (init, file_name, out_file);
 
       bool error = parser->error_level_;
-      scm_gc_unprotect_object (parser->self_scm ());
+      parser->unprotect ();
       parser = 0;
       if (error)
 	/* TODO: pass renamed input file too.  */
@@ -139,7 +139,7 @@ LY_DEFINE (ly_parse_string, "ly:parse-string",
   sources.set_path (&global_path);
   Lily_parser *parser = new Lily_parser (&sources);
   parser->parse_string (ly_scm2string (ly_code));
-  scm_gc_unprotect_object (parser->self_scm ());
+  parser->unprotect ();
   parser = 0;
 
   return SCM_UNSPECIFIED;
@@ -152,7 +152,7 @@ LY_DEFINE (ly_clone_parser, "ly:clone-parser",
   Lily_parser *parser = unsmob_lily_parser (parser_smob);
   Lily_parser *clone = new Lily_parser (*parser);
 
-  return scm_gc_unprotect_object (clone->self_scm ());
+  return clone->unprotect ();
 }
 
 LY_DEFINE (ly_parser_define, "ly:parser-define!",
diff --git a/lily/lily-parser.cc b/lily/lily-parser.cc
index 2c39ea6da3..08fae1ad64 100644
--- a/lily/lily-parser.cc
+++ b/lily/lily-parser.cc
@@ -33,7 +33,7 @@ Lily_parser::Lily_parser (Sources *sources)
   smobify_self ();
 
   lexer_ = new Lily_lexer (sources_);
-  scm_gc_unprotect_object (lexer_->self_scm ());
+  lexer_->unprotect ();
 }
 
 Lily_parser::Lily_parser (Lily_parser const &src)
@@ -47,7 +47,7 @@ Lily_parser::Lily_parser (Lily_parser const &src)
   if (src.lexer_)
     lexer_ = new Lily_lexer (*src.lexer_);
 
-  scm_gc_unprotect_object (lexer_->self_scm ());
+  lexer_->unprotect ();
 }
 
 Lily_parser::~Lily_parser ()
diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc
index 14b084780b..b016e6e5aa 100644
--- a/lily/music-iterator.cc
+++ b/lily/music-iterator.cc
@@ -91,7 +91,7 @@ Music_iterator::get_static_get_iterator (Music *m)
 	p = new Simple_music_iterator;
 
       iter = p->self_scm ();
-      scm_gc_unprotect_object (iter);
+      p->unprotect ();
     }
 
   p->music_ = m;
diff --git a/lily/music-scheme.cc b/lily/music-scheme.cc
index e2e4c73d1f..f898ba8f6a 100644
--- a/lily/music-scheme.cc
+++ b/lily/music-scheme.cc
@@ -71,9 +71,7 @@ LY_DEFINE (ly_make_music, "ly:make-music",
 	   "for creating music objects. ")
 {
   Music *ms = new Music (props);
-  SCM s = ms->self_scm ();
-  scm_gc_unprotect_object (s);
-  return s;
+  return ms->unprotect ();
 }
 
 /* todo: property args */
@@ -112,8 +110,8 @@ LY_DEFINE (ly_music_deep_copy, "ly:music-deep-copy",
   SCM copy = m;
   if (unsmob_music (m))
     {
-      copy = unsmob_music (m)->clone ()->self_scm ();
-      scm_gc_unprotect_object (copy);
+      Music * mcopy = unsmob_music (m)->clone ();
+      copy = mcopy->unprotect ();
     }
   else if (scm_is_pair (m))
     copy = scm_cons (ly_music_deep_copy (scm_car (m)),
diff --git a/lily/music.cc b/lily/music.cc
index 942e2dbc24..5ce63556ba 100644
--- a/lily/music.cc
+++ b/lily/music.cc
@@ -320,8 +320,9 @@ make_music_by_name (SCM sym)
   SCM rv = scm_call_1 (make_music_proc, sym);
 
   /* UGH. */
-  scm_gc_protect_object (rv);
-  return unsmob_music (rv);
+  Music *m = unsmob_music (rv);
+  m->protect ();
+  return m;
 }
 
 
diff --git a/lily/object-key-dumper-scheme.cc b/lily/object-key-dumper-scheme.cc
index 3a3d77575c..972b63175b 100644
--- a/lily/object-key-dumper-scheme.cc
+++ b/lily/object-key-dumper-scheme.cc
@@ -16,9 +16,7 @@ LY_DEFINE (ly_make_dumper, "ly:make-dumper",
 	   "Create a key dumper. ")
 {
   Object_key_dumper *u = new Object_key_dumper ();
-  SCM x = u->self_scm ();
-  scm_gc_unprotect_object (x);
-  return x;
+  return u->unprotect ();
 }
 
 LY_DEFINE (ly_dumper_definitions, "ly:dumper-definitions",
diff --git a/lily/object-key-undumper-scheme.cc b/lily/object-key-undumper-scheme.cc
index 713659eea4..7e31b8ceb8 100644
--- a/lily/object-key-undumper-scheme.cc
+++ b/lily/object-key-undumper-scheme.cc
@@ -26,9 +26,7 @@ LY_DEFINE (ly_make_undumper, "ly:make-undumper",
 	   "Create a key undumper. ")
 {
   Object_key_undumper *u = new Object_key_undumper ();
-  SCM x = u->self_scm ();
-  scm_gc_unprotect_object (x);
-  return x;
+  return u->unprotect ();
 }
 
 LY_DEFINE (ly_undumper_lookup, "ly:undumper-lookup",
diff --git a/lily/object-key-undumper.cc b/lily/object-key-undumper.cc
index 59bcaa65b6..2004c3b2b8 100644
--- a/lily/object-key-undumper.cc
+++ b/lily/object-key-undumper.cc
@@ -72,7 +72,7 @@ Object_key_undumper::parse_contents (SCM contents)
 
       Object_key *k = Object_key::undump (new_key);
       keys_[number] = k;
-      scm_gc_unprotect_object (k->self_scm ());
+      k->unprotect ();
     }
 }
 
diff --git a/lily/output-def-scheme.cc b/lily/output-def-scheme.cc
index f71e15926f..6e3af7194f 100644
--- a/lily/output-def-scheme.cc
+++ b/lily/output-def-scheme.cc
@@ -59,9 +59,9 @@ LY_DEFINE (ly_output_def_clone, "ly:output-def-clone",
 {
   Output_def *op = unsmob_output_def (def);
   SCM_ASSERT_TYPE (op, def, SCM_ARG1, __FUNCTION__, "Output definition");
-  SCM s = op->clone ()->self_scm ();
-  scm_gc_unprotect_object (s);
-  return s;
+
+  Output_def *clone =  op->clone ();
+  return clone->unprotect ();
 }
 
 LY_DEFINE (ly_output_description, "ly:output-description",
@@ -104,7 +104,7 @@ LY_DEFINE (ly_make_output_def, "ly:make-output-def",
 	   "Make a output def.")
 {
   Output_def *bp = new Output_def ;
-  return scm_gc_unprotect_object (bp->self_scm ());
+  return bp->unprotect ();
 }
 
 LY_DEFINE (ly_paper_get_font, "ly:paper-get-font", 2, 0, 0,
diff --git a/lily/paper-book.cc b/lily/paper-book.cc
index 08e378b41e..79b4597464 100644
--- a/lily/paper-book.cc
+++ b/lily/paper-book.cc
@@ -239,7 +239,7 @@ Paper_book::add_score_title (SCM header)
     {
       Paper_system *ps = new Paper_system (title, true);
       systems_ = scm_cons (ps->self_scm (), systems_);
-      scm_gc_unprotect_object (ps->self_scm ());
+      ps->unprotect ();
       set_system_penalty (ps, header);
     }
 }
@@ -259,7 +259,7 @@ Paper_book::systems ()
       set_system_penalty (ps, header_);
 
       systems_ = scm_cons (ps->self_scm (), systems_);
-      scm_gc_unprotect_object (ps->self_scm ());
+      ps->unprotect ();
     }
 
   SCM page_properties
@@ -315,7 +315,7 @@ Paper_book::systems ()
 	  // FIXME: title=true?
 	  Paper_system *ps = new Paper_system (*unsmob_stencil (t), true);
 	  systems_ = scm_cons (ps->self_scm (), systems_);
-	  scm_gc_unprotect_object (ps->self_scm ());
+	  ps->unprotect ();
 	  // FIXME: figure out penalty.
 	  //set_system_penalty (ps, scores_[i].header_);
 	}
diff --git a/lily/paper-def.cc b/lily/paper-def.cc
index 2048ec2170..0ef9ddbb11 100644
--- a/lily/paper-def.cc
+++ b/lily/paper-def.cc
@@ -60,7 +60,7 @@ find_scaled_font (Output_def *mod, Font_metric *f, Real m)
   SCM val = Modified_font_metric::make_scaled_font_metric (f, lookup_mag);
 
   sizes = scm_acons (scm_make_real (lookup_mag), val, sizes);
-  scm_gc_unprotect_object (val);
+  unsmob_metrics (val)->unprotect ();
   scm_hashq_set_x (font_table, f->self_scm (), sizes);
   return unsmob_metrics (val);
 }
@@ -100,8 +100,9 @@ scale_output_def (Output_def *o, Real amount)
 {
   SCM proc = ly_lily_module_constant ("scale-layout");
   SCM new_pap = scm_call_2 (proc, o->self_scm (), scm_double2num (amount));
-  scm_gc_protect_object (new_pap);
 
-  return unsmob_output_def (new_pap);
+  o = unsmob_output_def (new_pap);
+  o->protect ();
+  return o;
 }
 
diff --git a/lily/paper-outputter-scheme.cc b/lily/paper-outputter-scheme.cc
index fe9c0a82ce..9c753f9b49 100644
--- a/lily/paper-outputter-scheme.cc
+++ b/lily/paper-outputter-scheme.cc
@@ -36,7 +36,7 @@ LY_DEFINE (ly_make_paper_outputter, "ly:make-paper-outputter",
   progress_indication ("\n");
   Paper_outputter *po = new Paper_outputter (port, f);
 
-  scm_gc_unprotect_object (po->self_scm ());
+  po->unprotect ();
   return po->self_scm ();
 }
 
diff --git a/lily/paper-score.cc b/lily/paper-score.cc
index 98b734a653..87b94f1531 100644
--- a/lily/paper-score.cc
+++ b/lily/paper-score.cc
@@ -54,7 +54,7 @@ Paper_score::typeset_system (System *system)
   systems_ = scm_cons (system->self_scm (), systems_);
   system->pscore_ = this;
 
-  scm_gc_unprotect_object (system->self_scm ());
+  system->unprotect ();
 }
 
 Array<Column_x_positions>
diff --git a/lily/parser.yy b/lily/parser.yy
index b83df69529..d7c87327f8 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -163,7 +163,8 @@ make_chord (SCM pitch, SCM dur, SCM modification_list)
 {
 	SCM chord_ctor = ly_lily_module_constant ("construct-chord");
 	SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
-	scm_gc_protect_object (ch);
+
+	unsmob_music (ch)->protect();	
 	return ch;
 }
 
@@ -363,7 +364,6 @@ parser.yy:352.8-24: warning: symbol `"\\<"' used more than once as a literal str
 %token HYPHEN "--"
 
 %token CHORDMODIFIERS
-%token COMMANDSPANREQUEST
 %token LYRIC_MARKUP
 %token MULTI_MEASURE_REST
 %token SCM_T
@@ -447,7 +447,7 @@ parser.yy:352.8-24: warning: symbol `"\\<"' used more than once as a literal str
 %type <music> chord_body
 %type <music> chord_body_element
 %type <music> command_element
-%type <music> command_req
+%type <music> command_event
 %type <music> context_change
 %type <music> direction_less_event
 %type <music> direction_reqd_event
@@ -577,20 +577,20 @@ toplevel_expression:
 		Book *book = $1;
 		SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
 		scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
- 		scm_gc_unprotect_object (book->self_scm ());
+		book->unprotect ();
 	}
 	| score_block {
 		Score *score = $1;
 		
 		SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
 		scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
- 		scm_gc_unprotect_object (score->self_scm ());
+		score->unprotect ();
 	}
 	| toplevel_music {
 		Music *music = $1;
 		SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
 		scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
- 		scm_gc_unprotect_object (music->self_scm ());
+		music->unprotect (); 
 	}
 	| full_markup {
 		SCM proc = THIS->lexer_->lookup_identifier ("toplevel-text-handler");
@@ -608,7 +608,7 @@ toplevel_expression:
 			id = ly_symbol2scm ("$defaultlayout");
 
 		THIS->lexer_->set_identifier (id, od->self_scm ());
-		scm_gc_unprotect_object (od->self_scm ());
+		od->unprotect();
 	}
 	;
 
@@ -671,22 +671,22 @@ all objects can be unprotected as soon as they're here.
 identifier_init:
 	score_block {
 		$$ = $1->self_scm ();
-		scm_gc_unprotect_object ($$);
+		$1->unprotect ();
 	}
 	| output_def {
 		$$ = $1->self_scm ();
-		scm_gc_unprotect_object ($$);
+		$1->unprotect ();
 	}
 	| context_def_spec_block {
 		$$ = $1;
 	}
 	| Music  {
 		$$ = $1->self_scm ();
-		scm_gc_unprotect_object ($$);
+		$1->unprotect();
 	}
 	| post_event {
 		$$ = $1->self_scm ();
-		scm_gc_unprotect_object ($$);
+		$1->unprotect();
 	}
 	| number_expression {
  		$$ = $1;
@@ -753,17 +753,17 @@ book_body:
 		$$ = new Book;
 		$$->set_spot (@$);
 		$$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
-		scm_gc_unprotect_object ($$->paper_->self_scm ());
+		$$->paper_->unprotect ();
 		$$->header_ = THIS->lexer_->lookup_identifier ("$globalheader"); 
 	}
 	| book_body paper_block {
 		$$->paper_ = $2;
-		scm_gc_unprotect_object ($2->self_scm ());
+		$2->unprotect ();
 	}
 	| book_body score_block {
 		SCM s = $2->self_scm ();
 		$$->add_score (s);
-		scm_gc_unprotect_object (s);
+		$2->unprotect();
 	}
 	| book_body full_markup {
 		$$->add_score ($2);
@@ -789,13 +789,13 @@ score_block:
 score_body:
 	Music {
 		SCM m = $1->self_scm ();
-		scm_gc_unprotect_object (m);
+		$1->unprotect();
 		SCM scorify = ly_lily_module_constant ("scorify-music");
 		SCM score = scm_call_2 (scorify, m, THIS->self_scm ());
 
-		// pass ownernship to C++ again. 
-		scm_gc_protect_object (score);
+		// pass ownernship to C++ again.
 		$$ = unsmob_score (score);
+		$$->protect ();
 		$$->set_spot (@$);
 	}
 	| SCORE_IDENTIFIER {
@@ -818,7 +818,7 @@ score_body:
 		{
 			$$->defs_.push ($2);
 		}
-		scm_gc_unprotect_object ($2->self_scm ());
+		$2->unprotect ();
 	}
 	| score_body error {
 		$$->error_found_ = true;
@@ -878,7 +878,7 @@ output_def_body:
 		THIS->lexer_->push_initial_state ();
 	}
 	| output_def_head '{' OUTPUT_DEF_IDENTIFIER 	{
-		scm_gc_unprotect_object ($1->self_scm ());
+		$1->unprotect ();
 		Output_def *o = unsmob_output_def ($3);
 		o->input_origin_.set_spot (@$);
 		$$ = o;
@@ -900,7 +900,7 @@ output_def_body:
 		int m = scm_to_int ($2->get_property ("metronome-count"));
 		Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
 		set_tempo ($$, d->get_length (), m);
-		scm_gc_unprotect_object ($2->self_scm ());
+		$2->unprotect ();
 	}
 	| output_def_body error {
 
@@ -929,7 +929,7 @@ Music_list:
 	| Music_list Music {
 		SCM s = $$;
  		SCM c = scm_cons ($2->self_scm (), SCM_EOL);
-		scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
+		$2->unprotect (); /* UGH */
 
 		if (scm_is_pair (scm_cdr (s)))
 			scm_set_cdr_x (scm_cdr (s), c); /* append */
@@ -946,7 +946,7 @@ Music_list:
 		m->set_property ("error-found", SCM_BOOL_T);
 		SCM s = $$;
  		SCM c = scm_cons (m->self_scm (), SCM_EOL);
-		scm_gc_unprotect_object (m->self_scm ()); /* UGH */
+		m->unprotect (); /* UGH */
 
 		if (scm_is_pair (scm_cdr (s)))
 			scm_set_cdr_x (scm_cdr (s), c); /* append */
@@ -989,12 +989,12 @@ Repeated_music:
 		SCM proc = ly_lily_module_constant ("make-repeated-music");
 
 		SCM mus = scm_call_1 (proc, $2);
-		scm_gc_protect_object (mus); // UGH.
 		Music *r = unsmob_music (mus);
+		r->protect ();
 		if (beg)
 			{
 			r-> set_property ("element", beg->self_scm ());
-			scm_gc_unprotect_object (beg->self_scm ());
+			beg->unprotect ();
 			}
 		r->set_property ("repeat-count", scm_int2num (max (times, 1)));
 
@@ -1107,11 +1107,11 @@ Generic_prefix_music_scm:
 	}
 	| MUSIC_FUNCTION_MUSIC Music {
 		$$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
-		scm_gc_unprotect_object ($2->self_scm ());
+		$2->unprotect ();
 	}
 	| MUSIC_FUNCTION_SCM_MUSIC embedded_scm Music {
 		$$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
-		scm_gc_unprotect_object ($3->self_scm ());
+		$3->unprotect ();
 	}
 	| MUSIC_FUNCTION_SCM_SCM embedded_scm embedded_scm {
 		$$ = scm_list_4 ($1, make_input (@$), $2, $3);
@@ -1121,25 +1121,25 @@ Generic_prefix_music_scm:
 	}
 	| MUSIC_FUNCTION_MARKUP_MUSIC full_markup Music {
 		$$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
-		scm_gc_unprotect_object ($3->self_scm ());
+		$3->unprotect ();
 	}
 	| MUSIC_FUNCTION_MARKUP_MARKUP full_markup full_markup {
 		$$ = scm_list_4 ($1, make_input (@$), $2, $3);
 	}
 	| MUSIC_FUNCTION_MUSIC_MUSIC Music Music {
 		$$ = scm_list_4 ($1, make_input (@$), $2->self_scm (), $3->self_scm ());
-		scm_gc_unprotect_object ($2->self_scm ());
-		scm_gc_unprotect_object ($3->self_scm ());
+		$2->unprotect ();
+		$3->unprotect ();
 	}
 	| MUSIC_FUNCTION_SCM_MUSIC_MUSIC embedded_scm Music Music {
 		$$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
-		scm_gc_unprotect_object ($4->self_scm ());
-		scm_gc_unprotect_object ($3->self_scm ());
+		$4->unprotect ();
+		$3->unprotect ();
 	}
 	| MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC full_markup Music Music {
 		$$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
-		scm_gc_unprotect_object ($3->self_scm ());
-		scm_gc_unprotect_object ($4->self_scm ());
+		$3->unprotect ();
+		$4->unprotect ();
 	}
 	;
 
@@ -1167,7 +1167,7 @@ Generic_prefix_music:
 		if (unsmob_music (m))
 			{
 			$$ = unsmob_music (m);
-			scm_gc_protect_object (m);
+			$$->protect ();
 			}
 		else
 			{
@@ -1206,7 +1206,7 @@ Prefix_composite_music:
 		$$->set_spot (@$);
 
 		$$->set_property ("element", mp->self_scm ());
-		scm_gc_unprotect_object (mp->self_scm ());
+		mp->unprotect();
 		$$->set_property ("numerator", scm_int2num (n));
 		$$->set_property ("denominator", scm_int2num (d));
 		$$->compress (Moment (Rational (n,d)));
@@ -1221,7 +1221,7 @@ Prefix_composite_music:
 
 		p->transpose (pitch_interval (from, to));
 		$$->set_property ("element", p->self_scm ());
-		scm_gc_unprotect_object (p->self_scm ());
+		p->unprotect();
 	}
 	| mode_changing_head Grouped_music_list {
 		if ($1 == ly_symbol2scm ("chords"))
@@ -1229,7 +1229,7 @@ Prefix_composite_music:
 		  Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
 		  chm->set_property ("element", $2->self_scm ());
 		  $$ = chm;
-		  scm_gc_unprotect_object ($2->self_scm ());
+		  $2->unprotect();
 		}
 		else
 		{
@@ -1244,7 +1244,7 @@ Prefix_composite_music:
 		{
 		  Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
 		  chm->set_property ("element", $$->self_scm ());
-		  scm_gc_unprotect_object ($$->self_scm ());
+		  $$->unprotect();
 		  $$ = chm;
 		}
 		THIS->lexer_->pop_state ();
@@ -1321,14 +1321,14 @@ relative_music:
 		Music *m = $3;
 		Pitch start = *unsmob_pitch ($2);
 		$$ = make_music_relative (start, m);
-		scm_gc_unprotect_object (m->self_scm ());
+		m->unprotect();
 	}
 	| RELATIVE Composite_music {
 		Music *m = $2;
 
 		Pitch middle_c (0, 0, 0);
 		$$ = make_music_relative (middle_c, m);
-		scm_gc_unprotect_object (m->self_scm ());
+		m->unprotect();
 	}
 	;
 
@@ -1377,7 +1377,7 @@ re_rhythmed_music:
 		all->set_property ("elements", scm_cons (voice->self_scm (),
 			lst));
 		$$ = all;
-		scm_gc_unprotect_object (voice->self_scm ());
+		voice->unprotect ();
 	}
 	| LYRICSTO simple_string {
 		THIS->lexer_->push_lyric_state ();
@@ -1386,7 +1386,7 @@ re_rhythmed_music:
 		Music *music = $4;
 		SCM name = $2;
 		$$ = make_lyric_combine_music (name, music);
-		scm_gc_unprotect_object (music->self_scm ());
+		music->unprotect();
 	}
 	;
 
@@ -1619,7 +1619,7 @@ chord_body_elements:
 	/* empty */ 		{ $$ = SCM_EOL; }
 	| chord_body_elements chord_body_element {
 		$$ = scm_cons ($2->self_scm (), $1);
-		scm_gc_unprotect_object ($2->self_scm ());
+		$2->unprotect ();
 	}
 	;
 
@@ -1671,15 +1671,15 @@ add_quote:
 		SCM adder = ly_lily_module_constant ("add-quotable");
 		
 		scm_call_2 (adder, $2, $3->self_scm ());
-		scm_gc_unprotect_object ($3->self_scm ());
+		$3->unprotect();
 	}
 	;
 
 command_element:
-	command_req {
+	command_event {
 		$$ = MY_MAKE_MUSIC ("EventChord");
 		$$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
-		scm_gc_unprotect_object ($1->self_scm ());
+		$1->unprotect();
 
 		$$-> set_spot (@$);
 		$1-> set_spot (@$);
@@ -1703,7 +1703,7 @@ command_element:
 
 		$$ = MY_MAKE_MUSIC ("EventChord");
 		$$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
-		scm_gc_unprotect_object (m->self_scm ());
+		m->unprotect();
 		$$->set_spot (@$);
 	}
 	| E_BRACKET_CLOSE {
@@ -1714,7 +1714,7 @@ command_element:
 		$$ = MY_MAKE_MUSIC ("EventChord");
 		$$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
 		$$->set_spot (@$);
-		scm_gc_unprotect_object (m->self_scm ());
+		m->unprotect ();
 	}
 	| E_BACKSLASH {
 		$$ = MY_MAKE_MUSIC ("VoiceSeparator");
@@ -1762,15 +1762,15 @@ command_element:
 		SCM proc = ly_lily_module_constant ("make-clef-set");
 
 		SCM result = scm_call_1 (proc, $2);
-		scm_gc_protect_object (result);
 		$$ = unsmob_music (result);
+		$$->protect ();
 	}
 	| TIME_T fraction  {
 		SCM proc = ly_lily_module_constant ("make-time-signature-set");
 
 		SCM result = scm_apply_2   (proc, scm_car ($2), scm_cdr ($2), SCM_EOL);
-		scm_gc_protect_object (result);
 		$$ = unsmob_music (result);
+		$$->protect ();
 	}
 	| MARK scalar {
 		SCM proc = ly_lily_module_constant ("make-mark-set");
@@ -1778,10 +1778,11 @@ command_element:
 		SCM result = scm_call_1 (proc, $2);
 		scm_gc_protect_object (result);
 		$$ = unsmob_music (result);
+		$$->protect ();
 	}
 	;
 
-command_req:
+command_event:
 	E_TILDE {
 		$$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
 	}
@@ -1820,12 +1821,12 @@ post_events:
 	| post_events post_event {
 		$2->set_spot (@2);
 		$$ = scm_cons ($2->self_scm (), $$);
-		scm_gc_unprotect_object ($2->self_scm ());
+		$2->unprotect ();
 	}
 	| post_events tagged_post_event {
 		$2 -> set_spot (@2);
 		$$ = scm_cons ($2->self_scm (), $$);
-		scm_gc_unprotect_object ($2->self_scm ());
+		$2->unprotect ();
 	}
 	;
 
@@ -2181,15 +2182,14 @@ bass_figure:
 	FIGURE_SPACE {
 		Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
 		$$ = bfr->self_scm ();
-		scm_gc_unprotect_object ($$);
+		bfr->unprotect ();
 	}
 	| bass_number  {
 		Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
 		$$ = bfr->self_scm ();
 
 		bfr->set_property ("figure", $1);
-
-		scm_gc_unprotect_object ($$);
+		bfr->unprotect ();
 	}
 	| bass_figure bass_mod {
 		Music *m = unsmob_music ($1);
@@ -2269,7 +2269,7 @@ simple_element:
 
 		Music *v = MY_MAKE_MUSIC ("EventChord");
 		v->set_property ("elements", scm_list_1 (n->self_scm ()));
-		scm_gc_unprotect_object (n->self_scm ());
+		n->unprotect ();
 
 		v->set_spot (@$);
 		n->set_spot (@$);
@@ -2282,7 +2282,7 @@ simple_element:
 
 		Music *v = MY_MAKE_MUSIC ("EventChord");
 		v->set_property ("elements", scm_list_1 (n->self_scm ()));
-		scm_gc_unprotect_object (n->self_scm ());
+		n->unprotect ();
 		v->set_spot (@$);
 		n->set_spot (@$);
 		$$ = v;
@@ -2313,27 +2313,27 @@ simple_element:
 		velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
 		velt->set_spot (@$);
 
-		scm_gc_unprotect_object (ev->self_scm ());
+		ev->unprotect();
 
  		$$ = velt;
 	}
 	| MULTI_MEASURE_REST optional_notemode_duration  	{
 		SCM proc = ly_lily_module_constant ("make-multi-measure-rest");
 		SCM mus = scm_call_2 (proc, $2, make_input (@$));
-		scm_gc_protect_object (mus);
 		$$ = unsmob_music (mus);
+		$$->protect ();
 	}
 	
 	| lyric_element optional_notemode_duration 	{
 		if (!THIS->lexer_->is_lyric_state ())
 			THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
 
-		Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
-		lreq->set_property ("text", $1);
-		lreq->set_property ("duration",$2);
-		lreq->set_spot (@$);
+		Music *levent = MY_MAKE_MUSIC ("LyricEvent");
+		levent->set_property ("text", $1);
+		levent->set_property ("duration",$2);
+		levent->set_spot (@$);
 		Music *velt = MY_MAKE_MUSIC ("EventChord");
-		velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
+		velt->set_property ("elements", scm_list_1 (levent->self_scm ()));
 
 		$$= velt;
 	}
@@ -2604,7 +2604,7 @@ simple_markup:
 	} '{' score_body '}' {
 		Score * sc = $4;
 		$$ = scm_list_2 (ly_lily_module_constant ("score-markup"), sc->self_scm ());
-		scm_gc_unprotect_object (sc->self_scm ());
+		sc->unprotect ();
 		THIS->lexer_->pop_state ();
 	}
 	| MARKUP_HEAD_SCM0 embedded_scm {
@@ -2771,7 +2771,7 @@ context_spec_music (SCM type, SCM id, Music *m, SCM ops)
 	Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
 
 	csm->set_property ("element", m->self_scm ());
-	scm_gc_unprotect_object (m->self_scm ());
+	m->unprotect ();
 
 	csm->set_property ("context-type",
 		scm_is_symbol (type) ? type : scm_string_to_symbol (type));
diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc
index 5c83021be4..adafbe64be 100644
--- a/lily/score-engraver.cc
+++ b/lily/score-engraver.cc
@@ -77,7 +77,7 @@ Score_engraver::initialize ()
     }
 
   pscore_ = new Paper_score (dynamic_cast<Output_def *> (context ()->get_output_def ()));
-  scm_gc_unprotect_object (pscore_->self_scm ()); 
+  pscore_->unprotect (); 
 
   SCM props = updated_grob_properties (context (), ly_symbol2scm ("System"));
 
diff --git a/lily/score-performer.cc b/lily/score-performer.cc
index 833a8575de..c2d3c731e7 100644
--- a/lily/score-performer.cc
+++ b/lily/score-performer.cc
@@ -103,7 +103,7 @@ void
 Score_performer::initialize ()
 {
   performance_ = new Performance;
-  scm_gc_unprotect_object (performance_->self_scm ());
+  performance_->unprotect ();
   performance_->midi_ = context ()->get_output_def ();
 
   Translator_group::initialize ();
diff --git a/lily/score-scheme.cc b/lily/score-scheme.cc
index 6ef6d216ec..df8b920956 100644
--- a/lily/score-scheme.cc
+++ b/lily/score-scheme.cc
@@ -25,9 +25,7 @@ LY_DEFINE (ly_make_score, "ly:make-score",
   Score *score = new Score;
   score->set_music (music);
 
-  SCM self = score->self_scm ();
-  scm_gc_unprotect_object (self);
-  return self;
+  return score->unprotect ();
 }
 
 LY_DEFINE (ly_score_embedded_format, "ly:score-embedded-format",
@@ -58,8 +56,7 @@ LY_DEFINE (ly_score_embedded_format, "ly:score-embedded-format",
     return SCM_BOOL_F;
 
   score_def = score_def->clone ();
-  SCM prot = score_def->self_scm ();
-  scm_gc_unprotect_object (prot);
+  SCM prot = score_def->unprotect ();
 
   /* TODO: SCORE_DEF should be scaled according to OD->parent_ or OD
      itself. */
@@ -113,7 +110,7 @@ LY_DEFINE (ly_score_process, "ly:score-process",
 			 header, basename, key->self_scm ());
     }
 
-  scm_gc_unprotect_object (key->self_scm ());
+  key->unprotect ();
   return SCM_UNSPECIFIED;
 }
 
diff --git a/lily/score.cc b/lily/score.cc
index 7bae956296..c3fcf3ae6f 100644
--- a/lily/score.cc
+++ b/lily/score.cc
@@ -74,14 +74,20 @@ Score::Score (Score const &s)
   smobify_self ();
 
   Music *m = unsmob_music (s.music_);
-  music_ = m ? m->clone ()->self_scm () : SCM_EOL;
-  scm_gc_unprotect_object (music_);
+  if (m)
+    {
+      Music *mclone =  m->clone ();
+      music_ = mclone->unprotect ();
+    }
+  else
+    music_ = SCM_EOL;
 
+  
   for (int i = 0, n = s.defs_.size (); i < n; i++)
     {
       Output_def * copy = s.defs_[i]->clone ();
       defs_.push (copy);
-      scm_gc_unprotect_object (copy->self_scm ());
+      copy->unprotect ();
     }
   header_ = ly_make_anonymous_module (false);
   if (ly_is_module (s.header_))
@@ -108,14 +114,14 @@ default_rendering (SCM music, SCM outdef,
       Real scale = scm_to_double (bpd->c_variable ("outputscale"));
 
       Output_def *def = scale_output_def (unsmob_output_def (outdef), scale);
-      scaled_def = def->self_scm ();
+      Output_def *bdef = scale_output_def (bpd, scale);
+      def->parent_ = bdef;
 
-      scaled_bookdef = scale_output_def (bpd, scale)->self_scm ();
-      unsmob_output_def (scaled_def)->parent_
-	= unsmob_output_def (scaled_bookdef);
+      scaled_def = def->self_scm ();
+      scaled_bookdef = bdef->self_scm();
 
-      scm_gc_unprotect_object (scaled_bookdef);
-      scm_gc_unprotect_object (scaled_def);
+      def->unprotect();
+      bdef->unprotect ();  
     }
 
   SCM context = ly_run_translator (music, scaled_def, key);
@@ -137,7 +143,7 @@ default_rendering (SCM music, SCM outdef,
       paper_book->add_score (systems);
 
       paper_book->classic_output (outname);
-      scm_gc_unprotect_object (paper_book->self_scm ());
+      paper_book->unprotect ();
     }
 
   scm_remember_upto_here_1 (scaled_def);
@@ -170,8 +176,7 @@ Score::book_rendering (Output_def *layoutbook,
   int outdef_count = defs_.size ();
 
   Object_key *key = new Lilypond_general_key (book_key, user_key_, 0);
-  SCM scm_key = key->self_scm ();
-  scm_gc_unprotect_object (scm_key);
+  SCM scm_key = key->unprotect ();
 
   for (int i = 0; !i || i < outdef_count; i++)
     {
@@ -182,8 +187,8 @@ Score::book_rendering (Output_def *layoutbook,
 	{
 	  def = scale_output_def (def, scale);
 	  def->parent_ = layoutbook;
-	  scaled = def->self_scm ();
-	  scm_gc_unprotect_object (scaled);
+
+	  scaled = def->unprotect ();
 	}
 
       /* TODO: fix or junk --no-layout.  */
@@ -217,7 +222,8 @@ Score::set_music (SCM music)
     {
       m->origin ()->error (_ ("errors found, ignoring music expression"));
 
-      this->error_found_ = this->error_found_ || to_boolean (m->get_property ("error-found"));
+      this->error_found_ = this->error_found_
+	|| to_boolean (m->get_property ("error-found"));
     }
 
   if (this->error_found_)
diff --git a/lily/system.cc b/lily/system.cc
index 4adadc6e58..9bd31d26c3 100644
--- a/lily/system.cc
+++ b/lily/system.cc
@@ -83,7 +83,7 @@ System::typeset_grob (Grob *elem)
     {
       elem->pscore_ = pscore_;
       all_elements_->add (elem);
-      scm_gc_unprotect_object (elem->self_scm ());
+      elem->unprotect ();
     }
 }
 
@@ -397,7 +397,7 @@ System::get_paper_system ()
   pl->break_before_penalty_
     = robust_scm2double (break_point->get_property ("page-penalty"), 0.0);
 
-  return scm_gc_unprotect_object (pl->self_scm ());
+  return pl->unprotect ();
 }
 
 Link_array<Item>
diff --git a/lily/translator-ctors.cc b/lily/translator-ctors.cc
index 7f9f41bce7..874402d490 100644
--- a/lily/translator-ctors.cc
+++ b/lily/translator-ctors.cc
@@ -38,7 +38,7 @@ add_translator (Translator *t)
   SCM k = ly_symbol2scm (classname (t));
   global_translator_dict->set (k, t->self_scm ());
 
-  scm_gc_unprotect_object (t->self_scm ());
+  t->unprotect ();
 }
 
 Translator *
diff --git a/lily/tweak-registration.cc b/lily/tweak-registration.cc
index 9604c5f202..4b5f244832 100644
--- a/lily/tweak-registration.cc
+++ b/lily/tweak-registration.cc
@@ -18,7 +18,7 @@ Tweak_registry::Tweak_registry ()
   undumper_ = 0;
   smobify_self ();
   undumper_ = new Object_key_undumper ();
-  scm_gc_unprotect_object (undumper_->self_scm ());
+  undumper_->unprotect ();
 }
 
 Tweak_registry::~Tweak_registry ()
@@ -30,7 +30,7 @@ Tweak_registry::clear ()
 {
   tweaks_.clear ();
   undumper_ = new Object_key_undumper ();
-  scm_gc_unprotect_object (undumper_->self_scm ());
+  undumper_->unprotect ();
 }
 
 void