gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog gui/Player.cpp libbase/GC.h lib...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog gui/Player.cpp libbase/GC.h lib...
Date: Fri, 15 Jun 2007 15:00:32 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/06/15 15:00:32

Modified files:
        .              : ChangeLog 
        gui            : Player.cpp 
        libbase        : GC.h Makefile.am ref_counted.h smart_ptr.h 
        plugin/klash   : klash.cpp 
        plugin/win32   : plugin.cpp 
        server         : GetterSetter.cpp GetterSetter.h Property.h 
                         PropertyList.cpp PropertyList.h 
                         as_environment.cpp as_environment.h 
                         as_function.cpp as_function.h as_object.cpp 
                         as_object.h as_value.cpp as_value.h 
                         character.cpp character.h debugger.cpp 
                         debugger.h dlist.cpp dlist.h 
                         edit_text_character.cpp edit_text_character.h 
                         font.cpp font.h fontlib.cpp gnash.h impl.cpp 
                         impl.h mouse_button_state.h movie_root.cpp 
                         movie_root.h sprite_instance.cpp 
                         sprite_instance.h swf_function.cpp 
                         swf_function.h 
        server/asobj   : Key.h Mouse.cpp Stage.cpp xmlnode.cpp 
        server/parser  : BitmapMovieDefinition.cpp 
                         BitmapMovieDefinition.h movie_def_impl.cpp 
                         movie_def_impl.h sprite_definition.cpp 
                         sprite_definition.h 
        server/vm      : ASHandlers.cpp VM.cpp VM.h 
        utilities      : processor.cpp 

Log message:
        ( A LOT OF FILES !)
                First big pass on Garbage Collection. We can now use a 
compile-time
                define (GNASH_USE_GC) to select wheter GC or RF (ref-counting) 
is
                used. By default RC is used as GC is still bogus. Next step 
would
                be improving the GC mark functions to ensure needed resources 
aren't
                prematurely deleted by the GC. See in GC.h the GcResource class
                documentation for informations about how to do taht.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3546&r2=1.3547
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/Player.cpp?cvsroot=gnash&r1=1.54&r2=1.55
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/GC.h?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/Makefile.am?cvsroot=gnash&r1=1.73&r2=1.74
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/ref_counted.h?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/smart_ptr.h?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/plugin/klash/klash.cpp?cvsroot=gnash&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/gnash/plugin/win32/plugin.cpp?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/server/GetterSetter.cpp?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/server/GetterSetter.h?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Property.h?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/server/PropertyList.cpp?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/server/PropertyList.h?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.cpp?cvsroot=gnash&r1=1.78&r2=1.79
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.h?cvsroot=gnash&r1=1.51&r2=1.52
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_function.cpp?cvsroot=gnash&r1=1.32&r2=1.33
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_function.h?cvsroot=gnash&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.cpp?cvsroot=gnash&r1=1.52&r2=1.53
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.h?cvsroot=gnash&r1=1.58&r2=1.59
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_value.cpp?cvsroot=gnash&r1=1.52&r2=1.53
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_value.h?cvsroot=gnash&r1=1.53&r2=1.54
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.cpp?cvsroot=gnash&r1=1.42&r2=1.43
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.h?cvsroot=gnash&r1=1.82&r2=1.83
http://cvs.savannah.gnu.org/viewcvs/gnash/server/debugger.cpp?cvsroot=gnash&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/gnash/server/debugger.h?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.cpp?cvsroot=gnash&r1=1.70&r2=1.71
http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.h?cvsroot=gnash&r1=1.43&r2=1.44
http://cvs.savannah.gnu.org/viewcvs/gnash/server/edit_text_character.cpp?cvsroot=gnash&r1=1.67&r2=1.68
http://cvs.savannah.gnu.org/viewcvs/gnash/server/edit_text_character.h?cvsroot=gnash&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/gnash/server/font.cpp?cvsroot=gnash&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/gnash/server/font.h?cvsroot=gnash&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/gnash/server/fontlib.cpp?cvsroot=gnash&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/gnash/server/gnash.h?cvsroot=gnash&r1=1.97&r2=1.98
http://cvs.savannah.gnu.org/viewcvs/gnash/server/impl.cpp?cvsroot=gnash&r1=1.108&r2=1.109
http://cvs.savannah.gnu.org/viewcvs/gnash/server/impl.h?cvsroot=gnash&r1=1.45&r2=1.46
http://cvs.savannah.gnu.org/viewcvs/gnash/server/mouse_button_state.h?cvsroot=gnash&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.65&r2=1.66
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.56&r2=1.57
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.286&r2=1.287
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.h?cvsroot=gnash&r1=1.118&r2=1.119
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf_function.cpp?cvsroot=gnash&r1=1.30&r2=1.31
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf_function.h?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Key.h?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Mouse.cpp?cvsroot=gnash&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Stage.cpp?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlnode.cpp?cvsroot=gnash&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/BitmapMovieDefinition.cpp?cvsroot=gnash&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/BitmapMovieDefinition.h?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/movie_def_impl.cpp?cvsroot=gnash&r1=1.71&r2=1.72
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/movie_def_impl.h?cvsroot=gnash&r1=1.43&r2=1.44
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/sprite_definition.cpp?cvsroot=gnash&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/sprite_definition.h?cvsroot=gnash&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.107&r2=1.108
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/VM.cpp?cvsroot=gnash&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/VM.h?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/utilities/processor.cpp?cvsroot=gnash&r1=1.58&r2=1.59

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.3546
retrieving revision 1.3547
diff -u -b -r1.3546 -r1.3547
--- ChangeLog   14 Jun 2007 20:28:50 -0000      1.3546
+++ ChangeLog   15 Jun 2007 15:00:25 -0000      1.3547
@@ -1,3 +1,37 @@
+       * gui/Player.cpp, libbase/GC.h, libbase/Makefile.am,
+         libbase/ref_counted.h, libbase/smart_ptr.h,
+         plugin/klash/klash.cpp, plugin/win32/plugin.cpp,
+         server/GetterSetter.cpp, server/GetterSetter.h,
+         server/Property.h, server/PropertyList.cpp,
+         server/PropertyList.h, server/as_environment.cpp,
+         server/as_environment.h, server/as_function.cpp,
+         server/as_function.h, server/as_object.cpp,
+         server/as_object.h, server/as_value.cpp,
+         server/as_value.h, server/character.cpp, server/character.h,
+         server/debugger.cpp, server/debugger.h, server/dlist.cpp,
+         server/dlist.h, server/edit_text_character.cpp,
+         server/edit_text_character.h, server/font.cpp, server/font.h,
+         server/fontlib.cpp, server/gnash.h, server/impl.cpp,
+         server/impl.h, server/mouse_button_state.h,
+         server/movie_root.cpp, server/movie_root.h,
+         server/sprite_instance.cpp, server/sprite_instance.h,
+         server/swf_function.cpp, server/swf_function.h,
+         server/asobj/Key.h, server/asobj/Mouse.cpp,
+         server/asobj/Stage.cpp, server/asobj/xmlnode.cpp,
+         server/parser/BitmapMovieDefinition.cpp,
+         server/parser/BitmapMovieDefinition.h,
+         server/parser/movie_def_impl.cpp,
+         server/parser/movie_def_impl.h,
+         server/parser/sprite_definition.cpp,
+         server/parser/sprite_definition.h, server/vm/ASHandlers.cpp,
+         server/vm/VM.cpp, server/vm/VM.h, utilities/processor.cpp:
+       First big pass on Garbage Collection. We can now use a compile-time
+       define (GNASH_USE_GC) to select wheter GC or RF (ref-counting) is
+       used. By default RC is used as GC is still bogus. Next step would
+       be improving the GC mark functions to ensure needed resources aren't
+       prematurely deleted by the GC. See in GC.h the GcResource class
+       documentation for informations about how to do taht.
+
 2007-06-14 Sandro Santilli <address@hidden>
 
        * libbase/: Makefile.am, GC.h: First draft at a garbage collector class.

