Get rid of Members and directly store MemberData::Data pointers

And do the same change for ArrayData.

Change-Id: Ia1ae56bd0ff586c9b987e15af7a53f395a37054a
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Lars Knoll 2014-11-01 21:44:57 +01:00 committed by Simon Hausmann
parent e22fc141c3
commit b340caa0d3
14 changed files with 135 additions and 118 deletions

View File

@ -65,10 +65,10 @@ ArgumentsObject::Data::Data(CallContext *context)
} else {
args->setHasAccessorProperty();
Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(context->d()->engine->id_callee));
args->memberData()[CalleePropertyIndex] = context->d()->function->asReturnedValue();
args->memberData()->data()[CalleePropertyIndex] = context->d()->function->asReturnedValue();
}
Q_ASSERT(LengthPropertyIndex == args->internalClass()->find(context->d()->engine->id_length));
args->memberData()[LengthPropertyIndex] = Primitive::fromInt32(context->d()->realArgumentCount);
args->memberData()->data()[LengthPropertyIndex] = Primitive::fromInt32(context->d()->realArgumentCount);
}
void ArgumentsObject::fullyCreate()
@ -80,9 +80,13 @@ void ArgumentsObject::fullyCreate()
uint argCount = qMin(context()->d()->realArgumentCount, context()->d()->callData->argc);
ArrayData::realloc(this, ArrayData::Sparse, argCount, true);
context()->d()->engine->requireArgumentsAccessors(numAccessors);
mappedArguments().ensureIndex(engine(), numAccessors);
Scope scope(engine());
Scoped<MemberData> md(scope, d()->mappedArguments);
if (md)
d()->mappedArguments = md->reallocate(engine(), d()->mappedArguments, numAccessors);
for (uint i = 0; i < (uint)numAccessors; ++i) {
mappedArguments()[i] = context()->d()->callData->args[i];
mappedArguments()->data[i] = context()->d()->callData->args[i];
arraySet(i, context()->d()->engine->argumentsAccessors[i], Attr_Accessor);
}
arrayPut(numAccessors, context()->d()->callData->args + numAccessors, argCount - numAccessors);
@ -111,7 +115,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
map.copy(*pd, mapAttrs);
setArrayAttributes(index, Attr_Data);
pd = arrayData()->getProperty(index);
pd->value = mappedArguments()[index];
pd->value = mappedArguments()->data[index];
}
bool strict = ctx->d()->strictMode;
@ -227,7 +231,8 @@ void ArgumentsObject::markObjects(HeapObject *that, ExecutionEngine *e)
ArgumentsObject::Data *o = static_cast<ArgumentsObject::Data *>(that);
if (o->context)
o->context->mark(e);
o->mappedArguments.mark(e);
if (o->mappedArguments)
o->mappedArguments->mark(e);
Object::markObjects(that, e);
}

View File

