Store all data members in FunctionObject as heap data
authorLars Knoll <lars.knoll@theqtcompany.com>
Fri, 7 Nov 2014 17:10:30 +0000 (18:10 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Wed, 12 Nov 2014 11:13:14 +0000 (12:13 +0100)
Change-Id: Ic061baaf7f5ff08c5e6e7130abd6a650148d3d2d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jsruntime/qv4context.cpp
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4functionobject_p.h
src/qml/jsruntime/qv4global_p.h
src/qml/jsruntime/qv4runtime.cpp

index 5d65138..a73b85d 100644 (file)
@@ -59,7 +59,7 @@ Returned<CallContext> *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();
 
index cc5d6ef..54853ee 100644 (file)
@@ -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<Object> proto(s, scope()->d()->engine->newObject(scope()->d()->engine->protoClass));
+        Scoped<Object> 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<MemberData> boundArgs(scope);
+    Scoped<MemberData> 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<BoundFunction *>(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<BoundFunction *>(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)
index 288777f..7cbdccb 100644 (file)
@@ -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<BoundFunction>(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);
index e1bef1d..ae51314 100644 (file)
@@ -181,6 +181,7 @@ typedef Scoped<String> ScopedString;
 typedef Scoped<Object> ScopedObject;
 typedef Scoped<ArrayObject> ScopedArrayObject;
 typedef Scoped<FunctionObject> ScopedFunctionObject;
+typedef Scoped<ExecutionContext> ScopedContext;
 template<typename T> struct Returned;
 typedef Returned<String> ReturnedString;
 typedef Returned<Object> ReturnedObject;
index f76e965..6dca0c8 100644 (file)
@@ -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<BoundFunction *>(f)->target();
+        f = static_cast<BoundFunction *>(f.getPointer())->target();
 
     Object *v = left->asObject();
     if (!v)