Index: gui/Player.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/Player.cpp,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -b -r1.54 -r1.55
--- gui/Player.cpp      1 Jun 2007 15:01:55 -0000       1.54
+++ gui/Player.cpp      15 Jun 2007 15:00:26 -0000      1.55
@@ -126,6 +126,9 @@
 void
 Player::init()
 {
+       /// Initialize gnash core library
+       gnashInit();
+
        set_use_cache_files(false);
 
        gnash::register_fscommand_callback(fs_callback);

Index: libbase/GC.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/GC.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libbase/GC.h        14 Jun 2007 20:28:51 -0000      1.1
+++ libbase/GC.h        15 Jun 2007 15:00:26 -0000      1.2
@@ -26,6 +26,7 @@
 #include <list>
 
 // Define the following macro to enable GC verbosity 
+// Define to > 1 to have info printed about scan of already reachable objects
 #define GNASH_GC_DEBUG 1
 
 #ifdef GNASH_GC_DEBUG
@@ -92,15 +93,15 @@
 
                if ( _reachable )
                {
-#ifdef GNASH_GC_DEBUG 
-                       log_debug("Instance %p of class %s already reachable, 
setReachable doing nothing",
+#if GNASH_GC_DEBUG > 1
+                       log_debug(_("Instance %p of class %s already reachable, 
setReachable doing nothing"),
                                        (void*)this, typeid(*this).name());
 #endif
                        return;
                }
 
 #ifdef GNASH_GC_DEBUG 
-               log_debug("Instance %p of class %s set to reachable, scanning 
reachable resources from it",
+               log_debug(_("Instance %p of class %s set to reachable, scanning 
reachable resources from it"),
                                (void*)this, typeid(*this).name());
 #endif
 
@@ -134,7 +135,7 @@
        {
                assert(_reachable);
 #ifdef GNASH_GC_DEBUG 
-               log_debug("Class %s didn't override the 
markReachableResources() method", typeid(*this).name());
+               log_debug(_("Class %s didn't override the 
markReachableResources() method"), typeid(*this).name());
 #endif
        }
 
@@ -172,27 +173,50 @@
 
 public:
 
-       friend class GcResource;
+       /// Init the singleton instance using the given GcRoot
+       //
+       static GC& init(GcRoot& r);
 
-       /// Get the singleton instance of the Garbage Collector
-       static GC& getInstance()
-       {
-               static GC singleton;
-               return singleton;
-       }
+       /// Delete the singleton. You'll need to call init() again
+       /// after this call, if you want to use the singleton.
+       //
+       /// See init(GcRoot&)
+       ///
+       static void cleanup();
+
+       /// Get the singleton 
+       //
+       /// An assertion will fail if the GC has not been initialized yet.
+       /// See init(GcRoot&).
+       ///
+       static GC& get();
 
-       /// Add a root resource to use for mark scanning
+       /// Add an heap object to the list of managed collectables
        //
-       /// @param root
-       ///     A GcResource to use as a root item to scan
-       ///     during the mark phase.
+       /// The given object is expected not to be already in the
+       /// list. Failing to do so would just decrease performances
+       /// but might not be a problem. Anyway, an assertion will fail
+       /// if adding an object twice.
+       ///
+       /// PRECONDITIONS:
+       ///     - the object isn't already in this GC list.
+       ///     - the object isn't marked as reachable.
+       ///     - the object isn't managed by another GC (UNCHECKED)
        ///
-       void addRoot(GcRoot* root)
+       /// @param item
+       ///     The item to be managed by this collector.
+       ///     Can't be NULL. The caller gives up ownerhip
+       ///     of it, which will only be deleted by this GC.
+       ///
+       void addCollectable(const GcResource* item)
        {
-               assert(root);
-               _roots.push_back(root);
+               assert(item);
+               assert(! item->isReachable());
+               assert(std::find(_resList.begin(), _resList.end(), item) == 
_resList.end());
+
+               _resList.push_back(item);
 #ifdef GNASH_GC_DEBUG
-               log_debug("GC %p: root %p added, num roots: " SIZET_FMT, 
(void*)this, (void*)root, _roots.size());
+               log_debug(_("GC %p: collectable %p added, num collectables: " 
SIZET_FMT), (void*)this, (void*)item, _resList.size());
 #endif
        }
 
@@ -204,7 +228,7 @@
        void collect()
        {
 #ifdef GNASH_GC_DEBUG 
-               log_debug("Starting collector: " SIZET_FMT " roots, " SIZET_FMT 
" collectables", _roots.size(), _resList.size());
+               log_debug(_("Starting collector: " SIZET_FMT " collectables"), 
_resList.size());
 #endif // GNASH_GC_DEBUG
 
                // Mark all resources as reachable
@@ -217,17 +241,13 @@
 
 private:
 
-       /// List of collectables
-       typedef std::list<const GcResource *> ResList;
-
-       /// List of roots
-       typedef std::list<const GcRoot *> RootList;
-
-       /// Create a garbage collector
-       GC()
+       /// Create a garbage collector, using the given root
+       GC(GcRoot& root)
+               :
+               _root(root)
        {
 #ifdef GNASH_GC_DEBUG 
-               log_debug("GC %p created", (void*)this);
+               log_debug(_("GC %p created"), (void*)this);
 #endif
        }
 
@@ -235,53 +255,29 @@
        ~GC()
        {
 #ifdef GNASH_GC_DEBUG 
-               log_debug("GC %p deleted, cleaning up all managed resources", 
(void*)this);
+               log_debug(_("GC %p deleted, NOT collecting again all managed 
resources"), (void*)this);
 #endif
+
+#if 0
                for (ResList::iterator i=_resList.begin(), e=_resList.end(); 
i!=e; ++i)
                {
                        delete *i;
                }
+#endif
        }
 
-       /// Add an heap object to the list of managed collectables
-       //
-       /// The given object is expected not to be already in the
-       /// list. Failing to do so would just decrease performances
-       /// but might not be a problem. Anyway, an assertion will fail
-       /// if adding an object twice.
-       ///
-       /// PRECONDITIONS:
-       ///     - the object isn't already in this GC list.
-       ///     - the object isn't marked as reachable.
-       ///     - the object isn't managed by another GC (UNCHECKED)
-       ///
-       /// @param item
-       ///     The item to be managed by this collector.
-       ///     Can't be NULL. The caller gives up ownerhip
-       ///     of it, which will only be deleted by this GC.
-       ///
-       void addCollectable(const GcResource* item)
-       {
-               assert(item);
-               assert(! item->isReachable());
-               assert(std::find(_resList.begin(), _resList.end(), item) == 
_resList.end());
 
-               _resList.push_back(item);
-#ifdef GNASH_GC_DEBUG 
-               log_debug("GC %p: collectable %p added, num collectables: " 
SIZET_FMT, (void*)this, (void*)item, _resList.size());
-#endif
-       }
+       /// List of collectables
+       typedef std::list<const GcResource *> ResList;
+
+       /// List of roots
+       typedef std::list<const GcRoot *> RootList;
 
        /// Mark all reachable resources
        void markReachable()
        {
-               /// By marking the roots as reachable, a chain effect should be
-               /// engaged so that every reachable resource is marked
-               for (RootList::iterator i=_roots.begin(), e=_roots.end(); i!=e; 
++i)
-               {
-                       const GcRoot* root = *i;
-                       root->markReachableResources(); 
-               }
+               log_debug(_("GC %p: MARK SCAN"), (void*)this);
+               _root.markReachableResources();
        }
 
        /// Delete all unreachable objects, and mark the others unreachable 
again
@@ -289,6 +285,7 @@
        {
 #ifdef GNASH_GC_DEBUG 
                size_t deleted = 0;
+               log_debug(_("GC %p: SWEEP SCAN"), (void*)this);
 #endif
                for (ResList::iterator i=_resList.begin(), e=_resList.end(); 
i!=e; )
                {
@@ -296,6 +293,8 @@
                        if ( ! res->isReachable() )
                        {
 #ifdef GNASH_GC_DEBUG 
+                               log_debug(_("GC %p: cleanUnreachable deleting 
object %p (%s)"),
+                                               (void*)this, (void*)res, 
typeid(*res).name());
                                ++deleted;
 #endif
                                delete res;
@@ -308,16 +307,17 @@
                        }
                }
 #ifdef GNASH_GC_DEBUG 
-               log_debug("GC %p: cleanUnreachable deleted " SIZET_FMT
-                               " resources marked as unreachable",
+               log_debug(_("GC %p: cleanUnreachable deleted " SIZET_FMT
+                               " resources marked as unreachable"),
                                (void*)this, deleted);
 #endif
        }
 
        ResList _resList;
 
-       RootList _roots;
+       GcRoot& _root;
 
+       static GC* _singleton;
 };
 
 
@@ -325,7 +325,7 @@
        :
        _reachable(false)
 {
-       GC::getInstance().addCollectable(this);
+       GC::get().addCollectable(this);
 }
 
 } // namespace gnash

Index: libbase/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/libbase/Makefile.am,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -b -r1.73 -r1.74
--- libbase/Makefile.am 14 Jun 2007 20:28:51 -0000      1.73
+++ libbase/Makefile.am 15 Jun 2007 15:00:26 -0000      1.74
@@ -105,7 +105,9 @@
        zlib_adapter.cpp \
        URL.cpp \
        LoadThread.cpp \
-       FLVParser.cpp
+       FLVParser.cpp \
+       GC.cpp \
+       $(NULL)
 
 noinst_HEADERS = \
        $(LIBLTDLHEAD) \

Index: libbase/ref_counted.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/ref_counted.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- libbase/ref_counted.h       14 Jun 2007 10:57:07 -0000      1.6
+++ libbase/ref_counted.h       15 Jun 2007 15:00:26 -0000      1.7
@@ -15,7 +15,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: ref_counted.h,v 1.6 2007/06/14 10:57:07 strk Exp $ */
+/* $Id: ref_counted.h,v 1.7 2007/06/15 15:00:26 strk Exp $ */
 
 #ifndef GNASH_REF_COUNTED_H
 #define GNASH_REF_COUNTED_H
@@ -27,20 +27,36 @@
 #include "container.h"
 #include "smart_ptr.h"
 
+// Define the following macro to enable GC verbosity 
+#define GNASH_GC_DEBUG 1
+
+#ifdef GNASH_USE_GC
+# include "GC.h"
+# ifdef GNASH_GC_DEBUG
+#  include "log.h"
+#  include <typeinfo>
+# endif // GNASH_GC_DEBUG
+#endif // GNASH_USE_GC
+
 namespace gnash {
 
 /// \brief
 /// For stuff that's tricky to keep track of w/r/t ownership & cleanup.
 /// The only use for this class seems to be for putting derived
 /// classes in smart_ptr
-/// TODO: remove use of this base class in favor of using
-/// boost::shared_ptr<> ???? boost::intrusive_ptr(?)
 ///
-
+#ifdef GNASH_USE_GC
+class DSOEXPORT ref_counted : public GcResource
+#else
 class DSOEXPORT ref_counted
+#endif
 {
+
 private:
+
+#ifndef GNASH_USE_GC
        mutable int             m_ref_count;
+#endif // ndef GNASH_USE_GC
        
 protected:
 
@@ -48,16 +64,21 @@
        // must never be explicitly deleted !
        virtual ~ref_counted()
        {
+#ifndef GNASH_USE_GC
                assert(m_ref_count == 0);
+#endif // ndef GNASH_USE_GC
        }
 
 public:
        ref_counted()
+#ifndef GNASH_USE_GC
        :
        m_ref_count(0)
+#endif // ndef GNASH_USE_GC
        {
        }
 
+#ifndef GNASH_USE_GC
        void    add_ref() const
        {
                assert(m_ref_count >= 0);
@@ -68,13 +89,15 @@
        {
                assert(m_ref_count > 0);
                m_ref_count--;
-               if (m_ref_count <= 0){
+               if (m_ref_count <= 0)
+               {
                        // Delete me!
                        delete this;
                }
        }
 
        int     get_ref_count() const { return m_ref_count; }
+#endif // ndef GNASH_USE_GC
 };
 
 } // namespace gnash

Index: libbase/smart_ptr.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/smart_ptr.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- libbase/smart_ptr.h 28 May 2007 15:41:02 -0000      1.19
+++ libbase/smart_ptr.h 15 Jun 2007 15:00:26 -0000      1.20
@@ -24,7 +24,7 @@
 // although the nice thing about templates is that no particular
 // ref-counted class is mandated.
 
-/* $Id: smart_ptr.h,v 1.19 2007/05/28 15:41:02 ann Exp $ */
+/* $Id: smart_ptr.h,v 1.20 2007/06/15 15:00:26 strk Exp $ */
 
 #ifndef SMART_PTR_H
 #define SMART_PTR_H
@@ -32,6 +32,19 @@
 #include "tu_config.h"
 #include "utility.h"
 
+// Define the following macro to use garbage collecting rather
+// then ref-counting. Currenlty this would make ref_counted
+// derive from GcResource and intrusive_ptr never really messing
+// with the stored pointer (not calling add_ref/drop_ref, which would
+// be not defined for ref_counted.
+// Is is a temporary hack to allow quick switch between GC and REFCOUNT
+// mechanism till the GC is stable
+//
+//#define GNASH_USE_GC 1
+
+// TODO: if GNASH_USE_GC is defined have smart_ptr map to intrusive_ptr
+//       else have it map to gc_ptr (yet to be defined)
+
 #include <boost/intrusive_ptr.hpp>
 
 #define COMPILER_SUPPORTS_ARGUMENT_DEPENDENT_LOOKUP 1
@@ -45,14 +58,22 @@
 void
 intrusive_ptr_add_ref(T* o)
 {
+#ifndef GNASH_USE_GC
        o->add_ref();
+#else
+       UNUSED(o);
+#endif // ndef GNASH_USE_GC
 }
 
 template <class T>
 void
 intrusive_ptr_release(T* o)
 {
+#ifndef GNASH_USE_GC
        o->drop_ref();
+#else
+       UNUSED(o);
+#endif // ndef GNASH_USE_GC
 }
 
 } 

Index: plugin/klash/klash.cpp
===================================================================
RCS file: /sources/gnash/gnash/plugin/klash/klash.cpp,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- plugin/klash/klash.cpp      18 Apr 2007 09:35:41 -0000      1.27
+++ plugin/klash/klash.cpp      15 Jun 2007 15:00:26 -0000      1.28
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: klash.cpp,v 1.27 2007/04/18 09:35:41 jgilmore Exp $ */
+/* $Id: klash.cpp,v 1.28 2007/06/15 15:00:26 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -597,7 +597,6 @@
               break;
         };
         m = gnash::get_current_root();
-        gnash::delete_unused_root();
         
        movie_root* root = dynamic_cast<movie_root*>(m);
        assert(root);

Index: plugin/win32/plugin.cpp
===================================================================
RCS file: /sources/gnash/gnash/plugin/win32/plugin.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- plugin/win32/plugin.cpp     18 Apr 2007 09:35:42 -0000      1.7
+++ plugin/win32/plugin.cpp     15 Jun 2007 15:00:27 -0000      1.8
@@ -298,7 +298,6 @@
                wglMakeCurrent(mhDC, mhRC);
 
                gnash::set_current_root(m);
-               gnash::delete_unused_root();
        
                uint64_t        ticks;
                ticks = tu_timer::get_ticks();

Index: server/GetterSetter.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/GetterSetter.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- server/GetterSetter.cpp     28 May 2007 15:41:04 -0000      1.7
+++ server/GetterSetter.cpp     15 Jun 2007 15:00:27 -0000      1.8
@@ -59,15 +59,23 @@
 {
        if ( s._getter != _getter )
        {
+#ifndef GNASH_USE_GC
                _getter->drop_ref();
+#endif // ndef GNASH_USE_GC
                _getter = s._getter;
+#ifndef GNASH_USE_GC
                _getter->add_ref();
+#endif // ndef GNASH_USE_GC
        }
        if ( s._setter != _setter )
        {
+#ifndef GNASH_USE_GC
                _setter->drop_ref();
+#endif // ndef GNASH_USE_GC
                _setter = s._setter;
+#ifndef GNASH_USE_GC
                _setter->add_ref();
+#endif // ndef GNASH_USE_GC
        }
        return *this;
 }
@@ -77,8 +85,10 @@
        _getter(s._getter),
        _setter(s._setter)
 {
+#ifndef GNASH_USE_GC
        _getter->add_ref();
        _setter->add_ref();
+#endif // ndef GNASH_USE_GC
 }
 
 GetterSetter::
@@ -87,16 +97,28 @@
        _getter(&getter),
        _setter(&setter)
 {
+#ifndef GNASH_USE_GC
        _getter->add_ref();
        _setter->add_ref();
+#endif // ndef GNASH_USE_GC
 }
 
 GetterSetter::~GetterSetter()
 {
+#ifndef GNASH_USE_GC
        _getter->drop_ref();
        _setter->drop_ref();
+#endif // ndef GNASH_USE_GC
 }
 
+void
+GetterSetter::setReachable() const
+{
+#ifdef GNASH_USE_GC
+       _getter->setReachable();
+       _setter->setReachable();
+#endif
+}
 
 } // end of gnash namespace
 

Index: server/GetterSetter.h
===================================================================
RCS file: /sources/gnash/gnash/server/GetterSetter.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- server/GetterSetter.h       28 May 2007 15:41:04 -0000      1.7
+++ server/GetterSetter.h       15 Jun 2007 15:00:27 -0000      1.8
@@ -77,6 +77,9 @@
 
        /// invoke the setter function
        void setValue(as_object* this_ptr, const as_value& val) const;
+
+       /// Mark both getter and setter as being reachable (for GC)
+       void setReachable() const;
 };
 
 

Index: server/Property.h
===================================================================
RCS file: /sources/gnash/gnash/server/Property.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- server/Property.h   28 May 2007 15:41:04 -0000      1.6
+++ server/Property.h   15 Jun 2007 15:00:27 -0000      1.7
@@ -117,6 +117,9 @@
 
        /// is this a Getter/Setter property ?
        virtual bool isGetterSetter() const { return false; }
+
+       /// Mark this property as being reachable (for the GC)
+       virtual void setReachable() const=0;
 };
 
 /// A simple property, consisting only of an as_value
@@ -164,6 +167,8 @@
 
        void setValue(as_object&, const as_value &value)  { _value = value; }
 
+       void setReachable() const { _value.setReachable(); }
+
 };
 
 /// A Getter/Setter property
@@ -219,6 +224,12 @@
 
        /// This *is* a Getter/Setter property !
        virtual bool isGetterSetter() const { return true; }
+
+       /// Set GetterSetter as reachable (for GC)
+       void setReachable() const
+       {
+               _getset.setReachable();
+       }
 };
 
 

Index: server/PropertyList.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/PropertyList.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- server/PropertyList.cpp     18 Apr 2007 09:35:42 -0000      1.14
+++ server/PropertyList.cpp     15 Jun 2007 15:00:27 -0000      1.15
@@ -260,5 +260,14 @@
                delete it->second;
 }
 
+void
+PropertyList::setReachable() const
+{
+       for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+       {
+               it->second->setReachable();
+       }
+}
+
 } // end of gnash namespace
 

Index: server/PropertyList.h
===================================================================
RCS file: /sources/gnash/gnash/server/PropertyList.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- server/PropertyList.h       28 May 2007 15:41:04 -0000      1.14
+++ server/PropertyList.h       15 Jun 2007 15:00:27 -0000      1.15
@@ -36,8 +36,6 @@
        class as_object;
        class as_environment;
        class as_function;
-       //class as_value;
-       //class Property;
 }
 
 namespace gnash {
@@ -354,6 +352,10 @@
        ///     so this method too is non-const.
        ///
        void dump(as_object& this_ptr);
+
+       /// Mark all simple properties, getters and setters
+       /// as being reachable (for the GC)
+       void setReachable() const;
 };
 
 

Index: server/as_environment.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_environment.cpp,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -b -r1.78 -r1.79
--- server/as_environment.cpp   25 May 2007 13:25:47 -0000      1.78
+++ server/as_environment.cpp   15 Jun 2007 15:00:27 -0000      1.79
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: as_environment.cpp,v 1.78 2007/05/25 13:25:47 strk Exp $ */
+/* $Id: as_environment.cpp,v 1.79 2007/06/15 15:00:27 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -447,7 +447,9 @@
                boost::intrusive_ptr<as_object> obj = val.to_object();
                assert (obj);
                character* s=dynamic_cast<character*>(obj.get());
+#ifndef GNASH_USE_GC
                assert(s->get_ref_count() > 1); // or the intrusive_ptr above 
going out-of-scope will kill it
+#endif // ndef GNASH_USE_GC
                //log_msg(_("find_target is a character, returning it"));
                return s; // might be NULL
        }
@@ -686,7 +688,9 @@
        }
 
        env = tmp.to_object().get();
+#ifndef GNASH_USE_GC
        assert(env->get_ref_count() > 0); // still alive...
+#endif // ndef GNASH_USE_GC
 
 
        //@@   _level0 --> root, .. --> parent, . --> this, other == character
@@ -831,7 +835,9 @@
                }
 
                env = tmp.to_object().get();
+#ifndef GNASH_USE_GC
                assert(env->get_ref_count() > 0);
+#endif // ndef GNASH_USE_GC
        }
 
        //@@   _level0 --> root, .. --> parent, . --> this, other == character
@@ -1028,6 +1034,51 @@
 {
 }
 
+#ifdef GNASH_USE_GC
+/// Mark all reachable resources
+//
+/// Reachable resources would be registers and
+/// locals (expected to be empty?) and function.
+void
+as_environment::CallFrame::markReachableResources() const
+{
+       if ( func ) func->setReachable();
+       for (Registers::const_iterator i=registers.begin(), e=registers.end(); 
i!=e; ++i)
+       {
+               i->setReachable();
+       }
+       locals->setReachable();
+}
+
+void
+as_environment::markReachableResources() const
+{
+       for (size_t i=0, s=4; i<4; ++i)
+       {
+               m_global_register[i].setReachable();
+       }
+
+       if ( m_target ) m_target->setReachable();
+       if ( _original_target ) _original_target->setReachable();
+
+       assert ( _localFrames.empty() );
+#if 1 // I think we expect the stack to be empty !
+       for (CallStack::const_iterator i=_localFrames.begin(), 
e=_localFrames.end(); i!=e; ++i)
+       {
+               i->markReachableResources();
+       }
+#endif
+
+       assert ( m_stack.empty() );
+#if 1 // I think we expect the stack to be empty !
+       for (std::vector<as_value>::const_iterator i=m_stack.begin(), 
e=m_stack.end(); i!=e; ++i)
+       {
+               i->setReachable();
+       }
+#endif
+}
+#endif // GNASH_USE_GC
+
 } // end of gnash namespace
 
 

Index: server/as_environment.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_environment.h,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -b -r1.51 -r1.52
--- server/as_environment.h     28 May 2007 15:41:05 -0000      1.51
+++ server/as_environment.h     15 Jun 2007 15:00:27 -0000      1.52
@@ -313,6 +313,16 @@
            }
        }
 
+#ifdef GNASH_USE_GC
+       /// Mark all reachable resources.
+       //
+       /// Reachable resources from an as_environment
+       /// would be global registers, stack (expected to be empty
+       /// actually), stack frames and targets (original and current).
+       ///
+       void markReachableResources() const;
+#endif
+
        /// Find the sprite/movie referenced by the given path.
        //
        /// Supports both /slash/syntax and dot.syntax
@@ -430,6 +440,14 @@
                Registers registers;
 
                as_function* func;
+
+#ifdef GNASH_USE_GC
+               /// Mark all reachable resources
+               //
+               /// Reachable resources would be registers and
+               /// locals (expected to be empty?) and function.
+               void markReachableResources() const;
+#endif // GNASH_USE_GC
        };
 
        /// Push a frame on the calls stack.

Index: server/as_function.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_function.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- server/as_function.cpp      14 May 2007 09:44:22 -0000      1.32
+++ server/as_function.cpp      15 Jun 2007 15:00:27 -0000      1.33
@@ -312,7 +312,9 @@
 {
 //     GNASH_REPORT_FUNCTION;
 
+#ifndef GNASH_USE_GC
        assert(get_ref_count() > 0);
+#endif // GNASH_USE_GC
 
        int swfversion = VM::get().getSWFVersion();
 

Index: server/as_function.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_function.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- server/as_function.h        28 May 2007 15:41:05 -0000      1.15
+++ server/as_function.h        15 Jun 2007 15:00:28 -0000      1.16
@@ -125,8 +125,39 @@
        /// Return the built-in Function constructor
        static boost::intrusive_ptr<builtin_function> getFunctionConstructor();
 
+#ifdef GNASH_USE_GC
+       /// Mark reachable resources. Override from GcResource
+       //
+       /// Reachable resources from this object is its prototype
+       /// and the default as_object reachables (properties and parent).
+       ///
+       /// The default implementation only marks that. If you
+       /// override this function from a derived class remember
+       /// to call markAsFunctionReachableResources() as a final step.
+       ///
+       virtual void markReachableResources() const
+       {
+               markAsFunctionReachable();
+       }
+#endif // GNASH_USE_GC
+
 protected:
 
+#ifdef GNASH_USE_GC
+       /// Mark prototype (properties) as being reachable and invoke
+       /// the as_object class marker.
+       //
+       /// Call this function from an override of markReachableResources
+       /// in a derived class
+       ///
+       void markAsFunctionReachable() const
+       {
+               _properties->setReachable();
+
+               markAsObjectReachable();
+       }
+#endif // GNASH_USE_GC
+
        /// Construct a function with given interface
        //
        /// If the given interface is NULL a default one

Index: server/as_object.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- server/as_object.cpp        8 Jun 2007 12:11:49 -0000       1.52
+++ server/as_object.cpp        15 Jun 2007 15:00:28 -0000      1.53
@@ -549,7 +549,11 @@
 
 as_object::as_object(const as_object& other)
        :
+#ifndef GNASH_USE_GC
        ref_counted(),
+#else
+       GcResource(), 
+#endif
        _members(other._members),
        _vm(VM::get()),
        m_prototype(other.m_prototype)

Index: server/as_object.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.h,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -b -r1.58 -r1.59
--- server/as_object.h  8 Jun 2007 12:11:49 -0000       1.58
+++ server/as_object.h  15 Jun 2007 15:00:28 -0000      1.59
@@ -25,7 +25,8 @@
 #include "tu_config.h"
 
 #include "container.h"
-#include "ref_counted.h" // for inheritance 
+#include "ref_counted.h" // for inheritance  (to drop)
+#include "GC.h" // for inheritance from GcResource (to complete)
 #include "PropertyList.h"
 #include "as_value.h" // for return of get_primitive_value
 #include "smart_ptr.h"
@@ -60,8 +61,13 @@
 /// Base-class for ActionScript script-defined objects.
 /// This would likely be ActionScript's 'Object' class.
 ///
-//class as_object : public resource
-class DSOEXPORT as_object : public ref_counted
+class DSOEXPORT as_object
+       :
+#ifdef GNASH_USE_GC
+       public GcResource
+#else
+       public ref_counted
+#endif
 {
        /// Properties of this objects 
        PropertyList _members;
@@ -121,12 +127,6 @@
        ///
        as_object(const as_object& other);
 
-       /// Default destructor for ActionScript objects.
-       //
-       /// Drops reference on prototype member, if any.
-       ///
-       virtual ~as_object() {}
-       
        /// Return a text representation for this object
        virtual std::string get_text_value() const { return "[object Object]"; }
 
@@ -479,6 +479,29 @@
        ///
        void set_member_default(const std::string& name, const as_value& val);
 
+#ifdef GNASH_USE_GC
+       /// Mark all reachable resources, override from GcResource.
+       //
+       /// The default implementation marks all properties
+       /// as being reachable, calling markAsObjectReachable().
+       ///
+       /// If a derived class provides access to more GC-managed
+       /// resources, it should override this method and call 
+       /// markAsObjectReachable() as the last step.
+       ///
+       virtual void markReachableResources() const
+       {
+               markAsObjectReachable();
+       }
+
+       /// Mark properties and __proto__ as reachable (for the GC)
+       void markAsObjectReachable() const
+       {
+               _members.setReachable();
+               if ( m_prototype.get() ) m_prototype->setReachable();
+       }
+#endif // GNASH_USE_GC
+
        /// The Virtual Machine used to create this object
        VM& _vm;
 

Index: server/as_value.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_value.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- server/as_value.cpp 10 May 2007 08:18:48 -0000      1.52
+++ server/as_value.cpp 15 Jun 2007 15:00:28 -0000      1.53
@@ -65,7 +65,9 @@
     m_object_value(func)
 {
     if (m_object_value) {
+#ifndef GNASH_USE_GC
        m_object_value->add_ref();
+#endif // GNASH_USE_GC
     } else {
         m_type = NULLTYPE;
     }
@@ -605,10 +607,12 @@
                drop_refs();
                m_type = OBJECT;
                m_object_value = obj;
+#ifndef GNASH_USE_GC
                if (m_object_value)
                {
                        m_object_value->add_ref();
                }
+#endif // GNASH_USE_GC
        }
 }
 
@@ -626,7 +630,9 @@
        m_type = AS_FUNCTION;
        m_object_value = func;
        if (m_object_value) {
+#ifndef GNASH_USE_GC
            m_object_value->add_ref();
+#endif // GNASH_USE_GC
        } else {
            m_type = NULLTYPE;
        }
@@ -707,6 +713,7 @@
 void
 as_value::drop_refs()
 {
+#ifndef GNASH_USE_GC
     if (m_type == AS_FUNCTION || m_type == OBJECT )
     {
        if (m_object_value) // should assert here ?
@@ -714,6 +721,7 @@
            m_object_value->drop_ref();
        }
     } 
+#endif // GNASH_USE_GC
 }
 
 const char*
@@ -1026,6 +1034,16 @@
        return std::string(_str);
 }
 
+void
+as_value::setReachable() const
+{
+#ifdef GNASH_USE_GC
+       if ( m_type == OBJECT || m_type == AS_FUNCTION )
+       {
+               m_object_value->setReachable();
+       }
+#endif // GNASH_USE_GC
+}
 
 } // namespace gnash
 

Index: server/as_value.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_value.h,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -b -r1.53 -r1.54
--- server/as_value.h   28 May 2007 15:41:05 -0000      1.53
+++ server/as_value.h   15 Jun 2007 15:00:28 -0000      1.54
@@ -15,7 +15,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: as_value.h,v 1.53 2007/05/28 15:41:05 ann Exp $ */
+/* $Id: as_value.h,v 1.54 2007/06/15 15:00:28 strk Exp $ */
 
 #ifndef GNASH_AS_VALUE_H
 #define GNASH_AS_VALUE_H
@@ -529,6 +529,12 @@
        /// Sets this value to this string plus the given string.
        void    string_concat(const std::string& str);
 
+       /// Set any object value as reachable (for the GC)
+       //
+       /// Object values are values stored by pointer (objects and functions)
+       ///
+       void setReachable() const;
+
 private:
 
        static sprite_instance* find_sprite_by_target(const std::string& 
target);

Index: server/character.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/character.cpp,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -b -r1.42 -r1.43
--- server/character.cpp        22 May 2007 14:23:51 -0000      1.42
+++ server/character.cpp        15 Jun 2007 15:00:28 -0000      1.43
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 // 
 
-/* $Id: character.cpp,v 1.42 2007/05/22 14:23:51 udog Exp $ */
+/* $Id: character.cpp,v 1.43 2007/06/15 15:00:28 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -135,7 +135,9 @@
 character::get_root_movie()
 {
        assert(m_parent != NULL);
+#ifndef GNASH_USE_GC
        assert(m_parent->get_ref_count() > 0);
+#endif // GNASH_USE_GC
        return m_parent->get_root_movie();
 }
 
@@ -143,7 +145,9 @@
 character::get_mouse_state(int& x, int& y, int& buttons)
 {
        assert(m_parent != NULL);
+#ifndef GNASH_USE_GC
        assert(m_parent->get_ref_count() > 0);
+#endif // GNASH_USE_GC
        get_parent()->get_mouse_state(x, y, buttons);
 }
 
@@ -651,7 +655,9 @@
        Events::const_iterator it = _event_handlers.find(id);
        if ( it == _event_handlers.end() ) return handler;
 
+#ifndef GNASH_USE_GC
        assert(get_ref_count() > 0);
+#endif // GNASH_USE_GC
        boost::intrusive_ptr<character> this_ptr = const_cast<character*>(this);
 
        handler.reset( new EventCode(this_ptr, it->second) );

Index: server/character.h
===================================================================
RCS file: /sources/gnash/gnash/server/character.h,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -b -r1.82 -r1.83
--- server/character.h  14 Jun 2007 02:03:17 -0000      1.82
+++ server/character.h  15 Jun 2007 15:00:28 -0000      1.83
@@ -19,7 +19,7 @@
 //
 //
 
-/* $Id: character.h,v 1.82 2007/06/14 02:03:17 zoulunkai Exp $ */
+/* $Id: character.h,v 1.83 2007/06/15 15:00:28 strk Exp $ */
 
 #ifndef GNASH_CHARACTER_H
 #define GNASH_CHARACTER_H
@@ -154,6 +154,31 @@
 
 protected:
 
+#ifdef GNASH_USE_GC
+       /// Mark all reachable resources, override from as_object.
+       //
+       /// The default implementation calls markCharacterReachableResources().
+       ///
+       /// If a derived class provides access to more GC-managed
+       /// resources, it should override this method and call 
+       /// markCharacterReachableResources() as the last step.
+       ///
+       virtual void markReachableResources() const
+       {
+               markCharacterReachable();
+       }
+
+       /// Mark character-specific reachable resources
+       //
+       /// These are: the character's parent and the defualt
+       /// as_object reachable stuff.
+       void markCharacterReachable() const
+       {
+               if ( m_parent ) m_parent->setReachable();
+               markAsObjectReachable();
+       }
+#endif // GNASH_USE_GC
+
        const Events& get_event_handlers() const
        {
            return _event_handlers;

Index: server/debugger.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/debugger.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- server/debugger.cpp 28 May 2007 15:41:05 -0000      1.20
+++ server/debugger.cpp 15 Jun 2007 15:00:28 -0000      1.21
@@ -587,7 +587,9 @@
                if (name.size()) {
                    cerr << " \"" << name << "\"";
                }
+#ifndef GNASH_USE_GC
                cerr << " has #" << o->get_ref_count() << " references";
+#endif
            }
            cerr << endl;
        }

Index: server/debugger.h
===================================================================
RCS file: /sources/gnash/gnash/server/debugger.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- server/debugger.h   28 May 2007 15:41:05 -0000      1.14
+++ server/debugger.h   15 Jun 2007 15:00:28 -0000      1.15
@@ -15,7 +15,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: debugger.h,v 1.14 2007/05/28 15:41:05 ann Exp $ */
+/* $Id: debugger.h,v 1.15 2007/06/15 15:00:28 strk Exp $ */
 
 #ifndef __DEBUGGER_H__
 #define __DEBUGGER_H__
@@ -136,6 +136,7 @@
     std::string &callStackFrame() { return _callstack.back(); };
     
     debug_state_e state() { return _state; };
+
 private:
     bool                        _enabled;
     bool                       _tracing;

Index: server/dlist.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/dlist.cpp,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -b -r1.70 -r1.71
--- server/dlist.cpp    14 Jun 2007 02:03:18 -0000      1.70
+++ server/dlist.cpp    15 Jun 2007 15:00:28 -0000      1.71
@@ -856,7 +856,9 @@
                it != endIt; ++it)
        {
     DisplayItem& dobj = *it;
+#ifndef GNASH_USE_GC
     assert(dobj->get_ref_count() > 0);
+#endif // ndef GNASH_USE_GC
     dobj->add_invalidated_bounds(ranges, force);
        }
        

Index: server/dlist.h
===================================================================
RCS file: /sources/gnash/gnash/server/dlist.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -b -r1.43 -r1.44
--- server/dlist.h      14 Jun 2007 02:03:18 -0000      1.43
+++ server/dlist.h      15 Jun 2007 15:00:29 -0000      1.44
@@ -352,6 +352,9 @@
        template <class V>
        inline void visitAll(V& visitor);
 
+       template <class V>
+       inline void visitAll(V& visitor) const;
+
        /// dump list to logfile/stderr
        void dump() const;
 
@@ -448,6 +451,18 @@
        }
 }
 
+template <class V>
+void
+DisplayList::visitAll(V& visitor) const
+{
+       for (const_iterator it = _characters.begin(),
+                       itEnd = _characters.end();
+               it != itEnd; ++it)
+       {
+               visitor(it->get());
+       }
+}
+
 std::ostream& operator<< (std::ostream&, const DisplayList&);
 
 } // namespace gnash

Index: server/edit_text_character.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/edit_text_character.cpp,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -b -r1.67 -r1.68
--- server/edit_text_character.cpp      13 Jun 2007 16:52:00 -0000      1.67
+++ server/edit_text_character.cpp      15 Jun 2007 15:00:29 -0000      1.68
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: edit_text_character.cpp,v 1.67 2007/06/13 16:52:00 strk Exp $ */
+/* $Id: edit_text_character.cpp,v 1.68 2007/06/15 15:00:29 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -1155,7 +1155,7 @@
                        {
                                // TODO: scan more glyphs till newline and 
continue
                                bool newlinefound = false;
-                               while (code = 
utf8::decode_next_unicode_character(&text))
+                               while ( (code = 
utf8::decode_next_unicode_character(&text)) )
                                {
                                        if (code == 13 || code == 10)
                                        {

Index: server/edit_text_character.h
===================================================================
RCS file: /sources/gnash/gnash/server/edit_text_character.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- server/edit_text_character.h        28 May 2007 15:41:06 -0000      1.31
+++ server/edit_text_character.h        15 Jun 2007 15:00:29 -0000      1.32
@@ -185,6 +185,22 @@
        /// 'TextFields.variable'
        std::string _variable_name;
 
+protected:
+
+#ifdef GNASH_USE_GC
+       /// Mark reachable reosurces (for GC)
+       //
+       /// Reachable resource is currenlty just our definition,
+       /// plus common character resources
+       ///
+       void markReachableResources() const
+       {
+               if ( m_def.get() ) m_def->setReachable();
+
+               // recurse to parent...
+               markCharacterReachable();
+       }
+#endif
 };
 
 /// Initialize the global TextField class

Index: server/font.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/font.cpp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- server/font.cpp     13 Jun 2007 15:17:30 -0000      1.38
+++ server/font.cpp     15 Jun 2007 15:00:29 -0000      1.39
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: font.cpp,v 1.38 2007/06/13 15:17:30 strk Exp $ */
+/* $Id: font.cpp,v 1.39 2007/06/15 15:00:29 strk Exp $ */
 
 // Based on the public domain work of Thatcher Ulrich <address@hidden> 2003
 
@@ -618,6 +618,30 @@
                return true;
        }
 
+#ifdef GNASH_USE_GC
+/// Mark reachable resources (for the GC)
+//
+/// Reachable resources are:
+///    - texture_glyphs
+///    - shape_character_defs (vector glyphs)
+void
+font::markReachableResources() const
+{
+       // Mark textured glyphs
+       for (TextureGlyphVect::const_iterator i=m_texture_glyphs.begin(), 
e=m_texture_glyphs.end(); i!=e; ++i)
+       {
+               i->setReachable();
+       }
+
+       // Mark vector glyphs
+       for (GlyphVect::const_iterator i=m_glyphs.begin(), e=m_glyphs.end(); 
i!=e; ++i)
+       {
+               (*i)->setReachable();
+       }
+
+}
+#endif // GNASH_USE_GC
+
 
 }      // end namespace gnash
 

Index: server/font.h
===================================================================
RCS file: /sources/gnash/gnash/server/font.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- server/font.h       13 Jun 2007 15:17:30 -0000      1.23
+++ server/font.h       15 Jun 2007 15:00:29 -0000      1.24
@@ -19,6 +19,9 @@
 #include "bitmap_info.h" // for dtor visibility by smart pointer
 #include "FreetypeGlyphsProvider.h" // for device fonts support
 #include "log.h"
+#ifdef GNASH_USE_GC
+# include "GC.h"
+#endif
 
 #include <map>
 
@@ -64,6 +67,15 @@
 
                // the origin of the glyph box, in uv coords
                point   m_uv_origin;
+       protected:
+
+#ifdef GNASH_USE_GC
+               /// Mark the contained bitmap info as being reachable
+               void markReachableResources() const
+               {
+                       if ( m_bitmap_info.get() ) 
m_bitmap_info->setReachable();
+               }
+#endif
 
        };
 
@@ -243,9 +255,11 @@
                /// Return true on success, false on error
                bool initDeviceFontProvider();
 
-               std::vector< boost::intrusive_ptr<shape_character_def> >        
m_glyphs;
+               typedef std::vector< boost::intrusive_ptr<shape_character_def> 
> GlyphVect;
+               GlyphVect m_glyphs;
 
-               std::vector< texture_glyph >    m_texture_glyphs;       // 
cached info, built by gnash_fontlib.
+               typedef std::vector< texture_glyph > TextureGlyphVect;
+               TextureGlyphVect m_texture_glyphs;      // cached info, built 
by gnash_fontlib.
 
                int     m_texture_glyph_nominal_size;
 
@@ -274,6 +288,18 @@
                kernings_table m_kerning_pairs;
 
                std::auto_ptr<FreetypeGlyphsProvider> _ftProvider;
+
+       protected:
+
+#ifdef GNASH_USE_GC
+               /// Mark reachable resources (for the GC)
+               //
+               /// Reachable resources are:
+               ///     - texture_glyphs
+               ///     - shape_character_defs (vector glyphs)
+               ///
+               void markReachableResources() const;
+#endif // GNASH_USE_GC
        };
 
 

Index: server/fontlib.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/fontlib.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- server/fontlib.cpp  13 Jun 2007 02:49:32 -0000      1.28
+++ server/fontlib.cpp  15 Jun 2007 15:00:29 -0000      1.29
@@ -5,7 +5,7 @@
 
 // A module to take care of all of gnash's loaded fonts.
 
-/* $Id: fontlib.cpp,v 1.28 2007/06/13 02:49:32 strk Exp $ */
+/* $Id: fontlib.cpp,v 1.29 2007/06/15 15:00:29 strk Exp $ */
 
 #include "container.h"
 #include "tu_file.h"
@@ -1129,7 +1129,9 @@
                                        h,
                                        s_current_cache_image);
                        owner->add_bitmap_info(bi.get());
+#ifndef GNASH_USE_GC
                        assert(bi->get_ref_count() == 2);       // one ref for 
bi, one for the owner.
+#endif // ndef GNASH_USE_GC
                        }
                        else {  // Skip image data bytes.
                                in->set_position(in->get_position() + w * h);

Index: server/gnash.h
===================================================================
RCS file: /sources/gnash/gnash/server/gnash.h,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -b -r1.97 -r1.98
--- server/gnash.h      28 May 2007 15:41:06 -0000      1.97
+++ server/gnash.h      15 Jun 2007 15:00:29 -0000      1.98
@@ -330,6 +330,10 @@
 /// the halting problem).
 void   precompute_cached_data(movie_definition* movie_def);
 
+/// Initialize gnash core library
+//
+DSOEXPORT void gnashInit();
+
 /// Maximum release of resources. 
 //
 /// Calls clear_library() and
@@ -339,18 +343,13 @@
 /// heap, with the exception of any objects that are still
 /// referenced by the host program and haven't had drop_ref()
 /// called on them.
+///
 DSOEXPORT void clear();
 
 //
 // Library management
 //
        
-/// Release any library movies we've cached. 
-//
-/// Do this when you want maximum cleanup.
-void   clear_library();
-       
-//
 // Font library control.  gnash is able to substitute fonts
 // from the font library, in case a movie lacks glyphs for a
 // declared font.  This would come into play since in recent

Index: server/impl.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/impl.cpp,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -b -r1.108 -r1.109
--- server/impl.cpp     1 Jun 2007 11:02:18 -0000       1.108
+++ server/impl.cpp     15 Jun 2007 15:00:29 -0000      1.109
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: impl.cpp,v 1.108 2007/06/01 11:02:18 strk Exp $ */
+/* $Id: impl.cpp,v 1.109 2007/06/15 15:00:29 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -53,6 +53,9 @@
 #include "RemoveObjectTag.h"
 #include "DoActionTag.h"
 #include "sound_handler.h" // for get_sound_handler
+#ifdef GNASH_USE_GC
+#include "GC.h"
+#endif
 
 #include <string>
 #include <map>
@@ -61,6 +64,7 @@
 namespace gnash
 {
 
+static void    clear_library();
 
 /// Namespace for global data (will likely turn into a class)
 namespace globals { // gnash::globals
@@ -538,8 +542,6 @@
 
     s_no_recurse_while_loading = false;
 
-    //m->add_ref();
-    /
     return m;
 }
 #endif
@@ -578,8 +580,10 @@
     // after it's been de-referenced
     set_sound_handler(NULL);
 
-}
+    GC::get().collect();
 
+    GC::cleanup();
+}
 
 //
 // library stuff, for sharing resources among different movies.
@@ -621,6 +625,17 @@
                }
        }
 
+#ifdef GNASH_USE_GC
+       /// Mark all library elements as reachable (for GC)
+       void markReachableResources() const
+       {
+               for ( container::const_iterator i=_map.begin(), e=_map.end(); 
i!=e; ++i)
+               {
+                       i->second->setReachable();
+               }
+       }
+#endif
+
        void add(const std::string& key, movie_definition* mov)
        {
                _map[key] = mov;
@@ -641,25 +656,6 @@
     s_extern_sprites.push_back(m);
 }
 
-//#if 0
-void delete_unused_root()
-{
-    for (unsigned int i = 0; i < s_extern_sprites.size(); i++)
-       {
-           sprite_instance* root_m = s_extern_sprites[i];
-           sprite_instance* m = root_m->get_root_movie();
-      
-           if (m->get_ref_count() < 2)
-               {
-                   log_action(_("extern movie deleted"));
-                   s_extern_sprites.erase(s_extern_sprites.begin() + i);
-                   i--;
-                   root_m->drop_ref();
-               }
-       }
-}
-//#endif // 0
-
 movie_root*
 get_current_root()
 {
@@ -677,7 +673,7 @@
     s_workdir = dir;
 }
 
-void   clear_library()
+static void    clear_library()
     // Drop all library references to movie_definitions, so they
     // can be cleaned up.
 {
@@ -702,8 +698,6 @@
        if ( s_movie_library.get(cache_label, &m) )
            {
                log_msg(_("Movie %s already in library"), cache_label.c_str());
-               // Return cached movie.
-               // m->add_ref(); let caller add the ref, if needed
                return m.get();
            }
     }
@@ -753,7 +747,6 @@
        if (m != NULL)
            {
                // Return cached movie instance.
-               // m->add_ref(); // let caller increment refcount
                return m.get();
            }
     }
@@ -772,7 +765,6 @@
            s_movie_library_inst.add(md, mov);
        }
 
-    // mov->add_ref(); // let caller increment refcount
     return mov;
 }
 
@@ -873,10 +865,43 @@
                }
        }
 
+#ifndef GNASH_USE_GC
     m->drop_ref();
+#endif //ndef GNASH_USE_GC
+}
+
+#ifdef GNASH_USE_GC
+/// A GC root used to mark all reachable collectable pointers
+class GnashGcRoot : public GcRoot 
+{
+
+public:
+
+       GnashGcRoot()
+       {
+       }
+
+       void markReachableResources() const
+       {
+               VM::get().markReachableResources();
+
+               // Mark library movies (TODO: redesign this part)
+               s_movie_library.markReachableResources();
+       }
+};
+#endif
+
+void gnashInit()
+{
+#ifdef GNASH_USE_GC
+       static GnashGcRoot gcRoot;
+       GC::init(gcRoot);
+#endif
 }
 
 
+
+
 } // namespace gnash
 
 // Local Variables:

Index: server/impl.h
===================================================================
RCS file: /sources/gnash/gnash/server/impl.h,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- server/impl.h       28 May 2007 15:41:06 -0000      1.45
+++ server/impl.h       15 Jun 2007 15:00:29 -0000      1.46
@@ -19,7 +19,7 @@
 //
 //
 
-/* $Id: impl.h,v 1.45 2007/05/28 15:41:06 ann Exp $ */
+/* $Id: impl.h,v 1.46 2007/06/15 15:00:29 strk Exp $ */
 
 #ifndef GNASH_IMPL_H
 #define GNASH_IMPL_H
@@ -67,7 +67,6 @@
 DSOEXPORT movie_root* get_current_root();
 DSOEXPORT const char* get_workdir();
 DSOEXPORT void set_workdir(const char* dir);
-DSOEXPORT void delete_unused_root();
 
 // Information about how to display a character.
 class display_info

Index: server/mouse_button_state.h
===================================================================
RCS file: /sources/gnash/gnash/server/mouse_button_state.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- server/mouse_button_state.h 27 Feb 2007 09:10:20 -0000      1.8
+++ server/mouse_button_state.h 15 Jun 2007 15:00:29 -0000      1.9
@@ -59,6 +59,14 @@
        {
        }
 
+#ifdef GNASH_USE_GC
+       /// Mark reachable objects (active and topmost entities)
+       void markReachableResources() const
+       {
+               if ( m_active_entity.get() ) m_active_entity->setReachable();
+               if ( m_topmost_entity.get() ) m_topmost_entity->setReachable();
+       }
+#endif // GNASH_USE_GC
 };
 
 }      // end namespace gnash

