aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-01-09 19:48:56 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2015-01-12 11:04:30 +0100
commit53e144ae8dec84f70870a5e315c3043b16b57d92 (patch)
tree8ddc93adb025c19d1c45daab39a6c63b1f1b561b /src/qml/jsruntime
parent7a0d121f9eafee9dfb948dce01de8204c4385e94 (diff)
Fold the inUse flag into the internalClass pointer
Revert the flag (ie. flag == 0 means the item is used), and fold it into the second lowest bit of the internalClass/nextFree field. Change-Id: I7b690fdce00d16aa538fa70a269a755511477c5c Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4managed_p.h2
-rw-r--r--src/qml/jsruntime/qv4mm.cpp54
-rw-r--r--src/qml/jsruntime/qv4value_p.h21
5 files changed, 46 insertions, 35 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 39528e396a..6dd33d3f47 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -913,7 +913,7 @@ void ExecutionEngine::markObjects()
Heap::ExecutionContext *c = currentContext();
while (c) {
- Q_ASSERT(c->inUse);
+ Q_ASSERT(c->inUse());
if (!c->markBit) {
c->markBit = 1;
c->internalClass->vtable->markObjects(c, this);
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 87aa3bb16f..017b2a8c52 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -411,7 +411,7 @@ void Managed::mark(QV4::ExecutionEngine *engine)
inline
void Heap::Base::mark(QV4::ExecutionEngine *engine)
{
- Q_ASSERT(inUse);
+ Q_ASSERT(inUse());
if (markBit)
return;
markBit = 1;
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 28b7059e4c..27a601ee13 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -290,7 +290,7 @@ public:
InternalClass *internalClass() const { return d()->internalClass; }
void setInternalClass(InternalClass *ic) { d()->internalClass = ic; }
- bool inUse() const { return d()->inUse; }
+ bool inUse() const { return d()->inUse(); }
bool markBit() const { return d()->markBit; }
static void destroy(Heap::Base *) {}
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index e2d1d19654..ff84e47ef9 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -77,7 +77,7 @@ struct MemoryManager::Data
ExecutionEngine *engine;
enum { MaxItemSize = 512 };
- Heap::Base *smallItems[MaxItemSize/16];
+ Heap::Base smallItems[MaxItemSize/16];
uint nChunks[MaxItemSize/16];
uint availableItems[MaxItemSize/16];
uint allocCount[MaxItemSize/16];
@@ -124,7 +124,8 @@ struct MemoryManager::Data
, totalLargeItemsAllocated(0)
, deletable(0)
{
- memset(smallItems, 0, sizeof(smallItems));
+ for (int i = 0; i < MaxItemSize/16; ++i)
+ smallItems[i].setNextFree(0);
memset(nChunks, 0, sizeof(nChunks));
memset(availableItems, 0, sizeof(availableItems));
memset(allocCount, 0, sizeof(allocCount));
@@ -165,9 +166,9 @@ bool operator<(const MemoryManager::Data::Chunk &a, const MemoryManager::Data::C
namespace {
struct ChunkSweepData {
- ChunkSweepData() : tail(&head), head(0), isEmpty(true) { }
- Heap::Base **tail;
- Heap::Base *head;
+ ChunkSweepData() : tail(&head), isEmpty(true) { head.setNextFree(0); }
+ Heap::Base *tail;
+ Heap::Base head;
bool isEmpty;
};
@@ -188,12 +189,12 @@ void sweepChunk(const MemoryManager::Data::Chunk &chunk, ChunkSweepData *sweepDa
Q_ASSERT((qintptr) item % 16 == 0);
if (m->markBit) {
- Q_ASSERT(m->inUse);
+ Q_ASSERT(m->inUse());
m->markBit = 0;
sweepData->isEmpty = false;
++(*itemsInUse);
} else {
- if (m->inUse) {
+ if (m->inUse()) {
// qDebug() << "-- collecting it." << m << sweepData->tail << m->nextFree();
#ifdef V4_USE_VALGRIND
VALGRIND_ENABLE_ERROR_REPORTING;
@@ -210,11 +211,11 @@ void sweepChunk(const MemoryManager::Data::Chunk &chunk, ChunkSweepData *sweepDa
++(*itemsInUse);
}
// Relink all free blocks to rewrite references to any released chunk.
- *sweepData->tail = m;
- sweepData->tail = m->nextFreeRef();
+ sweepData->tail->setNextFree(m);
+ sweepData->tail = m;
}
}
- *sweepData->tail = 0;
+ sweepData->tail->setNextFree(0);
#ifdef V4_USE_VALGRIND
VALGRIND_ENABLE_ERROR_REPORTING;
#endif
@@ -262,14 +263,14 @@ Heap::Base *MemoryManager::allocData(std::size_t size)
return item->heapObject();
}
- Heap::Base *m = m_d->smallItems[pos];
+ Heap::Base *m = m_d->smallItems[pos].nextFree();
if (m)
goto found;
// try to free up space, otherwise allocate
if (m_d->allocCount[pos] > (m_d->availableItems[pos] >> 1) && m_d->totalAlloc > (m_d->totalItems >> 1) && !m_d->aggressiveGC) {
runGC();
- m = m_d->smallItems[pos];
+ m = m_d->smallItems[pos].nextFree();
if (m)
goto found;
}
@@ -292,15 +293,15 @@ Heap::Base *MemoryManager::allocData(std::size_t size)
char *chunk = (char *)allocation.memory.base();
char *end = chunk + allocation.memory.size() - size;
- Heap::Base **last = &m_d->smallItems[pos];
+ Heap::Base *last = &m_d->smallItems[pos];
while (chunk <= end) {
Heap::Base *o = reinterpret_cast<Heap::Base *>(chunk);
- *last = o;
- last = o->nextFreeRef();
+ last->setNextFree(o);
+ last = o;
chunk += size;
}
- *last = 0;
- m = m_d->smallItems[pos];
+ last->setNextFree(0);
+ m = m_d->smallItems[pos].nextFree();
const size_t increase = allocation.memory.size()/size - 1;
m_d->availableItems[pos] += uint(increase);
m_d->totalItems += int(increase);
@@ -317,7 +318,7 @@ Heap::Base *MemoryManager::allocData(std::size_t size)
++m_d->allocCount[pos];
++m_d->totalAlloc;
- m_d->smallItems[pos] = m->nextFree();
+ m_d->smallItems[pos].setNextFree(m->nextFree());
return m;
}
@@ -431,10 +432,11 @@ void MemoryManager::sweep(bool lastSweep)
sweepChunk(chunk, &chunkSweepData[i], &itemsInUse[chunk.chunkSize >> 4], m_d->engine);
}
- Heap::Base **tails[MemoryManager::Data::MaxItemSize/16];
- memset(m_d->smallItems, 0, sizeof(m_d->smallItems));
- for (int pos = 0; pos < MemoryManager::Data::MaxItemSize/16; ++pos)
+ Heap::Base *tails[MemoryManager::Data::MaxItemSize/16];
+ for (int pos = 0; pos < MemoryManager::Data::MaxItemSize/16; ++pos) {
+ m_d->smallItems[pos].setNextFree(0);
tails[pos] = &m_d->smallItems[pos];
+ }
#ifdef V4_USE_VALGRIND
VALGRIND_DISABLE_ERROR_REPORTING;
@@ -454,11 +456,11 @@ void MemoryManager::sweep(bool lastSweep)
chunkIter->memory.deallocate();
chunkIter = m_d->heapChunks.erase(chunkIter);
continue;
- } else if (chunkSweepData[i].head) {
+ } else if (chunkSweepData[i].head.nextFree()) {
#ifdef V4_USE_VALGRIND
VALGRIND_DISABLE_ERROR_REPORTING;
#endif
- *tails[pos] = chunkSweepData[i].head;
+ tails[pos]->setNextFree(chunkSweepData[i].head.nextFree());
#ifdef V4_USE_VALGRIND
VALGRIND_ENABLE_ERROR_REPORTING;
#endif
@@ -470,7 +472,7 @@ void MemoryManager::sweep(bool lastSweep)
#ifdef V4_USE_VALGRIND
VALGRIND_DISABLE_ERROR_REPORTING;
for (int pos = 0; pos < MemoryManager::Data::MaxItemSize/16; ++pos)
- Q_ASSERT(*tails[pos] == 0);
+ Q_ASSERT(tails[pos]->nextFree() == 0);
VALGRIND_ENABLE_ERROR_REPORTING;
#endif
@@ -478,7 +480,7 @@ void MemoryManager::sweep(bool lastSweep)
Data::LargeItem **last = &m_d->largeItems;
while (i) {
Heap::Base *m = i->heapObject();
- Q_ASSERT(m->inUse);
+ Q_ASSERT(m->inUse());
if (m->markBit) {
m->markBit = 0;
last = &i->next;
@@ -563,7 +565,7 @@ size_t MemoryManager::getUsedMem() const
for (char *chunk = chunkStart; chunk <= chunkEnd; chunk += i->chunkSize) {
Heap::Base *m = reinterpret_cast<Heap::Base *>(chunk);
Q_ASSERT((qintptr) chunk % 16 == 0);
- if (m->inUse)
+ if (m->inUse())
usedMem += i->chunkSize;
}
}
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 02a4fcf6e0..12e81d4f30 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -47,10 +47,10 @@ typedef uint Bool;
namespace Heap {
struct Q_QML_EXPORT Base {
+ Base() {}
Base(InternalClass *internal)
: internalClass(internal)
, markBit(0)
- , inUse(1)
, extensible(1)
{
// ####
@@ -59,7 +59,7 @@ struct Q_QML_EXPORT Base {
InternalClass *internalClass;
struct {
uchar markBit : 1;
- uchar inUse : 1;
+ uchar _inUse : 1;
uchar extensible : 1; // used by Object
uchar _needsActivation : 1; // used by FunctionObject
uchar _strictMode : 1; // used by FunctionObject
@@ -76,14 +76,23 @@ struct Q_QML_EXPORT Base {
inline ReturnedValue asReturnedValue() const;
inline void mark(QV4::ExecutionEngine *engine);
- Base **nextFreeRef() {
- return reinterpret_cast<Base **>(this);
+ inline bool isMarked() const {
+ return markBit;
}
+
+ enum {
+ NotInUse = 0x2,
+ PointerMask = ~0x3
+ };
+ inline bool inUse() const {
+ return !((quintptr)internalClass & NotInUse);
+ }
+
Base *nextFree() {
- return *reinterpret_cast<Base **>(this);
+ return reinterpret_cast<Base *>(reinterpret_cast<quintptr>(internalClass) & PointerMask);
}
void setNextFree(Base *m) {
- *reinterpret_cast<Base **>(this) = m;
+ internalClass = reinterpret_cast<InternalClass *>(reinterpret_cast<quintptr>(m) | NotInUse);
}
void *operator new(size_t, Managed *m) { return m; }