Author: mvidner
Date: Mon Oct 3 17:23:37 2011
New Revision: 66205
URL: http://svn.opensuse.org/viewcvs/yast?rev=66205&view=rev
Log:
Assist mark+sweep garbage collection by marking values referenced from YCP.
Countess Reference marries Mark Sweep.
Modified:
trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc
trunk/ruby-bindings/src/ruby/YRuby.cc
trunk/ruby-bindings/src/ruby/YRuby.h
Modified: trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc?rev=66205&r1=66204&r2=66205&view=diff
==============================================================================
--- trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc (original)
+++ trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc Mon Oct 3 17:23:37 2011
@@ -46,6 +46,9 @@
#include
#include
+#include <cassert>
+
+#include "YRuby.h"
#include "Y2RubyTypePath.h"
#include "Y2RubyTypeTerm.h"
@@ -98,9 +101,31 @@
#define YCP_EXTERNAL_MAGIC "Ruby object"
+static void ycpexternal_finalizer(void * value_v, string /*magic*/)
+{
+ VALUE value = (VALUE)value_v;
+
+ YRuby::refcount_map_t& vrby = YRuby::yRuby()->value_references_from_ycp;
+ YRuby::refcount_map_t::iterator it = vrby.find(value);
+ assert(it != vrby.end());
+
+ int & count = it->second;
+ --count;
+ y2internal("Refcount of value %ld decremented to %d", value, count);
+ assert(count >= 0);
+
+ if (count == 0) {
+ vrby.erase(it);
+ }
+}
+
static YCPExternal rbobject_2_ycpexternal( VALUE value )
{
- YCPExternal ex((void*) value, string(YCP_EXTERNAL_MAGIC), NULL);
+ YCPExternal ex((void*) value, string(YCP_EXTERNAL_MAGIC), ycpexternal_finalizer);
+
+ // defaults to zero, ok
+ int count = ++YRuby::yRuby()->value_references_from_ycp[value];
+ y2internal("Refcount of value %ld incremented to %d", value, count);
return ex;
}
Modified: trunk/ruby-bindings/src/ruby/YRuby.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/ruby-bindings/src/ruby/YRuby.cc?rev=66205&r1=66204&r2=66205&view=diff
==============================================================================
--- trunk/ruby-bindings/src/ruby/YRuby.cc (original)
+++ trunk/ruby-bindings/src/ruby/YRuby.cc Mon Oct 3 17:23:37 2011
@@ -82,6 +82,32 @@
//ruby_options(argc - 1, ++argv);
ruby_script("yast");
ruby_init_loadpath();
+
+ VALUE ycp_references = Data_Wrap_Struct(rb_cObject, gc_mark, gc_free, & value_references_from_ycp);
+ rb_global_variable(&ycp_references);
+}
+
+void YRuby::gc_mark(void *object)
+{
+ refcount_map_t * vrby = (refcount_map_t *) object;
+
+ y2internal("mark: map size is %u", vrby->size());
+ refcount_map_t::iterator
+ b = vrby->begin(),
+ e = vrby->end(),
+ it;
+ for (it = b; it != e; ++it) {
+ y2internal("marking: value %ld refcount %d", it->first, it->second);
+ rb_gc_mark(it->first);
+ }
+}
+
+void YRuby::gc_free(void *object)
+{
+ refcount_map_t * vrby = (refcount_map_t *) object;
+
+ y2internal("free: map size is %u", vrby->size());
+ y2internal("should happen quite last or we are in trouble FIXME");
}
YRuby::~YRuby()
Modified: trunk/ruby-bindings/src/ruby/YRuby.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/ruby-bindings/src/ruby/YRuby.h?rev=66205&r1=66204&r2=66205&view=diff
==============================================================================
--- trunk/ruby-bindings/src/ruby/YRuby.h (original)
+++ trunk/ruby-bindings/src/ruby/YRuby.h Mon Oct 3 17:23:37 2011
@@ -97,11 +97,23 @@
**/
YCPValue callInner (string module, string function, bool method,
YCPList argList, constTypePtr wanted_result_type);
+ /**
+ * Ruby VALUEs do not have a reference count like YCP or Perl.
+ * To protect them from being garbage-collected, they must be marked
+ * via ruby_gc_mark
+ *
+ * A set is not enough: one VALUE can be referenced by multiple
+ * YCPValueReps
+ */
+ typedef std::map refcount_map_t;
-protected:
-
+private:
+ static void gc_mark(void *object);
+ static void gc_free(void *object);
+
public:
static YRuby * _yRuby;
+ refcount_map_t value_references_from_ycp;
};
#endif // YRuby_h
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org