Move most of the ExecutionContext's over to the new mark handling

CallContext still requires further work, as the handling of locals
is different between a CallContext and a SimpleCallContext.

Change-Id: I74945ef701f60907aab0fb1a9939da1331235f6e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Lars Knoll 2017-01-25 15:24:27 +01:00
parent 6b4b2f5f1b
commit 4de7e48ab1
3 changed files with 48 additions and 60 deletions

View File

@ -264,52 +264,21 @@ bool CallContext::needsOwnArguments() const
return (f && f->needsActivation()) || (argc() < (f ? static_cast<int>(f->nFormals) : 0));
}
void ExecutionContext::markObjects(Heap::Base *m, ExecutionEngine *engine)
void CallContext::markObjects(Heap::Base *m, ExecutionEngine *engine)
{
ExecutionContext::Data *ctx = static_cast<ExecutionContext::Data *>(m);
QV4::Heap::CallContext *ctx = static_cast<Heap::CallContext *>(m);
if (ctx->outer)
ctx->outer->mark(engine);
switch (ctx->type) {
case Heap::ExecutionContext::Type_CatchContext: {
CatchContext::Data *c = static_cast<CatchContext::Data *>(ctx);
c->exceptionVarName->mark(engine);
c->exceptionValue.mark(engine);
break;
}
case Heap::ExecutionContext::Type_WithContext: {
WithContext::Data *w = static_cast<WithContext::Data *>(ctx);
if (w->withObject)
w->withObject->mark(engine);
break;
}
case Heap::ExecutionContext::Type_GlobalContext: {
GlobalContext::Data *g = static_cast<GlobalContext::Data *>(ctx);
g->global->mark(engine);
break;
}
case Heap::ExecutionContext::Type_SimpleCallContext:
break;
case Heap::ExecutionContext::Type_CallContext: {
QV4::Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx);
Q_ASSERT(c->v4Function);
if (ctx->type == Heap::ExecutionContext::Type_CallContext) {
Q_ASSERT(ctx->v4Function);
ctx->callData->thisObject.mark(engine);
for (int arg = 0; arg < qMax(ctx->callData->argc, (int)c->v4Function->nFormals); ++arg)
for (int arg = 0; arg < qMax(ctx->callData->argc, (int)ctx->v4Function->nFormals); ++arg)
ctx->callData->args[arg].mark(engine);
for (unsigned local = 0, lastLocal = c->v4Function->compiledFunction->nLocals; local < lastLocal; ++local)
c->locals[local].mark(engine);
if (c->activation)
c->activation->mark(engine);
if (c->function)
c->function->mark(engine);
break;
}
case Heap::ExecutionContext::Type_QmlContext: {
QmlContext::Data *g = static_cast<QmlContext::Data *>(ctx);
g->qml->mark(engine);
break;
}
for (unsigned local = 0, lastLocal = ctx->v4Function->compiledFunction->nLocals; local < lastLocal; ++local)
ctx->locals[local].mark(engine);
if (ctx->activation)
ctx->activation->mark(engine);
if (ctx->function)
ctx->function->mark(engine);
}
}

View File

@ -95,7 +95,11 @@ namespace Heap {
struct QmlContext;
struct ExecutionContext : Base {
#define ExecutionContextMembers(class, Member) \
Member(class, Pointer<ExecutionContext>, outer)
DECLARE_HEAP_OBJECT(ExecutionContext, Base) {
DECLARE_MARK_TABLE(ExecutionContext);
enum ContextType {
Type_GlobalContext = 0x1,
Type_CatchContext = 0x2,
@ -117,7 +121,6 @@ struct ExecutionContext : Base {
CallData *callData;
ExecutionEngine *engine;
Pointer<ExecutionContext> outer;
Lookup *lookups;
const QV4::Value *constantTable;
CompiledData::CompilationUnit *compilationUnit;
@ -128,7 +131,12 @@ struct ExecutionContext : Base {
};
V4_ASSERT_IS_TRIVIAL(ExecutionContext)
struct CallContext : ExecutionContext {
#define CallContextMembers(class, Member) \
Member(class, Pointer<FunctionObject>, function) \
Member(class, Pointer<Object>, activation)
DECLARE_HEAP_OBJECT(CallContext, ExecutionContext) {
DECLARE_MARK_TABLE(CallContext);
static CallContext *createSimpleContext(ExecutionEngine *v4);
void freeSimpleCallContext();
@ -139,27 +147,38 @@ struct CallContext : ExecutionContext {
inline unsigned int formalParameterCount() const;
Pointer<FunctionObject> function;
QV4::Function *v4Function;
Value *locals;
Pointer<Object> activation;
};
V4_ASSERT_IS_TRIVIAL(CallContext)
struct GlobalContext : ExecutionContext {
#define GlobalContextMembers(class, Member) \
Member(class, Pointer<Object>, global)
DECLARE_HEAP_OBJECT(GlobalContext, ExecutionContext) {
DECLARE_MARK_TABLE(GlobalContext);
void init(ExecutionEngine *engine);
Pointer<Object> global;
};
V4_ASSERT_IS_TRIVIAL(GlobalContext)
struct CatchContext : ExecutionContext {
#define CatchContextMembers(class, Member) \
Member(class, Pointer<String>, exceptionVarName) \
Member(class, Value, exceptionValue)
DECLARE_HEAP_OBJECT(CatchContext, ExecutionContext) {
DECLARE_MARK_TABLE(CatchContext);
void init(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue);
Pointer<String> exceptionVarName;
Value exceptionValue;
};
V4_ASSERT_IS_TRIVIAL(CatchContext)
struct WithContext : ExecutionContext {
#define WithContextMembers(class, Member) \
Member(class, Pointer<Object>, withObject)
DECLARE_HEAP_OBJECT(WithContext, ExecutionContext) {
DECLARE_MARK_TABLE(WithContext);
void init(ExecutionContext *outerContext, Object *with)
{
Heap::ExecutionContext::init(outerContext->engine, Heap::ExecutionContext::Type_WithContext);
@ -171,8 +190,6 @@ struct WithContext : ExecutionContext {
withObject = with;
}
Pointer<Object> withObject;
};
V4_ASSERT_IS_TRIVIAL(WithContext)
@ -207,8 +224,6 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
Function *getFunction() const;
static void markObjects(Heap::Base *m, ExecutionEngine *e);
Value &thisObject() const {
return d()->callData->thisObject;
}
@ -239,6 +254,7 @@ struct Q_QML_EXPORT CallContext : public ExecutionContext
inline ReturnedValue argument(int i) const;
bool needsOwnArguments() const;
static void markObjects(Heap::Base *m, ExecutionEngine *e);
};
inline ReturnedValue CallContext::argument(int i) const {

View File

@ -77,10 +77,13 @@ struct QmlContextWrapper : Object {
QQmlQPointer<QObject> scopeObject;
};
struct QmlContext : ExecutionContext {
void init(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml);
#define QmlContextMembers(class, Member) \
Member(class, Pointer<QmlContextWrapper>, qml)
Pointer<QmlContextWrapper> qml;
DECLARE_HEAP_OBJECT(QmlContext, ExecutionContext) {
DECLARE_MARK_TABLE(QmlContext);
void init(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml);
};
}