aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-01-24 14:29:40 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-24 14:32:37 +0100
commitab2b5219876a60867e67b47827196114d238155d (patch)
treec2ecc7d22dcb8c4eadeede664ba97b3be64baffe /src/qml/jsruntime
parentc53fef423a8f607e1443b1d409712864f8cac9d5 (diff)
Allocate the ArrayData object and it's data together
Reduce the amount of allocations required for Arrays, and allows freeing the array data more easily in the GC. Change-Id: I3e3213f089c45c83a227038ce444aa60b2735b7f 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.cpp247
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h24
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4object.cpp52
-rw-r--r--src/qml/jsruntime/qv4object_p.h9
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp4
7 files changed, 170 insertions, 172 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 8f1c030462..5dedd59770 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -91,9 +91,7 @@ void ArgumentsObject::fullyCreate()
uint numAccessors = qMin((int)context->function->formalParameterCount, context->realArgumentCount);
uint argCount = qMin(context->realArgumentCount, context->callData->argc);
- arrayReserve(argCount);
- initSparseArray();
- arrayData->ensureAttributes();
+ ArrayData::realloc(this, ArrayData::Sparse, 0, argCount, true);
context->engine->requireArgumentsAccessors(numAccessors);
for (uint i = 0; i < (uint)numAccessors; ++i) {
mappedArguments.append(context->callData->args[i]);
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 7626a33106..9c6ff94583 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -41,6 +41,7 @@
#include "qv4arraydata_p.h"
#include "qv4object_p.h"
#include "qv4functionobject_p.h"
+#include "qv4mm_p.h"
using namespace QV4;
@@ -48,7 +49,7 @@ const ArrayVTable SimpleArrayData::static_vtbl =
{
DEFINE_MANAGED_VTABLE_INT(SimpleArrayData),
SimpleArrayData::Simple,
- SimpleArrayData::reserve,
+ SimpleArrayData::reallocate,
SimpleArrayData::get,
SimpleArrayData::put,
SimpleArrayData::putArray,
@@ -65,7 +66,7 @@ const ArrayVTable SparseArrayData::static_vtbl =
{
DEFINE_MANAGED_VTABLE_INT(SparseArrayData),
ArrayData::Sparse,
- SparseArrayData::reserve,
+ SparseArrayData::reallocate,
SparseArrayData::get,
SparseArrayData::put,
SparseArrayData::putArray,
@@ -79,72 +80,134 @@ const ArrayVTable SparseArrayData::static_vtbl =
};
-void SimpleArrayData::getHeadRoom(ArrayData *d)
+void ArrayData::realloc(Object *o, Type newType, uint offset, uint alloc, bool enforceAttributes)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
- Q_ASSERT(dd);
- Q_ASSERT(!dd->offset);
- dd->offset = qMax(dd->len >> 2, (uint)16);
- SafeValue *newArray = new SafeValue[dd->offset + dd->alloc];
- memcpy(newArray + dd->offset, dd->data, dd->len*sizeof(SafeValue));
- delete [] dd->data;
- dd->data = newArray + dd->offset;
- if (dd->attrs) {
- PropertyAttributes *newAttrs = new PropertyAttributes[dd->offset + dd->alloc];
- memcpy(newAttrs + dd->offset, dd->attrs, dd->len*sizeof(PropertyAttributes));
- delete [] dd->attrs;
- dd->attrs = newAttrs + dd->offset;
+ ArrayData *d = o->arrayData;
+
+ uint oldAlloc = 0;
+ uint toCopy = 0;
+ if (alloc < 8)
+ alloc = 8;
+
+ if (d) {
+ bool hasAttrs = d->attrs;
+ enforceAttributes |= hasAttrs;
+
+ if (!offset && alloc <= d->alloc && newType == d->type && hasAttrs == enforceAttributes)
+ return;
+
+ oldAlloc = d->alloc;
+ if (d->type < Sparse) {
+ offset = qMax(offset, static_cast<SimpleArrayData *>(d)->offset);
+ toCopy = static_cast<SimpleArrayData *>(d)->len;
+ } else {
+ Q_ASSERT(!offset);
+ toCopy = d->alloc;
+ newType = Sparse;
+ }
+ }
+ if (enforceAttributes && newType == Simple)
+ newType = Complex;
+
+ alloc = qMax(alloc, 2*oldAlloc) + offset;
+ size_t size = alloc*sizeof(SafeValue);
+ if (enforceAttributes)
+ size += alloc*sizeof(PropertyAttributes);
+
+ if (newType < Sparse) {
+ size += sizeof(SimpleArrayData);
+ SimpleArrayData *newData = static_cast<SimpleArrayData *>(o->engine()->memoryManager->allocManaged(size));
+ new (newData) SimpleArrayData(o->engine());
+ newData->alloc = alloc - offset;
+ newData->type = newType;
+ newData->data = reinterpret_cast<SafeValue *>(newData + 1) + offset;
+ newData->attrs = enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->data + alloc) + offset : 0;
+ newData->offset = offset;
+ newData->len = d ? static_cast<SimpleArrayData *>(d)->len : 0;
+ o->arrayData = newData;
+ } else {
+ size += sizeof(SparseArrayData);
+ SparseArrayData *newData = static_cast<SparseArrayData *>(o->engine()->memoryManager->allocManaged(size));
+ new (newData) SparseArrayData(o->engine());
+ newData->alloc = alloc;
+ newData->type = newType;
+ newData->data = reinterpret_cast<SafeValue *>(newData + 1);
+ newData->attrs = enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->data + alloc) : 0;
+ o->arrayData = newData;
}
-}
-void SimpleArrayData::reserve(ArrayData *d, uint n)
-{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
- if (n < 8)
- n = 8;
- if (n <= dd->alloc)
+ if (d) {
+ memcpy(o->arrayData->data, d->data, sizeof(SafeValue)*toCopy);
+ if (enforceAttributes) {
+ if (d->attrs)
+ memcpy(o->arrayData->attrs, d->attrs, sizeof(PropertyAttributes)*toCopy);
+ else
+ for (uint i = 0; i < toCopy; ++i)
+ o->arrayData->attrs[i] = Attr_Data;
+ }
+ }
+
+ if (newType != Sparse)
return;
- dd->alloc = qMax(n, 2*dd->alloc);
- SafeValue *newArrayData = new SafeValue[dd->alloc + dd->offset];
- if (dd->data) {
- memcpy(newArrayData + dd->offset, dd->data, sizeof(SafeValue)*dd->len);
- delete [] (dd->data - dd->offset);
+ SparseArrayData *newData = static_cast<SparseArrayData *>(o->arrayData);
+ if (d && d->type == Sparse) {
+ SparseArrayData *old = static_cast<SparseArrayData *>(d);
+ newData->sparse = old->sparse;
+ old->sparse = 0;
+ newData->freeList = old->freeList;
+ return;
}
- dd->data = newArrayData + dd->offset;
-
- if (dd->attrs) {
- PropertyAttributes *newAttrs = new PropertyAttributes[dd->alloc];
- memcpy(newAttrs, dd->attrs, sizeof(PropertyAttributes)*dd->len);
- delete [] (dd->attrs - dd->offset);
- dd->attrs = newAttrs;
+ newData->sparse = new SparseArray;
+ uint *lastFree = &newData->freeList;
+ for (uint i = 0; i < toCopy; ++i) {
+ if (!newData->data[i].isEmpty()) {
+ SparseArrayNode *n = newData->sparse->insert(i);
+ n->value = i;
+ } else {
+ *lastFree = i;
+ newData->data[i].tag = Value::Empty_Type;
+ lastFree = &newData->data[i].uint_32;
+ }
+ }
+ for (uint i = toCopy; i < newData->alloc; ++i) {
+ *lastFree = i;
+ newData->data[i].tag = Value::Empty_Type;
+ lastFree = &newData->data[i].uint_32;
}
+ *lastFree = newData->alloc;
+
+ // ### Could explicitly free the old data
}
-void ArrayData::ensureAttributes()
+
+void SimpleArrayData::getHeadRoom(Object *o)
{
- if (attrs)
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
+ Q_ASSERT(dd);
+ Q_ASSERT(!dd->offset);
+ uint offset = qMax(dd->len >> 2, (uint)16);
+ realloc(o, Simple, offset, 0, false);
+}
+
+ArrayData *SimpleArrayData::reallocate(Object *o, uint n, bool enforceAttributes)
+{
+ realloc(o, Simple, 0, n, enforceAttributes);
+ return o->arrayData;
+}
+
+void ArrayData::ensureAttributes(Object *o)
+{
+ if (o->arrayData && o->arrayData->attrs)
return;
- uint off = 0;
- if (type == Simple) {
- type = Complex;
- off = static_cast<SimpleArrayData *>(this)->offset;
- }
- attrs = new PropertyAttributes[alloc + off];
- attrs += off;
- for (uint i = 0; i < alloc; ++i)
- attrs[i] = Attr_Data;
+ ArrayData::realloc(o, Simple, 0, 0, true);
}
-void SimpleArrayData::destroy(Managed *d)
+void SimpleArrayData::destroy(Managed *)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
- delete [] (dd->data - dd->offset);
- if (dd->attrs)
- delete [] (dd->attrs - dd->offset);
}
void SimpleArrayData::markObjects(Managed *d, ExecutionEngine *e)
@@ -209,8 +272,11 @@ void SimpleArrayData::push_front(Object *o, SafeValue *values, uint n)
SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
Q_ASSERT(!dd->attrs);
for (int i = n - 1; i >= 0; --i) {
- if (!dd->offset)
- getHeadRoom(dd);
+ if (!dd->offset) {
+ getHeadRoom(o);
+ dd = static_cast<SimpleArrayData *>(o->arrayData);
+ }
+
--dd->offset;
--dd->data;
@@ -265,8 +331,10 @@ uint SimpleArrayData::length(const ArrayData *d)
bool SimpleArrayData::putArray(Object *o, uint index, SafeValue *values, uint n)
{
SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
- if (index + n > dd->alloc)
- reserve(dd, index + n + 1);
+ if (index + n > dd->alloc) {
+ reallocate(o, index + n + 1, false);
+ dd = static_cast<SimpleArrayData *>(o->arrayData);
+ }
for (uint i = dd->len; i < index; ++i)
dd->data[i] = Primitive::emptyValue();
for (uint i = 0; i < n; ++i)
@@ -300,9 +368,6 @@ void SparseArrayData::destroy(Managed *d)
{
SparseArrayData *dd = static_cast<SparseArrayData *>(d);
delete dd->sparse;
- delete [] dd->data;
- if (dd->attrs)
- delete [] dd->attrs;
}
void SparseArrayData::markObjects(Managed *d, ExecutionEngine *e)
@@ -313,42 +378,23 @@ void SparseArrayData::markObjects(Managed *d, ExecutionEngine *e)
dd->data[i].mark(e);
}
-void SparseArrayData::reserve(ArrayData *d, uint n)
+ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttributes)
{
- if (n < 8)
- n = 8;
- if (n <= d->alloc)
- return;
-
- SparseArrayData *dd = static_cast<SparseArrayData *>(d);
- uint oldAlloc = dd->alloc;
- dd->alloc = qMax(n, 2*dd->alloc);
- SafeValue *newArrayData = new SafeValue[dd->alloc];
- if (dd->data) {
- memcpy(newArrayData, dd->data, sizeof(SafeValue)*oldAlloc);
- delete [] dd->data;
- }
- dd->data = newArrayData;
- if (dd->attrs) {
- PropertyAttributes *newAttrs = new PropertyAttributes[dd->alloc];
- memcpy(newAttrs, dd->attrs, sizeof(PropertyAttributes)*oldAlloc);
- delete [] dd->attrs;
- dd->attrs = newAttrs;
- }
- for (uint i = oldAlloc; i < dd->alloc; ++i)
- dd->data[i] = Primitive::fromInt32(i + 1);
+ realloc(o, Sparse, 0, n, enforceAttributes);
+ return o->arrayData;
}
// double slots are required for accessor properties
-uint SparseArrayData::allocate(ArrayData *d, bool doubleSlot)
+uint SparseArrayData::allocate(Object *o, bool doubleSlot)
{
- Q_ASSERT(d->type == ArrayData::Sparse);
- SparseArrayData *dd = static_cast<SparseArrayData *>(d);
+ Q_ASSERT(o->arrayData->type == ArrayData::Sparse);
+ SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData);
if (doubleSlot) {
uint *last = &dd->freeList;
while (1) {
if (*last + 1 >= dd->alloc) {
- reserve(d, d->alloc + 2);
+ reallocate(o, o->arrayData->alloc + 2, true);
+ dd = static_cast<SparseArrayData *>(o->arrayData);
last = &dd->freeList;
}
@@ -356,14 +402,16 @@ uint SparseArrayData::allocate(ArrayData *d, bool doubleSlot)
// found two slots in a row
uint idx = *last;
*last = dd->data[*last + 1].uint_32;
- d->attrs[idx] = Attr_Accessor;
+ o->arrayData->attrs[idx] = Attr_Accessor;
return idx;
}
last = &dd->data[*last].uint_32;
}
} else {
- if (dd->alloc == dd->freeList)
- reserve(d, d->alloc + 2);
+ if (dd->alloc == dd->freeList) {
+ reallocate(o, o->arrayData->alloc + 2, false);
+ dd = static_cast<SparseArrayData *>(o->arrayData);
+ }
uint idx = dd->freeList;
dd->freeList = dd->data[idx].uint_32;
if (dd->attrs)
@@ -388,7 +436,7 @@ bool SparseArrayData::put(Object *o, uint index, ValueRef value)
SparseArrayNode *n = static_cast<SparseArrayData *>(o->arrayData)->sparse->insert(index);
Q_ASSERT(n->value == UINT_MAX || !o->arrayData->attrs || !o->arrayData->attrs[n->value].isAccessor());
if (n->value == UINT_MAX)
- n->value = allocate(o->arrayData);
+ n->value = allocate(o);
o->arrayData->data[n->value] = value;
if (o->arrayData->attrs)
o->arrayData->attrs[n->value] = Attr_Data;
@@ -434,14 +482,16 @@ void SparseArrayData::setAttribute(Object *o, uint index, PropertyAttributes att
{
SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData);
SparseArrayNode *n = d->sparse->insert(index);
- if (n->value == UINT_MAX)
- n->value = allocate(d, attrs.isAccessor());
+ if (n->value == UINT_MAX) {
+ n->value = allocate(o, attrs.isAccessor());
+ d = static_cast<SparseArrayData *>(o->arrayData);
+ }
else if (attrs.isAccessor() != d->attrs[n->value].isAccessor()) {
// need to convert the slot
free(d, n->value);
- n->value = allocate(d, attrs.isAccessor());
+ n->value = allocate(o, attrs.isAccessor());
}
- d->attrs[n->value] = attrs;
+ o->arrayData->attrs[n->value] = attrs;
}
PropertyAttributes SparseArrayData::attribute(const ArrayData *d, uint index)
@@ -456,7 +506,7 @@ void SparseArrayData::push_front(Object *o, SafeValue *values, uint n)
{
Q_ASSERT(!o->arrayData->attrs);
for (int i = n - 1; i >= 0; --i) {
- uint idx = allocate(o->arrayData);
+ uint idx = allocate(o);
o->arrayData->data[idx] = values[i];
static_cast<SparseArrayData *>(o->arrayData)->sparse->push_front(idx);
}
@@ -576,7 +626,7 @@ Property *ArrayData::insert(Object *o, uint index, bool isAccessor)
o->initSparseArray();
SparseArrayNode *n = static_cast<SparseArrayData *>(o->arrayData)->sparse->insert(index);
if (n->value == UINT_MAX)
- n->value = SparseArrayData::allocate(o->arrayData, isAccessor);
+ n->value = SparseArrayData::allocate(o, isAccessor);
return reinterpret_cast<Property *>(o->arrayData->data + n->value);
}
@@ -604,14 +654,13 @@ void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const Valu
if (!sparse->sparse->nEntries())
return;
- SimpleArrayData *d = new (context->engine->memoryManager) SimpleArrayData(context->engine);
- thisObject->arrayData = d;
- d->vtable()->reserve(d, sparse->sparse->nEntries());
+ thisObject->arrayData = 0;
+ ArrayData::realloc(thisObject, ArrayData::Simple, 0, sparse->sparse->nEntries(), sparse->attrs ? true : false);
+ SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData);
SparseArrayNode *n = sparse->sparse->begin();
uint i = 0;
if (sparse->attrs) {
- d->ensureAttributes();
while (n != sparse->sparse->end()) {
if (n->value >= len)
break;
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index ea6c95bb5d..48b17a239f 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -64,7 +64,7 @@ struct ArrayVTable
{
ManagedVTable managedVTable;
uint type;
- void (*reserve)(ArrayData *d, uint n);
+ ArrayData *(*reallocate)(Object *o, uint n, bool enforceAttributes);
ReturnedValue (*get)(const ArrayData *d, uint index);
bool (*put)(Object *o, uint index, ValueRef value);
bool (*putArray)(Object *o, uint index, SafeValue *values, uint n);
@@ -82,10 +82,6 @@ struct Q_QML_EXPORT ArrayData : public Managed
{
ArrayData(InternalClass *ic)
: Managed(ic)
- , alloc(0)
- , type(0)
- , attrs(0)
- , data(0)
{
}
@@ -97,7 +93,7 @@ struct Q_QML_EXPORT ArrayData : public Managed
};
uint alloc;
- uint type;
+ Type type;
PropertyAttributes *attrs;
SafeValue *data;
@@ -113,7 +109,6 @@ struct Q_QML_EXPORT ArrayData : public Managed
bool hasAttributes() const {
return this && attrs;
}
- void ensureAttributes();
PropertyAttributes attributes(int i) const {
Q_ASSERT(this);
return attrs ? vtable()->attribute(this, i) : Attr_Data;
@@ -132,6 +127,9 @@ struct Q_QML_EXPORT ArrayData : public Managed
}
inline Property *getProperty(uint index) const;
+ static void ensureAttributes(Object *o);
+ static void realloc(Object *o, Type newType, uint offset, uint alloc, bool enforceAttributes);
+
static void sort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint dataLen);
static uint append(Object *obj, const ArrayObject *otherObj, uint n);
static Property *insert(Object *o, uint index, bool isAccessor = false);
@@ -143,15 +141,13 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData
SimpleArrayData(ExecutionEngine *engine)
: ArrayData(engine->emptyClass)
- , len(0)
- , offset(0)
{ setVTable(staticVTable()); }
uint len;
uint offset;
- static void getHeadRoom(ArrayData *d);
- static void reserve(ArrayData *d, uint n);
+ static void getHeadRoom(Object *o);
+ static ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
static void destroy(Managed *d);
static void markObjects(Managed *d, ExecutionEngine *e);
@@ -174,20 +170,18 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
SparseArrayData(ExecutionEngine *engine)
: ArrayData(engine->emptyClass)
- , freeList(0)
- , sparse(0)
{ setVTable(staticVTable()); }
uint freeList;
SparseArray *sparse;
- static uint allocate(ArrayData *d, bool doubleSlot = false);
+ static uint allocate(Object *o, bool doubleSlot = false);
static void free(ArrayData *d, uint idx);
static void destroy(Managed *d);
static void markObjects(Managed *d, ExecutionEngine *e);
- static void reserve(ArrayData *d, uint n);
+ static ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
static ReturnedValue get(const ArrayData *d, uint index);
static bool put(Object *o, uint index, ValueRef value);
static bool putArray(Object *o, uint index, SafeValue *values, uint n);
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 995c711a02..b967741af3 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -504,6 +504,8 @@ Returned<ArrayObject> *ExecutionEngine::newArrayObject(int count)
ArrayObject *object = new (memoryManager) ArrayObject(this);
if (count) {
+ Scope scope(this);
+ ScopedValue protectArray(scope, object);
if (count < 0x1000)
object->arrayReserve(count);
object->setArrayLengthUnchecked(count);
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 86c7ab1986..93ad51d26f 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -1107,22 +1107,18 @@ void Object::copyArrayData(Object *other)
}
} else {
Q_ASSERT(!arrayData && other->arrayData);
+ ArrayData::realloc(this, other->arrayData->type, 0, other->arrayData->alloc, other->arrayData->attrs);
if (other->arrayType() == ArrayData::Sparse) {
SparseArrayData *od = static_cast<SparseArrayData *>(other->arrayData);
- SparseArrayData *dd = new (engine()->memoryManager) SparseArrayData(engine());
- dd->type = ArrayData::Sparse;
+ SparseArrayData *dd = static_cast<SparseArrayData *>(arrayData);
dd->sparse = new SparseArray(*od->sparse);
dd->freeList = od->freeList;
- arrayData = dd;
- }
- arrayReserve(other->arrayData->alloc);
- if (other->arrayType() != ArrayData::Sparse) {
+ } else {
SimpleArrayData *d = static_cast<SimpleArrayData *>(arrayData);
d->len = static_cast<SimpleArrayData *>(other->arrayData)->len;
d->offset = 0;
}
memcpy(arrayData->data, other->arrayData->data, arrayData->alloc*sizeof(SafeValue));
-
}
setArrayLengthUnchecked(other->getLength());
}
@@ -1164,47 +1160,7 @@ void Object::initSparseArray()
if (arrayType() == ArrayData::Sparse)
return;
- SparseArrayData *data = new (engine()->memoryManager) SparseArrayData(engine());
- data->type = ArrayData::Sparse;
- data->sparse = new SparseArray;
- if (!arrayData) {
- arrayData = data;
- return;
- }
- SimpleArrayData *simple = static_cast<SimpleArrayData *>(arrayData);
-
- uint oldOffset = simple->offset;
- uint length = simple->ArrayData::length();
- data->data = simple->data - simple->offset;
- data->attrs = simple->attrs;
- data->alloc = simple->alloc;
- simple->data = 0;
- simple->attrs = 0;
- // ### explicitly free old data? delete simple;
- arrayData = data;
-
- uint *lastFree = &data->freeList;
- for (uint i = 0; i < oldOffset; ++i) {
- *lastFree = i;
- data->data[i].tag = Value::Empty_Type;
- lastFree = &data->data[i].uint_32;
- }
- for (uint i = 0; i < length; ++i) {
- if (!data->data[i + oldOffset].isEmpty()) {
- SparseArrayNode *n = data->sparse->insert(i);
- n->value = i + oldOffset;
- } else {
- *lastFree = i + oldOffset;
- data->data[i + oldOffset].tag = Value::Empty_Type;
- lastFree = &data->data[i + oldOffset].uint_32;
- }
- }
- for (uint i = length + oldOffset; i < data->alloc; ++i) {
- *lastFree = i;
- data->data[i].tag = Value::Empty_Type;
- lastFree = &data->data[i].uint_32;
- }
- *lastFree = data->alloc;
+ ArrayData::realloc(this, ArrayData::Sparse, 0, 0, false);
}
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 9c272ce7d0..ca54388359 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -197,7 +197,7 @@ public:
void setArrayAttributes(uint i, PropertyAttributes a) {
Q_ASSERT(arrayData);
if (arrayData->attrs || a != Attr_Data) {
- arrayData->ensureAttributes();
+ ArrayData::ensureAttributes(this);
a.resolve();
arrayData->vtable()->setAttribute(this, i, a);
}
@@ -216,13 +216,12 @@ public:
}
inline void arrayReserve(uint n) {
- arrayCreate();
- arrayData->vtable()->reserve(arrayData, n);
+ ArrayData::realloc(this, ArrayData::Simple, 0, n, false);
}
void arrayCreate() {
if (!arrayData)
- arrayData = new (engine()->memoryManager) SimpleArrayData(engine());
+ ArrayData::realloc(this, ArrayData::Simple, 0, 0, false);
#ifdef CHECK_SPARSE_ARRAYS
initSparseArray();
#endif
@@ -383,7 +382,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()->reallocate(this, index + 1, false);
}
setArrayAttributes(index, attributes);
Property *pd = ArrayData::insert(this, index, attributes.isAccessor());
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index e8623d131d..51d6b8d414 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -273,7 +273,7 @@ ReturnedValue ObjectPrototype::method_seal(CallContext *ctx)
o->internalClass = o->internalClass->sealed();
if (o->arrayData) {
- o->arrayData->ensureAttributes();
+ ArrayData::ensureAttributes(o.getPointer());
for (uint i = 0; i < o->arrayData->alloc; ++i) {
if (!o->arrayData->isEmpty(i))
o->arrayData->attrs[i].setConfigurable(false);
@@ -298,7 +298,7 @@ ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx)
o->internalClass = o->internalClass->frozen();
if (o->arrayData) {
- o->arrayData->ensureAttributes();
+ ArrayData::ensureAttributes(o.getPointer());
for (uint i = 0; i < o->arrayData->alloc; ++i) {
if (!o->arrayData->isEmpty(i))
o->arrayData->attrs[i].setConfigurable(false);