Use an array of Value's for Object::memberData
authorLars Knoll <lars.knoll@digia.com>
Thu, 6 Mar 2014 11:06:36 +0000 (12:06 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 7 Mar 2014 20:16:01 +0000 (21:16 +0100)
This cuts the memory required to store properties
in an object in half for the common case. Accessor
properties require two slots inside memberData,
but data properties only one.

Change-Id: I0bab1b88ca9ed5930abf065c77c89985b9ed5320
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jsruntime/qv4argumentsobject.cpp
src/qml/jsruntime/qv4argumentsobject_p.h
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4functionobject_p.h
src/qml/jsruntime/qv4internalclass.cpp
src/qml/jsruntime/qv4lookup.cpp
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4regexpobject.cpp
src/qml/jsruntime/qv4runtime.cpp

index 1f28219..3a0aad2 100644 (file)
@@ -61,8 +61,8 @@ ArgumentsObject::ArgumentsObject(CallContext *context)
         Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
         Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee));
         Q_ASSERT(CallerPropertyIndex == internalClass->find(context->engine->id_caller));
-        memberData[CalleePropertyIndex] = pd;
-        memberData[CallerPropertyIndex] = pd;
+        *propertyAt(CalleePropertyIndex) = pd;
+        *propertyAt(CallerPropertyIndex) = pd;
 
         arrayReserve(context->callData->argc);
         arrayPut(0, context->callData->args, context->callData->argc);
@@ -70,11 +70,10 @@ ArgumentsObject::ArgumentsObject(CallContext *context)
     } else {
         hasAccessorProperty = 1;
         Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee));
-        memberData[CalleePropertyIndex].value = context->function->asReturnedValue();
+        memberData[CalleePropertyIndex] = context->function->asReturnedValue();
     }
     Q_ASSERT(LengthPropertyIndex == internalClass->find(context->engine->id_length));
-    Property *lp = memberData + ArrayObject::LengthPropertyIndex;
-    lp->value = Primitive::fromInt32(context->realArgumentCount);
+    memberData[LengthPropertyIndex] = Primitive::fromInt32(context->realArgumentCount);
 
     Q_ASSERT(internalClass->vtable == staticVTable());
 }
index b50c4f0..a790410 100644 (file)
@@ -92,7 +92,7 @@ struct ArgumentsObject: Object {
     enum {
         LengthPropertyIndex = 0,
         CalleePropertyIndex = 1,
-        CallerPropertyIndex = 2
+        CallerPropertyIndex = 3
     };
     bool defineOwnProperty(ExecutionContext *ctx, uint index, const Property &desc, PropertyAttributes attrs);
     static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
index 9a3aa33..9b502a0 100644 (file)
@@ -111,7 +111,7 @@ FunctionObject::FunctionObject(InternalClass *ic)
 {
     needsActivation = false;
     strictMode = false;
-    memberData[Index_Prototype].value = Encode::undefined();
+    memberData[Index_Prototype] = Encode::undefined();
 }
 
 FunctionObject::~FunctionObject()
@@ -130,11 +130,10 @@ void FunctionObject::init(const StringRef n, bool createProto)
 
     if (createProto) {
         Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass));
-        proto->memberData[Index_ProtoConstructor].value = this->asReturnedValue();
-        memberData[Index_Prototype].value = proto.asReturnedValue();
+        proto->memberData[Index_ProtoConstructor] = this->asReturnedValue();
+        memberData[Index_Prototype] = proto.asReturnedValue();
     } else {
-        // ### Empty or undefined?
-        memberData[Index_Prototype].value = Encode::undefined();
+        memberData[Index_Prototype] = Encode::undefined();
     }
 
     ScopedValue v(s, n.asReturnedValue());
index a08dc60..778b315 100644 (file)
@@ -137,7 +137,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
 
     static FunctionObject *creatScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true);
 
-    ReturnedValue protoProperty() { return memberData[Index_Prototype].value.asReturnedValue(); }
+    ReturnedValue protoProperty() { return memberData[Index_Prototype].asReturnedValue(); }
 
 protected:
     FunctionObject(InternalClass *ic);
