From 241b8693d69c73b1177235830049d470aa056aa1 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Fri, 9 Feb 2024 21:35:09 +0100 Subject: Prepare for white allocation during gc(3/9): Function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Function(Data) keeps references to two heap-items; use the newly introduced wrapper classes to ensure writes always go through the WriteBarrier. Provide a "mark" function in ExecutableCompilationUnit so that the wrapper can actually pick it up - the existing function there was called markObjects. We don't rename the existing function to keep the diff minimal. Provide a mark function in Function for the same reason. Task-number: QTBUG-121910 Change-Id: Ib56eb2f3f2315036ce43273c9ebc629d10458e9a Reviewed-by: Olivier De Cannière Reviewed-by: Ulf Hermann --- src/qml/jsruntime/qv4executablecompilationunit_p.h | 1 + src/qml/jsruntime/qv4function.cpp | 24 ++++++++++++++++------ src/qml/jsruntime/qv4function_p.h | 12 +++++------ src/qml/jsruntime/qv4script.cpp | 7 ++++--- src/qml/jsruntime/qv4script_p.h | 6 +++--- 5 files changed, 32 insertions(+), 18 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index 81de2965c2..a67086e57a 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -166,6 +166,7 @@ public: void evaluate(); void evaluateModuleRequests(); + void mark(MarkStack *markStack) const { markObjects(markStack); } void markObjects(MarkStack *markStack) const; QString bindingValueAsString(const CompiledData::Binding *binding) const; diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index ca6574d32b..caba2b1a9a 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -91,6 +91,12 @@ void Function::destroy() delete this; } +void Function::mark(MarkStack *ms) +{ + if (internalClass) + internalClass->mark(ms); +} + static bool isSpecificType(const CompiledData::ParameterType &type) { return type.typeNameIndexOrCommonType() @@ -100,7 +106,7 @@ static bool isSpecificType(const CompiledData::ParameterType &type) Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit, const CompiledData::Function *function, const QQmlPrivate::AOTCompiledFunction *aotFunction) - : FunctionData(unit) + : FunctionData(engine, unit) , compiledFunction(function) , codeData(function->code()) , jittedCode(nullptr) @@ -124,7 +130,7 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit, if (enforceJsTypes && !isSpecificType(formalsIndices[i].type)) enforceJsTypes = false; } - internalClass = ic->d(); + internalClass.set(engine, ic->d()); nFormals = compiledFunction->nFormals; @@ -216,22 +222,23 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QListinternalClasses(EngineBase::Class_CallContext); + Scope scope(engine); + Scoped ic(scope, engine->internalClasses(EngineBase::Class_CallContext)); // first locals const quint32_le *localsIndices = compiledFunction->localsTable(); for (quint32 i = 0; i < compiledFunction->nLocals; ++i) { - internalClass = internalClass->addMember( + ic = ic->addMember( engine->identifierTable->asPropertyKey(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable); } - Scope scope(engine); ScopedString arg(scope); for (const QString ¶meterName : parameterNames) { arg = engine->newIdentifier(parameterName); - internalClass = internalClass->addMember(arg->propertyKey(), Attr_NotConfigurable); + ic = ic->addMember(arg->propertyKey(), Attr_NotConfigurable); } + internalClass.set(engine, ic->d()); nFormals = parameters.size(); } @@ -252,6 +259,11 @@ QQmlSourceLocation Function::sourceLocation() const sourceFile(), compiledFunction->location.line(), compiledFunction->location.column()); } +FunctionData::FunctionData(EngineBase *engine, ExecutableCompilationUnit *compilationUnit_) +{ + compilationUnit.set(engine, compilationUnit_); +} + } // namespace QV4 QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 6cefae8fa8..3c9617f359 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -32,15 +32,13 @@ namespace QV4 { struct Q_QML_EXPORT FunctionData { - CompilationUnitRuntimeData *compilationUnit; + WriteBarrier::HeapObjectWrapper compilationUnit; // Intentionally require an ExecutableCompilationUnit but save only a pointer to // CompilationUnitBase. This is so that we can take advantage of the standard layout // of CompilationUnitBase in the JIT. Furthermore we can safely static_cast to // ExecutableCompilationUnit where we need it. - FunctionData(ExecutableCompilationUnit *compilationUnit) - : compilationUnit(compilationUnit) - {} + FunctionData(EngineBase *engine, ExecutableCompilationUnit *compilationUnit_); }; // Make sure this class can be accessed through offsetof (done by the assemblers): Q_STATIC_ASSERT(std::is_standard_layout< FunctionData >::value); @@ -62,7 +60,7 @@ public: QV4::ExecutableCompilationUnit *executableCompilationUnit() const { // This is safe: We require an ExecutableCompilationUnit in the ctor. - return static_cast(compilationUnit); + return static_cast(compilationUnit.get()); } QV4::Heap::String *runtimeString(uint i) const @@ -86,7 +84,7 @@ public: }; // first nArguments names in internalClass are the actual arguments - Heap::InternalClass *internalClass; + QV4::WriteBarrier::Pointer internalClass; int interpreterCallCount = 0; quint16 nFormals; enum Kind : quint8 { JsUntyped, JsTyped, AotCompiled, Eval }; @@ -98,6 +96,8 @@ public: const QQmlPrivate::AOTCompiledFunction *aotFunction); void destroy(); + void mark(QV4::MarkStack *ms); + // used when dynamically assigning signal handlers (QQmlConnection) void updateInternalClass(ExecutionEngine *engine, const QList ¶meters); diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 05ea21d950..894426ce3b 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -26,14 +26,15 @@ using namespace QQmlJS; Script::Script(ExecutionEngine *v4, QmlContext *qml, const QQmlRefPointer &compilationUnit) : line(1), column(0), context(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false) - , compilationUnit(compilationUnit), vmFunction(nullptr), parseAsBinding(true) + , compilationUnit(compilationUnit), parseAsBinding(true) { if (qml) qmlContext.set(v4, *qml); parsed = true; - vmFunction = compilationUnit ? compilationUnit->rootFunction() : nullptr; + vmFunction.set(v4, + compilationUnit ? compilationUnit->rootFunction() : nullptr); } Script::~Script() @@ -95,7 +96,7 @@ void Script::parse() return; compilationUnit = v4->insertCompilationUnit(cg.generateCompilationUnit()); - vmFunction = compilationUnit->rootFunction(); + vmFunction.set(v4, compilationUnit->rootFunction()); } if (!vmFunction) { diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h index 64bccf1c47..7b3dcae486 100644 --- a/src/qml/jsruntime/qv4script_p.h +++ b/src/qml/jsruntime/qv4script_p.h @@ -36,11 +36,11 @@ struct Q_QML_EXPORT Script { Script(ExecutionContext *scope, QV4::Compiler::ContextType mode, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0) : sourceFile(source), line(line), column(column), sourceCode(sourceCode) , context(scope), strictMode(false), inheritContext(false), parsed(false), contextType(mode) - , vmFunction(nullptr), parseAsBinding(false) {} + , parseAsBinding(false) {} Script(ExecutionEngine *engine, QmlContext *qml, bool parseAsBinding, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0) : sourceFile(source), line(line), column(column), sourceCode(sourceCode) , context(engine->rootContext()), strictMode(false), inheritContext(true), parsed(false) - , vmFunction(nullptr), parseAsBinding(parseAsBinding) { + , parseAsBinding(parseAsBinding) { if (qml) qmlContext.set(engine, *qml); } @@ -57,7 +57,7 @@ struct Q_QML_EXPORT Script { QV4::Compiler::ContextType contextType = QV4::Compiler::ContextType::Eval; QV4::PersistentValue qmlContext; QQmlRefPointer compilationUnit; - Function *vmFunction; + QV4::WriteBarrier::Pointer vmFunction; bool parseAsBinding; void parse(); -- cgit v1.2.3