[Kde-bindings] Ruby 1.9.x GC.stress + qtruby ([BUG] object allocation during garbage collection phase)

Richard Dale rdale at foton.es
Thu Mar 12 18:53:24 UTC 2009


On Thursday 12 March 2009 17:15:51 Davor Ocelic wrote:
> Hello folks,
>
> We have noticed an issue with qtruby and Ruby 1.9.x when
> GC.stress= true.
>
> When the GC is marking objects, and it encounters any kind of
> Qt layout, it uses itemAt() to dive in and access individual
> contained widgets.
During GC the calls to itemAt() are in C++ in the smokeruby_mark() function in 
handlers.cpp:
		if (o->smoke->isDerivedFromByName(className, "QLayout")) {
			QLayout * qlayout = (QLayout *) o->smoke->cast(o->ptr, o->classId, o-
>smoke->idClass("QLayout").index);
			for (int i = 0; i < qlayout->count(); ++i) {
				QLayoutItem * item = qlayout->itemAt(i);
				if (item != 0) {
					obj = getPointerObject(item);
					if (obj != Qnil) {
						if (do_debug & qtdb_gc) qWarning("Marking (%s*)%p -> %p", "QLayoutItem", 
item, (void*)obj);
						rb_gc_mark(obj);
					}
				}
			}

So we could have a global flag to switch off these virtual method callbacks 
tests during GC.

> It calls respond_to() to see whether itemAt() is redefined
> in Ruby; if not (which is most of the time), before the first
> call to Qt's itemAt(), it tries to intern the method name,
> which in Ruby 1.9.x creates a new string, but object creation
> is not allowed during garbage collection phase.
>
> So the program fails with an error
>  "[BUG] object allocation during garbage collection phase"
>
> The quick solution to the problem is interning the symbols
> manually, before layouts are used. For example, just
> saying:
>
>   ...
>   'itemAt'.intern
>   ...
>   l= Qt::HBoxLayout.new...
>
>
> I think this may be affecting all types of Qt objects
> that can contain other widgets (not just layouts).
> (Just of course it would not be itemAt() but some other
> function.)
>
> Would the right solution be to add support for this
> directly in qtruby and intern the needed method names
> there automatically, before they are used by GC?
I think turning off virtual method callbacks during GC is more reliable. But I 
had thought of caching the result for a virtual method callback test, so it 
only has to be done once for an instance (or once per Ruby class perhaps). It 
needs a bit more thought. 

We could also change the smoke library code generation so that there would be 
a flag for each virtual method call, and set that after the first test, instead 
of testing each time.

-- Richard



More information about the Kde-bindings mailing list