aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4persistent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4persistent.cpp')
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp68
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;
}