aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-02-03 12:34:32 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2013-02-04 15:49:59 +0100
commit10f24399a7c626f6c497bd47d5aff6e212dcc0cb (patch)
tree3dc632f11d529b85acc98bbcabde06c1732344b1
parentb18b6ecbfd55903d57bb8853b2ad614c083647ec (diff)
Don't use a QVector to hold the member data
We don't need any implicit sharing or atomic refcounting. In addition, array access is faster this way. Change-Id: I85e897b74bad92e126e7502fa8e934c9519b4a63 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/v4/qv4object.cpp32
-rw-r--r--src/v4/qv4object.h5
-rw-r--r--src/v4/qv4objectiterator.cpp2
3 files changed, 25 insertions, 14 deletions
diff --git a/src/v4/qv4object.cpp b/src/v4/qv4object.cpp
index ff4fffc4df..7ea8f3aeaf 100644
--- a/src/v4/qv4object.cpp
+++ b/src/v4/qv4object.cpp
@@ -70,6 +70,7 @@ using namespace QQmlJS::VM;
//
Object::~Object()
{
+ delete memberData;
delete sparseArray;
}
@@ -189,8 +190,8 @@ void Object::markObjects()
continue;
(*it)->name->mark();
}
- for (int i = 0; i < (uint)memberData.size(); ++i) {
- const PropertyDescriptor &pd = memberData.at(i);
+ for (int i = 0; i < memberDataSize; ++i) {
+ const PropertyDescriptor &pd = memberData[i];
if (pd.isData()) {
if (Managed *m = pd.value.asManaged())
m->mark();
@@ -212,10 +213,17 @@ PropertyDescriptor *Object::insertMember(String *s)
PropertyTableEntry *e = members->insert(s);
if (e->valueIndex == UINT_MAX) {
- e->valueIndex = memberData.size();
- memberData.resize(memberData.size() + 1);
+ if (memberDataSize == memberDataAlloc) {
+ memberDataAlloc = qMax((uint)8, 2*memberDataAlloc);
+ PropertyDescriptor *newMemberData = new PropertyDescriptor[memberDataAlloc];
+ memcpy(newMemberData, memberData, sizeof(PropertyDescriptor)*memberDataSize);
+ delete memberData;
+ memberData = newMemberData;
+ }
+ e->valueIndex = memberDataSize;
+ ++memberDataSize;
}
- return memberData.data() + e->valueIndex;
+ return memberData + e->valueIndex;
}
// Section 8.12.1
@@ -228,7 +236,7 @@ PropertyDescriptor *Object::__getOwnProperty__(ExecutionContext *ctx, String *na
if (members) {
uint idx = members->find(name);
if (idx < UINT_MAX)
- return memberData.data() + idx;
+ return memberData + idx;
}
return 0;
}
@@ -257,7 +265,7 @@ PropertyDescriptor *Object::__getPropertyDescriptor__(ExecutionContext *ctx, Str
if (o->members) {
uint idx = o->members->find(name);
if (idx < UINT_MAX)
- return o->memberData.data() + idx;
+ return o->memberData + idx;
}
o = o->prototype;
}
@@ -303,7 +311,7 @@ Value Object::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
if (idx < UINT_MAX) {
if (hasProperty)
*hasProperty = true;
- return getValue(ctx, o->memberData.data() + idx);
+ return getValue(ctx, o->memberData + idx);
}
}
o = o->prototype;
@@ -561,7 +569,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr
PropertyDescriptor *current;
if (isArrayObject() && name->isEqualTo(ctx->engine->id_length)) {
- PropertyDescriptor *lp = memberData.data() + ArrayObject::LengthPropertyIndex;
+ PropertyDescriptor *lp = memberData + ArrayObject::LengthPropertyIndex;
assert(0 == members->find(ctx->engine->id_length));
if (desc->isEmpty() || desc->isSubset(lp))
return true;
@@ -610,7 +618,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Prop
PropertyDescriptor *current;
// 15.4.5.1, 4b
- if (isArrayObject() && index >= arrayLength() && !memberData.at(ArrayObject::LengthPropertyIndex).isWritable())
+ if (isArrayObject() && index >= arrayLength() && !memberData[ArrayObject::LengthPropertyIndex].isWritable())
goto reject;
if (isNonStrictArgumentsObject)
@@ -837,7 +845,7 @@ void Object::setArrayLengthUnchecked(uint l)
bool Object::setArrayLength(uint newLen) {
assert(isArrayObject());
- const PropertyDescriptor *lengthProperty = memberData.constData() + ArrayObject::LengthPropertyIndex;
+ const PropertyDescriptor *lengthProperty = memberData + ArrayObject::LengthPropertyIndex;
if (lengthProperty && !lengthProperty->isWritable())
return false;
uint oldLen = arrayLength();
@@ -909,7 +917,7 @@ void ArrayObject::init(ExecutionContext *context)
if (!members)
members.reset(new PropertyTable());
PropertyDescriptor *pd = insertMember(context->engine->id_length);
- assert(pd == memberData.constData() + LengthPropertyIndex);
+ assert(pd == memberData + LengthPropertyIndex);
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Disabled;
diff --git a/src/v4/qv4object.h b/src/v4/qv4object.h
index 0b781095ee..e4b5c9f1c9 100644
--- a/src/v4/qv4object.h
+++ b/src/v4/qv4object.h
@@ -103,7 +103,9 @@ struct URIErrorPrototype;
struct Q_V4_EXPORT Object: Managed {
Object *prototype;
QScopedPointer<PropertyTable> members;
- QVector<PropertyDescriptor> memberData;
+ uint memberDataSize;
+ uint memberDataAlloc;
+ PropertyDescriptor *memberData;
uint arrayLen;
union {
@@ -115,6 +117,7 @@ struct Q_V4_EXPORT Object: Managed {
Object()
: prototype(0)
+ , memberDataSize(0), memberDataAlloc(0), memberData(0)
, arrayLen(0), arrayOffset(0), sparseArray(0) { type = Type_Object; }
virtual ~Object();
diff --git a/src/v4/qv4objectiterator.cpp b/src/v4/qv4objectiterator.cpp
index d94d778675..04f11c6d20 100644
--- a/src/v4/qv4objectiterator.cpp
+++ b/src/v4/qv4objectiterator.cpp
@@ -129,7 +129,7 @@ PropertyDescriptor *ObjectIterator::next(String **name, uint *index)
++tableIndex;
// ### check that it's not a repeated attribute
if (pt) {
- PropertyDescriptor *pd = current->memberData.data() + pt->valueIndex;
+ PropertyDescriptor *pd = current->memberData + pt->valueIndex;
if (!(flags & EnumberableOnly) || pd->isEnumerable()) {
*name = pt->name;
p = pd;