@ -82,14 +82,14 @@ struct ArgumentsObject: Object {
Data(CallContext *context);
CallContext *context;
bool fullyCreated;
Members mappedArguments;
MemberData::Data *mappedArguments;
};
V4_OBJECT(Object)
Q_MANAGED_TYPE(ArgumentsObject)
CallContext *context() const { return d()->context; }
bool fullyCreated() const { return d()->fullyCreated; }
Members &mappedArguments() { return d()->mappedArguments; }
MemberData::Data *mappedArguments() { return d()->mappedArguments; }
static bool isNonStrictArgumentsObject(Managed *m) {
return m->internalClass()->vtable->type == Type_ArgumentsObject &&

View File

@ -77,7 +77,6 @@ struct SyntaxErrorObject;
struct ArgumentsObject;
struct ExecutionContext;
struct ExecutionEngine;
struct Members;
class MemoryManager;
class ExecutableAllocator;

View File

@ -96,8 +96,10 @@ FunctionObject::Data::Data(InternalClass *ic)
: Object::Data(ic)
, scope(ic->engine->rootContext)
{
memberData.ensureIndex(ic->engine, Index_Prototype);
memberData[Index_Prototype] = Encode::undefined();
Scope scope(ic->engine);
ScopedObject o(scope, this);
o->ensureMemberIndex(ic->engine, Index_Prototype);
memberData->data[Index_Prototype] = Encode::undefined();
}
@ -115,13 +117,14 @@ void FunctionObject::init(String *n, bool createProto)
d()->needsActivation = true;
d()->strictMode = false;
memberData().ensureIndex(s.engine, Index_Prototype);
ensureMemberIndex(s.engine, Index_Prototype);
if (createProto) {
Scoped<Object> proto(s, scope()->d()->engine->newObject(scope()->d()->engine->protoClass));
proto->memberData()[Index_ProtoConstructor] = this->asReturnedValue();
memberData()[Index_Prototype] = proto.asReturnedValue();
proto->ensureMemberIndex(s.engine, Index_ProtoConstructor);
proto->memberData()->data()[Index_ProtoConstructor] = this->asReturnedValue();
memberData()->data()[Index_Prototype] = proto.asReturnedValue();
} else {
memberData()[Index_Prototype] = Encode::undefined();
memberData()->data()[Index_Prototype] = Encode::undefined();
}
ScopedValue v(s, n);
@ -333,14 +336,12 @@ ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
return ctx->engine()->throwTypeError();
ScopedValue boundThis(scope, ctx->argument(0));
Members boundArgs;
boundArgs.reset();
Scoped<MemberData> boundArgs(scope);
if (ctx->d()->callData->argc > 1) {
boundArgs.ensureIndex(scope.engine, ctx->d()->callData->argc - 1);
boundArgs.d()->d()->size = ctx->d()->callData->argc - 1;
memcpy(boundArgs.data(), ctx->d()->callData->args + 1, (ctx->d()->callData->argc - 1)*sizeof(Value));
boundArgs = MemberData::reallocate(scope.engine, 0, ctx->d()->callData->argc - 1);
boundArgs->d()->size = ctx->d()->callData->argc - 1;
memcpy(boundArgs->data(), ctx->d()->callData->args + 1, (ctx->d()->callData->argc - 1)*sizeof(Value));
}
ScopedValue protectBoundArgs(scope, boundArgs.d());
return BoundFunction::create(ctx->d()->engine->rootContext, target, boundThis, boundArgs)->asReturnedValue();
}
@ -584,10 +585,10 @@ DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
DEFINE_OBJECT_VTABLE(BoundFunction);
BoundFunction::Data::Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const Members &boundArgs)
BoundFunction::Data::Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, MemberData *boundArgs)
: FunctionObject::Data(scope, QStringLiteral("__bound function__"))
, target(target)
, boundArgs(boundArgs)
, boundArgs(boundArgs ? boundArgs->d() : 0)
{
this->boundThis = boundThis;
setVTable(staticVTable());
@ -598,7 +599,8 @@ BoundFunction::Data::Data(ExecutionContext *scope, FunctionObject *target, const
ScopedValue l(s, target->get(s.engine->id_length));
int len = l->toUInt32();
len -= boundArgs.size();
if (boundArgs)
len -= boundArgs->size();
if (len < 0)
len = 0;
f->defineReadonlyProperty(s.engine->id_length, Primitive::fromInt32(len));
@ -617,10 +619,15 @@ ReturnedValue BoundFunction::call(Managed *that, CallData *dd)
if (scope.hasException())
return Encode::undefined();
ScopedCallData callData(scope, f->boundArgs().size() + dd->argc);
Scoped<MemberData> boundArgs(scope, f->boundArgs());
ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + dd->argc);
callData->thisObject = f->boundThis();
memcpy(callData->args, f->boundArgs().data(), f->boundArgs().size()*sizeof(Value));
memcpy(callData->args + f->boundArgs().size(), dd->args, dd->argc*sizeof(Value));
Value *argp = callData->args;
if (boundArgs) {
memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value));
argp += boundArgs->size();
}
memcpy(argp, dd->args, dd->argc*sizeof(Value));
return f->target()->call(callData);
}
@ -631,9 +638,14 @@ ReturnedValue BoundFunction::construct(Managed *that, CallData *dd)
if (scope.hasException())
return Encode::undefined();
ScopedCallData callData(scope, f->boundArgs().size() + dd->argc);
memcpy(callData->args, f->boundArgs().data(), f->boundArgs().size()*sizeof(Value));
memcpy(callData->args + f->boundArgs().size(), dd->args, dd->argc*sizeof(Value));
Scoped<MemberData> boundArgs(scope, f->boundArgs());
ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + dd->argc);
Value *argp = callData->args;
if (boundArgs) {
memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value));
argp += boundArgs->size();
}
memcpy(argp, dd->args, dd->argc*sizeof(Value));
return f->target()->construct(callData);
}
@ -642,6 +654,7 @@ void BoundFunction::markObjects(HeapObject *that, ExecutionEngine *e)
BoundFunction::Data *o = static_cast<BoundFunction::Data *>(that);
o->target->mark(e);
o->boundThis.mark(e);
o->boundArgs.mark(e);
if (o->boundArgs)
o->boundArgs->mark(e);
FunctionObject::markObjects(that, e);
}

