[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdebindings/qtruby
From: Richard Dale <Richard_Dale () tipitina ! demon ! co ! uk>
Date: 2006-08-17 18:30:30
Message-ID: 1155839430.936897.21960.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 573991 by rdale:
* Used the excellent MallocDebug tool on Mac OS X to track down and fix
some memory leaks. Some QRegExps and QByteArrays are now allocated
statically to minimise memory usage.
M +6 -0 ChangeLog
M +87 -54 rubylib/qtruby/Qt.cpp
--- trunk/KDE/kdebindings/qtruby/ChangeLog #573990:573991
@@ -1,3 +1,9 @@
+2006-08-17 Richard Dale <rdale@foton.es>
+
+ * Used the excellent MallocDebug tool on Mac OS X to track down and fix
+ some memory leaks. Some QRegExps and QByteArrays are now allocated
+ statically to minimise memory usage.
+
2006-07-18 Richard Dale <rdale@foton.es>
* The code to change a Ruby 'foo?' method call to a Qt C++ 'setFoo()' was
--- trunk/KDE/kdebindings/qtruby/rubylib/qtruby/Qt.cpp #573990:573991
@@ -1420,28 +1420,32 @@
return obj;
}
-static QByteArray
+static QByteArray *
find_cached_selector(int argc, VALUE * argv, VALUE klass, char * methodName)
{
// Look in the cache
- QByteArray mcid(rb_class2name(klass));
- mcid += ';';
- mcid += methodName;
+static QByteArray * mcid = 0;
+ if (mcid == 0) {
+ mcid = new QByteArray();
+ }
+ *mcid = rb_class2name(klass);
+ *mcid += ';';
+ *mcid += methodName;
for(int i=3; i<argc ; i++)
{
- mcid += ';';
- mcid += get_VALUEtype(argv[i]);
+ *mcid += ';';
+ *mcid += get_VALUEtype(argv[i]);
}
- Smoke::Index *rcid = methcache.value(mcid);
+ Smoke::Index *rcid = methcache.value(*mcid);
#ifdef DEBUG
- if (do_debug & qtdb_calls) qWarning("method_missing mcid: %s", (const char *) \
mcid); + if (do_debug & qtdb_calls) qWarning("method_missing mcid: %s", (const char \
*) *mcid); #endif
if (rcid) {
// Got a hit
#ifdef DEBUG
- if (do_debug & qtdb_calls) qWarning("method_missing cache hit, mcid: %s", (const \
char *) mcid); + if (do_debug & qtdb_calls) qWarning("method_missing cache hit, \
mcid: %s", (const char *) *mcid); #endif
_current_method = *rcid;
} else {
@@ -1458,27 +1462,28 @@
VALUE klass = rb_funcall(self, rb_intern("class"), 0);
// Look for 'thing?' methods, and try to match isThing() or hasThing() in the Smoke \
runtime
- QByteArray pred(rb_id2name(SYM2ID(argv[0])));
- if (pred.endsWith("?")) {
+ QByteArray * pred = new QByteArray(rb_id2name(SYM2ID(argv[0])));
+ if (pred->endsWith("?")) {
smokeruby_object *o = value_obj_info(self);
if(!o || !o->ptr) {
+ delete pred;
return rb_call_super(argc, argv);
}
// Drop the trailing '?'
- pred.replace(pred.length() - 1, 1, "");
+ pred->replace(pred->length() - 1, 1, "");
- pred.replace(0, 1, pred.mid(0, 1).toUpper());
- pred.replace(0, 0, QByteArray("is"));
- Smoke::Index meth = o->smoke->findMethod(o->smoke->classes[o->classId].className, \
(const char *) pred); + pred->replace(0, 1, pred->mid(0, 1).toUpper());
+ pred->replace(0, 0, "is");
+ Smoke::Index meth = o->smoke->findMethod(o->smoke->classes[o->classId].className, \
(const char *) *pred);
if (meth == 0) {
- pred.replace(0, 2, QByteArray("has"));
- meth = o->smoke->findMethod(o->smoke->classes[o->classId].className, pred);
+ pred->replace(0, 2, "has");
+ meth = o->smoke->findMethod(o->smoke->classes[o->classId].className, *pred);
}
if (meth > 0) {
- methodName = (char *) (const char *) pred;
+ methodName = (char *) (const char *) *pred;
}
}
@@ -1488,22 +1493,30 @@
temp_stack[2] = klass;
temp_stack[3] = self;
for (int count = 1; count < argc; count++) {
- temp_stack[count+3] = argv[count];
+ temp_stack[count+3] = argv[count];
}
{
- QByteArray mcid = find_cached_selector(argc+3, temp_stack, klass, methodName);
+ QByteArray * mcid = find_cached_selector(argc+3, temp_stack, klass, methodName);
if (_current_method == -1) {
// Find the C++ method to call. Do that from Ruby for now
VALUE retval = rb_funcall2(qt_internal_module, rb_intern("do_method_missing"), \
argc+3, temp_stack); if (_current_method == -1) {
- QRegExp rx("^[-+%/|]$");
- QString op(rb_id2name(SYM2ID(argv[0])));
- if (rx.indexIn(op) != -1) {
+ char * op = rb_id2name(SYM2ID(argv[0]));
+ if ( qstrcmp(op, "-") == 0
+ || qstrcmp(op, "+") == 0
+ || qstrcmp(op, "/") == 0
+ || qstrcmp(op, "%") == 0
+ || qstrcmp(op, "|") == 0 )
+ {
// Look for operator methods of the form 'operator+=', 'operator-=' and so on..
- temp_stack[1] = rb_str_new2(op.append("=").toLatin1());
+ char op1[3];
+ op1[0] = op[0];
+ op1[1] = '=';
+ op1[2] = '\0';
+ temp_stack[1] = rb_str_new2(op1);
retval = rb_funcall2(qt_internal_module, rb_intern("do_method_missing"), \
argc+3, temp_stack); }
@@ -1517,35 +1530,42 @@
&& isDerivedFrom(o->smoke, o->classId, o->smoke->idClass("QObject")) )
{
QObject * qobject = (QObject *) o->smoke->cast(o->ptr, o->classId, \
o->smoke->idClass("QObject"));
- QByteArray prop(rb_id2name(SYM2ID(argv[0])));
+ QByteArray * prop = new QByteArray(rb_id2name(SYM2ID(argv[0])));
const QMetaObject * meta = qobject->metaObject();
if (argc == 1) {
- if (prop.endsWith("?")) {
- prop.replace(0, 1, pred.mid(0, 1).toUpper());
- prop.replace(0, 0, QByteArray("is"));
- if (meta->indexOfProperty(prop) == -1) {
- prop.replace(0, 2, QByteArray("has"));
+ if (prop->endsWith("?")) {
+ prop->replace(0, 1, pred->mid(0, 1).toUpper());
+ prop->replace(0, 0, "is");
+ if (meta->indexOfProperty(*prop) == -1) {
+ prop->replace(0, 2, "has");
}
}
- if (meta->indexOfProperty(prop) != -1) {
- VALUE qvariant = rb_funcall(self, rb_intern("property"), 1, \
rb_str_new2(prop)); + if (meta->indexOfProperty(*prop) != -1) {
+ VALUE qvariant = rb_funcall(self, rb_intern("property"), 1, \
rb_str_new2(*prop)); + delete pred;
+ delete prop;
return rb_funcall(qvariant, rb_intern("to_ruby"), 0);
}
- } else if (argc == 2 && prop.endsWith("=")) {
- prop.replace("=", "");
- if (meta->indexOfProperty(prop) != -1) {
+ } else if (argc == 2 && prop->endsWith("=")) {
+ prop->replace("=", "");
+ if (meta->indexOfProperty(*prop) != -1) {
VALUE qvariant = rb_funcall(self, rb_intern("qVariantFromValue"), 1, \
argv[1]);
- return rb_funcall(self, rb_intern("setProperty"), 2, rb_str_new2(prop), \
qvariant); + delete pred;
+ VALUE str = rb_str_new2(*prop);
+ delete prop;
+ return rb_funcall(self, rb_intern("setProperty"), 2, str, qvariant);
}
}
+ delete prop;
}
-
+
+ delete pred;
return rb_call_super(argc, argv);
}
}
// Success. Cache result.
- methcache.insert(mcid, new Smoke::Index(_current_method));
+ methcache.insert(*mcid, new Smoke::Index(_current_method));
}
}
@@ -1553,7 +1573,7 @@
c.next();
VALUE result = *(c.var());
free(temp_stack);
-
+ delete pred;
return result;
}
@@ -1568,37 +1588,42 @@
temp_stack[2] = klass;
temp_stack[3] = Qnil;
for (int count = 1; count < argc; count++) {
- temp_stack[count+3] = argv[count];
+ temp_stack[count+3] = argv[count];
}
{
- QByteArray mcid = find_cached_selector(argc+3, temp_stack, klass, methodName);
+ QByteArray * mcid = find_cached_selector(argc+3, temp_stack, klass, methodName);
if (_current_method == -1) {
VALUE retval = rb_funcall2(qt_internal_module, rb_intern("do_method_missing"), \
argc+3, temp_stack);
- Q_UNUSED(retval);
+ Q_UNUSED(retval);
if (_current_method != -1) {
// Success. Cache result.
- methcache.insert(mcid, new Smoke::Index(_current_method));
+ methcache.insert(*mcid, new Smoke::Index(_current_method));
}
}
}
if (_current_method == -1) {
- QRegExp rx("[a-zA-Z]+");
- if (rx.indexIn(methodName) == -1) {
+static QRegExp * rx = 0;
+ if (rx == 0) {
+ rx = new QRegExp("[a-zA-Z]+");
+ }
+
+ if (rx->indexIn(methodName) == -1) {
// If an operator method hasn't been found as an instance method,
// then look for a class method - after 'op(self,a)' try 'self.op(a)'
VALUE * method_stack = (VALUE *) calloc(argc - 1, sizeof(VALUE));
method_stack[0] = argv[0];
for (int count = 1; count < argc - 1; count++) {
- method_stack[count] = argv[count+1];
+ method_stack[count] = argv[count+1];
}
result = method_missing(argc-1, method_stack, argv[1]);
free(method_stack);
free(temp_stack);
return result;
} else {
+ free(temp_stack);
return rb_call_super(argc, argv);
}
}
@@ -1676,13 +1701,13 @@
{
// Put this in a C block so that the mcid will be de-allocated at the end of the \
block, // rather than on f'n exit, to avoid the longjmp problem described below
- QByteArray mcid = find_cached_selector(argc+4, temp_stack, klass, \
rb_class2name(klass)); + QByteArray * mcid = find_cached_selector(argc+4, \
temp_stack, klass, rb_class2name(klass));
if (_current_method == -1) {
retval = rb_funcall2(qt_internal_module, rb_intern("do_method_missing"), argc+4, \
temp_stack); if (_current_method != -1) {
// Success. Cache result.
- methcache.insert(mcid, new Smoke::Index(_current_method));
+ methcache.insert(*mcid, new Smoke::Index(_current_method));
}
}
}
@@ -1874,7 +1899,11 @@
rb_str_new2(method.signature()) );
QString name(method.signature());
- name.replace(QRegExp("\\(.*"), "");
+static QRegExp * rx = 0;
+ if (rx == 0) {
+ rx = new QRegExp("\\(.*");
+ }
+ name.replace(*rx, "");
InvokeSlot slot(self, rb_intern(name.toLatin1()), mocArgs, _o);
slot.next();
@@ -2627,7 +2656,11 @@
{
VALUE klass = Qnil;
QString packageName(package);
- QRegExp scope_op("^([^:]+)::([^:]+)$");
+
+static QRegExp * scope_op = 0;
+ if (scope_op == 0) {
+ scope_op = new QRegExp("^([^:]+)::([^:]+)$");
+ }
if (packageName.startsWith("KDE::ConfigSkeleton::ItemEnum::")) {
klass = rb_define_class_under(kconfigskeleton_itemenum_class, \
package+strlen("KDE::ConfigSkeleton::EnumItem::"), base_class); @@ -2665,7 +2698,7 @@
} else if (packageName.startsWith("Kontact::")) {
klass = rb_define_class_under(kontact_module, package+strlen("Kontact::"), \
base_class); rb_define_singleton_method(klass, "new", (VALUE (*) (...)) _new_kde, \
-1);
- } else if (packageName.startsWith("Ko") && scope_op.indexIn(packageName) == -1) {
+ } else if (packageName.startsWith("Ko") && scope_op->indexIn(packageName) == -1) {
klass = rb_define_class_under(koffice_module, package+strlen("Ko"), base_class);
rb_define_singleton_method(klass, "new", (VALUE (*) (...)) _new_kde, -1);
} else if (packageName.startsWith("Kate::")) {
@@ -2677,11 +2710,11 @@
} else if (packageName.startsWith("KTextEditor::")) {
klass = rb_define_class_under(ktexteditor_module, package+strlen("KTextEditor::"), \
base_class); rb_define_singleton_method(klass, "new", (VALUE (*) (...)) _new_kde, \
-1);
- } else if (scope_op.indexIn(packageName) != -1) {
+ } else if (scope_op->indexIn(packageName) != -1) {
// If an unrecognised classname of the form 'XXXXXX::YYYYYY' is found,
// then create a module XXXXXX to put the class YYYYYY under
- VALUE module = rb_define_module(scope_op.cap(1).toLatin1());
- klass = rb_define_class_under(module, scope_op.cap(2).toLatin1(), base_class);
+ VALUE module = rb_define_module(scope_op->cap(1).toLatin1());
+ klass = rb_define_class_under(module, scope_op->cap(2).toLatin1(), base_class);
} else if ( packageName.startsWith("K")
&& packageName.mid(1, 1).contains(QRegExp("[A-Z]")) == 1 )
{
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic