aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/memory
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-05-12 15:12:45 +0200
committerLars Knoll <lars.knoll@qt.io>2017-05-19 06:23:26 +0000
commitcae7975a036352ca4bbcf1381a445362f8e01367 (patch)
treecb5c3213160cb20ac3a9927125bf01fc7b72a67b /src/qml/memory
parent0cdea188727e203ecc529ef8e4e8859cca0be232 (diff)
Move the internalClass field from Heap::Object to Heap::Base
And do not store the vtable in Heap::Base anymore. This change makes the internal class the main distinguishing feature of all garbage collected objects. It also saves one pointer on all Objects. No measurable impact on runtime performance. Change-Id: I040a28b7581b993f1886b5219e279173dfa567e8 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/memory')
-rw-r--r--src/qml/memory/qv4heap_p.h10
-rw-r--r--src/qml/memory/qv4mm.cpp3
-rw-r--r--src/qml/memory/qv4mm_p.h17
3 files changed, 20 insertions, 10 deletions
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index cd0a6d9a81..a4e96b4c84 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -53,6 +53,7 @@
#include <QtCore/QString>
#include <private/qv4global_p.h>
#include <private/qv4mmdefs_p.h>
+#include <private/qv4internalclass_p.h>
#include <QSharedPointer>
// To check if Heap::Base::init is called (meaning, all subclasses did their init and called their
@@ -69,6 +70,8 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+struct InternalClass;
+
struct VTable
{
const VTable * const parent;
@@ -93,13 +96,12 @@ namespace Heap {
struct Q_QML_EXPORT Base {
void *operator new(size_t) = delete;
- const VTable *vt;
+ InternalClass *internalClass;
inline ReturnedValue asReturnedValue() const;
inline void mark(QV4::ExecutionEngine *engine);
- void setVtable(const VTable *v) { vt = v; }
- const VTable *vtable() const { return vt; }
+ const VTable *vtable() const { return internalClass->vtable; }
inline bool isMarked() const {
const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
Chunk *c = h->chunk();
@@ -166,7 +168,7 @@ V4_ASSERT_IS_TRIVIAL(Base)
// for a size/offset translation when cross-compiling between 32- and
// 64-bit.
Q_STATIC_ASSERT(std::is_standard_layout<Base>::value);
-Q_STATIC_ASSERT(offsetof(Base, vt) == 0);
+Q_STATIC_ASSERT(offsetof(Base, internalClass) == 0);
Q_STATIC_ASSERT(sizeof(Base) == QT_POINTER_SIZE);
template <typename T>
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index ef36e62373..56f1254421 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -787,7 +787,8 @@ Heap::Object *MemoryManager::allocObjectWithMemberData(const QV4::VTable *vtable
m = *blockAllocator.allocate(memberSize, true);
memset(m, 0, memberSize);
o->memberData = static_cast<Heap::MemberData *>(m);
- o->memberData->setVtable(MemberData::staticVTable());
+ o->memberData->internalClass = engine->internalClasses[EngineBase::Class_MemberData];
+ Q_ASSERT(o->memberData->internalClass);
o->memberData->size = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
o->memberData->init();
// qDebug() << " got" << o->memberData << o->memberData->size;
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index 9b4c2cd8df..8f12fa7cbd 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -210,7 +210,8 @@ public:
{
Heap::CallContext *ctxt = stackAllocator.allocate();
memset(ctxt, 0, sizeof(Heap::CallContext));
- ctxt->setVtable(QV4::CallContext::staticVTable());
+ ctxt->internalClass = CallContext::defaultInternalClass(engine);
+ Q_ASSERT(ctxt->internalClass && ctxt->internalClass->vtable);
ctxt->init(v4);
return ctxt;
@@ -224,7 +225,10 @@ public:
V4_ASSERT_IS_TRIVIAL(typename ManagedType::Data)
size = align(size);
Heap::Base *o = allocData(size);
- o->setVtable(ManagedType::staticVTable());
+ InternalClass *ic = ManagedType::defaultInternalClass(engine);
+ ic = ic->changeVTable(ManagedType::staticVTable());
+ o->internalClass = ic;
+ Q_ASSERT(o->internalClass && o->internalClass->vtable);
return static_cast<typename ManagedType::Data *>(o);
}
@@ -232,8 +236,9 @@ public:
typename ObjectType::Data *allocateObject(InternalClass *ic)
{
Heap::Object *o = allocObjectWithMemberData(ObjectType::staticVTable(), ic->size);
- o->setVtable(ObjectType::staticVTable());
o->internalClass = ic;
+ Q_ASSERT(o->internalClass && o->internalClass->vtable);
+ Q_ASSERT(ic->vtable == ObjectType::staticVTable());
return static_cast<typename ObjectType::Data *>(o);
}
@@ -241,10 +246,11 @@ public:
typename ObjectType::Data *allocateObject()
{
InternalClass *ic = ObjectType::defaultInternalClass(engine);
+ ic = ic->changeVTable(ObjectType::staticVTable());
Heap::Object *o = allocObjectWithMemberData(ObjectType::staticVTable(), ic->size);
- o->setVtable(ObjectType::staticVTable());
Object *prototype = ObjectType::defaultPrototype(engine);
o->internalClass = ic;
+ Q_ASSERT(o->internalClass && o->internalClass->vtable);
o->prototype = prototype->d();
return static_cast<typename ObjectType::Data *>(o);
}
@@ -253,7 +259,8 @@ public:
typename ManagedType::Data *allocWithStringData(std::size_t unmanagedSize, Arg1 arg1)
{
typename ManagedType::Data *o = reinterpret_cast<typename ManagedType::Data *>(allocString(unmanagedSize));
- o->setVtable(ManagedType::staticVTable());
+ o->internalClass = ManagedType::defaultInternalClass(engine);
+ Q_ASSERT(o->internalClass && o->internalClass->vtable);
o->init(this, arg1);
return o;
}