Reduce memory consumption of signal handlers

Move the connect/disconnect methods for signal handlers into
their prototype, so that we don't need to define them per instance
anymore.

Change-Id: Iac1e6d1dd7bce86730dbb6c51e2c3f79713641f7
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This commit is contained in:
Lars Knoll 2015-09-09 15:23:18 +02:00
parent c736b099c0
commit 6565e78610
4 changed files with 23 additions and 8 deletions

View File

@ -429,6 +429,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
jsObjects[DataViewProto] = memoryManager->allocObject<DataViewPrototype>();
static_cast<DataViewPrototype *>(dataViewPrototype())->init(this, dataViewCtor());
jsObjects[ValueTypeProto] = (Heap::Base *) 0;
jsObjects[SignalHandlerProto] = (Heap::Base *) 0;
for (int i = 0; i < Heap::TypedArray::NTypes; ++i) {
static_cast<Value &>(typedArrayCtors[i]) = memoryManager->allocObject<TypedArrayCtor>(global, Heap::TypedArray::Type(i));

View File

@ -149,6 +149,7 @@ public:
ArrayBufferProto,
DataViewProto,
ValueTypeProto,
SignalHandlerProto,
Object_Ctor,
String_Ctor,
@ -219,6 +220,7 @@ public:
Object *typedArrayPrototype;
Object *valueTypeWrapperPrototype() const { return reinterpret_cast<Object *>(jsObjects + ValueTypeProto); }
Object *signalHandlerPrototype() const { return reinterpret_cast<Object *>(jsObjects + SignalHandlerProto); }
InternalClassPool *classPool;
InternalClass *emptyClass;

View File

@ -335,14 +335,8 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje
ScopedContext global(scope, scope.engine->qmlContext());
return QV4::QObjectMethod::create(global, object, property->coreIndex);
} else if (property->isSignalHandler()) {
QV4::Scoped<QV4::QmlSignalHandler> handler(scope, scope.engine->memoryManager->allocObject<QV4::QmlSignalHandler>(object, property->coreIndex));
QV4::ScopedString connect(scope, engine->newIdentifier(QStringLiteral("connect")));
QV4::ScopedString disconnect(scope, engine->newIdentifier(QStringLiteral("disconnect")));
handler->put(connect, QV4::ScopedValue(scope, engine->functionPrototype()->get(connect)));
handler->put(disconnect, QV4::ScopedValue(scope, engine->functionPrototype()->get(disconnect)));
return handler.asReturnedValue();
QmlSignalHandler::initProto(engine);
return engine->memoryManager->allocObject<QV4::QmlSignalHandler>(object, property->coreIndex)->asReturnedValue();
} else {
ExecutionContext *global = scope.engine->rootContext();
return QV4::QObjectMethod::create(global, object, property->coreIndex);
@ -1891,6 +1885,21 @@ Heap::QmlSignalHandler::QmlSignalHandler(QObject *object, int signalIndex)
DEFINE_OBJECT_VTABLE(QmlSignalHandler);
void QmlSignalHandler::initProto(ExecutionEngine *engine)
{
if (engine->signalHandlerPrototype()->d())
return;
Scope scope(engine);
ScopedObject o(scope, engine->newObject());
QV4::ScopedString connect(scope, engine->newIdentifier(QStringLiteral("connect")));
QV4::ScopedString disconnect(scope, engine->newIdentifier(QStringLiteral("disconnect")));
o->put(connect, QV4::ScopedValue(scope, engine->functionPrototype()->get(connect)));
o->put(disconnect, QV4::ScopedValue(scope, engine->functionPrototype()->get(disconnect)));
engine->jsObjects[QV4::ExecutionEngine::SignalHandlerProto] = o->d();
}
void MultiplyWrappedQObjectMap::insert(QObject *key, Heap::Object *value)
{
QV4::WeakValue v;

View File

@ -169,10 +169,13 @@ struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject
struct QmlSignalHandler : public QV4::Object
{
V4_OBJECT2(QmlSignalHandler, QV4::Object)
V4_PROTOTYPE(signalHandlerPrototype)
V4_NEEDS_DESTROY
int signalIndex() const { return d()->signalIndex; }
QObject *object() const { return d()->object.data(); }
static void initProto(ExecutionEngine *v4);
};
class MultiplyWrappedQObjectMap : public QObject,