diff options
author | Lars Knoll <[email protected]> | 2014-03-03 21:00:30 +0100 |
---|---|---|
committer | The Qt Project <[email protected]> | 2014-03-07 16:55:12 +0100 |
commit | 48251fd737447710775727f55e7334ec1c6af1f4 (patch) | |
tree | cf9fe657bf65c6c6a984ab73f2dc0785f07d45b5 /src | |
parent | f5f4c3c47c8ee4141f8355f2bce95ef3ef1890bf (diff) |
Reduce memory consumption of FunctionObject
Remove varCount and formalParameterCount members
in FunctionObject and retrieve them from the
CompiledFunction instead.
Change-Id: I8a6cdc6d354b0f33da9d67a4c3dbfe8a7cc96176
Reviewed-by: Simon Hausmann <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 51 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 27 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4script.cpp | 2 |
6 files changed, 39 insertions, 52 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 5dedd59770..1f2821910a 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -89,7 +89,7 @@ void ArgumentsObject::fullyCreate() if (fullyCreated) return; - uint numAccessors = qMin((int)context->function->formalParameterCount, context->realArgumentCount); + uint numAccessors = qMin((int)context->function->formalParameterCount(), context->realArgumentCount); uint argCount = qMin(context->realArgumentCount, context->callData->argc); ArrayData::realloc(this, ArrayData::Sparse, 0, argCount, true); context->engine->requireArgumentsAccessors(numAccessors); @@ -189,7 +189,7 @@ PropertyAttributes ArgumentsObject::queryIndexed(const Managed *m, uint index) if (args->fullyCreated) return Object::queryIndexed(m, index); - uint numAccessors = qMin((int)args->context->function->formalParameterCount, args->context->realArgumentCount); + uint numAccessors = qMin((int)args->context->function->formalParameterCount(), args->context->realArgumentCount); uint argCount = qMin(args->context->realArgumentCount, args->context->callData->argc); if (index >= argCount) return PropertyAttributes(); diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 8a78b18df1..4878592426 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -55,6 +55,8 @@ DEFINE_MANAGED_VTABLE(ExecutionContext); CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData) { + Q_ASSERT(function->function); + CallContext *c = static_cast<CallContext *>(engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(function, callData->argc))); new (c) CallContext(engine, Type_CallContext); @@ -66,21 +68,20 @@ CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData c->activation = 0; - if (function->function) { - c->compilationUnit = function->function->compilationUnit; - c->lookups = c->compilationUnit->runtimeLookups; - } - + c->compilationUnit = function->function->compilationUnit; + c->lookups = c->compilationUnit->runtimeLookups; c->locals = (Value *)((quintptr(c + 1) + 7) & ~7); - if (function->varCount) - std::fill(c->locals, c->locals + function->varCount, Primitive::undefinedValue()); + const CompiledData::Function *compiledFunction = function->function->compiledFunction; + int nLocals = compiledFunction->nLocals; + if (nLocals) + std::fill(c->locals, c->locals + nLocals, Primitive::undefinedValue()); - c->callData = reinterpret_cast<CallData *>(c->locals + function->varCount); + c->callData = reinterpret_cast<CallData *>(c->locals + nLocals); ::memcpy(c->callData, callData, sizeof(CallData) + (callData->argc - 1) * sizeof(Value)); - if (callData->argc < static_cast<int>(function->formalParameterCount)) - std::fill(c->callData->args + c->callData->argc, c->callData->args + function->formalParameterCount, Primitive::undefinedValue()); - c->callData->argc = qMax((uint)callData->argc, function->formalParameterCount); + if (callData->argc < static_cast<int>(compiledFunction->nFormals)) + std::fill(c->callData->args + c->callData->argc, c->callData->args + compiledFunction->nFormals, Primitive::undefinedValue()); + c->callData->argc = qMax((uint)callData->argc, compiledFunction->nFormals); return c; } @@ -145,7 +146,7 @@ unsigned int ExecutionContext::formalCount() const if (type < Type_SimpleCallContext) return 0; QV4::FunctionObject *f = static_cast<const CallContext *>(this)->function; - return f ? f->formalParameterCount : 0; + return f ? f->formalParameterCount() : 0; } String * const *ExecutionContext::variables() const @@ -161,7 +162,7 @@ unsigned int ExecutionContext::variableCount() const if (type < Type_SimpleCallContext) return 0; QV4::FunctionObject *f = static_cast<const CallContext *>(this)->function; - return f ? f->varCount : 0; + return f ? f->varCount() : 0; } @@ -215,8 +216,8 @@ CallContext::CallContext(ExecutionEngine *engine, ObjectRef qml, FunctionObject } locals = (Value *)(this + 1); - if (function->varCount) - std::fill(locals, locals + function->varCount, Primitive::undefinedValue()); + if (function->varCount()) + std::fill(locals, locals + function->varCount(), Primitive::undefinedValue()); } @@ -259,7 +260,7 @@ bool ExecutionContext::deleteProperty(const StringRef name) bool CallContext::needsOwnArguments() const { - return function->needsActivation || callData->argc < static_cast<int>(function->formalParameterCount); + return function->needsActivation || callData->argc < static_cast<int>(function->formalParameterCount()); } void ExecutionContext::markObjects(Managed *m, ExecutionEngine *engine) @@ -314,10 +315,10 @@ void ExecutionContext::setProperty(const StringRef name, const ValueRef value) if (c->function->function) { uint index = c->function->function->internalClass->find(name); if (index < UINT_MAX) { - if (index < c->function->formalParameterCount) { - c->callData->args[c->function->formalParameterCount - index - 1] = *value; + if (index < c->function->formalParameterCount()) { + c->callData->args[c->function->formalParameterCount() - index - 1] = *value; } else { - index -= c->function->formalParameterCount; + index -= c->function->formalParameterCount(); c->locals[index] = *value; } return; @@ -380,9 +381,9 @@ ReturnedValue ExecutionContext::getProperty(const StringRef name) if (f->function && (f->needsActivation || hasWith || hasCatchScope)) { uint index = f->function->internalClass->find(name); if (index < UINT_MAX) { - if (index < c->function->formalParameterCount) - return c->callData->args[c->function->formalParameterCount - index - 1].asReturnedValue(); - return c->locals[index - c->function->formalParameterCount].asReturnedValue(); + if (index < c->function->formalParameterCount()) + return c->callData->args[c->function->formalParameterCount() - index - 1].asReturnedValue(); + return c->locals[index - c->function->formalParameterCount()].asReturnedValue(); } } if (c->activation) { @@ -446,9 +447,9 @@ ReturnedValue ExecutionContext::getPropertyAndBase(const StringRef name, ObjectR if (f->function && (f->needsActivation || hasWith || hasCatchScope)) { uint index = f->function->internalClass->find(name); if (index < UINT_MAX) { - if (index < c->function->formalParameterCount) - return c->callData->args[c->function->formalParameterCount - index - 1].asReturnedValue(); - return c->locals[index - c->function->formalParameterCount].asReturnedValue(); + if (index < c->function->formalParameterCount()) + return c->callData->args[c->function->formalParameterCount() - index - 1].asReturnedValue(); + return c->locals[index - c->function->formalParameterCount()].asReturnedValue(); } } if (c->activation) { diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index c22d983329..952582ac00 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -256,7 +256,7 @@ inline Scope::Scope(ExecutionContext *ctx) /* Function *f, int argc */ #define requiredMemoryForExecutionContect(f, argc) \ - ((sizeof(CallContext) + 7) & ~7) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount)) + sizeof(CallData) + ((sizeof(CallContext) + 7) & ~7) + sizeof(Value) * (f->varCount() + qMax((uint)argc, f->formalParameterCount())) + sizeof(CallData) } // namespace QV4 diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index e8a442faca..f0002b3b4e 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -77,8 +77,6 @@ DEFINE_OBJECT_VTABLE(FunctionObject); FunctionObject::FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto) : Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass) , scope(scope) - , formalParameterCount(0) - , varCount(0) , function(0) , protoCacheClass(0) , protoCacheIndex(UINT_MAX) @@ -89,8 +87,6 @@ FunctionObject::FunctionObject(ExecutionContext *scope, const StringRef name, bo FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, bool createProto) : Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass) , scope(scope) - , formalParameterCount(0) - , varCount(0) , function(0) , protoCacheClass(0) , protoCacheIndex(UINT_MAX) @@ -107,8 +103,6 @@ FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, boo FunctionObject::FunctionObject(InternalClass *ic) : Object(ic) , scope(ic->engine->rootContext) - , formalParameterCount(0) - , varCount(0) , function(0) { name = ic->engine->id_undefined; @@ -171,11 +165,6 @@ void FunctionObject::markObjects(Managed *that, ExecutionEngine *e) FunctionObject *o = static_cast<FunctionObject *>(that); if (o->name.managed()) o->name->mark(e); - // these are marked in VM::Function: -// for (uint i = 0; i < formalParameterCount; ++i) -// formalParameterList[i]->mark(); -// for (uint i = 0; i < varCount; ++i) -// varList[i]->mark(); o->scope->mark(e); Object::markObjects(that, e); @@ -416,10 +405,8 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function) needsActivation = function->needsActivation(); strictMode = function->isStrict(); - formalParameterCount = function->compiledFunction->nFormals; - varCount = function->internalClass->size - function->compiledFunction->nFormals; - defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount)); + defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount())); if (scope->strictMode) { Property pd = Property::fromAccessor(v4->thrower, v4->thrower); @@ -501,10 +488,8 @@ SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *fu needsActivation = function->needsActivation(); strictMode = function->isStrict(); - formalParameterCount = function->compiledFunction->nFormals; - varCount = function->internalClass->size - function->compiledFunction->nFormals; - defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount)); + defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount())); if (scope->strictMode) { Property pd = Property::fromAccessor(v4->thrower, v4->thrower); @@ -536,8 +521,8 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData) ctx.compilationUnit = f->function->compilationUnit; ctx.lookups = ctx.compilationUnit->runtimeLookups; ctx.outer = f->scope; - ctx.locals = v4->stackPush(f->varCount); - while (callData->argc < (int)f->formalParameterCount) { + ctx.locals = v4->stackPush(f->varCount()); + while (callData->argc < (int)f->formalParameterCount()) { callData->args[callData->argc] = Encode::undefined(); ++callData->argc; } @@ -573,8 +558,8 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData) ctx.compilationUnit = f->function->compilationUnit; ctx.lookups = ctx.compilationUnit->runtimeLookups; ctx.outer = f->scope; - ctx.locals = v4->stackPush(f->varCount); - while (callData->argc < (int)f->formalParameterCount) { + ctx.locals = v4->stackPush(f->varCount()); + while (callData->argc < (int)f->formalParameterCount()) { callData->args[callData->argc] = Encode::undefined(); ++callData->argc; } diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 1f5bced8f8..ac7fe5daba 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -49,6 +49,7 @@ #include "qv4string_p.h" #include "qv4managed_p.h" #include "qv4property_p.h" +#include "qv4function_p.h" #include "qv4objectiterator_p.h" #include <QtCore/QString> @@ -112,8 +113,8 @@ struct Q_QML_EXPORT FunctionObject: Object { ExecutionContext *scope; StringValue name; - unsigned int formalParameterCount; - unsigned int varCount; + unsigned int formalParameterCount() { return function ? function->compiledFunction->nFormals : 0; } + unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; } Function *function; InternalClass *protoCacheClass; uint protoCacheIndex; diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index cb5424b0ee..195eac669d 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -111,7 +111,7 @@ ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *) Q_ASSERT(This->function); CallContext *ctx = This->qmlContext; - std::fill(ctx->locals, ctx->locals + ctx->function->varCount, Primitive::undefinedValue()); + std::fill(ctx->locals, ctx->locals + ctx->function->varCount(), Primitive::undefinedValue()); engine->pushContext(ctx); ScopedValue result(scope, This->function->code(ctx, This->function->codeData)); engine->popContext(); |