[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