Index: server/movie_root.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.cpp,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -b -r1.65 -r1.66
--- server/movie_root.cpp       13 Jun 2007 02:49:33 -0000      1.65
+++ server/movie_root.cpp       15 Jun 2007 15:00:30 -0000      1.66
@@ -318,7 +318,9 @@
                                // onDragOut
                                if (active_entity != NULL)
                                {
+#ifndef GNASH_USE_GC
                                        assert(active_entity->get_ref_count() > 
1); // we are NOT the only object holder !
+#endif // GNASH_USE_GC
                                        
active_entity->on_button_event(event_id::DRAG_OUT);
                                        // TODO: have on_button_event return
                                        //       wheter the action must trigger
@@ -615,6 +617,11 @@
                        _movie->get_play_state() == sprite_instance::STOP ? " - 
now in STOP mode" : "");
 #endif
 
+#ifdef GNASH_USE_GC
+       // Run the garbage collector (step back !!)
+       GC::get().collect();
+#endif
+
        assert(testInvariant());
 }
 
@@ -1009,5 +1016,19 @@
        _actionQueue.push_back(new FunctionCode(func, target));
 }
 
+#ifdef GNASH_USE_GC
+void
+movie_root::markReachableResources() const
+{
+       // Mark root movie as reachable
+       // TODO: mark all levels !!
+       _movie->setReachable();
+
+       // Mark mouse entities 
+       m_mouse_button_state.markReachableResources();
+       
+}
+#endif // GNASH_USE_GC
+
 } // namespace gnash
 

