Bug 964214 - Don't recompact store buffer if there are no new entries r=terrence
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 28 Jan 2014 10:37:14 +0000
changeset 181603 34ac931fc286ec5a495cb94977c14b34d120c9de
parent 181602 3fd32a07dccac44f1144783e1d1b6e5b6f232f26
child 181604 c459007b7461a1a57708715ed858d3d766528b9f
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs964214
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 964214 - Don't recompact store buffer if there are no new entries r=terrence
js/src/gc/StoreBuffer.cpp
js/src/gc/StoreBuffer.h
--- a/js/src/gc/StoreBuffer.cpp
+++ b/js/src/gc/StoreBuffer.cpp
@@ -105,32 +105,40 @@ StoreBuffer::MonoTypeBuffer<T>::compactR
 
     duplicates.clear();
 }
 
 template <typename T>
 void
 StoreBuffer::MonoTypeBuffer<T>::compact(StoreBuffer *owner)
 {
-    if (!storage_)
-        return;
+    JS_ASSERT(storage_);
+    compactRemoveDuplicates(owner);
+    usedAtLastCompact_ = storage_->used();
+}
 
-    compactRemoveDuplicates(owner);
+template <typename T>
+void
+StoreBuffer::MonoTypeBuffer<T>::maybeCompact(StoreBuffer *owner)
+{
+    JS_ASSERT(storage_);
+    if (storage_->used() != usedAtLastCompact_)
+        compact(owner);
 }
 
 template <typename T>
 void
 StoreBuffer::MonoTypeBuffer<T>::mark(StoreBuffer *owner, JSTracer *trc)
 {
     JS_ASSERT(owner->isEnabled());
     ReentrancyGuard g(*owner);
     if (!storage_)
         return;
 
-    compact(owner);
+    maybeCompact(owner);
     for (LifoAlloc::Enum e(*storage_); !e.empty(); e.popFront<T>()) {
         T *edge = e.get<T>();
         if (edge->isNullEdge())
             continue;
         edge->mark(trc);
 
     }
 }
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -86,47 +86,52 @@ class StoreBuffer
      * This buffer holds only a single type of edge. Using this buffer is more
      * efficient than the generic buffer when many writes will be to the same
      * type of edge: e.g. Value or Cell*.
      */
     template<typename T>
     struct MonoTypeBuffer
     {
         LifoAlloc *storage_;
+        size_t usedAtLastCompact_;
 
-        explicit MonoTypeBuffer() : storage_(nullptr) {}
+        explicit MonoTypeBuffer() : storage_(nullptr), usedAtLastCompact_(0) {}
         ~MonoTypeBuffer() { js_delete(storage_); }
 
         bool init() {
             if (!storage_)
                 storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
             clear();
             return bool(storage_);
         }
 
         void clear() {
             if (!storage_)
                 return;
 
             storage_->used() ? storage_->releaseAll() : storage_->freeAll();
+            usedAtLastCompact_ = 0;
         }
 
         bool isAboutToOverflow() const {
             return !storage_->isEmpty() && storage_->availableInCurrentChunk() < MinAvailableSize;
         }
 
         /* Compaction algorithms. */
         void compactRemoveDuplicates(StoreBuffer *owner);
 
         /*
          * Attempts to reduce the usage of the buffer by removing unnecessary
          * entries.
          */
         virtual void compact(StoreBuffer *owner);
 
+        /* Compacts if any entries have been added since the last compaction. */
+        void maybeCompact(StoreBuffer *owner);
+
         /* Add one item to the buffer. */
         void put(StoreBuffer *owner, const T &t) {
             JS_ASSERT(storage_);
 
             T *tp = storage_->new_<T>(t);
             if (!tp)
                 CrashAtUnhandlableOOM("Failed to allocate for MonoTypeBuffer::put.");