diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2024-02-09 21:29:26 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2024-03-05 14:06:28 +0100 |
commit | e19750538268c4d45fc6c60d2c90b17dd25c81e8 (patch) | |
tree | 03326ac7eab1f453e318f9f93b3447d26724eb7e /src/qml/jsruntime/qv4lookup.cpp | |
parent | 688c98a12da19a88becc152f832beb5c5a01ec47 (diff) |
Prepare for white allocations during gc (1/9): Write barrier for Lookups
Lookups can (and do) reference HeapItems. This was safe in a
non-incremental gc world, as Lookups are always reachable via their
containing CompilationUnits, which are part of the root set. However,
when using an incremental gc, an already marked Lookup might reference a
new heap item, which then becomes otherwise unreachable.
This is alleviated by the fact that Lookups generally either refer to
something already existing or a freshly allocated string. The latter
however is only safe when we can rely on black allocations during gc,
and the former is somewhat reckless.
Remedy this by employing the WriteBarrier for Lookups. We wrap all
HeapItems in a helper class, which -while trivial itself- can't be used
for direct assignments. Intead, it employs a set method which ensures
that the WriteBarrier is used.
Task-number: QTBUG-121910
Change-Id: I6a0ede66ad044076d2e87f134bc95686cb586aee
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4lookup.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4lookup.cpp | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 402cf70408..654275a709 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -54,12 +54,12 @@ ReturnedValue Lookup::resolvePrimitiveGetter(ExecutionEngine *engine, const Valu return engine->throwTypeError(message); } case Value::Boolean_Type: - primitiveLookup.proto = engine->booleanPrototype()->d(); + primitiveLookup.proto.set(engine, engine->booleanPrototype()->d()); break; case Value::Managed_Type: { // ### Should move this over to the Object path, as strings also have an internalClass Q_ASSERT(object.isStringOrSymbol()); - primitiveLookup.proto = static_cast<const Managed &>(object).internalClass()->prototype; + primitiveLookup.proto.set(engine, static_cast<const Managed &>(object).internalClass()->prototype); Q_ASSERT(primitiveLookup.proto); Scope scope(engine); ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]); @@ -72,7 +72,7 @@ ReturnedValue Lookup::resolvePrimitiveGetter(ExecutionEngine *engine, const Valu } case Value::Integer_Type: default: // Number - primitiveLookup.proto = engine->numberPrototype()->d(); + primitiveLookup.proto.set(engine, engine->numberPrototype()->d()); } PropertyKey name = engine->identifierTable->asPropertyKey(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]); @@ -122,9 +122,10 @@ static inline void setupObjectLookupTwoClasses(Lookup *l, const Lookup &first, c const uint offset1 = first.objectLookup.offset; Heap::InternalClass *ic2 = second.objectLookup.ic; const uint offset2 = second.objectLookup.offset; + auto engine = ic1->engine; - l->objectLookupTwoClasses.ic = ic1; - l->objectLookupTwoClasses.ic2 = ic2; + l->objectLookupTwoClasses.ic.set(engine, ic1); + l->objectLookupTwoClasses.ic2.set(engine, ic2); l->objectLookupTwoClasses.offset = offset1; l->objectLookupTwoClasses.offset2 = offset2; } @@ -565,8 +566,9 @@ bool Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, } if (l->setter == Lookup::setter0MemberData || l->setter == Lookup::setter0Inline) { - l->objectLookupTwoClasses.ic = ic; - l->objectLookupTwoClasses.ic2 = ic; + auto engine = ic->engine; + l->objectLookupTwoClasses.ic.set(engine, ic); + l->objectLookupTwoClasses.ic2.set(engine, ic); l->objectLookupTwoClasses.offset = index; l->objectLookupTwoClasses.offset2 = index; l->setter = setter0setter0; |