aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4propertykey_p.h
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-12-20 12:31:52 +0100
committerUlf Hermann <ulf.hermann@qt.io>2023-01-12 10:49:10 +0100
commitc7722d4ed61d6a887e9f6c403ffa10b2048de2a4 (patch)
tree2d01090de983e4a354eb0359888aad0b78a26a08 /src/qml/jsruntime/qv4propertykey_p.h
parentc333d4108da6d3db06c17142226c28e14e89703f (diff)
Change value encoding scheme to make space for larger pointers
On android and on some other platforms, the upper bits of a pointer are significant. We need to store them in our JS value encoding. Shift the bits around to make this happen. We now can store pointers of up to 57 bits. That's enough for everything we've seen so far. Fixes: QTBUG-101686 Fixes: QTBUG-91150 Pick-to: 6.5 Change-Id: I72e0fe63b27fca94840f82963e4d3936b3581b28 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4propertykey_p.h')
-rw-r--r--src/qml/jsruntime/qv4propertykey_p.h88
1 files changed, 44 insertions, 44 deletions
diff --git a/src/qml/jsruntime/qv4propertykey_p.h b/src/qml/jsruntime/qv4propertykey_p.h
index a0e10e7675..0b8ad084d2 100644
--- a/src/qml/jsruntime/qv4propertykey_p.h
+++ b/src/qml/jsruntime/qv4propertykey_p.h
@@ -15,6 +15,7 @@
//
#include <private/qv4global_p.h>
+#include <private/qv4staticvalue_p.h>
#include <QtCore/qhashfunctions.h>
QT_BEGIN_NAMESPACE
@@ -36,57 +37,56 @@ private:
// * If the key is a Symbol it simply points to the referenced symbol object
// * if the key is an array index (a uint < UINT_MAX), it's encoded as an
// integer value
- quint64 val;
+ QV4::StaticValue val;
- // Important: Always keep this in sync with the definitions for Integers and heap objects in Value
- static const quint64 ArrayIndexMask = 0x3800000000000ull;
- enum {
- IsManagedOrUndefined_Shift = 64-15,
- };
- inline bool isManaged() const { return (val >> IsManagedOrUndefined_Shift) == 0; }
- inline quint32 value() const { return val & quint64(~quint32(0)); }
+ inline bool isManaged() const { return val.isManaged(); }
+ inline quint32 value() const { return val.value(); }
-#if QT_POINTER_SIZE == 8
- QML_NEARLY_ALWAYS_INLINE Heap::StringOrSymbol *m() const
+public:
+ static PropertyKey invalid()
{
- Heap::StringOrSymbol *b;
- memcpy(&b, &val, 8);
- return b;
+ PropertyKey key;
+ key.val = StaticValue::undefinedValue();
+ return key;
}
- QML_NEARLY_ALWAYS_INLINE void setM(Heap::StringOrSymbol *b)
+
+ static PropertyKey fromArrayIndex(uint idx)
{
- memcpy(&val, &b, 8);
+ PropertyKey key;
+ key.val.setInt_32(idx);
+ return key;
}
-#elif QT_POINTER_SIZE == 4
- QML_NEARLY_ALWAYS_INLINE Heap::StringOrSymbol *m() const
+
+ bool isStringOrSymbol() const { return isManaged(); }
+ uint asArrayIndex() const
{
- Q_STATIC_ASSERT(sizeof(Heap::StringOrSymbol*) == sizeof(quint32));
- Heap::StringOrSymbol *b;
- quint32 v = value();
- memcpy(&b, &v, 4);
- return b;
+ Q_ASSERT(isArrayIndex());
+ return value();
}
- QML_NEARLY_ALWAYS_INLINE void setM(Heap::StringOrSymbol *b)
+
+ bool isArrayIndex() const { return val.isInteger(); }
+ bool isValid() const { return !val.isUndefined(); }
+
+ // We cannot #include the declaration of Heap::StringOrSymbol here.
+ // Therefore we do some gymnastics to enforce the type safety.
+
+ template<typename StringOrSymbol = Heap::StringOrSymbol>
+ static PropertyKey fromStringOrSymbol(StringOrSymbol *b)
{
- quint32 v;
- memcpy(&v, &b, 4);
- val = v;
+ static_assert(std::is_base_of_v<Heap::StringOrSymbol, StringOrSymbol>);
+ PropertyKey key;
+ key.val.setM(b);
+ Q_ASSERT(key.isManaged());
+ return key;
}
-#endif
-public:
- static PropertyKey invalid() { PropertyKey key; key.val = 0; return key; }
- static PropertyKey fromArrayIndex(uint idx) { PropertyKey key; key.val = ArrayIndexMask | static_cast<quint64>(idx); return key; }
- bool isStringOrSymbol() const { return isManaged() && val != 0; }
- uint asArrayIndex() const { Q_ASSERT(isArrayIndex()); return static_cast<uint>(val & 0xffffffff); }
- uint isArrayIndex() const { return !isManaged() && val != 0; }
- bool isValid() const { return val != 0; }
- static PropertyKey fromStringOrSymbol(Heap::StringOrSymbol *b)
- { PropertyKey key; key.setM(b); return key; }
- Heap::StringOrSymbol *asStringOrSymbol() const {
+ template<typename StringOrSymbol = Heap::StringOrSymbol>
+ StringOrSymbol *asStringOrSymbol() const
+ {
+ static_assert(std::is_base_of_v<Heap::StringOrSymbol, StringOrSymbol>);
if (!isManaged())
return nullptr;
- return m();
+ return static_cast<StringOrSymbol *>(val.m());
}
Q_QML_PRIVATE_EXPORT bool isString() const;
@@ -95,9 +95,9 @@ public:
Q_QML_PRIVATE_EXPORT QString toQString() const;
Heap::StringOrSymbol *toStringOrSymbol(ExecutionEngine *e);
- quint64 id() const { return val; }
+ quint64 id() const { return val._val; }
static PropertyKey fromId(quint64 id) {
- PropertyKey key; key.val = id; return key;
+ PropertyKey key; key.val._val = id; return key;
}
enum FunctionNamePrefix {
@@ -107,10 +107,10 @@ public:
};
Heap::String *asFunctionName(ExecutionEngine *e, FunctionNamePrefix prefix) const;
- bool operator ==(const PropertyKey &other) const { return val == other.val; }
- bool operator !=(const PropertyKey &other) const { return val != other.val; }
- bool operator <(const PropertyKey &other) const { return val < other.val; }
- friend size_t qHash(const PropertyKey &key, size_t seed = 0) { return qHash(key.val, seed); }
+ bool operator ==(const PropertyKey &other) const { return val._val == other.val._val; }
+ bool operator !=(const PropertyKey &other) const { return val._val != other.val._val; }
+ bool operator <(const PropertyKey &other) const { return val._val < other.val._val; }
+ friend size_t qHash(const PropertyKey &key, size_t seed = 0) { return qHash(key.val._val, seed); }
};
}