aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-01-20 16:01:26 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-23 21:47:27 +0100
commit9fb297a54bd0226b4827b5d7ca093a7f9c4922fa (patch)
treeb53967ff783246a094ccd136f8f8acc2bb511949 /src/qml/jsruntime
parent07429ea2a581dbf25d36e51375918e4cdb0962c9 (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.cpp4
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp42
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h81
-rw-r--r--src/qml/jsruntime/qv4context.cpp15
-rw-r--r--src/qml/jsruntime/qv4managed.cpp1
-rw-r--r--src/qml/jsruntime/qv4managed_p.h58
-rw-r--r--src/qml/jsruntime/qv4object.cpp10
-rw-r--r--src/qml/jsruntime/qv4object_p.h6
-rw-r--r--src/qml/jsruntime/qv4string.cpp14
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*/,