diff options
Diffstat (limited to 'src/qml/jsruntime/qv4persistent.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4persistent.cpp | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp index 0b31c971f9..79c372348f 100644 --- a/src/qml/jsruntime/qv4persistent.cpp +++ b/src/qml/jsruntime/qv4persistent.cpp @@ -68,6 +68,22 @@ Page *getPage(Value *val) { return reinterpret_cast<Page *>(reinterpret_cast<quintptr>(val) & ~((quintptr)(WTF::pageSize() - 1))); } +QML_NEARLY_ALWAYS_INLINE void insertInFront(PersistentValueStorage *storage, Page *p) +{ + p->header.next = reinterpret_cast<Page *>(storage->firstPage); + p->header.prev = reinterpret_cast<Page **>(&storage->firstPage); + if (p->header.next) + p->header.next->header.prev = &p->header.next; + storage->firstPage = p; +} + +QML_NEARLY_ALWAYS_INLINE void unlink(Page *p) +{ + if (p->header.prev) + *p->header.prev = p->header.next; + if (p->header.next) + p->header.next->header.prev = p->header.prev; +} Page *allocatePage(PersistentValueStorage *storage) { @@ -78,18 +94,13 @@ Page *allocatePage(PersistentValueStorage *storage) p->header.engine = storage->engine; p->header.alloc = page; - p->header.next = reinterpret_cast<Page *>(storage->firstPage); - p->header.prev = reinterpret_cast<Page **>(&storage->firstPage); p->header.refCount = 0; p->header.freeList = 0; - if (p->header.next) - p->header.next->header.prev = &p->header.next; + insertInFront(storage, p); for (int i = 0; i < kEntriesPerPage - 1; ++i) { - p->values[i].setEmpty(i + 1); + p->values[i] = Encode(i + 1); } - p->values[kEntriesPerPage - 1].setEmpty(-1); - - storage->firstPage = p; + p->values[kEntriesPerPage - 1] = Encode(-1); return p; } @@ -161,7 +172,7 @@ Value &PersistentValueStorage::Iterator::operator *() PersistentValueStorage::PersistentValueStorage(ExecutionEngine *engine) : engine(engine), - firstPage(0) + firstPage(nullptr) { } @@ -174,9 +185,9 @@ PersistentValueStorage::~PersistentValueStorage() p->values[i] = Encode::undefined(); } Page *n = p->header.next; - p->header.engine = 0; - p->header.prev = 0; - p->header.next = 0; + p->header.engine = nullptr; + p->header.prev = nullptr; + p->header.next = nullptr; Q_ASSERT(p->header.refCount); p = n; } @@ -195,6 +206,12 @@ Value *PersistentValueStorage::allocate() Value *v = p->values + p->header.freeList; p->header.freeList = v->int_32(); + + if (p->header.freeList != -1 && p != firstPage) { + unlink(p); + insertInFront(this, p); + } + ++p->header.refCount; v->setRawValue(Encode::undefined()); @@ -209,7 +226,7 @@ void PersistentValueStorage::free(Value *v) Page *p = getPage(v); - v->setEmpty(p->header.freeList); + *v = Encode(p->header.freeList); p->header.freeList = v - p->values; if (!--p->header.refCount) freePage(p); @@ -237,16 +254,13 @@ ExecutionEngine *PersistentValueStorage::getEngine(Value *v) void PersistentValueStorage::freePage(void *page) { Page *p = static_cast<Page *>(page); - if (p->header.prev) - *p->header.prev = p->header.next; - if (p->header.next) - p->header.next->header.prev = p->header.prev; + unlink(p); p->header.alloc.deallocate(); } PersistentValue::PersistentValue(const PersistentValue &other) - : val(0) + : val(nullptr) { if (other.val) { val = other.engine()->memoryManager->m_persistentValues->allocate(); @@ -267,7 +281,7 @@ PersistentValue::PersistentValue(ExecutionEngine *engine, ReturnedValue value) } PersistentValue::PersistentValue(ExecutionEngine *engine, Object *object) - : val(0) + : val(nullptr) { if (!object) return; @@ -288,6 +302,10 @@ PersistentValue &PersistentValue::operator=(const PersistentValue &other) return *this; val = other.engine()->memoryManager->m_persistentValues->allocate(); } + if (!other.val) { + *val = Encode::undefined(); + return *this; + } Q_ASSERT(engine() == other.engine()); @@ -302,6 +320,10 @@ PersistentValue &PersistentValue::operator=(const WeakValue &other) return *this; val = other.engine()->memoryManager->m_persistentValues->allocate(); } + if (!other.valueRef()) { + *val = Encode::undefined(); + return *this; + } Q_ASSERT(engine() == other.engine()); @@ -344,7 +366,7 @@ void PersistentValue::set(ExecutionEngine *engine, Heap::Base *obj) } WeakValue::WeakValue(const WeakValue &other) - : val(0) + : val(nullptr) { if (other.val) { allocVal(other.engine()); @@ -365,6 +387,10 @@ WeakValue &WeakValue::operator=(const WeakValue &other) return *this; allocVal(other.engine()); } + if (!other.val) { + *val = Encode::undefined(); + return *this; + } Q_ASSERT(engine() == other.engine()); @@ -404,6 +430,6 @@ void WeakValue::free() PersistentValueStorage::free(val); } - val = 0; + val = nullptr; } |