aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-10-22 16:00:35 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2014-10-27 15:19:10 +0100
commit8539aa87345fc9a972d9b400fa42fd742b01d4ed (patch)
treec3b40f383f75871e4d545140062c10eb10bf98c4
parent51d8f62dacc9b37a50e522162d5438a624ee9168 (diff)
Reduce size of ArrayData by one pointer
The pointer to the real data is not required anymore, as it always follows the class itself. Like this we save one pointer of overhead, and one indirection when doing reads and writes of array data. Change-Id: If6afdac8e97b57420b50e7b7eb8979f77e8dbbcf Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp22
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h45
-rw-r--r--src/qml/jsruntime/qv4object.cpp5
-rw-r--r--src/qml/jsruntime/qv4object_p.h3
4 files changed, 42 insertions, 33 deletions
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 469081e683..c40f50153d 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -119,7 +119,7 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
while (alloc < requested)
alloc *= 2;
- size_t size = sizeof(ArrayData::Data) + alloc*sizeof(Value);
+ size_t size = sizeof(ArrayData::Data) + (alloc - 1)*sizeof(Value);
if (enforceAttributes)
size += alloc*sizeof(PropertyAttributes);
@@ -137,7 +137,6 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
}
newData->setAlloc(alloc);
newData->setType(newType);
- newData->d()->arrayData = reinterpret_cast<Value *>(newData->d() + 1);
newData->setAttrs(enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->d()->arrayData + alloc) : 0);
o->setArrayData(newData);
@@ -417,10 +416,10 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
ReturnedValue SparseArrayData::get(const ArrayData *d, uint index)
{
const SparseArrayData *s = static_cast<const SparseArrayData *>(d);
- SparseArrayNode *n = s->sparse()->findNode(index);
- if (!n)
+ index = s->mappedIndex(index);
+ if (index == UINT_MAX)
return Primitive::emptyValue().asReturnedValue();
- return s->arrayData()[n->value].asReturnedValue();
+ return s->arrayData()[index].asReturnedValue();
}
bool SparseArrayData::put(Object *o, uint index, ValueRef value)
@@ -428,7 +427,7 @@ bool SparseArrayData::put(Object *o, uint index, ValueRef value)
if (value->isEmpty())
return true;
- const SparseArrayData *s = static_cast<const SparseArrayData *>(o->arrayData());
+ SparseArrayData *s = static_cast<SparseArrayData *>(o->arrayData());
SparseArrayNode *n = s->sparse()->insert(index);
Q_ASSERT(n->value == UINT_MAX || !o->arrayData()->attrs() || !o->arrayData()->attrs()[n->value].isAccessor());
if (n->value == UINT_MAX)
@@ -442,6 +441,7 @@ bool SparseArrayData::put(Object *o, uint index, ValueRef value)
bool SparseArrayData::del(Object *o, uint index)
{
SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData());
+
SparseArrayNode *n = dd->sparse()->findNode(index);
if (!n)
return true;
@@ -567,14 +567,14 @@ bool SparseArrayData::putArray(Object *o, uint index, Value *values, uint n)
}
-uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
+uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n)
{
Q_ASSERT(!obj->arrayData()->hasAttributes());
if (!n)
return obj->getLength();
- const ArrayData *other = otherObj->arrayData();
+ ArrayData *other = otherObj->arrayData();
if (other->isSparse())
obj->initSparseArray();
@@ -584,7 +584,7 @@ uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
uint oldSize = obj->getLength();
if (other->isSparse()) {
- const SparseArrayData *os = static_cast<const SparseArrayData *>(other);
+ SparseArrayData *os = static_cast<SparseArrayData *>(other);
if (otherObj->hasAccessorProperty() && other->hasAttributes()) {
Scope scope(obj->engine());
ScopedValue v(scope);
@@ -599,7 +599,7 @@ uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
obj->arraySet(oldSize + it->key(), ValueRef(os->arrayData()[it->value]));
}
} else {
- const SimpleArrayData *os = static_cast<const SimpleArrayData *>(other);
+ SimpleArrayData *os = static_cast<SimpleArrayData *>(other);
uint toCopy = n;
uint chunk = toCopy;
if (chunk > os->alloc() - os->d()->offset)
@@ -628,7 +628,7 @@ Property *ArrayData::insert(Object *o, uint index, bool isAccessor)
d->data(i) = Primitive::emptyValue();
d->len() = index + 1;
}
- return reinterpret_cast<Property *>(d->d()->arrayData + d->realIndex(index));
+ return reinterpret_cast<Property *>(d->d()->arrayData + d->mappedIndex(index));
}
}
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index cd080baa4a..70c581d75d 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -98,7 +98,7 @@ struct Q_QML_EXPORT ArrayData : public Managed
uint offset;
SparseArray *sparse;
};
- Value *arrayData;
+ Value arrayData[1];
};
V4_MANAGED(Managed)
@@ -109,8 +109,8 @@ struct Q_QML_EXPORT ArrayData : public Managed
void setType(Type t) { d()->type = t; }
PropertyAttributes *attrs() const { return d()->attrs; }
void setAttrs(PropertyAttributes *a) { d()->attrs = a; }
- Value *arrayData() const { return d()->arrayData; }
- Value *&arrayData() { return d()->arrayData; }
+ const Value *arrayData() const { return &d()->arrayData[0]; }
+ Value *arrayData() { return &d()->arrayData[0]; }
const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass()->vtable); }
bool isSparse() const { return this && type() == Sparse; }
@@ -140,13 +140,13 @@ struct Q_QML_EXPORT ArrayData : public Managed
return Primitive::emptyValue().asReturnedValue();
return vtable()->get(this, i);
}
- inline Property *getProperty(uint index) const;
+ inline Property *getProperty(uint index);
static void ensureAttributes(Object *o);
static void realloc(Object *o, Type newType, uint alloc, bool enforceAttributes);
static void sort(ExecutionContext *context, Object *thisObject, const ValueRef comparefn, uint dataLen);
- static uint append(Object *obj, const ArrayObject *otherObj, uint n);
+ static uint append(Object *obj, ArrayObject *otherObj, uint n);
static Property *insert(Object *o, uint index, bool isAccessor = false);
};
@@ -160,14 +160,14 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData
};
V4_ARRAYDATA
- uint realIndex(uint index) const { return (index + d()->offset) % d()->alloc; }
- Value data(uint index) const { return d()->arrayData[realIndex(index)]; }
- Value &data(uint index) { return d()->arrayData[realIndex(index)]; }
+ uint mappedIndex(uint index) const { return (index + d()->offset) % d()->alloc; }
+ Value data(uint index) const { return d()->arrayData[mappedIndex(index)]; }
+ Value &data(uint index) { return d()->arrayData[mappedIndex(index)]; }
- Property *getProperty(uint index) const {
+ Property *getProperty(uint index) {
if (index >= len())
return 0;
- index = realIndex(index);
+ index = mappedIndex(index);
if (d()->arrayData[index].isEmpty())
return 0;
return reinterpret_cast<Property *>(d()->arrayData + index);
@@ -209,6 +209,20 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
static uint allocate(Object *o, bool doubleSlot = false);
static void free(ArrayData *d, uint idx);
+ Property *getProperty(uint index) {
+ SparseArrayNode *n = sparse()->findNode(index);
+ if (!n)
+ return 0;
+ return reinterpret_cast<Property *>(arrayData() + n->value);
+ }
+
+ uint mappedIndex(uint index) const {
+ SparseArrayNode *n = sparse()->findNode(index);
+ if (!n)
+ return UINT_MAX;
+ return n->value;
+ }
+
static void destroy(Managed *d);
static void markObjects(Managed *d, ExecutionEngine *e);
@@ -226,19 +240,16 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
};
-inline Property *ArrayData::getProperty(uint index) const
+inline Property *ArrayData::getProperty(uint index)
{
if (!this)
return 0;
if (type() != Sparse) {
- const SimpleArrayData *that = static_cast<const SimpleArrayData *>(this);
+ SimpleArrayData *that = static_cast<SimpleArrayData *>(this);
return that->getProperty(index);
} else {
- const SparseArrayData *that = static_cast<const SparseArrayData *>(this);
- SparseArrayNode *n = that->sparse()->findNode(index);
- if (!n)
- return 0;
- return reinterpret_cast<Property *>(that->arrayData() + n->value);
+ SparseArrayData *that = static_cast<SparseArrayData *>(this);
+ return that->getProperty(index);
}
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 1b2532018e..d53ca013b4 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -1075,9 +1075,8 @@ void Object::copyArrayData(Object *other)
} else if (other->hasAccessorProperty() && other->arrayData()->attrs() && other->arrayData()->isSparse()){
// do it the slow way
ScopedValue v(scope);
- const SparseArrayData *osa = static_cast<const SparseArrayData *>(other->arrayData());
- for (const SparseArrayNode *it = osa->sparse()->begin();
- it != osa->sparse()->end(); it = it->nextNode()) {
+ SparseArrayData *osa = static_cast<SparseArrayData *>(other->arrayData());
+ for (const SparseArrayNode *it = osa->sparse()->begin(); it != osa->sparse()->end(); it = it->nextNode()) {
v = other->getValue(reinterpret_cast<Property *>(osa->arrayData() + it->value), other->arrayData()->attrs()[it->value]);
arraySet(it->key(), v);
}
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 86e4e78d28..4e9d1527c2 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -114,8 +114,7 @@ struct Q_QML_EXPORT Object: Managed {
Members &memberData() { return d()->memberData; }
const Members &memberData() const { return d()->memberData; }
- const ArrayData *arrayData() const { return d()->arrayData; }
- ArrayData *arrayData() { return d()->arrayData; }
+ ArrayData *arrayData() const { return d()->arrayData; }
void setArrayData(ArrayData *a) { d()->arrayData = a; }
Property *propertyAt(uint index) const { return reinterpret_cast<Property *>(memberData().data() + index); }