aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-03-03 21:00:30 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-07 16:55:12 +0100
commit48251fd737447710775727f55e7334ec1c6af1f4 (patch)
treecf9fe657bf65c6c6a984ab73f2dc0785f07d45b5 /src/qml/jsruntime
parentf5f4c3c47c8ee4141f8355f2bce95ef3ef1890bf (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 <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4context.cpp51
-rw-r--r--src/qml/jsruntime/qv4context_p.h2
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp27
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h5
-rw-r--r--src/qml/jsruntime/qv4script.cpp2
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();