Bug 1194832 - Use a one element cache in the store buffer; r=jonco

--HG--
extra : rebase_source : 53008889e2d5f52fbe96fcbec49251ce87db5f7e
This commit is contained in:
Terrence Cole 2015-08-18 09:17:13 -07:00
Родитель fe42d2decd
Коммит 4e2856a22c
2 изменённых файлов: 32 добавлений и 29 удалений

Просмотреть файл

@ -1900,7 +1900,7 @@ js::gc::StoreBuffer::MonoTypeBuffer<T>::trace(StoreBuffer* owner, TenuringTracer
mozilla::ReentrancyGuard g(*owner);
MOZ_ASSERT(owner->isEnabled());
MOZ_ASSERT(stores_.initialized());
sinkStores(owner);
sinkStore(owner);
for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront())
r.front().trace(mover);
}

Просмотреть файл

@ -62,17 +62,15 @@ class StoreBuffer
StoreSet stores_;
/*
* A small, fixed-size buffer in front of the canonical set to simplify
* insertion via jit code.
* A one element cache in front of the canonical set to speed up
* temporary instances of RelocatablePtr.
*/
const static size_t NumBufferEntries = 4096 / sizeof(T);
T buffer_[NumBufferEntries];
T* insert_;
T last_;
/* Maximum number of entries before we request a minor GC. */
const static size_t MaxEntries = 48 * 1024 / sizeof(T);
explicit MonoTypeBuffer() { clearBuffer(); }
explicit MonoTypeBuffer() : last_(T()) {}
~MonoTypeBuffer() { stores_.finish(); }
bool init() {
@ -82,13 +80,8 @@ class StoreBuffer
return true;
}
void clearBuffer() {
JS_POISON(buffer_, JS_EMPTY_STOREBUFFER_PATTERN, NumBufferEntries * sizeof(T));
insert_ = buffer_;
}
void clear() {
clearBuffer();
last_ = T();
if (stores_.initialized())
stores_.clear();
}
@ -96,33 +89,35 @@ class StoreBuffer
/* Add one item to the buffer. */
void put(StoreBuffer* owner, const T& t) {
MOZ_ASSERT(stores_.initialized());
*insert_++ = t;
if (MOZ_UNLIKELY(insert_ == buffer_ + NumBufferEntries))
sinkStores(owner);
sinkStore(owner);
last_ = t;
}
/* Remove an item from the store buffer. */
void unput(StoreBuffer* owner, const T& v) {
// Fast, hashless remove of last put.
if (last_ == v) {
last_ = T();
return;
}
stores_.remove(v);
}
/* Move any buffered stores to the canonical store set. */
void sinkStores(StoreBuffer* owner) {
void sinkStore(StoreBuffer* owner) {
MOZ_ASSERT(stores_.initialized());
for (T* p = buffer_; p < insert_; ++p) {
if (!stores_.put(*p))
CrashAtUnhandlableOOM("Failed to allocate for MonoTypeBuffer::sinkStores.");
if (last_) {
if (!stores_.put(last_))
CrashAtUnhandlableOOM("Failed to allocate for MonoTypeBuffer::put.");
}
clearBuffer();
last_ = T();
if (MOZ_UNLIKELY(stores_.count() > MaxEntries))
owner->setAboutToOverflow();
}
/* Remove an item from the store buffer. */
void unput(StoreBuffer* owner, const T& v) {
sinkStores(owner);
stores_.remove(v);
}
bool has(StoreBuffer* owner, const T& v) {
sinkStores(owner);
sinkStore(owner);
return stores_.has(v);
}
@ -226,6 +221,8 @@ class StoreBuffer
CellPtrEdge untagged() const { return CellPtrEdge((Cell**)(uintptr_t(edge) & ~1)); }
bool isTagged() const { return bool(uintptr_t(edge) & 1); }
explicit operator bool() const { return edge != nullptr; }
typedef PointerEdgeHasher<CellPtrEdge> Hasher;
};
@ -251,6 +248,8 @@ class StoreBuffer
ValueEdge untagged() const { return ValueEdge((JS::Value*)(uintptr_t(edge) & ~1)); }
bool isTagged() const { return bool(uintptr_t(edge) & 1); }
explicit operator bool() const { return edge != nullptr; }
typedef PointerEdgeHasher<ValueEdge> Hasher;
};
@ -293,6 +292,8 @@ class StoreBuffer
void trace(TenuringTracer& mover) const;
explicit operator bool() const { return objectAndKind_ != 0; }
typedef struct {
typedef SlotsEdge Lookup;
static HashNumber hash(const Lookup& l) { return l.objectAndKind_ ^ l.start_ ^ l.count_; }
@ -319,6 +320,8 @@ class StoreBuffer
void trace(TenuringTracer& mover) const;
explicit operator bool() const { return edge != nullptr; }
typedef PointerEdgeHasher<WholeCellEdges> Hasher;
};