index 7c4a8de..4fe8f0b 100644 (file)
@@ -160,10 +160,10 @@ void InternalClass::changeMember(Object *object, String *string, PropertyAttribu
 
     if (newClass->size > object->internalClass->size) {
         Q_ASSERT(newClass->size == object->internalClass->size + 1);
-        memmove(object->memberData + idx + 2, object->memberData + idx + 1, (object->internalClass->size - idx - 1)*sizeof(Property));
+        memmove(object->memberData + idx + 2, object->memberData + idx + 1, (object->internalClass->size - idx - 1)*sizeof(Value));
     } else if (newClass->size < object->internalClass->size) {
         Q_ASSERT(newClass->size == object->internalClass->size - 1);
-        memmove(object->memberData + idx + 1, object->memberData + idx + 2, (object->internalClass->size - idx - 2)*sizeof(Property));
+        memmove(object->memberData + idx + 1, object->memberData + idx + 2, (object->internalClass->size - idx - 2)*sizeof(Value));
     }
     object->internalClass = newClass;
 }
@@ -368,7 +368,7 @@ void InternalClass::removeMember(Object *object, Identifier *id)
     }
 
     // remove the entry in memberdata
-    memmove(object->memberData + propIdx, object->memberData + propIdx + 1, (object->internalClass->size - propIdx)*sizeof(Property));
+    memmove(object->memberData + propIdx, object->memberData + propIdx + 1, (object->internalClass->size - propIdx)*sizeof(Value));
 
     oldClass->transitions.insert(t, object->internalClass);
 }
@@ -400,6 +400,8 @@ InternalClass *InternalClass::sealed()
     m_sealed = m_sealed->changePrototype(prototype);
     for (uint i = 0; i < size; ++i) {
         PropertyAttributes attrs = propertyData.at(i);
+        if (attrs.isEmpty())
+            continue;
         attrs.setConfigurable(false);
         m_sealed = m_sealed->addMember(nameMap.at(i), attrs);
     }
@@ -418,6 +420,8 @@ InternalClass *InternalClass::frozen()
     m_frozen = m_frozen->changePrototype(prototype);
     for (uint i = 0; i < size; ++i) {
         PropertyAttributes attrs = propertyData.at(i);
+        if (attrs.isEmpty())
+            continue;
         attrs.setWritable(false);
         attrs.setConfigurable(false);
         m_frozen = m_frozen->addMember(nameMap.at(i), attrs);
index 4a75272..3508316 100644 (file)
@@ -57,7 +57,7 @@ ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttribute
         if (index != UINT_MAX) {
             level = i;
             *attrs = obj->internalClass->propertyData.at(index);
-            return !attrs->isAccessor() ? obj->memberData[index].value.asReturnedValue() : obj->getValue(thisObject, obj->memberData + index, *attrs);
+            return !attrs->isAccessor() ? obj->memberData[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
         }
 
         obj = obj->prototype();
@@ -69,7 +69,7 @@ ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttribute
         index = obj->internalClass->find(name);
         if (index != UINT_MAX) {
             *attrs = obj->internalClass->propertyData.at(index);
-            return !attrs->isAccessor() ? obj->memberData[index].value.asReturnedValue() : obj->getValue(thisObject, obj->memberData + index, *attrs);
+            return !attrs->isAccessor() ? obj->memberData[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
         }
 
         obj = obj->prototype();
@@ -88,7 +88,7 @@ ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs)
         if (index != UINT_MAX) {
             level = i;
             *attrs = obj->internalClass->propertyData.at(index);
-            return !attrs->isAccessor() ? obj->memberData[index].value.asReturnedValue() : thisObject->getValue(obj->memberData + index, *attrs);
+            return !attrs->isAccessor() ? obj->memberData[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
         }
 
         obj = obj->prototype();
@@ -100,7 +100,7 @@ ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs)
         index = obj->internalClass->find(name);
         if (index != UINT_MAX) {
             *attrs = obj->internalClass->propertyData.at(index);
-            return !attrs->isAccessor() ? obj->memberData[index].value.asReturnedValue() : thisObject->getValue(obj->memberData + index, *attrs);
+            return !attrs->isAccessor() ? obj->memberData[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
         }
 
         obj = obj->prototype();
@@ -295,7 +295,7 @@ ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object)
         // the internal class won't match
         Object *o = object->objectValue();
         if (l->classList[0] == o->internalClass)
-            return static_cast<Object *>(o)->memberData[l->index].value.asReturnedValue();
+            return static_cast<Object *>(o)->memberData[l->index].asReturnedValue();
     }
     l->getter = getterGeneric;
     return getterGeneric(l, object);
@@ -309,7 +309,7 @@ ReturnedValue Lookup::getter1(Lookup *l, const ValueRef object)
         Object *o = object->objectValue();
         if (l->classList[0] == o->internalClass &&
             l->classList[1] == o->prototype()->internalClass)
-            return o->prototype()->memberData[l->index].value.asReturnedValue();
+            return o->prototype()->memberData[l->index].asReturnedValue();
     }
     l->getter = getterGeneric;
     return getterGeneric(l, object);