Index: server/movie_root.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.h,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -b -r1.56 -r1.57
--- server/movie_root.h 8 Jun 2007 12:11:50 -0000       1.56
+++ server/movie_root.h 15 Jun 2007 15:00:30 -0000      1.57
@@ -15,7 +15,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: movie_root.h,v 1.56 2007/06/08 12:11:50 zoulunkai Exp $ */
+/* $Id: movie_root.h,v 1.57 2007/06/15 15:00:30 strk Exp $ */
 
 /// \page events_handling Handling of user events
 ///
@@ -113,7 +113,7 @@
        };
 #endif 
 
-/// The absolute top level movie
+/// The movie stage (absolute top level node in the characters hierarchy)
 //
 /// This is a wrapper around the top-level movie_instance that is being played.
 /// There is a *single* instance of this class for each run;
@@ -439,6 +439,11 @@
        /// Push a function code to the ActionQueue
        void pushAction(boost::intrusive_ptr<as_function> func, 
boost::intrusive_ptr<character> target);
 
+#ifdef GNASH_USE_GC
+       /// Mark all reachable resources (for GC)
+       void markReachableResources() const;
+#endif // GNASH_USE_GC
+
 private:
 
        /// Forbid copy 

Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.286
retrieving revision 1.287
diff -u -b -r1.286 -r1.287
--- server/sprite_instance.cpp  14 Jun 2007 02:03:18 -0000      1.286
+++ server/sprite_instance.cpp  15 Jun 2007 15:00:30 -0000      1.287
@@ -192,7 +192,9 @@
        boost::intrusive_ptr<character> newch = 
