diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4lookup.cpp | 49 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4lookup_p.h | 34 |
5 files changed, 32 insertions, 64 deletions
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 737f377730..4316967484 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -374,7 +374,7 @@ public: const bool m_canAllocateExecutableMemory; #endif - int internalClassIdCount = 0; + quintptr protoIdCount = 1; ExecutionEngine(QJSEngine *jsEngine = nullptr); ~ExecutionEngine(); @@ -398,7 +398,8 @@ public: return static_cast<ExecutionContext *>(¤tStackFrame->jsFrame->context); } - int newInternalClassId() { return ++internalClassIdCount; } + // ensure we always get odd prototype IDs. This helps make marking in QV4::Lookup fast + quintptr newProtoId() { return (protoIdCount += 2); } Heap::InternalClass *newInternalClass(const VTable *vtable, Object *prototype); diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index be9a12bc34..a01e42e817 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -145,7 +145,7 @@ void InternalClass::init(ExecutionEngine *engine) isFrozen = false; isSealed = false; isUsedAsProto = false; - protoId = engine->newInternalClassId(); + protoId = engine->newProtoId(); // Also internal classes need an internal class pointer. Simply make it point to itself internalClass.set(engine, this); @@ -170,7 +170,7 @@ void InternalClass::init(Heap::InternalClass *other) isSealed = other->isSealed; isFrozen = other->isFrozen; isUsedAsProto = other->isUsedAsProto; - protoId = engine->newInternalClassId(); + protoId = engine->newProtoId(); internalClass.set(engine, other->internalClass); } @@ -611,7 +611,7 @@ Heap::InternalClass *InternalClass::asProtoClass() static void updateProtoUsage(Heap::Object *o, Heap::InternalClass *ic) { if (ic->prototype == o) - ic->protoId = ic->engine->newInternalClassId(); + ic->protoId = ic->engine->newProtoId(); for (auto &t : ic->transitions) { if (t.lookup) updateProtoUsage(o, t.lookup); diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index 909335df58..0b6f088bd3 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -264,9 +264,9 @@ struct InternalClassTransition namespace Heap { struct InternalClass : Base { - int protoId; // unique across the engine, gets changed whenever the proto chain changes ExecutionEngine *engine; const VTable *vtable; + quintptr protoId; // unique across the engine, gets changed whenever the proto chain changes Heap::Object *prototype; InternalClass *parent; diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 5730ea7bc0..fdf3d7685d 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -598,53 +598,4 @@ bool Lookup::arrayLengthSetter(Lookup *, ExecutionEngine *engine, Value &object, return true; } -void Lookup::markObjects(MarkStack *stack) -{ - if (getter == getterGeneric || - getter == getterTwoClasses || - getter == getterFallback) { - ; - } else if (getter == getter0MemberData || - getter == getter0Inline || - getter == getterAccessor) { - objectLookup.ic->mark(stack); - } else if (getter == getterProto) { - ; - } else if (getter == getter0Inlinegetter0Inline || - getter == getter0Inlinegetter0MemberData || - getter == getter0MemberDatagetter0MemberData) { - objectLookupTwoClasses.ic->mark(stack); - objectLookupTwoClasses.ic2->mark(stack); - } else if (getter == getterProtoTwoClasses || - getter == getterProtoAccessor || - getter == getterProtoAccessorTwoClasses) { - - } else if (getter == primitiveGetterProto || - getter == primitiveGetterAccessor) { - primitiveLookup.proto->mark(stack); - } else if (getter == stringLengthGetter) { - ; - - } else if (globalGetter == globalGetterGeneric || - globalGetter == globalGetterProto || - globalGetter == globalGetterProtoAccessor) { - ; - - } else if (setter == setterGeneric || - setter == setterTwoClasses || - setter == setterFallback) { - ; - } else if (setter == setter0 || - setter == setter0Inline) { - objectLookup.ic->mark(stack); - } else if (setter == setter0setter0) { - objectLookupTwoClasses.ic->mark(stack); - objectLookupTwoClasses.ic2->mark(stack); - } else if (setter == setterInsert) { - insertionLookup.newClass->mark(stack); - } else if (setter == arrayLengthSetter) { - ; - } -} - QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index 75219d1b84..49eb66d1fb 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -65,7 +65,6 @@ QT_BEGIN_NAMESPACE namespace QV4 { struct Lookup { - enum { Size = 4 }; union { ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const Value &object); ReturnedValue (*globalGetter)(Lookup *l, ExecutionEngine *engine); @@ -73,12 +72,20 @@ struct Lookup { }; union { struct { + Heap::Base *h1; + Heap::Base *h2; + quintptr unused; + quintptr unused2; + } markDef; + struct { Heap::InternalClass *ic; + quintptr _unused; int offset; } objectLookup; struct { + quintptr protoId; + quintptr _unused; const Value *data; - int protoId; } protoLookup; struct { Heap::InternalClass *ic; @@ -87,21 +94,21 @@ struct Lookup { int offset2; } objectLookupTwoClasses; struct { + quintptr protoId; + quintptr protoId2; const Value *data; const Value *data2; - int protoId; - int protoId2; } protoLookupTwoClasses; struct { // Make sure the next two values are in sync with protoLookup - const Value *data; - int protoId; - unsigned type; + quintptr protoId; Heap::Object *proto; + const Value *data; + quintptr type; } primitiveLookup; struct { Heap::InternalClass *newClass; - int protoId; + quintptr protoId; int offset; } insertionLookup; }; @@ -145,7 +152,16 @@ struct Lookup { static bool setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); static bool arrayLengthSetter(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); - void markObjects(MarkStack *stack); + void markObjects(MarkStack *stack) { + if (markDef.h1 && !(reinterpret_cast<quintptr>(markDef.h1) & 1)) + markDef.h1->mark(stack); + if (markDef.h2 && !(reinterpret_cast<quintptr>(markDef.h2) & 1)) + markDef.h2->mark(stack); + } + + void clear() { + memset(&markDef, 0, sizeof(markDef)); + } }; Q_STATIC_ASSERT(std::is_standard_layout<Lookup>::value); |