@@ -326,7 +326,7 @@ ReturnedValue Lookup::getter2(Lookup *l, const ValueRef object)
             if (l->classList[1] == o->internalClass) {
                 o = o->prototype();
                 if (l->classList[2] == o->internalClass)
-                    return o->memberData[l->index].value.asReturnedValue();
+                    return o->memberData[l->index].asReturnedValue();
             }
         }
     }
@@ -342,7 +342,7 @@ ReturnedValue Lookup::getterAccessor0(Lookup *l, const ValueRef object)
         Object *o = object->objectValue();
         if (l->classList[0] == o->internalClass) {
             Scope scope(o->engine());
-            FunctionObject *getter = o->memberData[l->index].getter();
+            FunctionObject *getter = o->propertyAt(l->index)->getter();
             if (!getter)
                 return Encode::undefined();
 
@@ -364,7 +364,7 @@ ReturnedValue Lookup::getterAccessor1(Lookup *l, const ValueRef object)
         if (l->classList[0] == o->internalClass &&
             l->classList[1] == o->prototype()->internalClass) {
             Scope scope(o->engine());
-            FunctionObject *getter = o->prototype()->memberData[l->index].getter();
+            FunctionObject *getter = o->prototype()->propertyAt(l->index)->getter();
             if (!getter)
                 return Encode::undefined();
 
@@ -389,7 +389,7 @@ ReturnedValue Lookup::getterAccessor2(Lookup *l, const ValueRef object)
                 o = o->prototype();
                 if (l->classList[2] == o->internalClass) {
                     Scope scope(o->engine());
-                    FunctionObject *getter = o->memberData[l->index].getter();
+                    FunctionObject *getter = o->propertyAt(l->index)->getter();
                     if (!getter)
                         return Encode::undefined();
 
@@ -410,7 +410,7 @@ ReturnedValue Lookup::primitiveGetter0(Lookup *l, const ValueRef object)
     if (object->type() == l->type) {
         Object *o = l->proto;
         if (l->classList[0] == o->internalClass)
-            return o->memberData[l->index].value.asReturnedValue();
+            return o->memberData[l->index].asReturnedValue();
     }
     l->getter = getterGeneric;
     return getterGeneric(l, object);
@@ -422,7 +422,7 @@ ReturnedValue Lookup::primitiveGetter1(Lookup *l, const ValueRef object)
         Object *o = l->proto;
         if (l->classList[0] == o->internalClass &&
             l->classList[1] == o->prototype()->internalClass)
-            return o->prototype()->memberData[l->index].value.asReturnedValue();
+            return o->prototype()->memberData[l->index].asReturnedValue();
     }
     l->getter = getterGeneric;
     return getterGeneric(l, object);
@@ -434,7 +434,7 @@ ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, const ValueRef object)
         Object *o = l->proto;
         if (l->classList[0] == o->internalClass) {
             Scope scope(o->engine());
-            FunctionObject *getter = o->memberData[l->index].getter();
+            FunctionObject *getter = o->propertyAt(l->index)->getter();
             if (!getter)
                 return Encode::undefined();
 
@@ -454,7 +454,7 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, const ValueRef object)
         if (l->classList[0] == o->internalClass &&
             l->classList[1] == o->prototype()->internalClass) {
             Scope scope(o->engine());
-            FunctionObject *getter = o->prototype()->memberData[l->index].getter();
+            FunctionObject *getter = o->prototype()->propertyAt(l->index)->getter();
             if (!getter)
                 return Encode::undefined();
 
@@ -479,7 +479,7 @@ ReturnedValue Lookup::stringLengthGetter(Lookup *l, const ValueRef object)
 ReturnedValue Lookup::arrayLengthGetter(Lookup *l, const ValueRef object)
 {
     if (ArrayObject *a = object->asArrayObject())
-        return a->memberData[ArrayObject::LengthPropertyIndex].value.asReturnedValue();
+        return a->memberData[ArrayObject::LengthPropertyIndex].asReturnedValue();
 
     l->getter = getterGeneric;
     return getterGeneric(l, object);
@@ -519,7 +519,7 @@ ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionContext *ctx)
 {
     Object *o = ctx->engine->globalObject;
     if (l->classList[0] == o->internalClass)
-        return o->memberData[l->index].value.asReturnedValue();
+        return o->memberData[l->index].asReturnedValue();
 
     l->globalGetter = globalGetterGeneric;
     return globalGetterGeneric(l, ctx);
@@ -530,7 +530,7 @@ ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionContext *ctx)
     Object *o = ctx->engine->globalObject;
     if (l->classList[0] == o->internalClass &&
         l->classList[1] == o->prototype()->internalClass)
-        return o->prototype()->memberData[l->index].value.asReturnedValue();
+        return o->prototype()->memberData[l->index].asReturnedValue();
 
     l->globalGetter = globalGetterGeneric;
     return globalGetterGeneric(l, ctx);
@@ -544,7 +544,7 @@ ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionContext *ctx)
         if (l->classList[1] == o->internalClass) {
             o = o->prototype();
             if (l->classList[2] == o->internalClass) {
-                return o->prototype()->memberData[l->index].value.asReturnedValue();
+                return o->prototype()->memberData[l->index].asReturnedValue();
             }
         }
     }
