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); mozilla::ReentrancyGuard g(*owner);
MOZ_ASSERT(owner->isEnabled()); MOZ_ASSERT(owner->isEnabled());
MOZ_ASSERT(stores_.initialized()); MOZ_ASSERT(stores_.initialized());
sinkStores(owner); sinkStore(owner);
for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront()) for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront())
r.front().trace(mover); r.front().trace(mover);
} }

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

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