aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4arraydata.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-11-17 14:54:52 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2014-11-22 07:58:59 +0100
commitef73060d05579c0c7ec9f272cc2b3acfb073a5a1 (patch)
treec2f382eea8112ef1a577f68472cae9ebd590c8b7 /src/qml/jsruntime/qv4arraydata.cpp
parentc044e33696170ae64a9f907d0bfb9f3513c2ca67 (diff)
Operate directly on Heap::ArrayData where possible
Change-Id: I87dfb3e9a07673b5c405619eab8b6ee292d5c097 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4arraydata.cpp')
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp222
1 files changed, 114 insertions, 108 deletions
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 87186d873d..5c3f3e1adc 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -325,16 +325,16 @@ uint SimpleArrayData::length(const ArrayData *d)
bool SimpleArrayData::putArray(Object *o, uint index, Value *values, uint n)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData());
- if (index + n > dd->alloc()) {
+ Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ if (index + n > dd->alloc) {
reallocate(o, index + n + 1, false);
- dd = static_cast<SimpleArrayData *>(o->arrayData());
+ dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
}
- for (uint i = dd->len(); i < index; ++i)
+ for (uint i = dd->len; i < index; ++i)
dd->data(i) = Primitive::emptyValue();
for (uint i = 0; i < n; ++i)
dd->data(index + i) = values[i];
- dd->len() = qMax(dd->len(), index + n);
+ dd->len = qMax(dd->len, index + n);
return true;
}
@@ -376,49 +376,49 @@ ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttributes
// double slots are required for accessor properties
uint SparseArrayData::allocate(Object *o, bool doubleSlot)
{
- Q_ASSERT(o->arrayData()->type() == Heap::ArrayData::Sparse);
- SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData());
+ Q_ASSERT(o->d()->arrayData->type == Heap::ArrayData::Sparse);
+ Heap::SparseArrayData *dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
if (doubleSlot) {
- uint *last = &dd->freeList();
+ uint *last = &dd->freeList;
while (1) {
if (*last == UINT_MAX) {
- reallocate(o, o->arrayData()->alloc() + 2, true);
- dd = static_cast<SparseArrayData *>(o->arrayData());
- last = &dd->freeList();
+ reallocate(o, dd->alloc + 2, true);
+ dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ last = &dd->freeList;
Q_ASSERT(*last != UINT_MAX);
}
- Q_ASSERT(dd->arrayData()[*last].uint_32 != *last);
- if (dd->arrayData()[*last].uint_32 == (*last + 1)) {
+ Q_ASSERT(dd->arrayData[*last].uint_32 != *last);
+ if (dd->arrayData[*last].uint_32 == (*last + 1)) {
// found two slots in a row
uint idx = *last;
- *last = dd->arrayData()[*last + 1].uint_32;
- o->arrayData()->attrs()[idx] = Attr_Accessor;
+ *last = dd->arrayData[*last + 1].uint_32;
+ dd->attrs[idx] = Attr_Accessor;
return idx;
}
- last = &dd->arrayData()[*last].uint_32;
+ last = &dd->arrayData[*last].uint_32;
}
} else {
- if (dd->freeList() == UINT_MAX) {
- reallocate(o, o->arrayData()->alloc() + 1, false);
- dd = static_cast<SparseArrayData *>(o->arrayData());
+ if (dd->freeList == UINT_MAX) {
+ reallocate(o, dd->alloc + 1, false);
+ dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
}
- uint idx = dd->freeList();
+ uint idx = dd->freeList;
Q_ASSERT(idx != UINT_MAX);
- dd->freeList() = dd->arrayData()[idx].uint_32;
- if (dd->attrs())
- dd->attrs()[idx] = Attr_Data;
+ dd->freeList = dd->arrayData[idx].uint_32;
+ if (dd->attrs)
+ dd->attrs[idx] = Attr_Data;
return idx;
}
}
ReturnedValue SparseArrayData::get(const ArrayData *d, uint index)
{
- const SparseArrayData *s = static_cast<const SparseArrayData *>(d);
+ const Heap::SparseArrayData *s = static_cast<const SparseArrayData *>(d)->d();
index = s->mappedIndex(index);
if (index == UINT_MAX)
return Primitive::emptyValue().asReturnedValue();
- return s->arrayData()[index].asReturnedValue();
+ return s->arrayData[index].asReturnedValue();
}
bool SparseArrayData::put(Object *o, uint index, ValueRef value)
@@ -426,96 +426,99 @@ bool SparseArrayData::put(Object *o, uint index, ValueRef value)
if (value->isEmpty())
return true;
- 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());
+ Heap::SparseArrayData *s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ SparseArrayNode *n = s->sparse->insert(index);
+ Q_ASSERT(n->value == UINT_MAX || !s->attrs || !s->attrs[n->value].isAccessor());
if (n->value == UINT_MAX)
n->value = allocate(o);
- s->arrayData()[n->value] = value;
- if (s->attrs())
- s->attrs()[n->value] = Attr_Data;
+ s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ s->arrayData[n->value] = value;
+ if (s->attrs)
+ s->attrs[n->value] = Attr_Data;
return true;
}
bool SparseArrayData::del(Object *o, uint index)
{
- SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData());
+ Heap::SparseArrayData *dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
- SparseArrayNode *n = dd->sparse()->findNode(index);
+ SparseArrayNode *n = dd->sparse->findNode(index);
if (!n)
return true;
uint pidx = n->value;
- Q_ASSERT(!dd->arrayData()[pidx].isEmpty());
+ Q_ASSERT(!dd->arrayData[pidx].isEmpty());
bool isAccessor = false;
- if (dd->attrs()) {
- if (!dd->attrs()[pidx].isConfigurable())
+ if (dd->attrs) {
+ if (!dd->attrs[pidx].isConfigurable())
return false;
- isAccessor = dd->attrs()[pidx].isAccessor();
- dd->attrs()[pidx] = Attr_Data;
+ isAccessor = dd->attrs[pidx].isAccessor();
+ dd->attrs[pidx] = Attr_Data;
}
if (isAccessor) {
// free up both indices
- dd->arrayData()[pidx + 1].tag = Value::Empty_Type;
- dd->arrayData()[pidx + 1].uint_32 = static_cast<SparseArrayData *>(dd)->freeList();
- dd->arrayData()[pidx].tag = Value::Undefined_Type;
- dd->arrayData()[pidx].uint_32 = pidx + 1;
+ dd->arrayData[pidx + 1].tag = Value::Empty_Type;
+ dd->arrayData[pidx + 1].uint_32 = dd->freeList;
+ dd->arrayData[pidx].tag = Value::Undefined_Type;
+ dd->arrayData[pidx].uint_32 = pidx + 1;
} else {
- dd->arrayData()[pidx].tag = Value::Empty_Type;
- dd->arrayData()[pidx].uint_32 = static_cast<SparseArrayData *>(dd)->freeList();
+ dd->arrayData[pidx].tag = Value::Empty_Type;
+ dd->arrayData[pidx].uint_32 = dd->freeList;
}
- dd->freeList() = pidx;
- dd->sparse()->erase(n);
+ dd->freeList = pidx;
+ dd->sparse->erase(n);
return true;
}
void SparseArrayData::setAttribute(Object *o, uint index, PropertyAttributes attrs)
{
- SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData());
- SparseArrayNode *n = d->sparse()->insert(index);
+ Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ SparseArrayNode *n = d->sparse->insert(index);
if (n->value == UINT_MAX) {
n->value = allocate(o, attrs.isAccessor());
- d = static_cast<SparseArrayData *>(o->arrayData());
+ d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
}
- else if (attrs.isAccessor() != d->attrs()[n->value].isAccessor()) {
+ else if (attrs.isAccessor() != d->attrs[n->value].isAccessor()) {
// need to convert the slot
- free(d, n->value);
+ free(o->arrayData(), n->value);
n->value = allocate(o, attrs.isAccessor());
+ d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
}
- o->arrayData()->attrs()[n->value] = attrs;
+ d->attrs[n->value] = attrs;
}
PropertyAttributes SparseArrayData::attribute(const ArrayData *d, uint index)
{
- SparseArrayNode *n = static_cast<const SparseArrayData *>(d)->sparse()->insert(index);
+ SparseArrayNode *n = d->d()->sparse->findNode(index);
if (!n)
return PropertyAttributes();
- return d->attrs()[n->value];
+ return d->d()->attrs[n->value];
}
void SparseArrayData::push_front(Object *o, Value *values, uint n)
{
- SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData());
- Q_ASSERT(!o->arrayData()->attrs());
+ Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Q_ASSERT(!d->attrs);
for (int i = n - 1; i >= 0; --i) {
uint idx = allocate(o);
- d->arrayData()[idx] = values[i];
- d->sparse()->push_front(idx);
+ d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ d->arrayData[idx] = values[i];
+ d->sparse->push_front(idx);
}
}
ReturnedValue SparseArrayData::pop_front(Object *o)
{
- SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData());
- Q_ASSERT(!o->arrayData()->attrs());
- uint idx = d->sparse()->pop_front();
+ Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Q_ASSERT(!d->attrs);
+ uint idx = d->sparse->pop_front();
ReturnedValue v;
if (idx != UINT_MAX) {
- v = d->arrayData()[idx].asReturnedValue();
+ v = d->arrayData[idx].asReturnedValue();
free(o->arrayData(), idx);
} else {
v = Encode::undefined();
@@ -525,21 +528,21 @@ ReturnedValue SparseArrayData::pop_front(Object *o)
uint SparseArrayData::truncate(Object *o, uint newLen)
{
- SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData());
- SparseArrayNode *begin = d->sparse()->lowerBound(newLen);
- if (begin != d->sparse()->end()) {
- SparseArrayNode *it = d->sparse()->end()->previousNode();
+ Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ SparseArrayNode *begin = d->sparse->lowerBound(newLen);
+ if (begin != d->sparse->end()) {
+ SparseArrayNode *it = d->sparse->end()->previousNode();
while (1) {
- if (d->attrs()) {
- if (!d->attrs()[it->value].isConfigurable()) {
+ if (d->attrs) {
+ if (!d->attrs[it->value].isConfigurable()) {
newLen = it->key() + 1;
break;
}
}
- free(d, it->value);
+ free(o->arrayData(), it->value);
bool brk = (it == begin);
SparseArrayNode *prev = it->previousNode();
- static_cast<SparseArrayData *>(d)->sparse()->erase(it);
+ d->sparse->erase(it);
if (brk)
break;
it = prev;
@@ -568,12 +571,13 @@ bool SparseArrayData::putArray(Object *o, uint index, Value *values, uint n)
uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n)
{
- Q_ASSERT(!obj->arrayData() || !obj->arrayData()->hasAttributes());
+ Q_ASSERT(!obj->d()->arrayData || !obj->d()->arrayData->attrs);
if (!n)
return obj->getLength();
- ArrayData *other = otherObj->arrayData();
+ Scope scope(obj->engine());
+ Scoped<ArrayData> other(scope, otherObj->arrayData());
if (other && other->isSparse())
obj->initSparseArray();
@@ -583,30 +587,29 @@ uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n)
uint oldSize = obj->getLength();
if (other && other->isSparse()) {
- SparseArrayData *os = static_cast<SparseArrayData *>(other);
+ Heap::SparseArrayData *os = static_cast<Heap::SparseArrayData *>(other->d());
if (otherObj->hasAccessorProperty() && other->hasAttributes()) {
- Scope scope(obj->engine());
ScopedValue v(scope);
- for (const SparseArrayNode *it = os->sparse()->begin();
- it != os->sparse()->end(); it = it->nextNode()) {
- v = otherObj->getValue(reinterpret_cast<Property *>(os->arrayData() + it->value), other->attrs()[it->value]);
+ for (const SparseArrayNode *it = os->sparse->begin();
+ it != os->sparse->end(); it = it->nextNode()) {
+ v = otherObj->getValue(reinterpret_cast<Property *>(os->arrayData + it->value), other->d()->attrs[it->value]);
obj->arraySet(oldSize + it->key(), v);
}
} else {
- for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other)->sparse()->begin();
- it != os->sparse()->end(); it = it->nextNode())
- obj->arraySet(oldSize + it->key(), ValueRef(os->arrayData()[it->value]));
+ for (const SparseArrayNode *it = other->d()->sparse->begin();
+ it != os->sparse->end(); it = it->nextNode())
+ obj->arraySet(oldSize + it->key(), ValueRef(os->arrayData[it->value]));
}
} else {
- SimpleArrayData *os = static_cast<SimpleArrayData *>(other);
+ Heap::SimpleArrayData *os = static_cast<Heap::SimpleArrayData *>(other->d());
uint toCopy = n;
uint chunk = toCopy;
- if (chunk > os->alloc() - os->d()->offset)
- chunk -= os->alloc() - os->d()->offset;
- obj->arrayPut(oldSize, os->arrayData() + os->d()->offset, chunk);
+ if (chunk > os->alloc - os->offset)
+ chunk -= os->alloc - os->offset;
+ obj->arrayPut(oldSize, os->arrayData + os->offset, chunk);
toCopy -= chunk;
if (toCopy)
- obj->arrayPut(oldSize + chunk, os->arrayData(), toCopy);
+ obj->arrayPut(oldSize + chunk, os->arrayData, toCopy);
}
return oldSize + n;
@@ -614,29 +617,30 @@ uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n)
Property *ArrayData::insert(Object *o, uint index, bool isAccessor)
{
- if (!isAccessor && o->arrayData()->type() != Heap::ArrayData::Sparse) {
- SimpleArrayData *d = static_cast<SimpleArrayData *>(o->arrayData());
- if (index < 0x1000 || index < d->len() + (d->len() >> 2)) {
- if (index >= o->arrayData()->alloc()) {
+ if (!isAccessor && o->d()->arrayData->type != Heap::ArrayData::Sparse) {
+ Heap::SimpleArrayData *d = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ if (index < 0x1000 || index < d->len + (d->len >> 2)) {
+ if (index >= d->alloc) {
o->arrayReserve(index + 1);
- d = static_cast<SimpleArrayData *>(o->arrayData());
+ d = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
}
- if (index >= d->len()) {
+ if (index >= d->len) {
// mark possible hole in the array
- for (uint i = d->len(); i < index; ++i)
+ for (uint i = d->len; i < index; ++i)
d->data(i) = Primitive::emptyValue();
- d->len() = index + 1;
+ d->len = index + 1;
}
- return reinterpret_cast<Property *>(d->d()->arrayData + d->mappedIndex(index));
+ return reinterpret_cast<Property *>(d->arrayData + d->mappedIndex(index));
}
}
o->initSparseArray();
- SparseArrayData *s = static_cast<SparseArrayData *>(o->arrayData());
- SparseArrayNode *n = s->sparse()->insert(index);
+ Heap::SparseArrayData *s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ SparseArrayNode *n = s->sparse->insert(index);
if (n->value == UINT_MAX)
n->value = SparseArrayData::allocate(o, isAccessor);
- return reinterpret_cast<Property *>(s->arrayData() + n->value);
+ s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ return reinterpret_cast<Property *>(s->arrayData + n->value);
}
@@ -739,7 +743,10 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const ValueRef
if (!len)
return;
- if (!thisObject->arrayData() || !thisObject->arrayData()->length())
+ Scope scope(engine);
+ Scoped<ArrayData> arrayData(scope, thisObject->arrayData());
+
+ if (!arrayData || !arrayData->length())
return;
if (!(comparefn->isUndefined() || comparefn->asObject())) {
@@ -750,17 +757,17 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const ValueRef
// The spec says the sorting goes through a series of get,put and delete operations.
// this implies that the attributes don't get sorted around.
- if (thisObject->arrayData()->type() == Heap::ArrayData::Sparse) {
+ if (arrayData->type() == Heap::ArrayData::Sparse) {
// since we sort anyway, we can simply iterate over the entries in the sparse
// array and append them one by one to a regular one.
- SparseArrayData *sparse = static_cast<SparseArrayData *>(thisObject->arrayData());
+ Scoped<SparseArrayData> sparse(scope, static_cast<Heap::SparseArrayData *>(arrayData->d()));
if (!sparse->sparse()->nEntries())
return;
thisObject->setArrayData(0);
ArrayData::realloc(thisObject, Heap::ArrayData::Simple, sparse->sparse()->nEntries(), sparse->attrs() ? true : false);
- SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData());
+ Heap::SimpleArrayData *d = static_cast<Heap::SimpleArrayData *>(thisObject->d()->arrayData);
SparseArrayNode *n = sparse->sparse()->begin();
uint i = 0;
@@ -771,7 +778,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const ValueRef
PropertyAttributes a = sparse->attrs() ? sparse->attrs()[n->value] : Attr_Data;
d->data(i) = thisObject->getValue(reinterpret_cast<Property *>(sparse->arrayData() + n->value), a);
- d->attrs()[i] = a.isAccessor() ? Attr_Data : a;
+ d->attrs[i] = a.isAccessor() ? Attr_Data : a;
n = n->nextNode();
++i;
@@ -785,7 +792,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const ValueRef
++i;
}
}
- d->len() = i;
+ d->len = i;
if (len > i)
len = i;
if (n != sparse->sparse()->end()) {
@@ -799,11 +806,10 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const ValueRef
}
}
- // ### explicitly delete sparse
} else {
- SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData());
- if (len > d->len())
- len = d->len();
+ Heap::SimpleArrayData *d = static_cast<Heap::SimpleArrayData *>(thisObject->d()->arrayData);
+ if (len > d->len)
+ len = d->len;
// sort empty values to the end
for (uint i = 0; i < len; i++) {
@@ -811,7 +817,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const ValueRef
while (--len > i)
if (!d->data(len).isEmpty())
break;
- Q_ASSERT(!d->attrs() || !d->attrs()[len].isAccessor());
+ Q_ASSERT(!d->attrs || !d->attrs[len].isAccessor());
d->data(i) = d->data(len);
d->data(len) = Primitive::emptyValue();
}