exported_movie->create_character_instance(sprite.get(), depth_val);
        assert( dynamic_cast<sprite_instance*>(newch.get()) );
        assert( newch.get() > (void*)0xFFFF );
+#ifndef GNASH_USE_GC
        assert(newch->get_ref_count() > 0);
+#endif // ndef GNASH_USE_GC
 
        newch->set_name(newname.c_str());
 
@@ -3178,7 +3180,9 @@
                ratio,
                clip_depth);
 
+#ifndef GNASH_USE_GC
        assert(ch == NULL || ch->get_ref_count() > 1);
+#endif // ndef GNASH_USE_GC
        return ch.get();
 }
 
@@ -3812,8 +3816,10 @@
        else
        {
                movie_root& root = _vm.getRoot();
+#ifndef GNASH_USE_GC
                // Make sure we won't kill ourself !
                assert(get_ref_count() > 1);
+#endif // ndef GNASH_USE_GC
                root.setRootMovie(extern_movie.get());
        }
 
@@ -3980,4 +3986,32 @@
        return enabled.to_bool();
 }
 
+#ifdef GNASH_USE_GC
+struct ReachableMarker {
+       void operator() (character *ch)
+       {
+               ch->setReachable();
+       }
+};
+void
+sprite_instance::markReachableResources() const
+{
+       ReachableMarker marker;
+
+       m_display_list.visitAll(marker);
+
+       oldDisplayList.visitAll(marker);
+
+       _drawable_inst->setReachable();
+
+       m_as_environment.markReachableResources();
+
+       // Mark our own definition
+       if ( m_def.get() ) m_def->setReachable();
+
+       markCharacterReachable();
+
+}
+#endif // GNASH_USE_GC
+
 } // namespace gnash

