Branch: Tag:

2000-03-16

2000-03-16 10:38:24 by Martin Stjernholm <mast@lysator.liu.se>

Fixed som reference bugs. Added more debug facilities to hunt down
leaking objects.

Rev: server/etc/modules/RXML.pmod/module.pmod:1.79

2:   //!   //! Created 1999-07-30 by Martin Stjernholm.   //! - //! $Id: module.pmod,v 1.78 2000/03/13 00:42:04 mast Exp $ + //! $Id: module.pmod,v 1.79 2000/03/16 10:38:24 mast Exp $      //! Kludge: Must use "RXML.refs" somewhere for the whole module to be   //! loaded correctly.
18:      #include <config.h>    + #ifdef RXML_OBJ_DEBUG + # ifndef OBJ_COUNT_DEBUG + # define OBJ_COUNT_DEBUG + # endif + mapping(string:int) object_markers = ([]); + class ObjectMarker + { +  string id; +  void create (string _id) {werror ("create %s\n", id = _id); object_markers[id] = 1;} +  void destroy() {werror ("destroy %s\n", id); m_delete (object_markers, id);} + } + # define MARK_OBJECT(marker) \ +  private ObjectMarker marker = ObjectMarker (sprintf ("%O", this_object())) + string report_leaks() + { +  string res = "leaks: " + sort (indices (object_markers)) * ", " + "\n"; +  object_markers = ([]); +  return res; + } + #else + # define MARK_OBJECT(marker) + #endif +    #ifdef OBJ_COUNT_DEBUG   // This debug mode gives every object a unique number in the   // _sprintf() string.
228:    {    return "RXML.Tag(" + [string] this_object()->name + COMMA_CNT (__count) + ")";    } +  +  MARK_OBJECT (__object_marker);   }      
526:    return name ? "RXML.TagSet(" + name + COMMA_CNT (__count) + ")" :    "RXML.TagSet" + PAREN_CNT (__count);    } +  +  MARK_OBJECT (__object_marker);   }      TagSet empty_tag_set;
997:    }       multiset(Tag) runtime_tags = (<>); -  -  class NewRuntimeTags -  { -  multiset(Tag) add_tags = (<>); -  multiset(Tag|string) remove_tags = (<>); -  } +     NewRuntimeTags new_runtime_tags;    // Used to record the result of any add_runtime_tag() and    // remove_runtime_tag() calls since the last time the parsers ran.
1031:       string _sprintf() {return "RXML.Context" + PAREN_CNT (__count);}    +  MARK_OBJECT (__object_marker); +    #ifdef MODULE_DEBUG   #if constant (thread_create)    Thread.Thread in_use;
1040:   #endif   }    + static class NewRuntimeTags + { +  multiset(Tag) add_tags = (<>); +  multiset(Tag|string) remove_tags = (<>); + } +    class Backtrace   //! The object used to throw RXML errors.   {
1074:    txt += current_var ? " | &" + current_var + ";\n" : "";    for (Frame f = frame; f; f = f->up) {    if (f->tag) txt += " | <" + f->tag->name; +  else if (f->tag_name) txt += " | <" + f->tag_name;    else if (!f->up) break;    else txt += " | <(unknown tag)";    if (f->args)
2034:    {    return "RXML.Frame(" + (tag && [string] tag->name) + COMMA_CNT (__count) + ")";    } +  +  MARK_OBJECT (__object_marker);   }      
2360:    DECLARE_CNT (__count);       string _sprintf() {return "RXML.Parser" + PAREN_CNT (__count);} +  +  MARK_OBJECT (__object_marker);   }      
2619:    // ^^^ Using interpreter lock to here.    if (pco->clone_parser)    p = pco->clone_parser->clone (ctx, this_object(), tset, @_parser_args); -  else if ((p = _parser_prog (0, this_object(), tset, @_parser_args))->clone) +  else if ((p = _parser_prog (ctx, this_object(), tset, @_parser_args))->clone) {    // pco->clone_parser might already be initialized here due    // to race, but that doesn't matter. -  +  p->context = 0; // Don't leave the context in the clone master.    p = (pco->clone_parser = p)->clone (ctx, this_object(), tset, @_parser_args);    } -  +  }       else {    // ^^^ Using interpreter lock to here.    pco = PCacheObj();    pco->tag_set_gen = tset->generation;    _p_cache[tset] = pco; // Might replace an object due to race, but that's ok. -  if ((p = _parser_prog (0, this_object(), tset, @_parser_args))->clone) +  if ((p = _parser_prog (ctx, this_object(), tset, @_parser_args))->clone) {    // pco->clone_parser might already be initialized here due    // to race, but that doesn't matter. -  +  p->context = 0; // Don't leave the context in the clone master.    p = (pco->clone_parser = p)->clone (ctx, this_object(), tset, @_parser_args);    } -  +  }       if (ctx->tag_set == tset && p->add_runtime_tag && sizeof (ctx->runtime_tags))    foreach (indices (ctx->runtime_tags), Tag tag)
2653:    // Relying on interpreter lock here.    p = clone_parser->clone (ctx, this_object(), @_parser_args);    -  else if ((p = _parser_prog (0, this_object(), @_parser_args))->clone) +  else if ((p = _parser_prog (ctx, this_object(), @_parser_args))->clone) {    // clone_parser might already be initialized here due to race,    // but that doesn't matter. -  +  p->context = 0; // Don't leave the context in the clone master.    p = (clone_parser = p)->clone (ctx, this_object(), @_parser_args);    } -  +  }       p->_parent = parent;    return p;
2679:    if (dont_switch_ctx) p->finish (in); // Optimize the job in p->write_end().    else p->write_end (in);    res = p->eval(); -  if (p->reset) +  if (p->reset) { +  p->context = p->_parent = 0;    if (_p_cache) {    // Relying on interpreter lock in this block.    PCacheObj pco = _p_cache[tag_set || ctx->tag_set];
2692:    free_parser = p;    }    } +  }    if (ctx->type_check) type_check (res);    return res;    }
2711:    private Parser free_parser; // The list of objects to reuse with Parser.reset().       // Cache used for parsers that depend on the tag set. -  private class PCacheObj -  { -  int tag_set_gen; -  Parser clone_parser; -  Parser free_parser; -  } +     /*private*/ mapping(TagSet:PCacheObj) _p_cache;       DECLARE_CNT (__count);       string _sprintf() {return "RXML.Type" + PAREN_CNT (__count);} -  +  +  MARK_OBJECT (__object_marker);   }    -  + static class PCacheObj + { +  int tag_set_gen; +  Parser clone_parser; +  Parser free_parser; + }    -  +    static class TAny   //! A completely unspecified nonsequential type.   {
2856:    DECLARE_CNT (__count);    string _sprintf()    {return "RXML.VarRef(" + scope + "." + var + COMMA_CNT (__count) + ")";} +  MARK_OBJECT (__object_marker);   }      class PCode
2895:    DECLARE_CNT (__count);       string _sprintf() {return "RXML.PCode" + PAREN_CNT (__count);} +  +  MARK_OBJECT (__object_marker);   }      
2916:   //! stream that takes unparsed strings and splits them into tokens   //! which are queued. Intended to be inherited in a Parser class.   { -  private class Link -  { -  array data; -  Link next; -  } +     private Link head = Link(); // Last link is an empty eof marker.    private Link tail = head;    private int next_token = 0;
3024:    DECLARE_CNT (__count);       string _sprintf() {return "RXML.ScanStream" + PAREN_CNT (__count);} +  +  MARK_OBJECT (__object_marker);   }    -  + private class Link + { +  array data; +  Link next; + }    -  +    // Various internal kludges.      static function(string,mixed...:void) _run_error = run_error;