diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-01-24 14:29:40 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-24 14:32:37 +0100 |
commit | ab2b5219876a60867e67b47827196114d238155d (patch) | |
tree | c2ecc7d22dcb8c4eadeede664ba97b3be64baffe /src/qml/jsruntime | |
parent | c53fef423a8f607e1443b1d409712864f8cac9d5 (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.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arraydata.cpp | 247 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arraydata_p.h | 24 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 52 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4objectproto.cpp | 4 |
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); |