diff options
author | Lars Knoll <lars.knoll@digia.com> | 2014-01-20 16:01:26 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-23 21:47:27 +0100 |
commit | 9fb297a54bd0226b4827b5d7ca093a7f9c4922fa (patch) | |
tree | b53967ff783246a094ccd136f8f8acc2bb511949 /src/qml/jsruntime | |
parent | 07429ea2a581dbf25d36e51375918e4cdb0962c9 (diff) |
Turn ArrayData into a Managed object
Memory manage ArrayData. Once the ArrayData is moved
to be inline inside the object, this will save quite
some time for allocating and freeing arrays.
Change-Id: I19a520161d41bfe3d83f377af0b41db4ac5b99e4
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arraydata.cpp | 42 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arraydata_p.h | 81 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 15 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4managed.cpp | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4managed_p.h | 58 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4string.cpp | 14 |
9 files changed, 86 insertions, 145 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 5e4debdd4a..4a3c3c1faa 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -51,12 +51,12 @@ ArgumentsObject::ArgumentsObject(CallContext *context) , context(context) , fullyCreated(false) { - setArrayType(ArrayData::Complex); - ExecutionEngine *v4 = context->engine; Scope scope(v4); ScopedObject protectThis(scope, this); + setArrayType(ArrayData::Complex); + if (context->strictMode) { Property pd = Property::fromAccessor(v4->thrower, v4->thrower); Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee)); diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index 933449b96e..a71aa12310 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -46,9 +46,8 @@ using namespace QV4; const ArrayVTable SimpleArrayData::static_vtbl = { + DEFINE_MANAGED_VTABLE_INT(SimpleArrayData), SimpleArrayData::Simple, - SimpleArrayData::destroy, - SimpleArrayData::markObjects, SimpleArrayData::reserve, SimpleArrayData::get, SimpleArrayData::put, @@ -64,9 +63,8 @@ const ArrayVTable SimpleArrayData::static_vtbl = const ArrayVTable SparseArrayData::static_vtbl = { + DEFINE_MANAGED_VTABLE_INT(SparseArrayData), ArrayData::Sparse, - SparseArrayData::destroy, - SparseArrayData::markObjects, SparseArrayData::reserve, SparseArrayData::get, SparseArrayData::put, @@ -141,20 +139,20 @@ void ArrayData::ensureAttributes() } -void SimpleArrayData::destroy(ArrayData *d) +void SimpleArrayData::destroy(Managed *d) { SimpleArrayData *dd = static_cast<SimpleArrayData *>(d); delete [] (dd->data - dd->offset); if (dd->attrs) delete [] (dd->attrs - dd->offset); - delete dd; } -void SimpleArrayData::markObjects(ArrayData *d, ExecutionEngine *e) +void SimpleArrayData::markObjects(Managed *d, ExecutionEngine *e) { - uint l = static_cast<SimpleArrayData *>(d)->len; + SimpleArrayData *dd = static_cast<SimpleArrayData *>(d); + uint l = dd->len; for (uint i = 0; i < l; ++i) - d->data[i].mark(e); + dd->data[i].mark(e); } ReturnedValue SimpleArrayData::get(const ArrayData *d, uint index) @@ -298,20 +296,21 @@ void SparseArrayData::free(ArrayData *d, uint idx) } -void SparseArrayData::destroy(ArrayData *d) +void SparseArrayData::destroy(Managed *d) { - delete static_cast<SparseArrayData *>(d)->sparse; - delete [] d->data; - if (d->attrs) - delete [] d->attrs; - delete d; + SparseArrayData *dd = static_cast<SparseArrayData *>(d); + delete dd->sparse; + delete [] dd->data; + if (dd->attrs) + delete [] dd->attrs; } -void SparseArrayData::markObjects(ArrayData *d, ExecutionEngine *e) +void SparseArrayData::markObjects(Managed *d, ExecutionEngine *e) { - uint l = d->alloc; + SparseArrayData *dd = static_cast<SparseArrayData *>(d); + uint l = dd->alloc; for (uint i = 0; i < l; ++i) - d->data[i].mark(e); + dd->data[i].mark(e); } void SparseArrayData::reserve(ArrayData *d, uint n) @@ -603,9 +602,9 @@ void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const Valu if (!sparse->sparse->nEntries()) return; - SimpleArrayData *d = new SimpleArrayData; + SimpleArrayData *d = new (context->engine->memoryManager) SimpleArrayData(context->engine); thisObject->arrayData = d; - d->vtable->reserve(d, sparse->sparse->nEntries()); + d->vtable()->reserve(d, sparse->sparse->nEntries()); SparseArrayNode *n = sparse->sparse->begin(); uint i = 0; @@ -645,8 +644,7 @@ void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const Valu } } - - sparse->ArrayData::destroy(); + // ### explicitly delete sparse } else { SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData); if (len > d->len) diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h index 9d9e5705d6..e0f8964bee 100644 --- a/src/qml/jsruntime/qv4arraydata_p.h +++ b/src/qml/jsruntime/qv4arraydata_p.h @@ -50,13 +50,20 @@ QT_BEGIN_NAMESPACE namespace QV4 { +#define V4_ARRAYDATA \ + public: \ + Q_MANAGED_CHECK \ + static const QV4::ArrayVTable static_vtbl; \ + static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \ + template <typename T> \ + QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \ + struct ArrayData; struct ArrayVTable { + ManagedVTable managedVTable; uint type; - void (*destroy)(ArrayData *d); - void (*markObjects)(ArrayData *, ExecutionEngine *e); void (*reserve)(ArrayData *d, uint n); ReturnedValue (*get)(const ArrayData *d, uint index); bool (*put)(ArrayData *d, uint index, ValueRef value); @@ -71,10 +78,10 @@ struct ArrayVTable }; -struct Q_QML_EXPORT ArrayData +struct Q_QML_EXPORT ArrayData : public Managed { - ArrayData() - : vtable(0) + ArrayData(InternalClass *ic) + : Managed(ic) , alloc(0) , type(0) , attrs(0) @@ -89,18 +96,18 @@ struct Q_QML_EXPORT ArrayData Custom = 3 }; - const ArrayVTable *vtable; uint alloc; uint type; PropertyAttributes *attrs; SafeValue *data; + const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass->vtable); } bool isSparse() const { return this && type == Sparse; } uint length() const { if (!this) return 0; - return vtable->length(this); + return vtable()->length(this); } bool hasAttributes() const { @@ -109,60 +116,52 @@ struct Q_QML_EXPORT ArrayData void ensureAttributes(); PropertyAttributes attributes(int i) const { Q_ASSERT(this); - return attrs ? vtable->attribute(this, i) : Attr_Data; + return attrs ? vtable()->attribute(this, i) : Attr_Data; } void setAttributes(uint i, PropertyAttributes a) { Q_ASSERT(this); if (attrs || a != Attr_Data) { ensureAttributes(); a.resolve(); - vtable->setAttribute(this, i, a); + vtable()->setAttribute(this, i, a); } } bool isEmpty(uint i) const { if (!this) return true; - return (vtable->get(this, i) == Primitive::emptyValue().asReturnedValue()); + return (vtable()->get(this, i) == Primitive::emptyValue().asReturnedValue()); } - inline void destroy() { - vtable->destroy(this); - } - - inline void markObjects(ExecutionEngine *e) { - vtable->markObjects(this, e); - } - inline void push_front(SafeValue *values, uint nValues) { - vtable->push_front(this, values, nValues); + vtable()->push_front(this, values, nValues); } inline ReturnedValue pop_front() { - return vtable->pop_front(this); + return vtable()->pop_front(this); } inline uint push_back(uint l, uint n, SafeValue *values) { - vtable->putArray(this, l, values, n); + vtable()->putArray(this, l, values, n); return length(); } inline bool deleteIndex(uint index) { - return vtable->del(this, index); + return vtable()->del(this, index); } inline uint truncate(uint newLen) { if (!this) return newLen; - return vtable->truncate(this, newLen); + return vtable()->truncate(this, newLen); } bool put(uint index, ValueRef value) { - return vtable->put(this, index, value); + return vtable()->put(this, index, value); } bool put(uint index, SafeValue *values, uint n) { - return vtable->putArray(this, index, values, n); + return vtable()->putArray(this, index, values, n); } ReturnedValue get(uint i) const { if (!this) return Primitive::emptyValue().asReturnedValue(); - return vtable->get(this, i); + return vtable()->get(this, i); } inline Property *getProperty(uint index) const; @@ -173,11 +172,13 @@ struct Q_QML_EXPORT ArrayData struct Q_QML_EXPORT SimpleArrayData : public ArrayData { - SimpleArrayData() - : ArrayData() + V4_ARRAYDATA + + SimpleArrayData(ExecutionEngine *engine) + : ArrayData(engine->emptyClass) , len(0) , offset(0) - { vtable = &static_vtbl; } + { setVTable(staticVTable()); } uint len; uint offset; @@ -185,8 +186,8 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData static void getHeadRoom(ArrayData *d); static void reserve(ArrayData *d, uint n); - static void destroy(ArrayData *d); - static void markObjects(ArrayData *d, ExecutionEngine *e); + static void destroy(Managed *d); + static void markObjects(Managed *d, ExecutionEngine *e); static ReturnedValue get(const ArrayData *d, uint index); static bool put(ArrayData *d, uint index, ValueRef value); @@ -198,17 +199,17 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData static ReturnedValue pop_front(ArrayData *d); static uint truncate(ArrayData *d, uint newLen); static uint length(const ArrayData *d); - - static const ArrayVTable static_vtbl; - }; struct Q_QML_EXPORT SparseArrayData : public ArrayData { - SparseArrayData() - : freeList(0) + V4_ARRAYDATA + + SparseArrayData(ExecutionEngine *engine) + : ArrayData(engine->emptyClass) + , freeList(0) , sparse(0) - { vtable = &static_vtbl; } + { setVTable(staticVTable()); } uint freeList; SparseArray *sparse; @@ -216,8 +217,8 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData static uint allocate(ArrayData *d, bool doubleSlot = false); static void free(ArrayData *d, uint idx); - static void destroy(ArrayData *d); - static void markObjects(ArrayData *d, ExecutionEngine *e); + static void destroy(Managed *d); + static void markObjects(Managed *d, ExecutionEngine *e); static void reserve(ArrayData *d, uint n); static ReturnedValue get(const ArrayData *d, uint index); @@ -230,8 +231,6 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData static ReturnedValue pop_front(ArrayData *d); static uint truncate(ArrayData *d, uint newLen); static uint length(const ArrayData *d); - - static const ArrayVTable static_vtbl; }; diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index d17a6cc09c..cc712c759b 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -51,20 +51,7 @@ using namespace QV4; -const ManagedVTable ExecutionContext::static_vtbl = -{ - ExecutionContext::IsExecutionContext, - ExecutionContext::IsString, - ExecutionContext::IsObject, - ExecutionContext::IsFunctionObject, - ExecutionContext::IsErrorObject, - 0, - ExecutionContext::MyType, - "ExecutionContext", - destroy, - markObjects, - isEqualTo -}; +DEFINE_MANAGED_VTABLE(ExecutionContext); CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData) { diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index 671ac5d362..1f4030a4ed 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -52,6 +52,7 @@ const ManagedVTable Managed::static_vtbl = Managed::IsObject, Managed::IsFunctionObject, Managed::IsErrorObject, + Managed::IsArrayData, 0, Managed::MyType, "Managed", diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index e97217b02a..da2aab627e 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -97,7 +97,8 @@ struct ManagedVTable uint isObject : 1; uint isFunctionObject : 1; uint isErrorObject : 1; - uint unused : 19; + uint isArrayData : 1; + uint unused : 18; uint type : 8; const char *className; void (*destroy)(Managed *); @@ -125,39 +126,31 @@ struct ObjectVTable void (*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes); }; -#define DEFINE_MANAGED_VTABLE(classname) \ -const QV4::ManagedVTable classname::static_vtbl = \ +#define DEFINE_MANAGED_VTABLE_INT(classname) \ { \ classname::IsExecutionContext, \ classname::IsString, \ classname::IsObject, \ classname::IsFunctionObject, \ classname::IsErrorObject, \ + classname::IsArrayData, \ 0, \ classname::MyType, \ #classname, \ destroy, \ markObjects, \ - isEqualTo, \ + isEqualTo \ } +#define DEFINE_MANAGED_VTABLE(classname) \ +const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname) + + #define DEFINE_OBJECT_VTABLE(classname) \ const QV4::ObjectVTable classname::static_vtbl = \ { \ - { \ - classname::IsExecutionContext, \ - classname::IsString, \ - classname::IsObject, \ - classname::IsFunctionObject, \ - classname::IsErrorObject, \ - 0, \ - classname::MyType, \ - #classname, \ - destroy, \ - markObjects, \ - isEqualTo, \ - }, \ + DEFINE_MANAGED_VTABLE_INT(classname), \ call, \ construct, \ 0, \ @@ -178,19 +171,7 @@ const QV4::ObjectVTable classname::static_vtbl = \ #define DEFINE_MANAGED_VTABLE_WITH_NAME(classname, name) \ const QV4::ObjectVTable classname::static_vtbl = \ { \ - { \ - classname::IsExecutionContext, \ - classname::IsString, \ - classname::IsObject, \ - classname::IsFunctionObject, \ - classname::IsErrorObject, \ - 0, \ - classname::MyType, \ - #name, \ - destroy, \ - markObjects, \ - isEqualTo, \ - }, \ + DEFINE_MANAGED_VTABLE_INT(name), \ call, \ construct, \ 0, \ @@ -211,19 +192,7 @@ const QV4::ObjectVTable classname::static_vtbl = \ #define DEFINE_MANAGED_VTABLE_WITH_DELETABLES(classname) \ const QV4::ObjectVTable classname::static_vtbl = \ { \ - { \ - classname::IsExecutionContext, \ - classname::IsString, \ - classname::IsObject, \ - classname::IsFunctionObject, \ - classname::IsErrorObject, \ - 0, \ - classname::MyType, \ - #classname, \ - destroy, \ - markObjects, \ - isEqualTo, \ - }, \ + DEFINE_MANAGED_VTABLE_INT(classname), \ call, \ construct, \ collectDeletables, \ @@ -249,7 +218,8 @@ struct Q_QML_EXPORT Managed IsString = false, IsObject = false, IsFunctionObject = false, - IsErrorObject = false + IsErrorObject = false, + IsArrayData = false }; private: void *operator new(size_t); diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index f45c40e469..89e32c4b17 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -91,8 +91,6 @@ Object::~Object() { if (memberData != inlineProperties) delete [] memberData; - if (arrayData) - arrayData->destroy(); _data = 0; } @@ -235,7 +233,7 @@ void Object::markObjects(Managed *that, ExecutionEngine *e) } } if (o->arrayData) - o->arrayData->markObjects(e); + o->arrayData->mark(e); } void Object::ensureMemberIndex(uint idx) @@ -1111,7 +1109,7 @@ void Object::copyArrayData(Object *other) Q_ASSERT(!arrayData && other->arrayData); if (other->arrayType() == ArrayData::Sparse) { SparseArrayData *od = static_cast<SparseArrayData *>(other->arrayData); - SparseArrayData *dd = new SparseArrayData; + SparseArrayData *dd = new (engine()->memoryManager) SparseArrayData(engine()); dd->type = ArrayData::Sparse; dd->sparse = new SparseArray(*od->sparse); dd->freeList = od->freeList; @@ -1162,7 +1160,7 @@ void Object::initSparseArray() if (arrayType() == ArrayData::Sparse) return; - SparseArrayData *data = new SparseArrayData; + SparseArrayData *data = new (engine()->memoryManager) SparseArrayData(engine()); data->type = ArrayData::Sparse; data->sparse = new SparseArray; if (!arrayData) { @@ -1178,7 +1176,7 @@ void Object::initSparseArray() data->alloc = simple->alloc; simple->data = 0; simple->attrs = 0; - delete simple; + // ### explicitly free old data? delete simple; arrayData = data; uint *lastFree = &data->freeList; diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 2f2b7cff49..0572c4efa5 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -204,12 +204,12 @@ public: inline void arrayReserve(uint n) { arrayCreate(); - arrayData->vtable->reserve(arrayData, n); + arrayData->vtable()->reserve(arrayData, n); } void arrayCreate() { if (!arrayData) - arrayData = new SimpleArrayData; + arrayData = new (engine()->memoryManager) SimpleArrayData(engine()); #ifdef CHECK_SPARSE_ARRAYS initSparseArray(); #endif @@ -370,7 +370,7 @@ inline void Object::arraySet(uint index, const Property &p, PropertyAttributes a } else if (index > 0x1000 && index > 2*arrayData->alloc) { initSparseArray(); } else { - arrayData->vtable->reserve(arrayData, index + 1); + arrayData->vtable()->reserve(arrayData, index + 1); } arrayData->setAttributes(index, attributes); Property *pd = ArrayData::insert(this, index, attributes.isAccessor()); diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index 15d27b3f49..3d0328dfcf 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -103,19 +103,7 @@ static uint toArrayIndex(const char *ch, const char *end, bool *ok) const ObjectVTable String::static_vtbl = { - { - String::IsExecutionContext, - String::IsString, - String::IsObject, - String::IsFunctionObject, - String::IsErrorObject, - 0, - String::MyType, - "String", - destroy, - markObjects, - isEqualTo - }, + DEFINE_MANAGED_VTABLE_INT(String), 0, 0, 0 /*collectDeletables*/, |