@@ -557,7 +557,7 @@ ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionContext *ctx)
     Object *o = ctx->engine->globalObject;
     if (l->classList[0] == o->internalClass) {
         Scope scope(o->engine());
-        FunctionObject *getter = o->memberData[l->index].getter();
+        FunctionObject *getter = o->propertyAt(l->index)->getter();
         if (!getter)
             return Encode::undefined();
 
@@ -575,7 +575,7 @@ ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionContext *ctx)
     if (l->classList[0] == o->internalClass &&
         l->classList[1] == o->prototype()->internalClass) {
         Scope scope(o->engine());
-        FunctionObject *getter = o->prototype()->memberData[l->index].getter();
+        FunctionObject *getter = o->prototype()->propertyAt(l->index)->getter();
         if (!getter)
             return Encode::undefined();
 
@@ -596,7 +596,7 @@ ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionContext *ctx)
             o = o->prototype();
             if (l->classList[2] == o->internalClass) {
                 Scope scope(o->engine());
-                FunctionObject *getter = o->memberData[l->index].getter();
+                FunctionObject *getter = o->propertyAt(l->index)->getter();
                 if (!getter)
                     return Encode::undefined();
 
@@ -629,7 +629,7 @@ void Lookup::setter0(Lookup *l, const ValueRef object, const ValueRef value)
 {
     Object *o = object->asObject();
     if (o && o->internalClass == l->classList[0]) {
-        o->memberData[l->index].value = *value;
+        o->memberData[l->index] = *value;
         return;
     }
 
@@ -644,7 +644,7 @@ void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef valu
         if (!o->prototype()) {
             if (l->index >= o->memberDataAlloc)
                 o->ensureMemberIndex(l->index);
-            o->memberData[l->index].value = *value;
+            o->memberData[l->index] = *value;
             o->internalClass = l->classList[3];
             return;
         }
@@ -662,7 +662,7 @@ void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef valu
         if (p && p->internalClass == l->classList[1]) {
             if (l->index >= o->memberDataAlloc)
                 o->ensureMemberIndex(l->index);
-            o->memberData[l->index].value = *value;
+            o->memberData[l->index] = *value;
             o->internalClass = l->classList[3];
             return;
         }
@@ -682,7 +682,7 @@ void Lookup::setterInsert2(Lookup *l, const ValueRef object, const ValueRef valu
             if (p && p->internalClass == l->classList[2]) {
                 if (l->index >= o->memberDataAlloc)
                     o->ensureMemberIndex(l->index);
-                o->memberData[l->index].value = *value;
+                o->memberData[l->index] = *value;
                 o->internalClass = l->classList[3];
                 return;
             }
index d0fc300..7ad3189 100644 (file)
@@ -83,7 +83,7 @@ Object::Object(InternalClass *ic)
 
     if (internalClass->size >= memberDataAlloc) {
         memberDataAlloc = internalClass->size;
-        memberData = new Property[memberDataAlloc];
+        memberData = new Value[memberDataAlloc];
     }
 }
 
@@ -222,17 +222,8 @@ void Object::markObjects(Managed *that, ExecutionEngine *e)
 {
     Object *o = static_cast<Object *>(that);
 
-    if (!o->hasAccessorProperty) {
-        for (uint i = 0; i < o->internalClass->size; ++i)
-            o->memberData[i].value.mark(e);
-    } else {
-        for (uint i = 0; i < o->internalClass->size; ++i) {
-            const Property &pd = o->memberData[i];
-            pd.value.mark(e);
-            if (o->internalClass->propertyData[i].isAccessor())
-                pd.set.mark(e);
-        }
-    }
+    for (uint i = 0; i < o->internalClass->size; ++i)
+        o->memberData[i].mark(e);
     if (o->arrayData)
         o->arrayData->mark(e);
 }
@@ -241,9 +232,9 @@ void Object::ensureMemberIndex(uint idx)
 {
     if (idx >= memberDataAlloc) {
         int newAlloc = qMax((uint)8, 2*memberDataAlloc);
-        Property *newMemberData = new Property[newAlloc];
-        memcpy(newMemberData, memberData, sizeof(Property)*memberDataAlloc);
-        memset(newMemberData + memberDataAlloc, 0, sizeof(Property)*(newAlloc - memberDataAlloc));
+        Value *newMemberData = new Value[newAlloc];
+        memcpy(newMemberData, memberData, sizeof(Value)*memberDataAlloc);
+        memset(newMemberData + memberDataAlloc, 0, sizeof(Value)*(newAlloc - memberDataAlloc));
         memberDataAlloc = newAlloc;
         if (memberData != inlineProperties)
             delete [] memberData;
@@ -256,12 +247,15 @@ void Object::insertMember(const StringRef s, const Property &p, PropertyAttribut
     uint idx;
     InternalClass::addMember(this, s.getPointer(), attributes, &idx);
 
-    if (attributes.isAccessor())
-        hasAccessorProperty = 1;
 
     ensureMemberIndex(internalClass->size);
 
-    memberData[idx] = p;
+    if (attributes.isAccessor()) {
+        hasAccessorProperty = 1;
+        *propertyAt(idx) = p;
+    } else {
+        memberData[idx] = p.value;
+    }
 }
 
 // Section 8.12.1
@@ -275,7 +269,7 @@ Property *Object::__getOwnProperty__(const StringRef name, PropertyAttributes *a
     if (member < UINT_MAX) {
         if (attrs)
             *attrs = internalClass->propertyData[member];
-        return memberData + member;
+        return propertyAt(member);
     }
 
     if (attrs)
@@ -316,7 +310,7 @@ Property *Object::__getPropertyDescriptor__(const StringRef name, PropertyAttrib
         if (idx < UINT_MAX) {
             if (attrs)
                 *attrs = o->internalClass->propertyData[idx];
-            return o->memberData + idx;
+            return o->propertyAt(idx);
         }
 
         o = o->prototype();
@@ -515,12 +509,12 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value)
             l->classList[0] = o->internalClass;
             l->index = idx;
             l->setter = Lookup::setter0;
-            o->memberData[idx].value = *value;
+            o->memberData[idx] = *value;
             return;
         }
 
         if (idx != UINT_MAX) {
-            o->putValue(o->memberData + idx, o->internalClass->propertyData[idx], value);
+            o->putValue(o->propertyAt(idx), o->internalClass->propertyData[idx], value);
             return;
         }
     }
@@ -604,7 +598,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uin
             continue;
         }
 
-        Property *p = o->memberData + it->memberIndex;
+        Property *p = o->propertyAt(it->memberIndex);
         PropertyAttributes a = o->internalClass->propertyData[it->memberIndex];
         ++it->memberIndex;
         if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
@@ -633,7 +627,7 @@ ReturnedValue Object::internalGet(const StringRef name, bool *hasProperty)
         if (idx < UINT_MAX) {
             if (hasProperty)
                 *hasProperty = true;
-            return getValue(o->memberData + idx, o->internalClass->propertyData.at(idx));
+            return getValue(o->propertyAt(idx), o->internalClass->propertyData.at(idx));
         }
 
         o = o->prototype();
@@ -694,7 +688,7 @@ void Object::internalPut(const StringRef name, const ValueRef value)
     Property *pd = 0;
     PropertyAttributes attrs;
     if (member < UINT_MAX) {
-        pd = memberData + member;
+        pd = propertyAt(member);
         attrs = internalClass->propertyData[member];
     }
 
@@ -886,7 +880,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name,
 
     if (isArrayObject() && name->equals(ctx->engine->id_length)) {
         assert(ArrayObject::LengthPropertyIndex == internalClass->find(ctx->engine->id_length));
-        Property *lp = memberData + ArrayObject::LengthPropertyIndex;
+        Property *lp = propertyAt(ArrayObject::LengthPropertyIndex);
         cattrs = internalClass->propertyData.constData() + ArrayObject::LengthPropertyIndex;
         if (attrs.isEmpty() || p.isSubset(attrs, *lp, *cattrs))
             return true;
@@ -914,7 +908,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name,
 
     // Clause 1
     memberIndex = internalClass->find(name.getPointer());
-    current = (memberIndex < UINT_MAX) ? memberData + memberIndex : 0;
+    current = (memberIndex < UINT_MAX) ? propertyAt(memberIndex) : 0;
     cattrs = internalClass->propertyData.constData() + memberIndex;
 
     if (!current) {
@@ -995,7 +989,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Stri
     Property *current;
     PropertyAttributes cattrs;
     if (!member.isNull()) {
-        current = memberData + index;
+        current = propertyAt(index);
         cattrs = internalClass->propertyData[index];
     } else {
         current = arrayData->getProperty(index);
@@ -1138,8 +1132,7 @@ uint Object::getLength(const Managed *m)
 bool Object::setArrayLength(uint newLen)
 {
     Q_ASSERT(isArrayObject());
-    const Property *lengthProperty = memberData + ArrayObject::LengthPropertyIndex;
-    if (lengthProperty && !internalClass->propertyData[ArrayObject::LengthPropertyIndex].isWritable())
+    if (!internalClass->propertyData[ArrayObject::LengthPropertyIndex].isWritable())
         return false;
     uint oldLen = getLength();
     bool ok = true;
@@ -1194,7 +1187,7 @@ void ArrayObject::init(ExecutionEngine *engine)
 {
     Q_UNUSED(engine);
 
-    memberData[LengthPropertyIndex].value = Primitive::fromInt32(0);
+    memberData[LengthPropertyIndex] = Primitive::fromInt32(0);
 }
 
 ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l)
@@ -1203,7 +1196,7 @@ ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l)
         // special case, as the property is on the object itself
         l->getter = Lookup::arrayLengthGetter;
         ArrayObject *a = static_cast<ArrayObject *>(m);
-        return a->memberData[ArrayObject::LengthPropertyIndex].value.asReturnedValue();
+        return a->memberData[ArrayObject::LengthPropertyIndex].asReturnedValue();
     }
     return Object::getLookup(m, l);
 }
@@ -1211,9 +1204,9 @@ ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l)
 uint ArrayObject::getLength(const Managed *m)
 {
     const ArrayObject *a = static_cast<const ArrayObject *>(m);
-    if (a->memberData[ArrayObject::LengthPropertyIndex].value.isInteger())
-        return a->memberData[ArrayObject::LengthPropertyIndex].value.integerValue();
-    return Primitive::toUInt32(a->memberData[ArrayObject::LengthPropertyIndex].value.doubleValue());
+    if (a->memberData[ArrayObject::LengthPropertyIndex].isInteger())
+        return a->memberData[ArrayObject::LengthPropertyIndex].integerValue();
+    return Primitive::toUInt32(a->memberData[ArrayObject::LengthPropertyIndex].doubleValue());
 }
 
 QStringList ArrayObject::toQStringList() const
index e3361ae..5c8590f 100644 (file)
@@ -108,14 +108,16 @@ struct Q_QML_EXPORT Object: Managed {
         IsObject = true
     };
     uint memberDataAlloc;
-    Property *memberData;
+    Value *memberData;
 
     ArrayData *arrayData;
 
     enum {
         InlinePropertySize = 4
     };
-    Property inlineProperties[InlinePropertySize];
+    Value inlineProperties[InlinePropertySize];
+
+    Property *propertyAt(uint index) const { return reinterpret_cast<Property *>(memberData + index); }
 
     Object(ExecutionEngine *engine);
     Object(InternalClass *internalClass);
@@ -355,11 +357,8 @@ struct ArrayObject: Object {
 
 inline void Object::setArrayLengthUnchecked(uint l)
 {
-    if (isArrayObject()) {
-        // length is always the first property of an array
-        Property &lengthProperty = memberData[ArrayObject::LengthPropertyIndex];
-        lengthProperty.value = Primitive::fromUInt32(l);
-    }
+    if (isArrayObject())
+        memberData[ArrayObject::LengthPropertyIndex] = Primitive::fromUInt32(l);
 }
 
 inline void Object::push_back(const ValueRef v)
index 74c8a2d..790eaf7 100644 (file)
@@ -186,7 +186,7 @@ Property *RegExpObject::lastIndexProperty(ExecutionContext *ctx)
 {
     Q_UNUSED(ctx);
     Q_ASSERT(0 == internalClass->find(ctx->engine->newIdentifier(QStringLiteral("lastIndex"))));
-    return &memberData[0];
+    return propertyAt(0);
 }
 
 // Converts a JS RegExp to a QRegExp.
@@ -394,8 +394,8 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
         array->arrayPut(i, v);
     }
     array->setArrayLengthUnchecked(len);
-    array->memberData[Index_ArrayIndex].value = Primitive::fromInt32(result);
-    array->memberData[Index_ArrayInput].value = arg.asReturnedValue();
+    array->memberData[Index_ArrayIndex] = Primitive::fromInt32(result);
+    array->memberData[Index_ArrayInput] = arg.asReturnedValue();
 
     regExpCtor->lastMatch = array;
     regExpCtor->lastInput = arg->stringValue();
index 2b63632..04a0d6f 100644 (file)
@@ -1112,16 +1112,8 @@ ReturnedValue __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx,
             o->initSparseArray();
     }
 
-    for (uint i = 0; i < klass->size; ++i) {
-        if (klass->propertyData[i].isData())
-            o->memberData[i].value = *args++;
-        else {
-            o->memberData[i].value = *args;
-            args++;
-            o->memberData[i].set = *args;
-            args++;
-        }
-    }
+    for (uint i = 0; i < klass->size; ++i)
+        o->memberData[i] = *args++;
 
     ScopedValue entry(scope);
     for (int i = 0; i < arrayValueCount; ++i) {