Index: server/sprite_instance.h
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.h,v
retrieving revision 1.118
retrieving revision 1.119
diff -u -b -r1.118 -r1.119
--- server/sprite_instance.h    14 Jun 2007 02:03:18 -0000      1.118
+++ server/sprite_instance.h    15 Jun 2007 15:00:30 -0000      1.119
@@ -657,8 +657,10 @@
        void testInvariant() const {
                assert(m_play_state == PLAY || m_play_state == STOP);
                assert(m_current_frame < m_def->get_frame_count());
+#ifndef GNASH_USE_GC 
                assert(get_ref_count() > 0); // or we're constructed but
                                             // not stored in a 
boost::intrusive_ptr
+#endif
        }
 
        /// Set the current m_sound_stream_id
@@ -980,6 +982,18 @@
 
        /// Process a completed loadVariables request
        void processCompletedLoadVariableRequest(LoadVariablesThread& request);
+
+#ifdef GNASH_USE_GC
+       /// Mark sprite-specific reachable resources and invoke
+       /// the parent's class version (markCharacterReachableResources)
+       //
+       /// sprite-specific reachable resources are:
+       ///     - DisplayList items (both current and backup one)
+       ///     - Drawable instance
+       ///     - sprite environment
+       ///
+       virtual void markReachableResources() const;
+#endif // GNASH_USE_GC
 };
 
 /// Initialize the global MovieClip class

