diff options
Diffstat (limited to 'src/qml/jsruntime/qv4persistent.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4persistent.cpp | 95 |
1 files changed, 74 insertions, 21 deletions
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp index 88dc1946b8..4a0f84b685 100644 --- a/src/qml/jsruntime/qv4persistent.cpp +++ b/src/qml/jsruntime/qv4persistent.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include "qv4persistent_p.h" -#include "qv4mm_p.h" +#include <private/qv4mm_p.h> #include "qv4object_p.h" #include "PageAllocation.h" @@ -78,11 +78,11 @@ Page *allocatePage(PersistentValueStorage *storage) if (p->header.next) p->header.next->header.prev = &p->header.next; for (int i = 0; i < kEntriesPerPage - 1; ++i) { - p->values[i].tag = QV4::Value::Empty_Type; - p->values[i].int_32 = i + 1; + p->values[i].setTag(QV4::Value::Empty_Type); + p->values[i].setInt_32(i + 1); } - p->values[kEntriesPerPage - 1].tag = QV4::Value::Empty_Type; - p->values[kEntriesPerPage - 1].int_32 = -1; + p->values[kEntriesPerPage - 1].setTag(QV4::Value::Empty_Type); + p->values[kEntriesPerPage - 1].setInt_32(-1); storage->firstPage = p; @@ -93,15 +93,57 @@ Page *allocatePage(PersistentValueStorage *storage) } +PersistentValueStorage::Iterator::Iterator(void *p, int idx) + : p(p), index(idx) +{ + Page *page = static_cast<Page *>(p); + if (page) + ++page->header.refCount; +} + +PersistentValueStorage::Iterator::Iterator(const PersistentValueStorage::Iterator &o) + : p(o.p), index(o.index) +{ + Page *page = static_cast<Page *>(p); + if (page) + ++page->header.refCount; +} + +PersistentValueStorage::Iterator &PersistentValueStorage::Iterator::operator=(const PersistentValueStorage::Iterator &o) +{ + Page *page = static_cast<Page *>(p); + if (page && !--page->header.refCount) + freePage(p); + p = o.p; + index = o.index; + page = static_cast<Page *>(p); + if (page) + ++page->header.refCount; + + return *this; +} + +PersistentValueStorage::Iterator::~Iterator() +{ + Page *page = static_cast<Page *>(p); + if (page && !--page->header.refCount) + freePage(page); +} + PersistentValueStorage::Iterator &PersistentValueStorage::Iterator::operator++() { while (p) { while (index < kEntriesPerPage - 1) { ++index; - if (static_cast<Page *>(p)->values[index].tag != QV4::Value::Empty_Type) + if (static_cast<Page *>(p)->values[index].tag() != QV4::Value::Empty_Type) return *this; } index = -1; - p = static_cast<Page *>(p)->header.next; + Page *next = static_cast<Page *>(p)->header.next; + if (!--static_cast<Page *>(p)->header.refCount) + freePage(p); + p = next; + if (next) + ++next->header.refCount; } index = 0; return *this; @@ -147,10 +189,10 @@ Value *PersistentValueStorage::allocate() p = allocatePage(this); Value *v = p->values + p->header.freeList; - p->header.freeList = v->int_32; + p->header.freeList = v->int_32(); ++p->header.refCount; - v->val = Encode::undefined(); + v->setRawValue(Encode::undefined()); return v; } @@ -162,24 +204,19 @@ void PersistentValueStorage::free(Value *v) Page *p = getPage(v); - v->tag = QV4::Value::Empty_Type; - v->int_32 = p->header.freeList; + v->setTag(QV4::Value::Empty_Type); + v->setInt_32(p->header.freeList); p->header.freeList = v - p->values; - if (!--p->header.refCount) { - if (p->header.prev) - *p->header.prev = p->header.next; - if (p->header.next) - p->header.next->header.prev = p->header.prev; - p->header.alloc.deallocate(); - } + if (!--p->header.refCount) + freePage(p); } static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase) { while (engine->jsStackTop > markBase) { Heap::Base *h = engine->popForGC(); - Q_ASSERT (h->gcGetVtable()->markObjects); - h->gcGetVtable()->markObjects(h, engine); + Q_ASSERT (h->vtable()->markObjects); + h->vtable()->markObjects(h, engine); } } @@ -190,7 +227,7 @@ void PersistentValueStorage::mark(ExecutionEngine *e) Page *p = static_cast<Page *>(firstPage); while (p) { for (int i = 0; i < kEntriesPerPage; ++i) { - if (Managed *m = p->values[i].asManaged()) + if (Managed *m = p->values[i].as<Managed>()) m->mark(e); } drainMarkStack(e, markBase); @@ -204,6 +241,16 @@ ExecutionEngine *PersistentValueStorage::getEngine(Value *v) return getPage(v)->header.engine; } +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; + p->header.alloc.deallocate(); +} + PersistentValue::PersistentValue(const PersistentValue &other) : val(0) @@ -312,6 +359,12 @@ WeakValue::WeakValue(const WeakValue &other) } } +WeakValue::WeakValue(ExecutionEngine *engine, const Value &value) +{ + val = engine->memoryManager->m_weakValues->allocate(); + *val = value; +} + WeakValue &WeakValue::operator=(const WeakValue &other) { if (!val) { |