From: Han-Wen Nienhuys Date: Thu, 24 Feb 2000 16:15:46 +0000 (+0100) Subject: patch::: 1.3.26.hwn3 X-Git-Tag: release/1.3.27~1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=06aaa8f02f831cfc94fcac1fb99eeded3b3cc6cc;p=lilypond.git patch::: 1.3.26.hwn3 * Plug memory leak in Paper_outputter::output_{String,Real,int}_def() * Plug memory leak in Score_engraver::set_columns () * Plug memory leak in Scheme_hash_table::set() * Plug memory leak in Score_element::molecule_extent () --- Generated by hanwen@cs.uu.nl, From = lilypond-1.3.26.hwn2, To = lilypond-1.3.26.hwn3 usage cd lilypond-source-dir; patch -E -p1 < lilypond-1.3.26.hwn3.diff Patches do not contain automatically generated files or (urg) empty directories, i.e., you should rerun autoconf, configure --- diff --git a/CHANGES b/CHANGES index 5a4ec57e68..eae8018ba1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,20 @@ -1.3.26.jcn2 +--- ../lilypond-1.3.26.hwn2/CHANGES Thu Feb 24 13:52:54 2000 +++ b/CHANGES Thu Feb 24 17:15:46 2000 +@@ -2,6 +2,14 @@ + 1.3.26.hwn2 + =========== + +* Plug memory leak in Paper_outputter::output_{String,Real,int}_def() + +* Plug memory leak in Score_engraver::set_columns () + +* Plug memory leak in Scheme_hash_table::set() + +* Plug memory leak in Score_element::molecule_extent () + + * Bugfix: don't crash if a slur doesn't span anything. + + * Bugfix: don't crash if doing beams without a staff symbol.1.3.26.jcn2 =========== * Bugfix: font used in volta-spanner calculation. diff --git a/VERSION b/VERSION index 8fac086972..6ea5f58835 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 PATCH_LEVEL=26 -MY_PATCH_LEVEL=jcn2 +MY_PATCH_LEVEL=hwn3 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/flower/include/hash-table.hh b/flower/include/hash-table.hh index 491feb3df7..aec7ae31af 100644 --- a/flower/include/hash-table.hh +++ b/flower/include/hash-table.hh @@ -151,8 +151,8 @@ public: } /** - Find and return element. If #s# is not in the table, create an entry in the table, and init - */ + Find and return element. If #s# is not in the table, create an + entry in the table, and init */ V& elem (K s) { int l; diff --git a/lily/all-font-metrics.cc b/lily/all-font-metrics.cc index 89936e5f0f..88f46c07a9 100644 --- a/lily/all-font-metrics.cc +++ b/lily/all-font-metrics.cc @@ -39,11 +39,10 @@ All_font_metrics::find_afm (String name) afm_p->name_ = ly_symbol2scm (name.ch_C ()); progress_indication ("]"); - afm_p_dict_[sname] = afm_p->self_scm_; - scm_unprotect_object (afm_p->self_scm_); + afm_p_dict_.set (sname,afm_p->self_scm_); } - return dynamic_cast (unsmob_metrics (afm_p_dict_[sname])); + return dynamic_cast (unsmob_metrics (afm_p_dict_.get (sname))); } Scaled_font_metric * @@ -58,12 +57,11 @@ All_font_metrics::find_scaled (String nm, int m) { Font_metric *f = find_font (nm); s = new Scaled_font_metric (f, m); - scaled_p_dict_[sname] = s->self_scm_; + scaled_p_dict_.set (sname, s->self_scm_); fm = s; - scm_unprotect_object (s->self_scm_); } else - fm = unsmob_metrics (scaled_p_dict_[sname]); + fm = unsmob_metrics (scaled_p_dict_.get (sname)); return dynamic_cast (fm); } @@ -83,12 +81,11 @@ All_font_metrics::find_tfm (String name) tfm_p->name_ = ly_symbol2scm (name.ch_C( )); progress_indication ("]"); - tfm_p_dict_[sname] = tfm_p->self_scm_; - scm_unprotect_object (tfm_p->self_scm_); + tfm_p_dict_.set (sname, tfm_p->self_scm_); } return - dynamic_cast (unsmob_metrics (tfm_p_dict_[sname])); + dynamic_cast (unsmob_metrics (tfm_p_dict_.get(sname))); } diff --git a/lily/include/scm-hash.hh b/lily/include/scm-hash.hh index a0382d0446..3bc455f88a 100644 --- a/lily/include/scm-hash.hh +++ b/lily/include/scm-hash.hh @@ -17,9 +17,18 @@ /** auto resizing hash table. This should come from GUILE. */ -class Scheme_hash_table : public Hash_table +class Scheme_hash_table : private Hash_table { -public: +public: + // bool elem_b (SCM k) const; + Hash_table::try_retrieve; + Hash_table::elem_b; + /** + WARNING: putting something in assumes responsibility for cleaning + up. */ + void set (SCM k, SCM v); + SCM get (SCM k); + Scheme_hash_table (); void operator = (Scheme_hash_table const &); Scheme_hash_table (Scheme_hash_table const &); diff --git a/lily/paper-def.cc b/lily/paper-def.cc index 233e2075d2..2f60f9e14c 100644 --- a/lily/paper-def.cc +++ b/lily/paper-def.cc @@ -81,7 +81,7 @@ Paper_def::get_realvar (SCM s) const Interval Paper_def::line_dimensions_int (int n) const { - SCM s = default_properties_ [ly_symbol2scm ("margin-shape")]; + SCM s = default_properties_.get (ly_symbol2scm ("margin-shape")); if (!gh_pair_p (s)) { Real lw = get_var ("linewidth"); diff --git a/lily/paper-outputter.cc b/lily/paper-outputter.cc index 9e9a57d9b1..40a4b966fe 100644 --- a/lily/paper-outputter.cc +++ b/lily/paper-outputter.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include "dimensions.hh" #include "dictionary-iter.hh" @@ -132,6 +133,21 @@ Paper_outputter::output_scheme (SCM scm) } +int +count_cells (SCM s) +{ + if (Atom * a = unsmob_atom (s)) + { + return 2 + count_cells (a->func_); + } + else if (gh_pair_p (s)) + { + return 2 + count_cells (gh_car (s))+ count_cells (gh_cdr (s)); + } + else + return 1; +} + void Paper_outputter::dump_onto (Paper_stream *ps) { @@ -206,7 +222,10 @@ Paper_outputter::dump_onto (Paper_stream *ps) *ps << c; free (c); } - } + cout << "\nCells in use: " << scm_cells_allocated << endl; + cout << "protects " << scm_ilength (scm_protects) << endl; + + } } void @@ -283,7 +302,7 @@ Paper_outputter::output_Real_def (String k, Real v) SCM_UNDEFINED); output_scheme (scm); - gh_define (k.ch_l (), gh_double2scm (v)); + // gh_define (k.ch_l (), gh_double2scm (v)); } void @@ -296,7 +315,7 @@ Paper_outputter::output_String_def (String k, String v) SCM_UNDEFINED); output_scheme (scm); - gh_define (k.ch_l (), ly_str02scm (v.ch_l ())); + // gh_define (k.ch_l (), ly_str02scm (v.ch_l ())); } void @@ -308,7 +327,7 @@ Paper_outputter::output_int_def (String k, int v) SCM_UNDEFINED); output_scheme (scm); - gh_define (k.ch_l (), gh_int2scm (v)); + // gh_define (k.ch_l (), gh_int2scm (v)); } diff --git a/lily/scm-hash.cc b/lily/scm-hash.cc index 4d417416f1..ca0920fd42 100644 --- a/lily/scm-hash.cc +++ b/lily/scm-hash.cc @@ -6,6 +6,7 @@ (c) 1999 Han-Wen Nienhuys */ +#include #include "scm-hash.hh" #include "hash-table-iter.hh" @@ -63,6 +64,9 @@ int Scheme_hash_table::print_smob (SCM s, SCM p, scm_print_state*) { assert (SMOB_IS_TYPE_B (Scheme_hash_table, s)); + char str[1000]; + sprintf (str, "# i (*me); i.ok(); i++) { @@ -71,10 +75,23 @@ Scheme_hash_table::print_smob (SCM s, SCM p, scm_print_state*) scm_display (i.val (), p); scm_puts ("\n",p); } + scm_puts ("> ",p); return 1; } +void +Scheme_hash_table::set (SCM k, SCM v) +{ + elem (k ) = v; + scm_unprotect_object (v); +} + +SCM +Scheme_hash_table::get (SCM k) +{ + return elem (k); +} Scheme_hash_table::~Scheme_hash_table( ) diff --git a/lily/score-element.cc b/lily/score-element.cc index 42a7d083c2..5a46ce458c 100644 --- a/lily/score-element.cc +++ b/lily/score-element.cc @@ -164,7 +164,11 @@ Score_element::molecule_extent(Dimension_cache const *c) { Score_element *s = dynamic_cast(c->element_l()); Molecule*m = s->do_brew_molecule_p(); - return m->extent()[c->axis ()]; + + Interval iv = m->extent()[c->axis ()]; + + delete m; + return iv; } diff --git a/lily/score-element.cc.orig b/lily/score-element.cc.orig new file mode 100644 index 0000000000..42a7d083c2 --- /dev/null +++ b/lily/score-element.cc.orig @@ -0,0 +1,649 @@ +/* + score-elem.cc -- implement Score_element + + source file of the GNU LilyPond music typesetter + + (c) 1997--2000 Han-Wen Nienhuys +*/ + + +#include + +#include "group-interface.hh" +#include "misc.hh" +#include "paper-score.hh" +#include "paper-def.hh" +#include "lookup.hh" +#include "molecule.hh" +#include "score-element.hh" +#include "debug.hh" +#include "spanner.hh" +#include "line-of-score.hh" +#include "item.hh" +#include "paper-column.hh" +#include "molecule.hh" +#include "misc.hh" +#include "paper-outputter.hh" +#include "dimension-cache.hh" +#include "side-position-interface.hh" +#include "item.hh" + +Score_element::Score_element() +{ + output_p_ =0; + dim_cache_[X_AXIS] = new Dimension_cache; + dim_cache_[Y_AXIS] = new Dimension_cache; + dim_cache_[X_AXIS]->elt_l_ = dim_cache_[Y_AXIS]->elt_l_ = this; + + used_b_ = false; + + dim_cache_[X_AXIS]->set_callback (molecule_extent); + dim_cache_[Y_AXIS]->set_callback (molecule_extent); + used_b_ = false; + pscore_l_=0; + lookup_l_ =0; + status_i_ = 0; + self_scm_ = SCM_EOL; + original_l_ = 0; + element_property_alist_ = SCM_EOL; + + smobify_self (); + + + set_elt_property ("dependencies", SCM_EOL); +} + +SCM ly_deep_copy (SCM); + +SCM +ly_deep_copy (SCM l) +{ + if (gh_pair_p (l)) + { + return gh_cons (ly_deep_copy (gh_car (l)), ly_deep_copy (gh_cdr (l))); + } + else + return l; +} + + +Score_element::Score_element (Score_element const&s) +{ + dim_cache_[X_AXIS] = new Dimension_cache (*s.dim_cache_[X_AXIS]); + dim_cache_[Y_AXIS] = new Dimension_cache (*s.dim_cache_[Y_AXIS]); + dim_cache_[X_AXIS]->elt_l_ = dim_cache_[Y_AXIS]->elt_l_ = this; + + self_scm_ = SCM_EOL; + used_b_ = true; + original_l_ =(Score_element*) &s; + + /* + should protect because smobify_self () might trigger GC. + */ + SCM onstack = ly_deep_copy (s.element_property_alist_); + element_property_alist_ = onstack; + + output_p_ =0; + status_i_ = s.status_i_; + lookup_l_ = s.lookup_l_; + pscore_l_ = s.pscore_l_; + + smobify_self (); +} + +Score_element::~Score_element() +{ + assert (!output_p_); + assert (status_i_ >=0); + status_i_ = -1; + + delete dim_cache_[X_AXIS]; + delete dim_cache_[Y_AXIS]; +} + + +Real +Score_element::get_real (String s) const +{ + return gh_scm2double (get_elt_property (s)); +} + +void +Score_element::set_real (String s, Real r) +{ + set_elt_property (s, gh_double2scm (r)); +} + +// should also have one that takes SCM arg. +SCM +Score_element::get_elt_property (String nm) const +{ + SCM sym = ly_symbol2scm (nm.ch_C()); + SCM s = scm_assq(sym, element_property_alist_); + + if (s != SCM_BOOL_F) + return gh_cdr (s); + + if (pscore_l_) + { + SCM sym2 = ly_symbol2scm ((name () + ("::" + nm)).ch_C()); + SCM val; + + // should probably check for Type::sym as well. + Paper_def * p= pscore_l_->paper_l_; + if (p->default_properties_.try_retrieve (sym2, &val)) + return val; + else if (p->default_properties_.try_retrieve (sym, &val)) + return val; + } + + return SCM_UNDEFINED; +} + +SCM +Score_element::remove_elt_property (String key) +{ + SCM s = get_elt_property (key); + SCM sym = ly_symbol2scm (key.ch_C()); + element_property_alist_ = scm_assq_remove_x (element_property_alist_, sym); + return s; +} + +/* + UGH. assoc vs. assq + */ +void +Score_element::set_elt_property (String k, SCM v) +{ + SCM s = ly_symbol2scm (k.ch_C( )); + element_property_alist_ = scm_assoc_set_x (element_property_alist_, s, v); +} + +Interval +Score_element::molecule_extent(Dimension_cache const *c) +{ + Score_element *s = dynamic_cast(c->element_l()); + Molecule*m = s->do_brew_molecule_p(); + return m->extent()[c->axis ()]; +} + + +void +Score_element::print() const +{ +#ifndef NPRINT + DEBUG_OUT << classname(this) << "{\n"; + + if (flower_dstream && !flower_dstream->silent_b ("Score_element")) + ly_display_scm (element_property_alist_); + + if (original_l_) + DEBUG_OUT << "Copy "; + do_print(); + + DEBUG_OUT << "}\n"; +#endif +} + +Paper_def* +Score_element::paper_l () const +{ + return pscore_l_ ? pscore_l_->paper_l_ : 0; +} + +Lookup const * +Score_element::lookup_l () const +{ + if (!lookup_l_) + { + Score_element * urg = (Score_element*)this; + SCM sz = urg->remove_elt_property ("fontsize"); + int i = (gh_number_p (sz)) + ? gh_scm2int (sz) + : 0; + + urg->lookup_l_ = (Lookup*)pscore_l_->paper_l_->lookup_l (i); + } + return lookup_l_; +} + +void +Score_element::add_processing() +{ + assert (status_i_ >=0); + if (status_i_) + return; + status_i_ ++; + +#if 0 + /* + UGH. UGH. UGH. + */ + if (get_elt_property ("self-alignment-X") != SCM_UNDEFINED + && !dim_cache_[X_AXIS]->off_callback_l_) + { + dim_cache_[X_AXIS]->off_callbacks_.push (Side_position_interface::aligned_on_self); + } + + if (get_elt_property ("self-alignment-Y") != SCM_UNDEFINED + && !dim_cache_[X_AXIS]->off_callback_l_) + + { + dim_cache_[Y_AXIS]->set_offset_callback (Side_position_interface::aligned_on_self); + } +#endif + + do_add_processing(); +} + +void +Score_element::calculate_dependencies (int final, int busy, + Score_element_method_pointer funcptr) +{ + assert (status_i_ >=0); + + if (status_i_ >= final) + return; + + assert (status_i_!= busy); + status_i_= busy; + + Link_array dependency_arr = + Group_interface__extract_elements (this, (Score_element*)0, "dependencies"); + + for (int i=0; i < dependency_arr.size(); i++) + dependency_arr[i]->calculate_dependencies (final, busy, funcptr); + + Link_array extra (get_extra_dependencies()); + for (int i=0; i < extra.size(); i++) + extra[i]->calculate_dependencies (final, busy, funcptr); + + (this->*funcptr)(); + status_i_= final; +} + +void +Score_element::output_processing () +{ + if (to_boolean (get_elt_property ("transparent"))) + return; + + // we're being silly here. + if (output_p_) + delete output_p_; + + output_p_ = do_brew_molecule_p (); + Offset o (relative_coordinate (0, X_AXIS), relative_coordinate (0, Y_AXIS)); + + SCM s = get_elt_property ("extra-offset"); + if (gh_pair_p (s)) + { + Real il = paper_l ()->get_var ("interline"); + o[X_AXIS] += il * gh_scm2double (gh_car (s)); + o[Y_AXIS] += il * gh_scm2double (gh_cdr (s)); + } + + pscore_l_->outputter_l_->output_molecule (output_p_, + o, + classname(this)); + + delete output_p_; + output_p_ =0; +} + +/* + + VIRTUAL STUBS + + */ +void +Score_element::do_break_processing() +{ +} + +void +Score_element::do_post_processing() +{ +} + +void +Score_element::do_breakable_col_processing() +{ + handle_prebroken_dependencies(); +} + +void +Score_element::do_pre_processing() +{ +} + +void +Score_element::do_space_processing () +{ +} + +void +Score_element::do_add_processing() +{ +} + + + +Molecule* +Score_element::do_brew_molecule_p() const +{ + SCM glyph = get_elt_property ("glyph"); + if (gh_string_p (glyph)) + { + Molecule*output = new Molecule (lookup_l ()->afm_find (String (ly_scm2string (glyph)))); + + return output; + } + else + { + Interval emp; + emp.set_empty (); + Molecule a (lookup_l ()->fill (Box (emp,emp))); + return new Molecule (a); + } +} + + +Line_of_score * +Score_element::line_l() const +{ + return 0; +} + +void +Score_element::add_dependency (Score_element*e) +{ + if (e) + { + Group_interface gi (this, "dependencies"); + gi.add_element (e); + } + else + programming_error ("Null dependency added"); +} + + + + +/** + Do break substitution in S, using CRITERION. Return new value. + CRITERION is either a SMOB pointer to the desired line, or a number + representing the break direction. */ +SCM +Score_element::handle_broken_smobs (SCM s, SCM criterion) +{ + again: + + + Score_element *sc = unsmob_element ( s); + if (sc) + { + if (criterion == SCM_UNDEFINED) + return SCM_UNDEFINED; + else if (gh_number_p (criterion)) + { + Item * i = dynamic_cast (sc); + Direction d = to_dir (criterion); + if (i && i->break_status_dir () != d) + { + Item *br = i->find_broken_piece (d); + return (br) ? br->self_scm_ : SCM_UNDEFINED; + } + } + else + { + Score_element * ln = unsmob_element ( criterion); + Line_of_score * line = dynamic_cast (ln); + Score_element * br =0; + Line_of_score * dep_line = sc->line_l (); + if (dep_line != line) + { + br = sc->find_broken_piece (line); + return (br) ? br->self_scm_ : SCM_UNDEFINED; + } + if (!dep_line) + return SCM_UNDEFINED; + } + } + else if (gh_pair_p (s)) + { + /* + UGH! breaks on circular lists. + */ + SCM car = handle_broken_smobs (gh_car (s), criterion); + SCM cdr = gh_cdr (s); + + if (car == SCM_UNDEFINED + && (gh_pair_p (cdr) || cdr == SCM_EOL)) + { + /* + This is tail-recursion, ie. + + return handle_broken_smobs (cdr, criterion); + + We don't want to rely on the compiler to do this. */ + s = cdr; + goto again; + } + + gh_set_car_x (s, car); + gh_set_cdr_x (s, handle_broken_smobs (cdr, criterion)); + return s; + } + return s; +} + +void +Score_element::handle_broken_dependencies() +{ + Line_of_score *line = line_l(); + element_property_alist_ = handle_broken_smobs (element_property_alist_, + line ? line->self_scm_ : SCM_UNDEFINED); + + if (!line) + return; +} + + +/* + TODO: cleanify. + */ +void +Score_element::handle_prebroken_dependencies() +{ + if (Item*i =dynamic_cast (this)) + { + element_property_alist_ + = handle_broken_smobs (element_property_alist_, + gh_int2scm (i->break_status_dir ())); + } +} + + + + + +Link_array +Score_element::get_extra_dependencies() const +{ + Link_array empty; + return empty; +} + +bool +Score_element::linked_b() const +{ + return used_b_; +} + +void +Score_element::do_print () const +{ +} + +Score_element* +Score_element::find_broken_piece (Line_of_score*) const +{ + return 0; +} + + + +void +Score_element::translate_axis (Real y, Axis a) +{ + dim_cache_[a]->translate (y); +} + +Real +Score_element::relative_coordinate (Score_element const*e, Axis a) const +{ + return dim_cache_[a]->relative_coordinate (e ? e->dim_cache_[a] : 0); +} + +Score_element * +Score_element::common_refpoint (Score_element const* s, Axis a) const +{ + Dimension_cache *dim = dim_cache_[a]->common_refpoint (s->dim_cache_[a]); + return dim ? dim->element_l () : 0; +} + +void +Score_element::set_empty (Axis a) +{ + dim_cache_[a]->callback_l_ =0; +} + +bool +Score_element::empty_b (Axis a)const +{ + return !dim_cache_[a]->callback_l_; +} + +Interval +Score_element::extent (Axis a) const +{ + Dimension_cache const * d = dim_cache_[a]; + + return d->get_dim (); +} + + +Score_element* +Score_element::parent_l (Axis a) const +{ + Dimension_cache*d= dim_cache_[a]->parent_l_; + return d ? d->elt_l_ : 0; +} + +Score_element * +Score_element::common_refpoint (Link_array gs, Axis a) const +{ + Dimension_cache * common = dim_cache_[a]; + for (int i=0; i < gs.size (); i++) + { + common = common->common_refpoint (gs[i]->dim_cache_[a]); + } + + return common->element_l (); +} + +char const * +Score_element::name () const +{ + return classname (this); +} + + +void +Score_element::set_parent (Score_element *g, Axis a) +{ + dim_cache_[a]->parent_l_ = g ? g->dim_cache_[a]: 0; +} + +void +Score_element::fixup_refpoint () +{ + for (int a = X_AXIS; a < NO_AXES; a ++) + { + Axis ax = (Axis)a; + Score_element * par = parent_l (ax); + + if (!par) + continue; + + if (par->line_l () != line_l ()) + { + Score_element * newpar = par->find_broken_piece (line_l ()); + set_parent (newpar, ax); + } + + if (Item * i = dynamic_cast (this)) + { + Item *pari = dynamic_cast (par); + + if (pari && i) + { + Direction my_dir = i->break_status_dir () ; + if (my_dir!= pari->break_status_dir()) + { + Item *newpar = pari->find_broken_piece (my_dir); + set_parent (newpar, ax); + } + } + } + } +} + + + +/**************************************************** + SMOB funcs + ****************************************************/ + + +#include "ly-smobs.icc" + +IMPLEMENT_SMOBS(Score_element); +IMPLEMENT_UNSMOB(Score_element, element); +SCM +Score_element::mark_smob (SCM ses) +{ + Score_element * s = SMOB_TO_TYPE (Score_element, ses); + if (s->self_scm_ != ses) + { + programming_error ("SMOB marking gone awry"); + return SCM_EOL; + } + return s->element_property_alist_; +} + +int +Score_element::print_smob (SCM s, SCM port, scm_print_state *) +{ + Score_element *sc = (Score_element *) gh_cdr (s); + + scm_puts ("#name (), port); + + // scm_puts (" properties = ", port); + // scm_display (sc->element_property_alist_, port); + scm_puts (" >", port); + return 1; +} + +void +Score_element::do_smobify_self () +{ +} + +SCM +Score_element::equal_p (SCM a, SCM b) +{ + return gh_cdr(a) == gh_cdr(b) ? SCM_BOOL_T : SCM_BOOL_F; +} diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index 812e94ff8f..8b9c53e05f 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -171,28 +171,29 @@ void Score_engraver::set_columns (Paper_column *new_command_l, Paper_column *new_musical_l) { - if (command_column_l_ && command_column_l_->linked_b()) - { - pscore_p_->add_column (command_column_l_); - scoreline_l_->add_column (command_column_l_); - } - else - command_column_l_ =0; - - if (new_command_l) - command_column_l_ = new_command_l; + Paper_column * news[] = {new_command_l, new_musical_l}; + Paper_column **current[] = {&command_column_l_, &musical_column_l_}; - if (musical_column_l_ && musical_column_l_->linked_b()) - { - pscore_p_->add_column (musical_column_l_); - scoreline_l_->add_column (musical_column_l_); - } - else - musical_column_l_ = 0; - - if (new_musical_l) + for (int i=00; i< 2; i++) { - musical_column_l_ = new_musical_l; + if (*current[i] && (*current[i])->linked_b()) + { + pscore_p_->add_column ((*current[i])); + scoreline_l_->add_column ((*current[i])); + } + else + { + *current[i] =0; + + /* + We're forgetting about this column. Dump it, and make SCM + forget it. + + (UGH.) */ + scm_unprotect_object ((*current[i])->self_scm_); + } + if (news[i]) + *current[i] = news[i]; } } diff --git a/lily/score.cc b/lily/score.cc index 3eda39de70..af396f13af 100644 --- a/lily/score.cc +++ b/lily/score.cc @@ -6,6 +6,8 @@ (c) 1997--2000 Han-Wen Nienhuys */ +#include + #include "score.hh" #include "debug.hh" #include "music-output-def.hh" @@ -22,7 +24,7 @@ Score::Score() - : Input() + : Input() { header_p_ = 0; music_p_ = 0; @@ -50,6 +52,11 @@ void Score::run_translator (Music_output_def *odef_l) { Cpu_timer timer; + scm_gc(); + cout << "\nCells in use: " << scm_cells_allocated << endl; + cout << "protects: " << scm_ilength (scm_protects) << endl; + + Global_translator * trans_p = odef_l->get_global_translator_p(); if (!trans_p) { @@ -94,6 +101,12 @@ Score::run_translator (Music_output_def *odef_l) progress_indication ("\n"); output->process(); delete output ; + + // force GC + scm_gc(); + cout << "\nCells in use: " << scm_cells_allocated <