View File

@ -96,7 +96,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
static Returned<FunctionObject> *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true);
ReturnedValue protoProperty() { return memberData()[Index_Prototype].asReturnedValue(); }
ReturnedValue protoProperty() { return memberData()->data()[Index_Prototype].asReturnedValue(); }
bool needsActivation() const { return d()->needsActivation; }
bool strictMode() const { return d()->strictMode; }
@ -202,21 +202,22 @@ struct ScriptFunction: SimpleScriptFunction {
struct BoundFunction: FunctionObject {
struct Data : FunctionObject::Data {
Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const Members &boundArgs);
Data(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, MemberData *boundArgs);
FunctionObject *target;
Value boundThis;
Members boundArgs;
MemberData::Data *boundArgs;
};
V4_OBJECT(FunctionObject)
static Returned<BoundFunction> *create(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const QV4::Members &boundArgs)
static Returned<BoundFunction> *create(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, QV4::MemberData *boundArgs)
{
return scope->engine()->memoryManager->alloc<BoundFunction>(scope, target, boundThis, boundArgs);
}
FunctionObject *target() { return d()->target; }
Value boundThis() const { return d()->boundThis; }
Members boundArgs() const { return d()->boundArgs; }
// ### GC
MemberData::Data *boundArgs() const { return d()->boundArgs; }
static ReturnedValue construct(Managed *, CallData *d);
static ReturnedValue call(Managed *that, CallData *dd);

View File

@ -153,10 +153,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().data() + idx + 2, object->memberData().data() + idx + 1, (object->internalClass()->size - idx - 1)*sizeof(Value));
memmove(object->memberData()->data() + idx + 2, object->memberData()->data() + 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().data() + idx + 1, object->memberData().data() + idx + 2, (object->internalClass()->size - idx - 2)*sizeof(Value));
memmove(object->memberData()->data() + idx + 1, object->memberData()->data() + idx + 2, (object->internalClass()->size - idx - 2)*sizeof(Value));
}
object->setInternalClass(newClass);
}
@ -351,7 +351,7 @@ void InternalClass::removeMember(Object *object, Identifier *id)
}
// remove the entry in memberdata
memmove(object->memberData().data() + propIdx, object->memberData().data() + propIdx + 1, (object->internalClass()->size - propIdx)*sizeof(Value));
memmove(object->memberData()->data() + propIdx, object->memberData()->data() + propIdx + 1, (object->internalClass()->size - propIdx)*sizeof(Value));
oldClass->transitions.insert(t, object->internalClass());
}

