aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2024-02-09 21:35:09 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2024-03-05 14:06:28 +0100
commit241b8693d69c73b1177235830049d470aa056aa1 (patch)
treeb6b6eeea3e04bc0d2db73a0dd0f16ba79533f5a5 /src/qml/jsruntime
parentb0d753ee3a76aaf57a7dafc79f951da2013b3025 (diff)
Prepare for white allocation during gc(3/9): Function
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 <olivier.decanniere@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit_p.h1
-rw-r--r--src/qml/jsruntime/qv4function.cpp24
-rw-r--r--src/qml/jsruntime/qv4function_p.h12
-rw-r--r--src/qml/jsruntime/qv4script.cpp7
-rw-r--r--src/qml/jsruntime/qv4script_p.h6
5 files changed, 32 insertions, 18 deletions
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 QList<QByteArr
}
- internalClass = engine->internalClasses(EngineBase::Class_CallContext);
+ Scope scope(engine);
+ Scoped<InternalClass> 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 &parameterName : 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<CompilationUnitRuntimeData, 1> 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<QV4::ExecutableCompilationUnit *>(compilationUnit);
+ return static_cast<QV4::ExecutableCompilationUnit *>(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<Heap::InternalClass> 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<QByteArray> &parameters);
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<ExecutableCompilationUnit> &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<ExecutableCompilationUnit> compilationUnit;
- Function *vmFunction;
+ QV4::WriteBarrier::Pointer<Function> vmFunction;
bool parseAsBinding;
void parse();