From 943583ca408f5d419de03e54aab48557f5e5bebb Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 7 Nov 2014 18:10:30 +0100 Subject: Store all data members in FunctionObject as heap data Change-Id: Ic061baaf7f5ff08c5e6e7130abd6a650148d3d2d Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4context.cpp | 4 +-- src/qml/jsruntime/qv4functionobject.cpp | 49 ++++++++++++++++++++------------- src/qml/jsruntime/qv4functionobject_p.h | 12 ++++---- src/qml/jsruntime/qv4global_p.h | 1 + src/qml/jsruntime/qv4runtime.cpp | 5 ++-- 5 files changed, 42 insertions(+), 29 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 5d651383c0..a73b85d580 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -59,7 +59,7 @@ Returned *ExecutionContext::newCallContext(FunctionObject *function c->realArgumentCount = callData->argc; c->strictMode = function->strictMode(); - c->outer = function->scope()->d(); + c->outer = function->scope(); c->activation = 0; @@ -168,7 +168,7 @@ Heap::CallContext::CallContext(ExecutionEngine *engine, QV4::Object *qml, QV4::F callData->thisObject = Primitive::undefinedValue(); strictMode = true; - outer = function->scope()->d(); + outer = function->scope(); activation = qml->d(); diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index cc5d6ef00e..54853eea4a 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -64,19 +64,18 @@ DEFINE_OBJECT_VTABLE(FunctionObject); Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, QV4::String *name, bool createProto) : Heap::Object(scope->d()->engine->functionClass) - , scope(scope) + , scope(scope->d()) { - Scope s(scope); + Scope s(scope->engine()); ScopedFunctionObject f(s, this); f->init(name, createProto); } - Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString &name, bool createProto) : Heap::Object(scope->d()->engine->functionClass) - , scope(scope) + , scope(scope->d()) { - Scope s(scope); + Scope s(scope->engine()); ScopedFunctionObject f(s, this); ScopedString n(s, s.engine->newString(name)); f->init(n.getPointer(), createProto); @@ -84,7 +83,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name) : Heap::Object(scope->d()->engine->functionClass) - , scope(scope) + , scope(scope->d()) { Scope s(scope); ScopedFunctionObject f(s, this); @@ -92,9 +91,19 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const Returne f->init(n.getPointer(), false); } +Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const ReturnedValue name) + : Heap::Object(scope->engine->functionClass) + , scope(scope) +{ + Scope s(scope->engine); + ScopedFunctionObject f(s, this); + ScopedString n(s, name); + f->init(n.getPointer(), false); +} + Heap::FunctionObject::FunctionObject(InternalClass *ic) : Heap::Object(ic) - , scope(ic->engine->rootContext) + , scope(ic->engine->rootContext->d()) { Scope scope(ic->engine); ScopedObject o(scope, this); @@ -119,7 +128,7 @@ void FunctionObject::init(String *n, bool createProto) ensureMemberIndex(s.engine, Heap::FunctionObject::Index_Prototype); if (createProto) { - Scoped proto(s, scope()->d()->engine->newObject(scope()->d()->engine->protoClass)); + Scoped proto(s, scope()->engine->newObject(scope()->engine->protoClass)); proto->ensureMemberIndex(s.engine, Heap::FunctionObject::Index_ProtoConstructor); proto->memberData()->data()[Heap::FunctionObject::Index_ProtoConstructor] = this->asReturnedValue(); memberData()->data()[Heap::FunctionObject::Index_Prototype] = proto.asReturnedValue(); @@ -133,7 +142,7 @@ void FunctionObject::init(String *n, bool createProto) ReturnedValue FunctionObject::name() { - return get(scope()->d()->engine->id_name); + return get(scope()->engine->id_name); } @@ -336,7 +345,7 @@ ReturnedValue FunctionPrototype::method_bind(CallContext *ctx) return ctx->engine()->throwTypeError(); ScopedValue boundThis(scope, ctx->argument(0)); - Scoped boundArgs(scope); + Scoped boundArgs(scope, (Heap::MemberData *)0); if (ctx->d()->callData->argc > 1) { boundArgs = MemberData::reallocate(scope.engine, 0, ctx->d()->callData->argc - 1); boundArgs->d()->size = ctx->d()->callData->argc - 1; @@ -460,7 +469,7 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData) ctx.function = f.getPointer()->d(); ctx.compilationUnit = f->function()->compilationUnit; ctx.lookups = ctx.compilationUnit->runtimeLookups; - ctx.outer = f->scope()->d(); + ctx.outer = f->scope(); ctx.locals = v4->stackPush(f->varCount()); while (callData->argc < (int)f->formalParameterCount()) { callData->args[callData->argc] = Encode::undefined(); @@ -497,7 +506,7 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData) ctx.function = f->d(); ctx.compilationUnit = f->function()->compilationUnit; ctx.lookups = ctx.compilationUnit->runtimeLookups; - ctx.outer = f->scope()->d(); + ctx.outer = f->scope(); ctx.locals = v4->stackPush(f->varCount()); while (callData->argc < (int)f->formalParameterCount()) { callData->args[callData->argc] = Encode::undefined(); @@ -555,7 +564,7 @@ ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData) ExecutionContextSaver ctxSaver(context); CallContext::Data ctx(v4); - ctx.strictMode = f->scope()->d()->strictMode; // ### needed? scope or parent context? + ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context? ctx.callData = callData; Q_ASSERT(v4->currentContext()->d() == &ctx); @@ -574,7 +583,7 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData) ExecutionContextSaver ctxSaver(context); CallContext::Data ctx(v4); - ctx.strictMode = f->scope()->d()->strictMode; // ### needed? scope or parent context? + ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context? ctx.callData = callData; Q_ASSERT(v4->currentContext()->d() == &ctx); @@ -588,7 +597,7 @@ DEFINE_OBJECT_VTABLE(BoundFunction); Heap::BoundFunction::BoundFunction(QV4::ExecutionContext *scope, QV4::FunctionObject *target, const ValueRef boundThis, QV4::MemberData *boundArgs) : Heap::FunctionObject(scope, QStringLiteral("__bound function__")) - , target(target) + , target(target->d()) , boundArgs(boundArgs ? boundArgs->d() : 0) { this->boundThis = boundThis; @@ -616,7 +625,7 @@ Heap::BoundFunction::BoundFunction(QV4::ExecutionContext *scope, QV4::FunctionOb ReturnedValue BoundFunction::call(Managed *that, CallData *dd) { BoundFunction *f = static_cast(that); - Scope scope(f->scope()->d()->engine); + Scope scope(f->engine()); if (scope.hasException()) return Encode::undefined(); @@ -629,13 +638,14 @@ ReturnedValue BoundFunction::call(Managed *that, CallData *dd) argp += boundArgs->size(); } memcpy(argp, dd->args, dd->argc*sizeof(Value)); - return f->target()->call(callData); + ScopedFunctionObject t(scope, f->target()); + return t->call(callData); } ReturnedValue BoundFunction::construct(Managed *that, CallData *dd) { BoundFunction *f = static_cast(that); - Scope scope(f->scope()->d()->engine); + Scope scope(f->engine()); if (scope.hasException()) return Encode::undefined(); @@ -647,7 +657,8 @@ ReturnedValue BoundFunction::construct(Managed *that, CallData *dd) argp += boundArgs->size(); } memcpy(argp, dd->args, dd->argc*sizeof(Value)); - return f->target()->construct(callData); + ScopedFunctionObject t(scope, f->target()); + return t->construct(callData); } void BoundFunction::markObjects(Heap::Base *that, ExecutionEngine *e) diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 288777f8eb..7cbdccb8fd 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -60,13 +60,14 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object { FunctionObject(QV4::ExecutionContext *scope, QV4::String *name, bool createProto = false); FunctionObject(QV4::ExecutionContext *scope, const QString &name = QString(), bool createProto = false); FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name); + FunctionObject(ExecutionContext *scope, const ReturnedValue name); FunctionObject(InternalClass *ic); ~FunctionObject(); unsigned int formalParameterCount() { return function ? function->compiledFunction->nFormals : 0; } unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; } - QV4::ExecutionContext *scope; + ExecutionContext *scope; Function *function; }; @@ -99,7 +100,7 @@ struct ScriptFunction : SimpleScriptFunction { struct BoundFunction : FunctionObject { BoundFunction(QV4::ExecutionContext *scope, QV4::FunctionObject *target, const ValueRef boundThis, QV4::MemberData *boundArgs); - QV4::FunctionObject *target; + FunctionObject *target; Value boundThis; MemberData *boundArgs; }; @@ -113,7 +114,7 @@ struct Q_QML_EXPORT FunctionObject: Object { V4_OBJECT2(FunctionObject, Object) Q_MANAGED_TYPE(FunctionObject) - ExecutionContext *scope() { return d()->scope; } + Heap::ExecutionContext *scope() { return d()->scope; } Function *function() { return d()->function; } ReturnedValue name(); @@ -231,10 +232,9 @@ struct BoundFunction: FunctionObject { return scope->engine()->memoryManager->alloc(scope, target, boundThis, boundArgs); } - FunctionObject *target() { return d()->target; } + Heap::FunctionObject *target() { return d()->target; } Value boundThis() const { return d()->boundThis; } - // ### GC - MemberData::Data *boundArgs() const { return d()->boundArgs; } + Heap::MemberData *boundArgs() const { return d()->boundArgs; } static ReturnedValue construct(Managed *, CallData *d); static ReturnedValue call(Managed *that, CallData *dd); diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index e1bef1dede..ae51314e64 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -181,6 +181,7 @@ typedef Scoped ScopedString; typedef Scoped ScopedObject; typedef Scoped ScopedArrayObject; typedef Scoped ScopedFunctionObject; +typedef Scoped ScopedContext; template struct Returned; typedef Returned ReturnedString; typedef Returned ReturnedObject; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index f76e9651a5..6dca0c8ed1 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -298,12 +298,13 @@ QV4::ReturnedValue Runtime::instanceof(ExecutionContext *ctx, const ValueRef lef // As nothing in this method can call into the memory manager, avoid using a Scope // for performance reasons - FunctionObject *f = right->asFunctionObject(); + Scope scope(ctx); + ScopedFunctionObject f(scope, right->asFunctionObject()); if (!f) return ctx->engine()->throwTypeError(); if (f->subtype() == Heap::FunctionObject::BoundFunction) - f = static_cast(f)->target(); + f = static_cast(f.getPointer())->target(); Object *v = left->asObject(); if (!v) -- cgit v1.2.3