View File

@ -49,7 +49,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].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
return !attrs->isAccessor() ? obj->memberData()->data()[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@ -61,7 +61,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].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
return !attrs->isAccessor() ? obj->memberData()->data()[index].asReturnedValue() : obj->getValue(thisObject, obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@ -80,7 +80,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].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
return !attrs->isAccessor() ? obj->memberData()->data()[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@ -92,7 +92,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].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
return !attrs->isAccessor() ? obj->memberData()->data()[index].asReturnedValue() : thisObject->getValue(obj->propertyAt(index), *attrs);
}
obj = obj->prototype();
@ -334,7 +334,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 o->memberData()[l->index].asReturnedValue();
return o->memberData()->data()[l->index].asReturnedValue();
}
return getterTwoClasses(l, object);
}
@ -347,7 +347,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].asReturnedValue();
return o->prototype()->memberData()->data()[l->index].asReturnedValue();
}
return getterTwoClasses(l, object);
}
@ -363,7 +363,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].asReturnedValue();
return o->memberData()->data()[l->index].asReturnedValue();
}
}
}
@ -378,9 +378,9 @@ ReturnedValue Lookup::getter0getter0(Lookup *l, const ValueRef object)
// the internal class won't match
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass())
return o->memberData()[l->index].asReturnedValue();
return o->memberData()->data()[l->index].asReturnedValue();
if (l->classList[2] == o->internalClass())
return o->memberData()[l->index2].asReturnedValue();
return o->memberData()->data()[l->index2].asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, object);
@ -393,10 +393,10 @@ ReturnedValue Lookup::getter0getter1(Lookup *l, const ValueRef object)
// the internal class won't match
Object *o = object->objectValue();
if (l->classList[0] == o->internalClass())
return o->memberData()[l->index].asReturnedValue();
return o->memberData()->data()[l->index].asReturnedValue();
if (l->classList[2] == o->internalClass() &&
l->classList[3] == o->prototype()->internalClass())
return o->prototype()->memberData()[l->index2].asReturnedValue();
return o->prototype()->memberData()->data()[l->index2].asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, object);
@ -410,10 +410,10 @@ ReturnedValue Lookup::getter1getter1(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].asReturnedValue();
return o->prototype()->memberData()->data()[l->index].asReturnedValue();
if (l->classList[2] == o->internalClass() &&
l->classList[3] == o->prototype()->internalClass())
return o->prototype()->memberData()[l->index2].asReturnedValue();
return o->prototype()->memberData()->data()[l->index2].asReturnedValue();
return getterFallback(l, object);
}
l->getter = getterFallback;
@ -496,7 +496,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].asReturnedValue();
return o->memberData()->data()[l->index].asReturnedValue();
}
l->getter = getterGeneric;
return getterGeneric(l, object);
@ -508,7 +508,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].asReturnedValue();
return o->prototype()->memberData()->data()[l->index].asReturnedValue();
}
l->getter = getterGeneric;
return getterGeneric(l, object);
@ -565,7 +565,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].asReturnedValue();
return a->memberData()->data()[ArrayObject::LengthPropertyIndex].asReturnedValue();
l->getter = getterGeneric;
return getterGeneric(l, object);
@ -605,7 +605,7 @@ ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->d()->engine->globalObject;
if (l->classList[0] == o->internalClass())
return o->memberData()[l->index].asReturnedValue();
return o->memberData()->data()[l->index].asReturnedValue();
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, ctx);
@ -616,7 +616,7 @@ ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionContext *ctx)
Object *o = ctx->d()->engine->globalObject;
if (l->classList[0] == o->internalClass() &&
l->classList[1] == o->prototype()->internalClass())
return o->prototype()->memberData()[l->index].asReturnedValue();
return o->prototype()->memberData()->data()[l->index].asReturnedValue();
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, ctx);
@ -630,7 +630,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].asReturnedValue();
return o->prototype()->memberData()->data()[l->index].asReturnedValue();
}
}
}
@ -744,7 +744,7 @@ void Lookup::setter0(Lookup *l, const ValueRef object, const ValueRef value)
{
Object *o = static_cast<Object *>(object->asManaged());
if (o && o->internalClass() == l->classList[0]) {
o->memberData()[l->index] = *value;
o->memberData()->data()[l->index] = *value;
return;
}
@ -756,9 +756,9 @@ void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef valu
Object *o = static_cast<Object *>(object->asManaged());
if (o && o->internalClass() == l->classList[0]) {
if (!o->prototype()) {
if (l->index >= o->memberData().size())
if (!o->memberData() || l->index >= o->memberData()->size())
o->ensureMemberIndex(l->index);
o->memberData()[l->index] = *value;
o->memberData()->data()[l->index] = *value;
o->setInternalClass(l->classList[3]);
return;
}
@ -774,9 +774,9 @@ void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef valu
if (o && o->internalClass() == l->classList[0]) {
Object *p = o->prototype();
if (p && p->internalClass() == l->classList[1]) {
if (l->index >= o->memberData().size())
if (!o->memberData() || l->index >= o->memberData()->size())
o->ensureMemberIndex(l->index);
o->memberData()[l->index] = *value;
o->memberData()->data()[l->index] = *value;
o->setInternalClass(l->classList[3]);
return;
}
@ -794,9 +794,9 @@ void Lookup::setterInsert2(Lookup *l, const ValueRef object, const ValueRef valu
if (p && p->internalClass() == l->classList[1]) {
p = p->prototype();
if (p && p->internalClass() == l->classList[2]) {
if (l->index >= o->memberData().size())
if (!o->memberData() || l->index >= o->memberData()->size())
o->ensureMemberIndex(l->index);
o->memberData()[l->index] = *value;
o->memberData()->data()[l->index] = *value;
o->setInternalClass(l->classList[3]);
return;
}
@ -812,11 +812,11 @@ void Lookup::setter0setter0(Lookup *l, const ValueRef object, const ValueRef val
Object *o = static_cast<Object *>(object->asManaged());
if (o) {
if (o->internalClass() == l->classList[0]) {
o->memberData()[l->index] = *value;
o->memberData()->data()[l->index] = *value;
return;
}
if (o->internalClass() == l->classList[1]) {
o->memberData()[l->index2] = *value;
o->memberData()->data()[l->index2] = *value;
return;
}
}

View File

@ -45,18 +45,19 @@ void MemberData::markObjects(HeapObject *that, ExecutionEngine *e)
m->data[i].mark(e);
}
void Members::ensureIndex(QV4::ExecutionEngine *e, uint idx)
MemberData::Data *MemberData::reallocate(ExecutionEngine *e, Data *old, uint idx)
{
uint s = size();
if (idx >= s) {
int newAlloc = qMax((uint)4, 2*idx);
uint alloc = sizeof(MemberData::Data) + (newAlloc)*sizeof(Value);
MemberData *newMemberData = static_cast<MemberData *>(e->memoryManager->allocManaged(alloc));
if (d())
memcpy(newMemberData, d(), sizeof(MemberData::Data) + s*sizeof(Value));
else
new (newMemberData) MemberData(e->memberDataClass);
newMemberData->d()->size = newAlloc;
m = &newMemberData->data;
}
uint s = old ? old->size : 0;
if (idx < s)
return old;
int newAlloc = qMax((uint)4, 2*idx);
uint alloc = sizeof(Data) + (newAlloc)*sizeof(Value);
MemberData *newMemberData = static_cast<MemberData *>(e->memoryManager->allocManaged(alloc));
if (old)
memcpy(newMemberData, old, sizeof(MemberData::Data) + s*sizeof(Value));
else
new (newMemberData) MemberData(e->memberDataClass);
newMemberData->d()->size = newAlloc;
return newMemberData->d();
}

View File

@ -53,26 +53,15 @@ struct MemberData : Managed
MemberData(QV4::InternalClass *ic) : Managed(ic) {}
Value &operator[] (uint idx) { return d()->data[idx]; }
const Value *data() const { return d()->data; }
Value *data() { return d()->data; }
inline uint size() const { return d()->size; }
static MemberData::Data *reallocate(QV4::ExecutionEngine *e, MemberData::Data *old, uint idx);
static void markObjects(HeapObject *that, ExecutionEngine *e);
};
struct Members : Value
{
void reset() { m = 0; }
void ensureIndex(QV4::ExecutionEngine *e, uint idx);
Value &operator[] (uint idx) const { return static_cast<MemberData *>(managed())->d()->data[idx]; }
inline uint size() const { return d() ? d()->d()->size : 0; }
inline MemberData *d() const { return static_cast<MemberData *>(managed()); }
Value *data() const { return static_cast<MemberData *>(managed())->d()->data; }
void mark(ExecutionEngine *e) const {
MemberData *m = d();
if (m)
m->mark(e);
}
};
}
QT_END_NAMESPACE

View File

@ -55,7 +55,7 @@ Object::Data::Data(InternalClass *internalClass)
if (internalClass->size) {
Scope scope(internalClass->engine);
ScopedObject o(scope, this);
o->memberData().ensureIndex(internalClass->engine, internalClass->size);
o->ensureMemberIndex(internalClass->engine, internalClass->size);
}
}
@ -182,14 +182,15 @@ void Object::markObjects(HeapObject *that, ExecutionEngine *e)
{
Object::Data *o = static_cast<Object::Data *>(that);
o->memberData.mark(e);
if (o->memberData)
o->memberData->mark(e);
if (o->arrayData)
o->arrayData->mark(e);
}
void Object::ensureMemberIndex(uint idx)
{
memberData().ensureIndex(engine(), idx);
d()->memberData = MemberData::reallocate(engine(), d()->memberData, idx);
}
void Object::insertMember(String *s, const Property &p, PropertyAttributes attributes)
@ -206,7 +207,7 @@ void Object::insertMember(String *s, const Property &p, PropertyAttributes attri
pp->value = p.value;
pp->set = p.set;
} else {
memberData()[idx] = p.value;
d()->memberData->data[idx] = p.value;
}
}
@ -262,7 +263,7 @@ Property *Object::__getPropertyDescriptor__(String *name, PropertyAttributes *at
if (idx < UINT_MAX) {
if (attrs)
*attrs = o->internalClass()->propertyData[idx];
return o->propertyAt(idx);
return const_cast<Property *>(o->propertyAt(idx));
}
o = o->prototype();
@ -465,7 +466,7 @@ 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;
o->memberData()->data()[idx] = *value;
return;
}
@ -1153,7 +1154,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].asReturnedValue();
return a->memberData()->data()[ArrayObject::LengthPropertyIndex].asReturnedValue();
}
return Object::getLookup(m, l);
}
@ -1161,9 +1162,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].isInteger())
return a->memberData()[ArrayObject::LengthPropertyIndex].integerValue();
return Primitive::toUInt32(a->memberData()[ArrayObject::LengthPropertyIndex].doubleValue());
if (a->memberData()->data()[ArrayObject::LengthPropertyIndex].isInteger())
return a->memberData()->data()[ArrayObject::LengthPropertyIndex].integerValue();
return Primitive::toUInt32(a->memberData()->data()[ArrayObject::LengthPropertyIndex].doubleValue());
}
QStringList ArrayObject::toQStringList() const

