[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog libbase/Makefile.am libbase/GC.h
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog libbase/Makefile.am libbase/GC.h |
Date: |
Thu, 14 Jun 2007 20:28:52 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 07/06/14 20:28:52
Modified files:
. : ChangeLog
libbase : Makefile.am
Added files:
libbase : GC.h
Log message:
* libbase/: Makefile.am, GC.h: First draft at a garbage collector class.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3545&r2=1.3546
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/Makefile.am?cvsroot=gnash&r1=1.72&r2=1.73
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/GC.h?cvsroot=gnash&rev=1.1
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.3545
retrieving revision 1.3546
diff -u -b -r1.3545 -r1.3546
--- ChangeLog 14 Jun 2007 16:34:01 -0000 1.3545
+++ ChangeLog 14 Jun 2007 20:28:50 -0000 1.3546
@@ -1,6 +1,7 @@
2007-06-14 Sandro Santilli <address@hidden>
- * cyngal/http.h: fix gnash::Network referencing, drop
+ * libbase/: Makefile.am, GC.h: First draft at a garbage collector class.
+ * cygnal/http.h: fix gnash::Network referencing, drop
'using namespace std'
2007-06-14 Sandro Santilli <address@hidden>
Index: libbase/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/libbase/Makefile.am,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -b -r1.72 -r1.73
--- libbase/Makefile.am 21 May 2007 15:46:48 -0000 1.72
+++ libbase/Makefile.am 14 Jun 2007 20:28:51 -0000 1.73
@@ -146,7 +146,9 @@
zlib_adapter.h \
URL.h \
LoadThread.h \
- FLVParser.h
+ FLVParser.h \
+ GC.h \
+ $(NULL)
Index: libbase/GC.h
===================================================================
RCS file: libbase/GC.h
diff -N libbase/GC.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libbase/GC.h 14 Jun 2007 20:28:51 -0000 1.1
@@ -0,0 +1,333 @@
+// GC.h: Garbage Collector, for Gnash
+//
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef GNASH_GC_H
+#define GNASH_GC_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <list>
+
+// Define the following macro to enable GC verbosity
+#define GNASH_GC_DEBUG 1
+
+#ifdef GNASH_GC_DEBUG
+# include "log.h"
+# include <typeinfo>
+#endif
+
+namespace gnash {
+
+class GC;
+
+/// Abstract class to allow the GC to store "roots" into a container
+//
+/// Any class expected to act as a "root" for the garbage collection
+/// should derive from this class, and implement the markReachableResources()
+/// method.
+///
+///
+class GcRoot
+{
+
+public:
+
+ /// Scan all GC resources reachable by this instance.
+ //
+ /// This function is invoked on roots registered to
+ /// the collector.
+ ///
+ /// Use setReachable() on the resources stored in this
+ /// container.
+ ///
+ virtual void markReachableResources() const=0;
+
+ virtual ~GcRoot() {}
+};
+
+/// Collectable resource
+//
+/// Instances of this class can be managed by a GC object.
+///
+class GcResource
+{
+
+public:
+
+ friend class GC;
+
+ /// Create a Garbage-collected resource.
+ //
+ /// The resource will be automatically registered with
+ /// the garbage collector singleton.
+ ///
+ GcResource();
+
+ /// \brief
+ /// Mark this resource as being reachable, possibly triggering
+ /// further marking of all resources reachable by this object.
+ //
+ /// If the object wasn't reachable before, this call triggers
+ /// scan of all contained objects too...
+ ///
+ void setReachable() const
+ {
+
+ if ( _reachable )
+ {
+#ifdef GNASH_GC_DEBUG
+ 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",
+ (void*)this, typeid(*this).name());
+#endif
+
+ _reachable = true;
+ markReachableResources();
+ }
+
+ /// Return true if this object is marked as reachable
+ bool isReachable() const { return _reachable; }
+
+ /// Clear the reachable flag
+ void clearReachable() const { _reachable = false; }
+
+protected:
+
+ /// Scan all GC resources reachable by this instance.
+ //
+ /// This function is invoked everytime this object
+ /// switches from unreachable to reachable, and is
+ /// used to recursively mark all contained resources
+ /// as reachable.
+ ///
+ /// See setReachable(), which is the function to invoke
+ /// against all reachable methods.
+ ///
+ /// Feel free to assert(_reachable) in your implementation.
+ ///
+ /// The default implementation doesn't mark anything.
+ ///
+ virtual void markReachableResources() const
+ {
+ assert(_reachable);
+#ifdef GNASH_GC_DEBUG
+ log_debug("Class %s didn't override the
markReachableResources() method", typeid(*this).name());
+#endif
+ }
+
+ /// Delete this resource.
+ //
+ /// This is protected to allow subclassing, but ideally it
+ /// sould be private, so only the GC is allowed to delete us.
+ ///
+ virtual ~GcResource()
+ {
+ }
+
+private:
+
+ mutable bool _reachable;
+
+};
+
+/// Garbage collector singleton
+//
+/// Instances of this class ( you' only use one, the singleton )
+/// manage a list of heap pointers (collectables) deleting them
+/// when no more needed/reachable.
+///
+/// Reachability of them is detected starting from a list
+/// of "root" containers each one expected to provide a
+/// function to return all reachable object.
+///
+/// Each "collectable" objects is also expected to be a container
+/// itself.
+///
+///
+class GC
+{
+
+public:
+
+ friend class GcResource;
+
+ /// Get the singleton instance of the Garbage Collector
+ static GC& getInstance()
+ {
+ static GC singleton;
+ return singleton;
+ }
+
+ /// Add a root resource to use for mark scanning
+ //
+ /// @param root
+ /// A GcResource to use as a root item to scan
+ /// during the mark phase.
+ ///
+ void addRoot(GcRoot* root)
+ {
+ assert(root);
+ _roots.push_back(root);
+#ifdef GNASH_GC_DEBUG
+ log_debug("GC %p: root %p added, num roots: " SIZET_FMT,
(void*)this, (void*)root, _roots.size());
+#endif
+ }
+
+
+ /// Run the collector
+ //
+ /// Find all reachable collectables, destroy all the others.
+ ///
+ void collect()
+ {
+#ifdef GNASH_GC_DEBUG
+ log_debug("Starting collector: " SIZET_FMT " roots, " SIZET_FMT
" collectables", _roots.size(), _resList.size());
+#endif // GNASH_GC_DEBUG
+
+ // Mark all resources as reachable
+ markReachable();
+
+ // clean unreachable resources, and mark them others as
reachable again
+ cleanUnreachable();
+
+ }
+
+private:
+
+ /// List of collectables
+ typedef std::list<const GcResource *> ResList;
+
+ /// List of roots
+ typedef std::list<const GcRoot *> RootList;
+
+ /// Create a garbage collector
+ GC()
+ {
+#ifdef GNASH_GC_DEBUG
+ log_debug("GC %p created", (void*)this);
+#endif
+ }
+
+ /// Destroy the collector, releasing all collectables.
+ ~GC()
+ {
+#ifdef GNASH_GC_DEBUG
+ log_debug("GC %p deleted, cleaning up all managed resources",
(void*)this);
+#endif
+ for (ResList::iterator i=_resList.begin(), e=_resList.end();
i!=e; ++i)
+ {
+ delete *i;
+ }
+ }
+
+ /// 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
+ }
+
+ /// 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();
+ }
+ }
+
+ /// Delete all unreachable objects, and mark the others unreachable
again
+ void cleanUnreachable()
+ {
+#ifdef GNASH_GC_DEBUG
+ size_t deleted = 0;
+#endif
+ for (ResList::iterator i=_resList.begin(), e=_resList.end();
i!=e; )
+ {
+ const GcResource* res = *i;
+ if ( ! res->isReachable() )
+ {
+#ifdef GNASH_GC_DEBUG
+ ++deleted;
+#endif
+ delete res;
+ i = _resList.erase(i);
+ }
+ else
+ {
+ res->clearReachable();
+ ++i;
+ }
+ }
+#ifdef GNASH_GC_DEBUG
+ log_debug("GC %p: cleanUnreachable deleted " SIZET_FMT
+ " resources marked as unreachable",
+ (void*)this, deleted);
+#endif
+ }
+
+ ResList _resList;
+
+ RootList _roots;
+
+};
+
+
+inline GcResource::GcResource()
+ :
+ _reachable(false)
+{
+ GC::getInstance().addCollectable(this);
+}
+
+} // namespace gnash
+
+#endif // GNASH_GC_H
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog libbase/Makefile.am libbase/GC.h,
Sandro Santilli <=