aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-01-31 13:25:09 +0100
committerLars Knoll <lars.knoll@qt.io>2017-03-09 08:58:31 +0000
commit518e258d59adc976e2e8aa9a7f9ef36d8b8cdb66 (patch)
tree33b90cb45ebfa4cb6767db85caaafcf6ac83d404 /src/qml
parent8b3cbc4403e3eac286613691c11aa1ded588da59 (diff)
Make every member of a Heap object aware of its offset inside the object
This will allow adding a write barrier to those fields with manageable effort. Change-Id: I7d06d7ffccbcefe66e2524c64c962353c91c2766 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/jsruntime/qv4context_p.h2
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4global_p.h1
-rw-r--r--src/qml/jsruntime/qv4object_p.h2
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4value_p.h5
-rw-r--r--src/qml/memory/qv4heap_p.h4
-rw-r--r--src/qml/memory/qv4mm.cpp2
-rw-r--r--src/qml/memory/qv4mmdefs_p.h48
-rw-r--r--src/qml/qml/qqmlcomponent.cpp4
10 files changed, 58 insertions, 14 deletions
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index ccea1dbc80..f544821729 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -171,7 +171,7 @@ V4_ASSERT_IS_TRIVIAL(GlobalContext)
#define CatchContextMembers(class, Member) \
Member(class, Pointer, String *, exceptionVarName) \
- Member(class, Value, Value, exceptionValue)
+ Member(class, HeapValue, HeapValue, exceptionValue)
DECLARE_HEAP_OBJECT(CatchContext, ExecutionContext) {
DECLARE_MARK_TABLE(CatchContext);
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 1fc40e6ff6..c7dac7d3e5 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -123,7 +123,7 @@ struct ScriptFunction : FunctionObject {
#define BoundFunctionMembers(class, Member) \
Member(class, Pointer, FunctionObject *, target) \
- Member(class, Value, Value, boundThis) \
+ Member(class, HeapValue, HeapValue, boundThis) \
Member(class, Pointer, MemberData *, boundArgs)
DECLARE_HEAP_OBJECT(BoundFunction, FunctionObject) {
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index ea3e1d750e..cd8fb91f7a 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -199,6 +199,7 @@ struct ScriptFunction;
struct InternalClass;
struct Property;
struct Value;
+template<size_t> struct HeapValue;
template<size_t> struct ValueArray;
struct Lookup;
struct ArrayData;
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 5b43710c03..63b132c2e6 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -82,6 +82,8 @@ DECLARE_HEAP_OBJECT(Object, Base) {
Value *propertyData(uint index) { return memberData->values.v + index; }
};
+Q_STATIC_ASSERT(Object::markTable == ((2 << 4) | (2 << 6) | (2 << 8)));
+
}
#define V4_OBJECT(superClass) \
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index b429524b71..c2eeb32b88 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -86,7 +86,7 @@ DECLARE_HEAP_OBJECT(RegExpObject, Object) {
};
#define RegExpCtorMembers(class, Member) \
- Member(class, Value, Value, lastMatch) \
+ Member(class, HeapValue, HeapValue, lastMatch) \
Member(class, Pointer, String *, lastInput) \
Member(class, NoMark, int, lastMatchStart) \
Member(class, NoMark, int, lastMatchEnd)
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 771d28dce8..3d7776b736 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -709,6 +709,11 @@ inline unsigned int Value::toUInt32() const
}
template <size_t offset>
+struct HeapValue : Value {
+ HeapValue &operator = (const Value &other) { setRawValue(other.rawValue()); return *this; }
+};
+
+template <size_t offset>
struct ValueArray {
uint size;
uint alloc;
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index febe4e6446..b3dfa407f8 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -164,8 +164,10 @@ struct Q_QML_EXPORT Base {
};
V4_ASSERT_IS_TRIVIAL(Base)
-template <typename T, size_t>
+template <typename T, size_t o>
struct Pointer {
+ static Q_CONSTEXPR size_t offset = o;
+ static Q_CONSTEXPR quint64 markBits = Mark_Pointer << (o >> 2);
T operator->() const { return ptr; }
operator T () const { return ptr; }
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 89cf9caf9e..edd26cf982 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -762,7 +762,7 @@ void MemoryManager::drainMarkStack(Value *markBase)
break;
case Mark_Pointer: {
// qDebug() << "marking pointer at " << mem;
- Heap::Base *p = reinterpret_cast<Heap::Base *>(mem);
+ Heap::Base *p = *reinterpret_cast<Heap::Base **>(mem);
if (p)
p->mark(engine);
break;
diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h
index e4d5ce9da2..63e51f9742 100644
--- a/src/qml/memory/qv4mmdefs_p.h
+++ b/src/qml/memory/qv4mmdefs_p.h
@@ -265,24 +265,58 @@ enum MarkFlags {
Mark_ValueArray = 3
};
+template <typename T>
+struct MarkFlagEvaluator {
+ static Q_CONSTEXPR quint64 value = 0;
+};
+template <typename T, size_t o>
+struct MarkFlagEvaluator<Heap::Pointer<T, o>> {
+ static Q_CONSTEXPR quint64 value = static_cast<quint64>(Mark_Pointer) << (2*o / sizeof(quintptr));
+};
+template <size_t o>
+struct MarkFlagEvaluator<ValueArray<o>> {
+ static Q_CONSTEXPR quint64 value = static_cast<quint64>(Mark_ValueArray) << (2*o / sizeof(quintptr));
+};
+template <size_t o>
+struct MarkFlagEvaluator<HeapValue<o>> {
+ static Q_CONSTEXPR quint64 value = static_cast<quint64>(Mark_Value) << (2 *o / sizeof(quintptr));
+};
+
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION(c, gcType, type, name) \
+ HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_##gcType(c, type, name)
+
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_Pointer(c, type, name) Pointer<type, 0> name;
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_NoMark(c, type, name) type name;
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_HeapValue(c, type, name) HeapValue<0> name;
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_ValueArray(c, type, name) ValueArray<0> name;
+
#define HEAP_OBJECT_MEMBER_EXPANSION(c, gcType, type, name) \
HEAP_OBJECT_MEMBER_EXPANSION_##gcType(c, type, name)
-#define HEAP_OBJECT_MEMBER_EXPANSION_Pointer(c, type, name) Pointer<type, 0> name;
-#define HEAP_OBJECT_MEMBER_EXPANSION_NoMark(c, type, name) type name;
-#define HEAP_OBJECT_MEMBER_EXPANSION_Value(c, type, name) type name;
-#define HEAP_OBJECT_MEMBER_EXPANSION_ValueArray(c, type, name) ValueArray<0> name;
+#define HEAP_OBJECT_MEMBER_EXPANSION_Pointer(c, type, name) \
+ Pointer<type, offsetof(c##OffsetStruct, name) + baseOffset> name;
+#define HEAP_OBJECT_MEMBER_EXPANSION_NoMark(c, type, name) \
+ type name;
+#define HEAP_OBJECT_MEMBER_EXPANSION_HeapValue(c, type, name) \
+ HeapValue<offsetof(c##OffsetStruct, name) + baseOffset> name;
+#define HEAP_OBJECT_MEMBER_EXPANSION_ValueArray(c, type, name) \
+ ValueArray<offsetof(c##OffsetStruct, name) + baseOffset> name;
#define HEAP_OBJECT_MARK_EXPANSION(class, gcType, type, name) \
- (Mark_##gcType << (offsetof(class, name) >> 2)) |
+ MarkFlagEvaluator<decltype(class::name)>::value |
#define DECLARE_HEAP_OBJECT(name, base) \
+struct name##OffsetStruct { \
+ name##Members(name, HEAP_OBJECT_OFFSET_MEMBER_EXPANSION) \
+}; \
+struct name##SizeStruct : base, name##OffsetStruct {}; \
struct name##Data { \
+ static Q_CONSTEXPR size_t baseOffset = sizeof(name##SizeStruct) - sizeof(name##OffsetStruct); \
name##Members(name, HEAP_OBJECT_MEMBER_EXPANSION) \
}; \
-struct name##SizeStruct : base, name##Data {}; \
+Q_STATIC_ASSERT(sizeof(name##SizeStruct) == sizeof(name##Data) + name##Data::baseOffset); \
static Q_CONSTEXPR quint64 name##_markTable = \
- (name##Members(name##Data, HEAP_OBJECT_MARK_EXPANSION) 0) << (((sizeof(name##SizeStruct) - sizeof(name##Data)) >> 2) | QV4::Heap::base::markTable; \
+ (name##Members(name##Data, HEAP_OBJECT_MARK_EXPANSION) 0) | QV4::Heap::base::markTable; \
\
struct name : base, name##Data
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 79e52f3914..c1a0637d00 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1047,8 +1047,8 @@ namespace QV4 {
namespace Heap {
#define QmlIncubatorObjectMembers(class, Member) \
- Member(class, Value, Value, valuemap) \
- Member(class, Value, Value, statusChanged) \
+ Member(class, HeapValue, HeapValue, valuemap) \
+ Member(class, HeapValue, HeapValue, statusChanged) \
Member(class, Pointer, QmlContext *, qmlContext) \
Member(class, NoMark, QQmlComponentIncubator *, incubator) \
Member(class, NoMark, QQmlQPointer<QObject>, parent)