View File

@ -49,8 +49,8 @@ struct Q_QML_EXPORT Object: Managed {
}
Data(InternalClass *internal = 0);
Members memberData;
ArrayData *arrayData;
MemberData::Data *memberData;
ArrayData::Data *arrayData;
};
V4_OBJECT(Object)
Q_MANAGED_TYPE(Object)
@ -59,12 +59,14 @@ struct Q_QML_EXPORT Object: Managed {
IsObject = true
};
Members &memberData() { return d()->memberData; }
const Members &memberData() const { return d()->memberData; }
ArrayData *arrayData() const { return d()->arrayData; }
void setArrayData(ArrayData *a) { d()->arrayData = a; }
// ### GC
MemberData *memberData() { return reinterpret_cast<MemberData *>(d()->memberData); }
const MemberData *memberData() const { return reinterpret_cast<const MemberData *>(d()->memberData); }
ArrayData *arrayData() const { return reinterpret_cast<ArrayData *>(d()->arrayData); }
void setArrayData(ArrayData *a) { d()->arrayData = a->d(); }
Property *propertyAt(uint index) const { return reinterpret_cast<Property *>(memberData().data() + index); }
const Property *propertyAt(uint index) const { return reinterpret_cast<const Property *>(memberData()->data() + index); }
Property *propertyAt(uint index) { return reinterpret_cast<Property *>(memberData()->data() + index); }
const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(internalClass()->vtable); }
Object *prototype() const { return internalClass()->prototype; }
@ -115,6 +117,10 @@ struct Q_QML_EXPORT Object: Managed {
void defineReadonlyProperty(const QString &name, ValueRef value);
void defineReadonlyProperty(String *name, ValueRef value);
void ensureMemberIndex(QV4::ExecutionEngine *e, uint idx) {
d()->memberData = MemberData::reallocate(e, d()->memberData, idx);
}
void insertMember(String *s, const ValueRef v, PropertyAttributes attributes = Attr_Data) {
Property p(*v);
insertMember(s, p, attributes);
@ -300,7 +306,7 @@ struct ArrayObject: Object {
Data(ExecutionEngine *engine, const QStringList &list);
Data(InternalClass *ic) : Object::Data(ic) { init(); }
void init()
{ memberData[LengthPropertyIndex] = Primitive::fromInt32(0); }
{ memberData->data[LengthPropertyIndex] = Primitive::fromInt32(0); }
};
V4_OBJECT(Object)
@ -321,7 +327,7 @@ struct ArrayObject: Object {
inline void Object::setArrayLengthUnchecked(uint l)
{
if (isArrayObject())
memberData()[ArrayObject::LengthPropertyIndex] = Primitive::fromUInt32(l);
memberData()->data()[ArrayObject::LengthPropertyIndex] = Primitive::fromUInt32(l);
}
inline void Object::push_back(const ValueRef v)

View File

@ -390,8 +390,8 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
array->arrayPut(i, v);
}
array->setArrayLengthUnchecked(len);
array->memberData()[Index_ArrayIndex] = Primitive::fromInt32(result);
array->memberData()[Index_ArrayInput] = arg.asReturnedValue();
array->memberData()->data()[Index_ArrayIndex] = Primitive::fromInt32(result);
array->memberData()->data()[Index_ArrayInput] = arg.asReturnedValue();
RegExpCtor::Data *dd = regExpCtor->d();
dd->lastMatch = array;

View File

@ -1172,7 +1172,7 @@ ReturnedValue Runtime::objectLiteral(QV4::ExecutionContext *ctx, const QV4::Valu
}
for (uint i = 0; i < klass->size; ++i)
o->memberData()[i] = *args++;
o->memberData()->data()[i] = *args++;
if (arrayValueCount > 0) {
ScopedValue entry(scope);

View File

@ -91,6 +91,8 @@ double Value::toNumberImpl() const
ExecutionContext *ctx = objectValue()->internalClass()->engine->currentContext();
Scope scope(ctx);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(ValueRef::fromRawValue(this), NUMBER_HINT));
if (scope.engine->hasException)
return 0;
return prim->toNumber();
}
#endif