Index: server/swf_function.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf_function.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- server/swf_function.cpp     28 May 2007 15:41:07 -0000      1.30
+++ server/swf_function.cpp     15 Jun 2007 15:00:30 -0000      1.31
@@ -41,7 +41,9 @@
 
 swf_function::~swf_function()
 {
+#ifndef GNASH_USE_GC
        if ( _properties ) _properties->drop_ref();
+#endif //ndef GNASH_USE_GC
 }
 
 swf_function::swf_function(const action_buffer* ab,
@@ -62,16 +64,6 @@
        assert(m_action_buffer);
        assert( m_start_pc < m_action_buffer->size() );
 
-       // Define the 'prototype' member as a new object with
-       // only the 'constructor' element defined.
-       //_properties = new as_object();
-       //as_object* proto = _properties;
-       //proto->add_ref();
-
-       //proto->init_member("constructor", this); 
-
-       //init_member("prototype", as_value(proto));
-
        init_member("constructor", 
as_value(as_function::getFunctionConstructor().get()));
 }
 
@@ -147,10 +139,12 @@
 as_array_object* 
 swf_function::getArguments(swf_function& callee, const fn_call& fn)
 { 
+#ifndef GNASH_USE_GC
        // We'll be storing the callee as_object into an as_value
        // so you must make sure you have a reference on it before
        // callign this function.
        assert(callee.get_ref_count() > 0);
+#endif // ndef GNASH_USE_GC
 
        // Super class prototype is : obj.__proto__.constructor.prototype 
        as_array_object* arguments = new as_array_object();
@@ -344,5 +338,22 @@
        m_length = len;
 }
 
+#ifdef GNASH_USE_GC
+void
+swf_function::markReachableResources() const
+{
+       // Mark scope stack objects
+       for (ScopeStack::const_iterator i=_scopeStack.begin(), 
e=_scopeStack.end(); i!=e; ++i)
+       {
+               (*i)->setReachable();
+       }
+
+       if ( m_env ) m_env->markReachableResources();
+
+       // Invoke parent class marker
+       markAsFunctionReachable(); 
+}
+#endif // GNASH_USE_GC
+
 } // end of gnash namespace
 

Index: server/swf_function.h
===================================================================
RCS file: /sources/gnash/gnash/server/swf_function.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- server/swf_function.h       28 May 2007 15:41:07 -0000      1.14
+++ server/swf_function.h       15 Jun 2007 15:00:30 -0000      1.15
@@ -227,6 +227,15 @@
        as_value        operator()(const fn_call& fn);
 
        //void  lazy_create_properties();
+
+#ifdef GNASH_USE_GC
+       /// Mark reachable resources. Override from as_function.
+       //
+       /// Reachable resources from this object is it's scope stack
+       /// and the prototype.
+       ///
+       virtual void markReachableResources() const;
+#endif // GNASH_USE_GC
 };
 
 

Index: server/asobj/Key.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Key.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/asobj/Key.h  8 Jun 2007 12:11:50 -0000       1.19
+++ server/asobj/Key.h  15 Jun 2007 15:00:30 -0000      1.20
@@ -16,7 +16,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 // 
 
-/* $Id: Key.h,v 1.19 2007/06/08 12:11:50 zoulunkai Exp $ */
+/* $Id: Key.h,v 1.20 2007/06/15 15:00:30 strk Exp $ */
 
 #ifndef __KEY_H__
 #define __KEY_H__
@@ -128,6 +128,7 @@
 #endif
 
        int get_last_key_pressed() const;
+
 };
 
 void key_class_init(as_object& global);

Index: server/asobj/Mouse.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Mouse.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- server/asobj/Mouse.cpp      26 Apr 2007 07:00:29 -0000      1.9
+++ server/asobj/Mouse.cpp      15 Jun 2007 15:00:30 -0000      1.10
@@ -72,6 +72,7 @@
 
        // override from as_object ?
        //double get_numeric_value() const { return 0; }
+
 };
 
 as_value mouse_addlistener(const fn_call& fn)

Index: server/asobj/Stage.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Stage.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- server/asobj/Stage.cpp      1 May 2007 18:47:48 -0000       1.14
+++ server/asobj/Stage.cpp      15 Jun 2007 15:00:30 -0000      1.15
@@ -81,8 +81,14 @@
                        itEnd=_listeners.end();
                        it != itEnd; ++it)
        {
+#ifndef GNASH_USE_GC
                if ( (*it)->get_ref_count() == 1 ) it=_listeners.erase(it);
-               else notifyResize(*it, env);
+               else
+#endif // ndef GNASH_USE_GC
+               notifyResize(*it, env);
+               // TODO: make sure objects deregister themselve from being 
listeners
+               //       when deleted by the GC ! (btw, how to ensure the GC 
didn't 
+               //       delete the Stage first  ? ...)
        }
 }
 
@@ -138,12 +144,15 @@
 void
 Stage::dropDanglingListeners()
 {
+       // TODO: find a way to find dangling listeners
+#ifndef GNASH_USE_GC
        for (ListenersList::iterator it=_listeners.begin(),
                        itEnd=_listeners.end();
                        it != itEnd; ++it)
        {
                if ( (*it)->get_ref_count() == 1 ) it=_listeners.erase(it);
        }
+#endif
 }
 
 const char*

