зеркало из https://github.com/mozilla/gecko-dev.git
Bug 780653 - Make CellIter work during incremental sweeping (r=jonco)
This commit is contained in:
Родитель
7fab12d963
Коммит
194848904e
|
@ -252,6 +252,10 @@ struct ArenaLists {
|
|||
return arenaLists[thingKind].head;
|
||||
}
|
||||
|
||||
ArenaHeader *getFirstArenaToSweep(AllocKind thingKind) const {
|
||||
return arenaListsToSweep[thingKind];
|
||||
}
|
||||
|
||||
bool arenaListsAreEmpty() const {
|
||||
for (size_t i = 0; i != FINALIZE_LIMIT; ++i) {
|
||||
/*
|
||||
|
|
|
@ -182,44 +182,61 @@ GCPoke(JSRuntime *rt, Value oldval)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke ArenaOp and CellOp on every arena and cell in a compartment which
|
||||
* have the specified thing kind.
|
||||
*/
|
||||
template <class ArenaOp, class CellOp>
|
||||
void
|
||||
ForEachArenaAndCell(JSCompartment *compartment, AllocKind thingKind,
|
||||
ArenaOp arenaOp, CellOp cellOp)
|
||||
class ArenaIter
|
||||
{
|
||||
size_t thingSize = Arena::thingSize(thingKind);
|
||||
ArenaHeader *aheader = compartment->arenas.getFirstArena(thingKind);
|
||||
ArenaHeader *aheader;
|
||||
ArenaHeader *remainingHeader;
|
||||
|
||||
for (; aheader; aheader = aheader->next) {
|
||||
Arena *arena = aheader->getArena();
|
||||
arenaOp(arena);
|
||||
FreeSpan firstSpan(aheader->getFirstFreeSpan());
|
||||
const FreeSpan *span = &firstSpan;
|
||||
public:
|
||||
ArenaIter() {
|
||||
init();
|
||||
}
|
||||
|
||||
for (uintptr_t thing = arena->thingsStart(thingKind); ; thing += thingSize) {
|
||||
JS_ASSERT(thing <= arena->thingsEnd());
|
||||
if (thing == span->first) {
|
||||
if (!span->hasNext())
|
||||
break;
|
||||
thing = span->last;
|
||||
span = span->nextSpan();
|
||||
} else {
|
||||
Cell *t = reinterpret_cast<Cell *>(thing);
|
||||
cellOp(t);
|
||||
}
|
||||
ArenaIter(JSCompartment *comp, AllocKind kind) {
|
||||
init(comp, kind);
|
||||
}
|
||||
|
||||
void init() {
|
||||
aheader = NULL;
|
||||
remainingHeader = NULL;
|
||||
}
|
||||
|
||||
void init(ArenaHeader *aheaderArg) {
|
||||
aheader = aheaderArg;
|
||||
remainingHeader = NULL;
|
||||
}
|
||||
|
||||
void init(JSCompartment *comp, AllocKind kind) {
|
||||
aheader = comp->arenas.getFirstArena(kind);
|
||||
remainingHeader = comp->arenas.getFirstArenaToSweep(kind);
|
||||
if (!aheader) {
|
||||
aheader = remainingHeader;
|
||||
remainingHeader = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool done() {
|
||||
return !aheader;
|
||||
}
|
||||
|
||||
ArenaHeader *get() {
|
||||
return aheader;
|
||||
}
|
||||
|
||||
void next() {
|
||||
aheader = aheader->next;
|
||||
if (!aheader) {
|
||||
aheader = remainingHeader;
|
||||
remainingHeader = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CellIterImpl
|
||||
{
|
||||
size_t firstThingOffset;
|
||||
size_t thingSize;
|
||||
ArenaHeader *aheader;
|
||||
ArenaIter aiter;
|
||||
FreeSpan firstSpan;
|
||||
const FreeSpan *span;
|
||||
uintptr_t thing;
|
||||
|
@ -239,15 +256,15 @@ class CellIterImpl
|
|||
}
|
||||
|
||||
void init(ArenaHeader *singleAheader) {
|
||||
aheader = singleAheader;
|
||||
initSpan(aheader->compartment, aheader->getAllocKind());
|
||||
initSpan(singleAheader->compartment, singleAheader->getAllocKind());
|
||||
aiter.init(singleAheader);
|
||||
next();
|
||||
aheader = NULL;
|
||||
aiter.init();
|
||||
}
|
||||
|
||||
void init(JSCompartment *comp, AllocKind kind) {
|
||||
initSpan(comp, kind);
|
||||
aheader = comp->arenas.getFirstArena(kind);
|
||||
aiter.init(comp, kind);
|
||||
next();
|
||||
}
|
||||
|
||||
|
@ -275,14 +292,15 @@ class CellIterImpl
|
|||
span = span->nextSpan();
|
||||
break;
|
||||
}
|
||||
if (!aheader) {
|
||||
if (aiter.done()) {
|
||||
cell = NULL;
|
||||
return;
|
||||
}
|
||||
ArenaHeader *aheader = aiter.get();
|
||||
firstSpan = aheader->getFirstFreeSpan();
|
||||
span = &firstSpan;
|
||||
thing = aheader->arenaAddress() | firstThingOffset;
|
||||
aheader = aheader->next;
|
||||
aiter.next();
|
||||
}
|
||||
cell = reinterpret_cast<Cell *>(thing);
|
||||
thing += thingSize;
|
||||
|
@ -350,6 +368,23 @@ class CellIter : public CellIterImpl
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Invoke ArenaOp and CellOp on every arena and cell in a compartment which
|
||||
* have the specified thing kind.
|
||||
*/
|
||||
template <class ArenaOp, class CellOp>
|
||||
void
|
||||
ForEachArenaAndCell(JSCompartment *compartment, AllocKind thingKind,
|
||||
ArenaOp arenaOp, CellOp cellOp)
|
||||
{
|
||||
for (ArenaIter aiter(compartment, thingKind); !aiter.done(); aiter.next()) {
|
||||
ArenaHeader *aheader = aiter.get();
|
||||
arenaOp(aheader->getArena());
|
||||
for (CellIterUnderGC iter(aheader); !iter.done(); iter.next())
|
||||
cellOp(iter.getCell());
|
||||
}
|
||||
}
|
||||
|
||||
/* Signatures for ArenaOp and CellOp above. */
|
||||
|
||||
inline void EmptyArenaOp(Arena *arena) {}
|
||||
|
|
Загрузка…
Ссылка в новой задаче