зеркало из https://github.com/mozilla/gecko-dev.git
bug 600687 - proper accounting for colors during the marking phase. r=anygregor
This commit is contained in:
Родитель
89bc0fd869
Коммит
9c10d09db3
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
@ -69,7 +69,6 @@ struct Cell {
|
|||
inline ArenaBitmap *bitmap() const;
|
||||
JS_ALWAYS_INLINE size_t cellIndex() const;
|
||||
|
||||
JS_ALWAYS_INLINE void mark(uint32 color) const;
|
||||
JS_ALWAYS_INLINE bool isMarked(uint32 color) const;
|
||||
JS_ALWAYS_INLINE bool markIfUnmarked(uint32 color) const;
|
||||
|
||||
|
|
|
@ -149,41 +149,40 @@ static const uint32 BLACK = 0;
|
|||
|
||||
/* An arena bitmap contains enough mark bits for all the cells in an arena. */
|
||||
struct ArenaBitmap {
|
||||
static const size_t BitsPerWord = sizeof(uintptr_t) == 4 ? 32 : 64;
|
||||
static const size_t BitmapSize = (Arena<FreeCell>::ThingsPerArena / BitsPerWord) + 1;
|
||||
uintptr_t bitmap[BitmapSize];
|
||||
static const size_t BitCount = Arena<FreeCell>::ArenaSize / Cell::CellSize;
|
||||
static const size_t BitWords = BitCount / JS_BITS_PER_WORD;
|
||||
|
||||
JS_ALWAYS_INLINE void mark(size_t bit, uint32 color) {
|
||||
uintptr_t *word = &bitmap[bit / BitsPerWord];
|
||||
JS_ASSERT(word < &bitmap[JS_ARRAY_LENGTH(bitmap)]);
|
||||
*word |= (uintptr_t(1) << ((bit + color) % BitsPerWord));
|
||||
}
|
||||
uintptr_t bitmap[BitWords];
|
||||
|
||||
JS_ALWAYS_INLINE bool isMarked(size_t bit, uint32 color) {
|
||||
uintptr_t *word = &bitmap[bit / BitsPerWord];
|
||||
JS_ASSERT(word < &bitmap[JS_ARRAY_LENGTH(bitmap)]);
|
||||
return *word & (uintptr_t(1) << ((bit + color) % BitsPerWord));
|
||||
bit += color;
|
||||
JS_ASSERT(bit < BitCount);
|
||||
uintptr_t *word = &bitmap[bit / JS_BITS_PER_WORD];
|
||||
return *word & (uintptr_t(1) << (bit % JS_BITS_PER_WORD));
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE bool markIfUnmarked(size_t bit, uint32 color) {
|
||||
uintptr_t *word = &bitmap[bit / BitsPerWord];
|
||||
JS_ASSERT(word < &bitmap[JS_ARRAY_LENGTH(bitmap)]);
|
||||
uintptr_t mask = (uintptr_t(1) << (bit % BitsPerWord));
|
||||
JS_ASSERT(bit + color < BitCount);
|
||||
uintptr_t *word = &bitmap[bit / JS_BITS_PER_WORD];
|
||||
uintptr_t mask = (uintptr_t(1) << (bit % JS_BITS_PER_WORD));
|
||||
if (*word & mask)
|
||||
return false;
|
||||
*word |= mask;
|
||||
if (color != BLACK) {
|
||||
mask = (uintptr_t(1) << ((bit + color) % BitsPerWord));
|
||||
bit += color;
|
||||
word = &bitmap[bit / JS_BITS_PER_WORD];
|
||||
mask = (uintptr_t(1) << (bit % JS_BITS_PER_WORD));
|
||||
if (*word & mask)
|
||||
return false;
|
||||
*word |= mask;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
JS_STATIC_ASSERT(Arena<FreeCell>::ArenaSize % ArenaBitmap::BitsPerWord == 0);
|
||||
/* Ensure that bitmap covers the whole arena. */
|
||||
JS_STATIC_ASSERT(Arena<FreeCell>::ArenaSize % Cell::CellSize == 0);
|
||||
JS_STATIC_ASSERT(ArenaBitmap::BitCount % JS_BITS_PER_WORD == 0);
|
||||
|
||||
/* Marking delay is used to resume marking later when recursive marking uses too much stack. */
|
||||
struct MarkingDelay {
|
||||
|
@ -366,12 +365,6 @@ Arena<T>::bitmap() const
|
|||
return &chunk()->bitmaps[arenaIndex()];
|
||||
}
|
||||
|
||||
inline void
|
||||
Cell::mark(uint32 color = BLACK) const
|
||||
{
|
||||
bitmap()->mark(cellIndex(), color);
|
||||
}
|
||||
|
||||
static void
|
||||
AssertValidColor(const void *thing, uint32 color)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче