From e2d9917878968986a9df21c9cfafc32a2360aee7 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 8 Jan 2014 15:59:34 +0100 Subject: Changes to the structure of Property Put the getter into the regular value, and the setter into the next value following. Like this we can compress property data to only use 8 bytes per property for regular properties and simply allocate two slots for accessor properties. Change-Id: I330b95dbd583ebc2658fed79d37ac3b53492c0cd Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4object.cpp | 6 +++--- src/qml/jsruntime/qv4objectproto.cpp | 24 ++++++++++++--------- src/qml/jsruntime/qv4property_p.h | 41 ++++++++++++++++-------------------- 3 files changed, 35 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 35fa998f21..4d02d46135 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -140,12 +140,12 @@ void Object::putValue(Property *pd, PropertyAttributes attrs, const ValueRef val return; if (attrs.isAccessor()) { - if (pd->set) { - Scope scope(pd->set->engine()); + if (FunctionObject *set = pd->setter()) { + Scope scope(set->engine()); ScopedCallData callData(scope, 1); callData->args[0] = *value; callData->thisObject = this; - pd->set->call(callData); + set->call(callData); return; } goto reject; diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 806da833ea..410f243a3c 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -501,14 +501,14 @@ ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx) return ctx->throwTypeError(); Scope scope(ctx); - Scoped prop(scope, ctx->argument(0), Scoped::Convert); - if (scope.engine->hasException) - return Encode::undefined(); - Scoped f(scope, ctx->argument(1)); if (!f) return ctx->throwTypeError(); + Scoped prop(scope, ctx->argument(0), Scoped::Convert); + if (scope.engine->hasException) + return Encode::undefined(); + Scoped o(scope, ctx->callData->thisObject); if (!o) { if (!ctx->callData->thisObject.isUndefined()) @@ -516,7 +516,9 @@ ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx) o = ctx->engine->globalObject; } - Property pd = Property::fromAccessor(f.getPointer(), 0); + Property pd; + pd.value = f; + pd.set = Primitive::emptyValue(); o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor); return Encode::undefined(); } @@ -527,14 +529,14 @@ ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx) return ctx->throwTypeError(); Scope scope(ctx); - Scoped prop(scope, ctx->argument(0), Scoped::Convert); - if (scope.engine->hasException) - return Encode::undefined(); - Scoped f(scope, ctx->argument(1)); if (!f) return ctx->throwTypeError(); + Scoped prop(scope, ctx->argument(0), Scoped::Convert); + if (scope.engine->hasException) + return Encode::undefined(); + Scoped o(scope, ctx->callData->thisObject); if (!o) { if (!ctx->callData->thisObject.isUndefined()) @@ -542,7 +544,9 @@ ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx) o = ctx->engine->globalObject; } - Property pd = Property::fromAccessor(0, f.getPointer()); + Property pd; + pd.value = Primitive::emptyValue(); + pd.set = f; o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor); return Encode::undefined(); } diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h index ff9ea59514..4b0896b264 100644 --- a/src/qml/jsruntime/qv4property_p.h +++ b/src/qml/jsruntime/qv4property_p.h @@ -52,13 +52,8 @@ namespace QV4 { struct FunctionObject; struct Property { - union { - SafeValue value; - struct { - FunctionObject *get; - FunctionObject *set; - }; - }; + SafeValue value; + SafeValue set; // Section 8.10 inline void fullyPopulated(PropertyAttributes *attrs) { @@ -67,10 +62,10 @@ struct Property { } if (attrs->type() == PropertyAttributes::Accessor) { attrs->clearWritable(); - if (get == (FunctionObject *)0x1) - get = 0; - if (set == (FunctionObject *)0x1) - set = 0; + if (value.managed() == (Managed *)0x1) + value = Primitive::fromManaged(0); + if (set.managed() == (Managed *)0x1) + set = Primitive::fromManaged(0); } attrs->resolve(); } @@ -82,8 +77,8 @@ struct Property { } static inline Property fromAccessor(FunctionObject *getter, FunctionObject *setter) { Property pd; - pd.get = getter; - pd.set = setter; + pd.value = Primitive::fromManaged(reinterpret_cast(getter)); + pd.set = Primitive::fromManaged(reinterpret_cast(setter)); return pd; } @@ -96,10 +91,10 @@ struct Property { inline bool isSubset(const PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs) const; inline void merge(PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs); - inline FunctionObject *getter() const { return get; } - inline FunctionObject *setter() const { return set; } - inline void setGetter(FunctionObject *g) { get = g; } - inline void setSetter(FunctionObject *s) { set = s; } + inline FunctionObject *getter() const { return reinterpret_cast(value.managed()); } + inline FunctionObject *setter() const { return reinterpret_cast(set.managed()); } + inline void setGetter(FunctionObject *g) { value = Primitive::fromManaged(reinterpret_cast(g)); } + inline void setSetter(FunctionObject *s) { set = Primitive::fromManaged(reinterpret_cast(s)); } }; inline bool Property::isSubset(const PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs) const @@ -115,9 +110,9 @@ inline bool Property::isSubset(const PropertyAttributes &attrs, const Property & if (attrs.type() == PropertyAttributes::Data && !value.sameValue(other.value)) return false; if (attrs.type() == PropertyAttributes::Accessor) { - if (get != other.get) + if (value.managed() != other.value.managed()) return false; - if (set != other.set) + if (set.managed() != other.set.managed()) return false; } return true; @@ -133,10 +128,10 @@ inline void Property::merge(PropertyAttributes &attrs, const Property &other, Pr attrs.setWritable(otherAttrs.isWritable()); if (otherAttrs.type() == PropertyAttributes::Accessor) { attrs.setType(PropertyAttributes::Accessor); - if (other.get) - get = (other.get == (FunctionObject *)0x1) ? 0 : other.get; - if (other.set) - set = (other.set == (FunctionObject *)0x1) ? 0 : other.set; + if (other.value.managed()) + value = (other.value.managed() == (Managed *)0x1) ? Primitive::fromManaged(0).asReturnedValue() : other.value.asReturnedValue(); + if (other.set.managed()) + set = (other.set.managed() == (Managed *)0x1) ? Primitive::fromManaged(0).asReturnedValue() : other.set.asReturnedValue(); } else if (otherAttrs.type() == PropertyAttributes::Data){ attrs.setType(PropertyAttributes::Data); value = other.value; -- cgit v1.2.3