From 4e2856a22cd718186b0498d024117b72ebc02b80 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Tue, 18 Aug 2015 09:17:13 -0700 Subject: [PATCH] Bug 1194832 - Use a one element cache in the store buffer; r=jonco --HG-- extra : rebase_source : 53008889e2d5f52fbe96fcbec49251ce87db5f7e --- js/src/gc/Marking.cpp | 2 +- js/src/gc/StoreBuffer.h | 59 ++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 7f48bfda44aa..49d83ddca4c3 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -1900,7 +1900,7 @@ js::gc::StoreBuffer::MonoTypeBuffer::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); } diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h index 2b1243e065cd..d0484524d18a 100644 --- a/js/src/gc/StoreBuffer.h +++ b/js/src/gc/StoreBuffer.h @@ -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 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 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 Hasher; };