diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-09-15 15:46:36 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-18 13:14:21 +0200 |
commit | 87f475cbdb89fcbfbce68c3b676a240bb255a6d9 (patch) | |
tree | 9ed2acca5036e70fdd9d60204e1dd5ca3ce0d758 /src/qml/jsruntime/qv4scopedvalue_p.h | |
parent | 43cdae853b726642893622d2feffcd0f4a2d6953 (diff) |
Refactor our NaN boxing to be more efficient
* Use a unified way to store all Managed objects inside
a Value, instead of distinguishing between strings
and other objects.
* On 64 bit we store pointers as pointers, so accessing them
through Scoped<> objects is cheap. This implies that doubles
are now stored in a mangled form (xor'ed with a mask).
Change-Id: I582e0fb167a62c0c527c6bfa3452550e37944069
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4scopedvalue_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4scopedvalue_p.h | 77 |
1 files changed, 36 insertions, 41 deletions
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 5fe870c21d..a800283cee 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -142,7 +142,7 @@ struct ScopedValue ScopedValue(const Scope &scope, Returned<T> *t) { ptr = scope.engine->jsStackTop++; - *ptr = T::toValue(t->getPointer()); + *ptr = t->getPointer() ? Value::fromManaged(t->getPointer()) : Value::undefinedValue(); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -160,7 +160,7 @@ struct ScopedValue template<typename T> ScopedValue &operator=(Returned<T> *t) { - *ptr = T::toValue(t->getPointer()); + *ptr = t->getPointer() ? Value::fromManaged(t->getPointer()) : Value::undefinedValue(); return *this; } @@ -189,6 +189,14 @@ struct ScopedValue template<typename T> struct Scoped { + inline void setPointer(Managed *p) { +#if QT_POINTER_SIZE == 8 + ptr->val = (quint64)p; +#else + *ptr = p ? QV4::Value::fromManaged(p) : QV4::Value::undefinedValue(); +#endif + } + Scoped(const Scope &scope) { ptr = scope.engine->jsStackTop++; @@ -201,10 +209,7 @@ struct Scoped Scoped(const Scope &scope, const Value &v) { ptr = scope.engine->jsStackTop++; - if (T::cast(v)) - *ptr = v; - else - *ptr = QV4::Value::undefinedValue(); + setPointer(T::cast(v)); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -215,7 +220,7 @@ struct Scoped Scoped(const Scope &scope, T *t) { ptr = scope.engine->jsStackTop++; - *ptr = T::toValue(t); + setPointer(t); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -224,8 +229,7 @@ struct Scoped Scoped(const Scope &scope, Returned<X> *x) { ptr = scope.engine->jsStackTop++; - T *t = Returned<T>::getPointer(x); - *ptr = T::toValue(t); + setPointer(Returned<T>::getPointer(x)); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -234,30 +238,21 @@ struct Scoped Scoped(const Scope &scope, const ReturnedValue &v) { ptr = scope.engine->jsStackTop++; - if (T::cast(QV4::Value::fromReturnedValue(v))) - ptr->val = v; - else - *ptr = QV4::Value::undefinedValue(); + setPointer(T::cast(QV4::Value::fromReturnedValue(v))); #ifndef QT_NO_DEBUG ++scope.size; #endif } Scoped<T> &operator=(const Value &v) { - if (T::cast(v)) - *ptr = v; - else - *ptr = QV4::Value::undefinedValue(); + setPointer(T::cast(v)); return *this; } Scoped<T> &operator=(const ValueRef &v); Scoped<T> &operator=(const ReturnedValue &v) { - if (T::cast(QV4::Value::fromReturnedValue(v))) - ptr->val = v; - else - *ptr = QV4::Value::undefinedValue(); + setPointer(T::cast(QV4::Value::fromReturnedValue(v))); return *this; } @@ -267,13 +262,13 @@ struct Scoped } Scoped<T> &operator=(T *t) { - *ptr = T::toValue(t); + setPointer(t); return *this; } template<typename X> Scoped<T> &operator=(Returned<X> *x) { - *ptr = T::toValue(Returned<T>::getPointer(x)); + setPointer(Returned<T>::getPointer(x)); return *this; } @@ -282,10 +277,6 @@ struct Scoped return static_cast<T *>(ptr->managed()); } - const Value *operator->() const { - return T::cast(*ptr); - } - bool operator!() const { return !ptr->managed(); } @@ -298,10 +289,20 @@ struct Scoped } Value asValue() const { +#if QT_POINTER_SIZE == 8 + return ptr->val ? *ptr : QV4::Value::undefinedValue(); +#else return *ptr; +#endif } - ReturnedValue asReturnedValue() const { return ptr->val; } + ReturnedValue asReturnedValue() const { +#if QT_POINTER_SIZE == 8 + return ptr->val ? ptr->val : Value::undefinedValue().asReturnedValue(); +#else + return ptr->val; +#endif + } Value *ptr; }; @@ -311,7 +312,7 @@ struct ScopedCallData { { int size = qMax(argc, (int)QV4::Global::ReservedArgumentCount) + offsetof(QV4::CallData, args)/sizeof(QV4::Value); ptr = reinterpret_cast<CallData *>(scope.engine->stackPush(size)); - ptr->tag = 0; + ptr->tag = QV4::Value::Integer_Type; ptr->argc = argc; #ifndef QT_NO_DEBUG scope.size += size; @@ -387,10 +388,7 @@ template<typename T> inline Scoped<T>::Scoped(const Scope &scope, const ValueRef &v) { ptr = scope.engine->jsStackTop++; - if (T::cast(*v.operator ->())) - *ptr = *v.operator ->(); - else - *ptr = QV4::Value::undefinedValue(); + setPointer(T::cast(*v.operator ->())); #ifndef QT_NO_DEBUG ++scope.size; #endif @@ -399,10 +397,7 @@ inline Scoped<T>::Scoped(const Scope &scope, const ValueRef &v) template<typename T> inline Scoped<T> &Scoped<T>::operator=(const ValueRef &v) { - if (T::cast(*v.operator ->())) - *ptr = *v.operator ->(); - else - *ptr = QV4::Value::undefinedValue(); + setPointer(T::cast(*v.operator ->())); return *this; } @@ -440,7 +435,7 @@ private: struct Encode : private Value { static ReturnedValue undefined() { - return quint64(_Undefined_Type) << Tag_Shift; + return quint64(Undefined_Type) << Tag_Shift; } static ReturnedValue null() { return quint64(_Null_Type) << Tag_Shift; @@ -451,7 +446,7 @@ struct Encode : private Value { int_32 = b; } Encode(double d) { - dbl = d; + setDouble(d); } Encode(int i) { tag = _Integer_Type; @@ -462,7 +457,7 @@ struct Encode : private Value { tag = _Integer_Type; int_32 = i; } else { - dbl = i; + setDouble(i); } } Encode(ReturnedValue v) { @@ -471,7 +466,7 @@ struct Encode : private Value { template<typename T> Encode(Returned<T> *t) { - val = T::toValue(t->getPointer()).val; + val = t->getPointer()->asReturnedValue(); } operator ReturnedValue() const { |