diff options
| author | Lars Knoll <lars.knoll@qt.io> | 2017-02-17 11:18:35 +0100 |
|---|---|---|
| committer | Lars Knoll <lars.knoll@qt.io> | 2017-03-09 08:58:40 +0000 |
| commit | 38c9bc6b9f5f019f55896369c3b46c77fc29fb41 (patch) | |
| tree | b5a6ec37f5f2a551c185904683014726d50c6dcf /src/qml/jsruntime/qv4arraydata_p.h | |
| parent | 9242e5a685695356b2c9101a5e1642a726a6fede (diff) | |
Change getValueOrSetter to be write barrier friendly
Don't return a naked pointer into the heap, as this makes
it impossible to track where and when we're writing into it.
Change-Id: I2b9b81779ef8e9fb7a643ddda82aa6af8af459a7
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4arraydata_p.h')
| -rw-r--r-- | src/qml/jsruntime/qv4arraydata_p.h | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h index 1ede463d6d..71ed96a9a5 100644 --- a/src/qml/jsruntime/qv4arraydata_p.h +++ b/src/qml/jsruntime/qv4arraydata_p.h @@ -103,6 +103,18 @@ DECLARE_HEAP_OBJECT(ArrayData, Base) { enum Type { Simple = 0, Complex = 1, Sparse = 2, Custom = 3 }; + struct Index { + Heap::ArrayData *arrayData; + uint index; + + void set(ExecutionEngine *e, Value newVal) { + arrayData->values.set(e, index, newVal); + } + const Value *operator->() const { return &arrayData->values[index]; } + const Value &operator*() const { return arrayData->values[index]; } + bool isNull() const { return !arrayData; } + }; + bool isSparse() const { return type == Sparse; } const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(Base::vtable()); } @@ -113,7 +125,7 @@ DECLARE_HEAP_OBJECT(ArrayData, Base) { inline void getProperty(uint index, Property *p, PropertyAttributes *attrs); inline void setProperty(uint index, const Property *p); inline Property *getProperty(uint index); - inline Value *getValueOrSetter(uint index, PropertyAttributes *attrs); + inline Index getValueOrSetter(uint index, PropertyAttributes *attrs); inline PropertyAttributes attributes(uint i) const; bool isEmpty(uint i) const { @@ -124,6 +136,7 @@ DECLARE_HEAP_OBJECT(ArrayData, Base) { return vtable()->length(this); } + uint mappedIndex(uint index) const; }; V4_ASSERT_IS_TRIVIAL(ArrayData) @@ -185,6 +198,8 @@ struct Q_QML_EXPORT ArrayData : public Managed IsArrayData = true }; + typedef Heap::ArrayData::Index Index; + uint alloc() const { return d()->values.alloc; } uint &alloc() { return d()->values.alloc; } void setAlloc(uint a) { d()->values.alloc = a; } @@ -281,6 +296,16 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData namespace Heap { +inline uint ArrayData::mappedIndex(uint index) const +{ + if (isSparse()) + return static_cast<const SparseArrayData *>(this)->mappedIndex(index); + if (index >= values.size) + return UINT_MAX; + uint idx = static_cast<const SimpleArrayData *>(this)->mappedIndex(index); + return values[idx].isEmpty() ? UINT_MAX : idx; +} + void ArrayData::getProperty(uint index, Property *p, PropertyAttributes *attrs) { Property *pd = getProperty(index); @@ -314,16 +339,16 @@ inline PropertyAttributes ArrayData::attributes(uint i) const return static_cast<const SimpleArrayData *>(this)->attributes(i); } -Value *ArrayData::getValueOrSetter(uint index, PropertyAttributes *attrs) +ArrayData::Index ArrayData::getValueOrSetter(uint index, PropertyAttributes *attrs) { - Property *p = getProperty(index); - if (!p) { + uint idx = mappedIndex(index); + if (idx == UINT_MAX) { *attrs = Attr_Invalid; - return 0; + return { 0, 0 }; } *attrs = attributes(index); - return attrs->isAccessor() ? &p->set : &p->value; + return { this, attrs->isAccessor() ? idx + 1 /* QV4::Object::SetterOffset*/ : idx }; } |
