aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4engine_p.h5
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp6
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h2
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp49
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h34
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 *>(&currentStackFrame->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);