aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-01-08 15:59:34 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-20 21:14:24 +0100
commite2d9917878968986a9df21c9cfafc32a2360aee7 (patch)
tree24c4009e65b0a358a1d30f36ab32ec546fe6cbe5
parent2ba2d245c152cdbb26f918bc4481c77b8004f3cd (diff)
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 <simon.hausmann@digia.com>
-rw-r--r--src/qml/jsruntime/qv4object.cpp6
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp24
-rw-r--r--src/qml/jsruntime/qv4property_p.h41
3 files changed, 35 insertions, 36 deletions
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<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
-
Scoped<FunctionObject> f(scope, ctx->argument(1));
if (!f)
return ctx->throwTypeError();
+ Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
Scoped<Object> 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<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
-
Scoped<FunctionObject> f(scope, ctx->argument(1));
if (!f)
return ctx->throwTypeError();
+ Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
Scoped<Object> 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<Managed *>(getter));
+ pd.set = Primitive::fromManaged(reinterpret_cast<Managed *>(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<FunctionObject *>(value.managed()); }
+ inline FunctionObject *setter() const { return reinterpret_cast<FunctionObject *>(set.managed()); }
+ inline void setGetter(FunctionObject *g) { value = Primitive::fromManaged(reinterpret_cast<Managed *>(g)); }
+ inline void setSetter(FunctionObject *s) { set = Primitive::fromManaged(reinterpret_cast<Managed *>(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;