diff options
author | Lars Knoll <[email protected]> | 2014-03-06 12:06:36 +0100 |
---|---|---|
committer | The Qt Project <[email protected]> | 2014-03-07 21:16:01 +0100 |
commit | af7ca3607cc6e530af8ed0d1fa5e6d132bc16ac1 (patch) | |
tree | 7be76616922e984d8ea59e40d5e1f797a4adc3e7 /src | |
parent | 19cd5c46693a287c08025c01ded8eaf140e21317 (diff) |
Use an array of Value's for Object::memberData
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 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject.cpp | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4lookup.cpp | 50 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 63 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 13 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 12 |
10 files changed, 81 insertions, 95 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 1f2821910a..3a0aad2fcf 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -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()); } diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h index b50c4f081d..a7904105e4 100644 --- a/src/qml/jsruntime/qv4argumentsobject_p.h +++ b/src/qml/jsruntime/qv4argumentsobject_p.h @@ -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); diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 9a3aa331dc..9b502a0927 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -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()); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index a08dc603ff..778b3157e8 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -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); diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index 7c4a8de284..4fe8f0bd44 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -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); diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 4a75272843..3508316c80 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -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; } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index d0fc30005b..7ad3189dd1 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -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 diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index e3361ae160..5c8590f037 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -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) diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 74c8a2d35e..790eaf79f7 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -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(); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 2b63632780..04a0d6fdec 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -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) { |