Index: server/asobj/xmlnode.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/xmlnode.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- server/asobj/xmlnode.cpp    28 May 2007 15:41:08 -0000      1.35
+++ server/asobj/xmlnode.cpp    15 Jun 2007 15:00:30 -0000      1.36
@@ -16,7 +16,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: xmlnode.cpp,v 1.35 2007/05/28 15:41:08 ann Exp $ */
+/* $Id: xmlnode.cpp,v 1.36 2007/06/15 15:00:30 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -209,14 +209,18 @@
 void
 XMLNode::removeNode()
 {
+#ifndef GNASH_USE_GC
     assert(get_ref_count() > 1);
+#endif
     boost::intrusive_ptr<XMLNode> oldparent = getParent();
     if ( oldparent )
     {
         oldparent->_children.remove(this);
     }
     _parent = NULL;
+#ifndef GNASH_USE_GC
     assert(get_ref_count() > 0);
+#endif
 }
 
 XMLNode *

Index: server/parser/BitmapMovieDefinition.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/BitmapMovieDefinition.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- server/parser/BitmapMovieDefinition.cpp     18 Apr 2007 14:07:32 -0000      
1.9
+++ server/parser/BitmapMovieDefinition.cpp     15 Jun 2007 15:00:31 -0000      
1.10
@@ -92,4 +92,13 @@
        // Do not create shape_character_def now (why?)
 }
 
+#ifdef GNASH_USE_GC
+void
+BitmapMovieDefinition::markReachableResources() const
+{
+       if ( _shapedef.get() ) _shapedef->setReachable();
+       if ( _bitmap.get() ) _bitmap->setReachable();
+}
+#endif // GNASH_USE_GC
+
 } // namespace gnash

Index: server/parser/BitmapMovieDefinition.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/BitmapMovieDefinition.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- server/parser/BitmapMovieDefinition.h       28 May 2007 15:41:09 -0000      
1.6
+++ server/parser/BitmapMovieDefinition.h       15 Jun 2007 15:00:31 -0000      
1.7
@@ -64,6 +64,18 @@
        ///
        shape_character_def* getShapeDef();
 
+protected:
+
+#ifdef GNASH_USE_GC
+       /// Mark reachable resources of a BitmapMovieDefinition
+       //
+       /// Reachable resources are:
+       ///     - dynamic shape (_shapedef)
+       ///     - bitmap (_bitmap)
+       ///
+       void markReachableResources() const;
+#endif // GNASH_USE_GC
+
 public:
 
 

Index: server/parser/movie_def_impl.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/movie_def_impl.cpp,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -b -r1.71 -r1.72
--- server/parser/movie_def_impl.cpp    21 May 2007 11:11:39 -0000      1.71
+++ server/parser/movie_def_impl.cpp    15 Jun 2007 15:00:31 -0000      1.72
@@ -329,7 +329,9 @@
 #endif // not NDEBUG
 
        boost::intrusive_ptr<character_def> ch = 
_dictionary.get_character(character_id);
+#ifndef GNASH_USE_GC
        assert(ch == NULL || ch->get_ref_count() > 1);
+#endif // ndef GNASH_USE_GC
        return ch.get(); // mm... why don't we return the boost::intrusive_ptr?
 }
 
@@ -353,7 +355,9 @@
     FontMap::iterator it = m_fonts.find(font_id);
     if ( it == m_fonts.end() ) return NULL;
     boost::intrusive_ptr<font> f = it->second;
+#ifndef GNASH_USE_GC
     assert(f->get_ref_count() > 1);
+#endif // ndef GNASH_USE_GC
     return f.get();
 }
 
@@ -384,7 +388,9 @@
     if ( it == m_sound_samples.end() ) return NULL;
 
     boost::intrusive_ptr<sound_sample> ch = it->second;
+#ifndef GNASH_USE_GC
     assert(ch->get_ref_count() > 1);
+#endif // ndef GNASH_USE_GC
 
     return ch.get();
 }
@@ -1102,4 +1108,40 @@
     return true;
 }
 
+#ifdef GNASH_USE_GC
+void
+movie_def_impl::markReachableResources() const
+{
+       for (FontMap::const_iterator i=m_fonts.begin(), e=m_fonts.end(); i!=e; 
++i)
+       {
+               i->second->setReachable();
+       }
+
+       for (BitmapMap::const_iterator i=m_bitmap_characters.begin(), 
e=m_bitmap_characters.end(); i!=e; ++i)
+       {
+               i->second->setReachable();
+       }
+
+       for (BitmapVect::const_iterator i=m_bitmap_list.begin(), 
e=m_bitmap_list.end(); i!=e; ++i)
+       {
+               (*i)->setReachable();
+       }
+
+       for (SoundSampleMap::const_iterator i=m_sound_samples.begin(), 
e=m_sound_samples.end(); i!=e; ++i)
+       {
+               i->second->setReachable();
+       }
+
+       for (ExportMap::const_iterator i=m_exports.begin(), e=m_exports.end(); 
i!=e; ++i)
+       {
+               i->second->setReachable();
+       }
+
+       for (ImportVect::const_iterator i=m_import_source_movies.begin(), 
e=m_import_source_movies.end(); i!=e; ++i)
+       {
+               (*i)->setReachable();
+       }
+}
+#endif // GNASH_USE_GC
+
 } // namespace gnash

Index: server/parser/movie_def_impl.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/movie_def_impl.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -b -r1.43 -r1.44
--- server/parser/movie_def_impl.h      28 May 2007 15:41:09 -0000      1.43
+++ server/parser/movie_def_impl.h      15 Jun 2007 15:00:31 -0000      1.44
@@ -215,11 +215,13 @@
 
        /// Movies we import from; hold a ref on these,
        /// to keep them alive
-       std::vector<boost::intrusive_ptr<movie_definition> > 
m_import_source_movies;
+       typedef std::vector<boost::intrusive_ptr<movie_definition> > ImportVect;
+       ImportVect m_import_source_movies;
 
        /// Bitmaps used in this movie; collected in one place to make
        /// it possible for the host to manage them as textures.
-       std::vector<boost::intrusive_ptr<bitmap_info> > m_bitmap_list;
+       typedef std::vector<boost::intrusive_ptr<bitmap_info> > BitmapVect;
+       BitmapVect m_bitmap_list;
 
        create_bitmaps_flag     m_create_bitmaps;
        create_font_shapes_flag m_create_font_shapes;
@@ -625,6 +627,24 @@
                _timeline.getFrameDepths(frameno, depths);
        }
 
+protected:
+
+#ifdef GNASH_USE_GC
+       /// Mark reachable resources of a movie_def_impl
+       //
+       /// Reachable resources are:
+       ///     - fonts (m_fonts)
+       ///     - bitmap characters (m_bitmap_characters)
+       ///     - bitmaps (m_bitmap_list) [ what's the difference with bitmap 
chracters ?? ]
+       ///     - sound samples (m_sound_samples)
+       ///     - exports (m_exports)
+       ///     - imported movies (m_import_source_movies)
+       ///
+       /// TODO: do we really need all this stuff to be a GcResource ??
+       ///
+       void markReachableResources() const;
+#endif // GNASH_USE_GC
+
 };
 
 } // namespace gnash

Index: server/parser/sprite_definition.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/sprite_definition.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- server/parser/sprite_definition.cpp 21 May 2007 11:11:39 -0000      1.15
+++ server/parser/sprite_definition.cpp 15 Jun 2007 15:00:31 -0000      1.16
@@ -215,4 +215,12 @@
 #endif
 }
 
+#ifdef GNASH_USE_GC
+void
+sprite_definition::markReachableResources() const
+{
+       if ( registeredClass.get() ) registeredClass->setReachable();
+}
+#endif // GNASH_USE_GC
+
 } // namespace gnash

Index: server/parser/sprite_definition.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/sprite_definition.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- server/parser/sprite_definition.h   24 May 2007 10:29:28 -0000      1.20
+++ server/parser/sprite_definition.h   15 Jun 2007 15:00:31 -0000      1.21
@@ -385,6 +385,17 @@
        ///
        Timeline _timeline;
 
+protected:
+
+
+#ifdef GNASH_USE_GC
+       /// Mark reachable resources of a sprite_definition
+       //
+       /// Reachable resources are:
+       ///     - registered class (registeredClass)
+       ///
+       void markReachableResources() const;
+#endif // GNASH_USE_GC
 };
 
 

Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -b -r1.107 -r1.108
--- server/vm/ASHandlers.cpp    2 Jun 2007 06:50:07 -0000       1.107
+++ server/vm/ASHandlers.cpp    15 Jun 2007 15:00:31 -0000      1.108
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: ASHandlers.cpp,v 1.107 2007/06/02 06:50:07 strk Exp $ */
+/* $Id: ASHandlers.cpp,v 1.108 2007/06/15 15:00:31 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -2341,12 +2341,14 @@
                        env, nargs, env.get_top_index());
 
 #ifdef USE_DEBUGGER
+#ifndef GNASH_USE_GC
        // WARNING: new_obj.to_object() can return a newly allocated
        //          thing into the intrusive_ptr, so the debugger
        //          will be left with a deleted object !!
        //          Rob: we don't want to use void pointers here..
        newobj->add_ref(); // this will leak, but at least debugger won't end up
                           // with a dandling reference...
+#endif //ndef GNASH_USE_GC
         debugger.addSymbol(newobj.get(), classname);
 #endif
 
@@ -3358,8 +3360,10 @@
        //          will be left with a deleted object !!
        //          Rob: we don't want to use void pointers here..
        boost::intrusive_ptr<as_object> o = function_value.to_object();
+#ifndef GNASH_USE_GC
        o->add_ref(); // this will leak, but at least debugger won't end up
                      // with a dandling reference...
+#endif //ndef GNASH_USE_GC
         debugger.addSymbol(o.get(), name);
 #endif
 }
@@ -3508,8 +3512,10 @@
                //          will be left with a deleted object !!
                //          Rob: we don't want to use void pointers here..
                boost::intrusive_ptr<as_object> o = function_value.to_object();
+#ifndef GNASH_USE_GC
                o->add_ref(); // this will leak, but at least debugger won't 
end up
                      // with a dandling reference...
+#endif //ndef GNASH_USE_GC
                 debugger.addSymbol(o.get(), name);
 #endif
        }

Index: server/vm/VM.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/VM.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- server/vm/VM.cpp    28 May 2007 15:41:10 -0000      1.9
+++ server/vm/VM.cpp    15 Jun 2007 15:00:31 -0000      1.10
@@ -1,3 +1,4 @@
+// VM.cpp: the Virtual Machine class, for Gnash
 // 
 //   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
 // 
@@ -15,7 +16,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: VM.cpp,v 1.9 2007/05/28 15:41:10 ann Exp $ */
+/* $Id: VM.cpp,v 1.10 2007/06/15 15:00:31 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -147,6 +148,21 @@
   return  (tu_timer::get_ticks() -  _start_time);
 }
 
+void
+VM::markReachableResources() const
+{
+#ifdef GNASH_USE_GC
+       _root_movie->markReachableResources();
+       _global->setReachable();
+#endif
+}
+
+void
+VmGcRoot::markReachableResources() const
+{
+       _vm.markReachableResources();
+}
+
 } // end of namespace gnash
 
 

Index: server/vm/VM.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/VM.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- server/vm/VM.h      28 May 2007 15:41:10 -0000      1.10
+++ server/vm/VM.h      15 Jun 2007 15:00:31 -0000      1.11
@@ -1,3 +1,4 @@
+// VM.h: the Virtual Machine class, for Gnash
 // 
 //   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
 // 
@@ -25,6 +26,7 @@
 #include "smart_ptr.h" // for boost::intrusive_ptr
 #include "movie_root.h" // for composition
 #include "tu_types.h"  // for uint64_t
+#include "GC.h" // for ineritance of VmGcRoot
 
 #include <memory> // for auto_ptr
 #include <locale>
@@ -37,6 +39,22 @@
 
 namespace gnash {
 
+/// A GC root used to mark all reachable collectable pointers
+class VmGcRoot : public GcRoot 
+{
+       VM& _vm;
+
+public:
+
+       VmGcRoot(VM& vm)
+               :
+               _vm(vm)
+       {
+       }
+
+       virtual void markReachableResources() const;
+};
+
 /// The virtual machine
 //
 /// This is the machine that executes all actions in the 
@@ -59,7 +77,12 @@
 ///
 class DSOEXPORT VM {
 
+       friend class VmGcRoot;
+
        /// Use VM::get() to access the singleton
+       //
+       /// Initializes the GC singleton
+       ///
        VM(movie_definition& movie);
 
        /// Don't copy
@@ -68,6 +91,8 @@
        /// Don't assign
        VM& operator=(const VM&);
 
+       /// Should deinitialize the GC singleton
+       /// If it doesn't is just because it corrupts memory :)
        ~VM();
 
        // We use an auto_ptr here to allow constructing
@@ -161,6 +186,9 @@
        /// Get the SWF locale to use 
        std::locale& getLocale() const;
 
+       /// Mark all reachable resources (for GC)
+       void markReachableResources() const;
+
 };
 
 } // namespace gnash

Index: utilities/processor.cpp
===================================================================
RCS file: /sources/gnash/gnash/utilities/processor.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -b -r1.58 -r1.59
--- utilities/processor.cpp     1 Jun 2007 11:02:18 -0000       1.58
+++ utilities/processor.cpp     15 Jun 2007 15:00:31 -0000      1.59
@@ -135,6 +135,9 @@
 {
     assert(tu_types_validate());
 
+    /// Initialize gnash core library
+    gnashInit();
+
     // Enable native language support, i.e. internationalization
     setlocale (LC_MESSAGES, "");
     bindtextdomain (PACKAGE, LOCALEDIR);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]